How to read a pixel from a Depth Texture efficiently?

opengl

Solution

The answer is contained in your error message:

if GL_READ_BUFFER is not GL_NONE

So do that; set the read buffer to `GL_NONE`. With `glReadBuffer`. Like this:

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); //where fbo is your FBO.
glReadBuffer(GL_NONE);

That way, the FBO is properly complete, even though it only has a depth texture.

Problem

I have an OpenGL Texture and want to be able to read back a single pixel's value, so I can display it on the screen. If the texture is a regular old RGB texture or the like, this is no problem: I take an empty Framebuffer Object that I have lying around, attach the texture to COLOR0 on the framebuffer and call: ``` glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, &c); ``` Where c is essentially a float[4]. However, when it is a depth texture, I have to go down a different code path, setting the DEPTH attachment instead of the COLOR0, and calling: ``` glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &c); ``` where c is a float. This works fine on my Windows 7 computer running NVIDIA GeForce 580, but causes an error on my old 2008 MacBook pro. Specifically, after attaching the depth texture to the framebuffer, if I call glCheckFrameBufferStatus(GL_READ_BUFFER), I get GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER. After searching the OpenGL documentation, I found this line, which seems to imply that OpenGL does not support reading from a depth component of a framebuffer if there is no color attachment: ``` GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER is returned if GL_READ_BUFFER is not GL_NONE and the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color attachment point named by GL_READ_BUFFER. ``` Sure enough, if I create a temporary color texture and bind it to COLOR0, no errors occur when I readPixels from the depth texture. Now creating a temporary texture every time (EDIT: or even once and having GPU memory tied up by it) through this code is annoying and potentially slow, so I was wondering if anyone knew of an alternative way to read a single pixel from a depth texture? (Of course if there is no better way I will keep around one texture to resize when needed and use only that for the temporary color attachment, but this seems rather roundabout).

Original source