Blit camera preview to framebuffer using SurfaceTexture, ExternalTexture

Started by roytornado, February 15, 2017, 09:41:43 AM

Previous topic - Next topic

roytornado

I would like to display my camera preview to the screen and put 3d models on top of it.
I view all related post at this forum and still can't display it correctly. (only white color is blit to the buffer)

Background:
GL Version: 2.0
Screen size for GLSurfaceView: 1080X1080
Camera preview size: 736X736

Step:

onSurfaceChanged:
    TextureManager.getInstance().flush();
    mExternalTexture = new Texture(32, 32);
    mTextureRender.surfaceCreated();
    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
    mSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
      @Override
      public void onFrameAvailable(SurfaceTexture surfaceTexture) {
        synchronized(CameraManager.this) {
          frameAvailable = true;
        }
      }
    });
    mExternalTexture.setExternalId(mTextureRender.getTextureId(), GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
    TextureManager.getInstance().addTexture("camera_texture", mExternalTexture);
    mCamera = Camera.open();
    mCamera.setPreviewTexture(mSurfaceTexture);
    mCamera.startPreview();



onDrawFrame:
    frameBuffer.clear();
    synchronized(cameraManager) {
      if (cameraManager.frameAvailable) {
        frameBuffer.blit(cameraManager.mExternalTexture, 0, 0, 0, 0, 100, 100, false);
        mSurfaceTexture.updateTexImage();
      }
    }
    world.renderScene(frameBuffer);
    world.draw(frameBuffer);
    frameBuffer.display();


Any suggestion for me?



EgonOlsen

I don't think that it's related, but why are you doing this twice;


    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());


?

roytornado

not related. just copy and paste issue from the sources.

Quote from: EgonOlsen on February 15, 2017, 10:22:15 AM
I don't think that it's related, but why are you doing this twice;


    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());


?

EgonOlsen

Can you post the code that actually creates the external texture as well?

roytornado

I am using this:

https://android.googlesource.com/platform/cts/+/master/tests/tests/media/src/android/media/cts/TextureRender.java


  public void surfaceCreated() {
    mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
    if (mProgram == 0) {
      throw new RuntimeException("failed creating program");
    }
    maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
    checkGlError("glGetAttribLocation aPosition");
    if (maPositionHandle == -1) {
      throw new RuntimeException("Could not get attrib location for aPosition");
    }
    maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
    checkGlError("glGetAttribLocation aTextureCoord");
    if (maTextureHandle == -1) {
      throw new RuntimeException("Could not get attrib location for aTextureCoord");
    }
    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    checkGlError("glGetUniformLocation uMVPMatrix");
    if (muMVPMatrixHandle == -1) {
      throw new RuntimeException("Could not get attrib location for uMVPMatrix");
    }
    muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
    checkGlError("glGetUniformLocation uSTMatrix");
    if (muSTMatrixHandle == -1) {
      throw new RuntimeException("Could not get attrib location for uSTMatrix");
    }
    int[] textures = new int[1];
    GLES20.glGenTextures(1, textures, 0);
    mTextureID = textures[0];
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
    checkGlError("glBindTexture mTextureID");
    GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
        GLES20.GL_NEAREST);
    GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
        GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
        GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
        GLES20.GL_CLAMP_TO_EDGE);
    checkGlError("glTexParameter");
  }


Quote from: EgonOlsen on February 15, 2017, 11:17:36 AM
Can you post the code that actually creates the external texture as well?

EgonOlsen

That looks fine at first glance....can you post a screen shot. Your blit-call should actually update the upper left 100x100 pixel region only. I would like to visually verify if that's the case or not.