Author Topic: Blit camera preview to framebuffer using SurfaceTexture, ExternalTexture  (Read 586 times)

Offline roytornado

  • byte
  • *
  • Posts: 3
    • View Profile
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:
Code: [Select]
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();

Code: [Select]
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?



Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11777
    • View Profile
    • http://www.jpct.net
Re: Blit camera preview to framebuffer using SurfaceTexture, ExternalTexture
« Reply #1 on: February 15, 2017, 10:22:15 am »
I don't think that it's related, but why are you doing this twice;

Code: [Select]
    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());

?

Offline roytornado

  • byte
  • *
  • Posts: 3
    • View Profile
Re: Blit camera preview to framebuffer using SurfaceTexture, ExternalTexture
« Reply #2 on: February 15, 2017, 10:48:16 am »
not related. just copy and paste issue from the sources.

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

Code: [Select]
    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
    mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());

?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11777
    • View Profile
    • http://www.jpct.net
Re: Blit camera preview to framebuffer using SurfaceTexture, ExternalTexture
« Reply #3 on: February 15, 2017, 11:17:36 am »
Can you post the code that actually creates the external texture as well?

Offline roytornado

  • byte
  • *
  • Posts: 3
    • View Profile
Re: Blit camera preview to framebuffer using SurfaceTexture, ExternalTexture
« Reply #4 on: February 16, 2017, 03:06:21 am »
I am using this:

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

Code: [Select]
  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");
  }

Can you post the code that actually creates the external texture as well?
« Last Edit: February 16, 2017, 07:49:55 am by roytornado »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11777
    • View Profile
    • http://www.jpct.net
Re: Blit camera preview to framebuffer using SurfaceTexture, ExternalTexture
« Reply #5 on: February 16, 2017, 09:16:19 am »
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.