问题
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
回答1:
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.
- Render the scene to an FBO, using a texture as the depth attachment.
- 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.
- Use
glReadPixels()
on the color buffer.
来源:https://stackoverflow.com/questions/35040060/read-the-depth-buffer-of-opengl-es-on-android