Problems trying to visualize the depth buffer.

I’m trying to render the depth buffer to the main screen by copying it to a texture, but all I’m getting is a black texture as a result; I tried commenting out my render calls so that it goes directly from clearing the buffers to drawing the depth buffer (clear color is set to blue so i know it’s rendering the polygons the depth texture should be attached to), so that it should be a white screen it if works, but I got no results.

This is my code:


glReadBuffer(GL_BACK);

if(s_depthTexture)
{
    glBindTexture(GL_TEXTURE_2D, s_depthTexture);
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1024, 1024);
}
else
{
    glGenTextures(1, &s_depthTexture);
    glBindTexture(GL_TEXTURE_2D, s_depthTexture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    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_MAX_LEVEL, 0);

//doesn't seem to help matters...
//  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);
}
//polygon rendering 

Vertex shader:


#version 130
uniform mat4 u_projection;
uniform mat4 u_modelview;

in vec2  v_position;
out vec2 f_uv;

void main()
{
    vec4 pos      = u_modelview * vec4(v_position, 0, 1.0);
    gl_Position   = u_projection * pos;
    f_uv          = (v_position + vec2(1, 1)) * .5;
}

Fragment shader:


#version 130
uniform sampler2D u_depthBuffer;
uniform float u_zNear;
uniform float u_zFar;

in vec2 f_uv;
out vec4 fragColor;

void main()
{
    float depth = texture2D(u_depthBuffer, f_uv).x;
//  depth = (2.0 * u_zNear) / (u_zFar + u_zNear - depth * (u_zFar - u_zNear));
     fragColor = vec4(depth, depth, depth, 1);
//    fragColor = vec4(f_uv, 0, 1);  /* UVs do seem to render correctly */
}

What am i doing wrong?

[QUOTE=GeatMaster;1288700]I’m trying to render the depth buffer to the main screen by copying it to a texture, but all I’m getting is a black texture as a result; I tried commenting out my render calls so that it goes directly from clearing the buffers to drawing the depth buffer (clear color is set to blue so i know it’s rendering the polygons the depth texture should be attached to), so that it should be a white screen it if works, but I got no results.

What am i doing wrong?[/QUOTE]

Recommendation: Take the shaders completely out-of-the-loop and do what you’re saying: clear the depth buffer, and then try to get reasonable depth values back. I’d start with glReadPixels(), pulling a depth value back to the GPU. Then try different glClearDepth() values. Then try switching it up and reading the depth values on the GPU from a depth texture.

Question: Why are you trying to copy from a depth buffer in some framebuffer (e.g. the system/default framebuffer) into a depth texture? Why not just render into the depth texture directly via FBO? Then you’ve already got the depth values in a depth texture from the start and there’s no need to copy them around.

Also, are you Checking for GL Errors?

Finally:

#version 130
uniform sampler2D u_depthBuffer;

void main()
{
float depth = texture2D(u_depthBuffer, f_uv).x;
depth = (2.0 * u_zNear) / (u_zFar + u_zNear - depth * (u_zFar - u_zNear));

It looks like you’ve found the Geeks3D formula. I never got that to work. You may want to take a look at this thread and this one.

For a perspective projection, what I think you want is:


eye_z = near * far / ((depth * (far - near)) - far);

That’ll get you eye-space Z. If you then want to map that linearly to a 0…1 value, use:


val = ( eye_z - (-near) ) / ( -far - (-near) )


//doesn't seem to help matters...
//  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);

Just like every other texture, you need to use glTexImage2D to generate the actual depth texture before using it. Thinking “doesn’t seem to help” and commenting that part out won’t help, since the problem is likely somewhere else.

[QUOTE=vampcat;1288710]


//doesn't seem to help matters...
//  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);

Just like every other texture, you need to use glTexImage2D to generate the actual depth texture before using it. Thinking “doesn’t seem to help” and commenting that part out won’t help, since the problem is likely somewhere else.[/QUOTE]

No, this is like glTexImage2D vs. glTexSubImage2D:

[ul]
[li]glTexImage2D - Allocate texture storage, and then load texels into that storage [/li][li]glTexSubImage2D - Load texels into the already-existing storage [/li][/ul]
Note the similarity:

[ul]
[li]glCopyTexImage2D - Allocate texture storage, and then copy texels into that storage [/li][li]glCopyTexSubImage2D - Copy texels into the already-existing storage [/li][/ul]
TexImage = Allocate first and then “do something”. TexSubImage = Just “do something”.

glTexStorage2D is the more modern way to allocate storage. In this case, you’d then follow that up with a glCopyTexSubImage2D because you’ve already allocated the texture storage.

Actually, the OP has commented out glTexImage2D, and my entire comment was revolved around asking him not to comment that out, since that is what allocates the texture storage.

Admittedly I should have removed the line immediately after it to avoid confusion.

you are using a depth texture, so tell us how you’ve set up your framebuffer object. if you get a black texture, it means that you get lots of 0s.

are you checking for GL errors ?
https://www.khronos.org/opengl/wiki/OpenGL_Error

are you checking for framebuffer completeness ?
https://www.khronos.org/opengl/wiki/Framebuffer_Object#Framebuffer_Completeness

are you checking for shader compilation / program linking errors ?
https://www.khronos.org/opengl/wiki/Shader_Compilation#Example

you can check if your depth texture is correctly attached by using:
https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetFramebufferAttachmentParameter.xhtml

once you are sure that your FBO is OK, try to clear your depth texture using a certain clear depth value:


/* bind framebuffer */
glBindFramebuffer(GL_FRAMEBUFFER, myFBO);
glViewPort(0, 0, myFBO_width, myFBO_height);

/* clear depth attachment */
GLfloat cleardepth[] = { 0.123f };
glClearBufferfv(GL_DEPTH, 0, cleardepth);

/* test depth value */
GLfloat testvalue = 0.0f;
glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &testvalue);

cout << "testvalue: " << testvalue  << endl;

then render your stuff into that FBO, enable depth testing

So does the glCopyTexImage2D immediately following it, which renders the glTexImage2D redundant.