Ky David
Ky David

Reputation: 11

Read the depth buffer of OpenGL ES on Android

I am trying to read the depth buffer in OpenGL ES on Android, but all the values are zero. Can someone explain why is that.

    public void onSurfaceChanged(GL10 unused, int width, int height) {
    // Adjust the viewport based on geometry changes,
    // such as screen rotation
    GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    GLES20.glClearDepthf(1.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    GLES20.glDepthMask( false );

    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;

    // this projection matrix is applied to object coordinates
    // in the onDrawFrame() method
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 4, 9);
}

Read the depth buffer:

        FloatBuffer buffer = FloatBuffer.allocate(720*945);
    GLES20.glReadPixels(0, 0, 720, 945, GLES20.GL_DEPTH_COMPONENT, GLES20.GL_FLOAT, buffer);
    float[] depth = buffer.array();
    for (int i = 0; i < 720*945; i++){
            Log.i("Depth", ""+depth[i]);
    }

The model has been draw on screen: ScreenShot

EDIT

I was moved my project to ES 3.0. I create a FrameBuffer, color and depth texture and then attach.I get error GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

 GLES30.glEnable(GLES30.GL_TEXTURE_2D);

    GLES30.glGenTextures(1, colorTex, 0);
    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, colorTex[0]);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
    GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA, fboWidth, fboHeight, 0, GLES30.GL_RGBA, GLES30.GL_FLOAT, null);

    GLES30.glGenTextures(1, depthTex, 0);
    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, depthTex[0]);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
    GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_DEPTH_COMPONENT24, fboWidth, fboHeight, 0, GLES30.GL_DEPTH_COMPONENT, GLES30.GL_FLOAT, null);


    GLES30.glGenFramebuffers(1, fb, 0);
    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fb[0]);

    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, colorTex[0], 0);

    checkStatus("Color Test");

    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_ATTACHMENT, GLES30.GL_TEXTURE_2D, depthTex[0], 0);

    checkStatus("Depth Test");

}

Q1: How can I resolve above error?

Q2: How to check the depth value in depth texture

Upvotes: 1

Views: 2218

Answers (1)

Reto Koradi
Reto Koradi

Reputation: 54642

OpenGL ES does not support glReadPixels() on the depth buffer. If you call glGetError() after your glReadPixels() call, you should see a GL_INVALID_OPERATION returned.

I only found a vendor specific extension for this functionality: NV_read_depth_stencil. The functionality is still not standard in the latest ES spec (3.2).

Other than this extension, I can't think of any way for reading back depth values in ES 2.0.

In ES 3.0 and later, there is at least an indirect way. These versions support depth textures. Using this, you can get the depth using the following steps.

  1. Render the scene to an FBO, using a texture as the depth attachment.
  2. Render a screen sized quad with a shader that samples the depth texture generated in the previous step, and writes the value to the color buffer.
  3. Use glReadPixels() on the color buffer.

Upvotes: 4

Related Questions