How to read value from texture

I created a framebuffer object and bound a texture object to the depth component of it. Then I draw the whole scene. Now, I want to read the depth value of the scene, but I do not know how.

I cannot use glReadPixel because it seems that the scene has been directly rendered to the texture, so I can get nothing from the framebuffer.

Is there any method in OpenGL to read texel to memory?

OK, I will render the scene twice, first to the texture, and then to the default framebuffer. And use glReadPixel to get the depth value from depth buffer after the second time of rendering.

Why? Can’t u use the FBO’s depth attachment directly?

Maybe because a texture has been attached to the depth buffer, I tried the following code:


glReadPixels(0, 0, TEX_WIDTH, TEX_HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, myArray);

and find nothing in myArray.

If the fbo has a depth attachment and the fbo is bound, the depths will be written to it.

Could u post the code of how you are setting up the fbo? and the display function ?

I setup the fbo like:


glGenFramebuffers(1, &depthFbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, depthFbo);

glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
	
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
	
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
	
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

and then in the display function (I am using the GLTools library introduced in the OpenGL superbible):


glBindFramebuffer(GL_DRAW_FRAMEBUFFER, depthFbo);
	
GLint viewPort[4];
glGetIntegerv(GL_VIEWPORT, viewPort);
glViewport(0, 0, TEX_WIDTH, TEX_HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

M3DMatrix44f lightCameraMatrix;
lightFrame.GetCameraMatrix(lightCameraMatrix, false);
lightModelViewMatrix.PushMatrix(lightCameraMatrix);

lightModelViewMatrix.MultMatrix(modelMat);

shaderManager.UseStockShader(GLT_SHADER_FLAT, lightTransformPipeline.GetModelViewProjectionMatrix(), vBlue);
DrawHairModel(myHairModel, dirs);

glReadPixels(0, 0, TEX_WIDTH, TEX_HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, myArray);

lightModelViewMatrix.PopMatrix();

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

You may only need to pay attention to the following statements:
[b]
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, depthFbo);

//use a pre-defined shader
shaderManager.UseStockShader(GLT_SHADER_FLAT, lightTransformPipeline.GetModelViewProjectionMatrix(), vBlue);

//draw the hair geometry
DrawHairModel(myHairModel, dirs);

glReadPixels(0, 0, TEX_WIDTH, TEX_HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, myArray);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
[/b]

If you are only binding GL_DRAW_FRAMEBUFFER, then you also need to bind the READ_FRAMEBUFFER to determine where glReadPixels should read from. If you want to bind both the draw + read framebuffer targets at the same time, use:

glBindFramebuffer(GL_FRAMEBUFFER, depthFbo);

Sorry, it does not work on my computer.

Personally, according to the OpenGL spec, glReadBuffer only specifies a color buffer for glReadPixels, so binding the READ_FRAMEBUFFER may not affect the depth buffer.