2

I'm trying to get depth value from depth buffer with glReadPixels function. It always return 0 to me.

first of all, I create depth buffer attachment:

glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[self.context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

if (USE_DEPTH_BUFFER)
{
    glGenRenderbuffersOES(1, &depthRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
}

then I call glReadPixels function to get the depth value from depth buffer:

float depth = 0.0f;

glReadPixels(point.x, self.renderUIView.frame.size.height - point.y, 1, 1, GL_DEPTH_COMPONENT16_OES, GL_FLOAT, &depth);

but it doesn't work, the depth value always is 0. I try to get error code from glGetError(), It return 1280. Is anything I missed to setup?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Tony Teng
  • 105
  • 8

1 Answers1

0

What you are trying isn't supported in OpenGL ES (any API version) - there is no means to use glReadPixels on depth buffers.

Also in general note that using glReadPixels for any real 3D game as part of your main rendering loop is a "really bad idea" - it forces a pipeline flush which will totally kill your performance.

solidpixel
  • 10,688
  • 1
  • 20
  • 33
  • thanks for your answering. BTW, how can I get depth buffer value in OpenGL ES 1.0? – Tony Teng Jan 03 '17 at 07:43
  • With OpenGL ES 1.0 you are out of luck - there isn't a means to do what you want. – solidpixel Jan 03 '17 at 07:47
  • With OpenGL ES 2.0 onwards, if you are rendering off-screen to an FBO then you can read the depth value as a texture in a second render pass, and e.g. use a fragment shader to encode it into a RGBA color buffer which you can call `glReadPixels` on (albeit, it will still kill your performance). If you are rendering to the main window surface, not to an offscreen surface, then you are out of luck as there is no means to map a window surface depth buffer as a texture. – solidpixel Jan 03 '17 at 07:48
  • What are you actually trying to do? I sounds like there might be a better way of doing it than what you are trying ... – solidpixel Jan 03 '17 at 07:49
  • Thanks for your answering, bro. I'm a starter on OpenGL ES. First of all, our product works on the Windows platform. and now we will move it to the iOS. On the desktop, I can left click the window and get the GDI point, than I can call `glReadPixels` with GL_DEPTH_COMPONENT to get the depth value. with the depth value, I can decide which model I selected. – Tony Teng Jan 03 '17 at 08:18
  • With the same operation, I can tap the screen with UIPanGestureRecognizer on the iOS device, I can get the point. I want to know which model will be selected. So, I want to get depth value. Any good way I can do for solving this problem? Anyway, my boss ask me to only use OpenGL ES 1.0 – Tony Teng Jan 03 '17 at 08:23
  • In general you don't want to use the rendered output to solve what was clicked on; the usual approaches are implemented entirely in software on the CPU (e.g. project your simplified collision boxes for each object into world space on the CPU, ray march in software to determine hits). – solidpixel Jan 03 '17 at 08:39
  • thanks, I will try it use your method. – Tony Teng Jan 03 '17 at 08:45