3

I am unable to read correct depth values from depth texture using glreadpixels function. FBO status is complete. other render targets also look fine after blitting to another FBO.

code snippet:

    // Create the FBO
    glGenFramebuffers(1, &m_fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);

    // Create the gbuffer textures
    glGenTextures(GBUFFER_NUM_TEXTURES, m_textures);
    glGenTextures(1, &m_depthTexture);

    for (unsigned int i = 0 ; i < GBUFFER_NUM_TEXTURES ; i++) {
        glBindTexture(GL_TEXTURE_2D, m_textures[i]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, fboWidth, fboHeight, 0, GL_RGBA, GL_FLOAT, NULL);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
    }

    // depth
    glBindTexture(GL_TEXTURE_2D, m_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_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, fboWidth, fboHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
                 NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);

    GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
    glDrawBuffers(GBUFFER_NUM_TEXTURES, DrawBuffers);

    GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if (Status != GL_FRAMEBUFFER_COMPLETE) {
        printf("FB error, status: 0x%x\n", Status);
        return 0;
    }


   // drawing something with depth test enabled.
   // Now i am using glreadpixels functions to read depth values from depth texture.

    int w = 4, h = 1;
   GLfloat windowDepth[4];
   glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
   glReadPixels(x, y, w, h, GL_DEPTH_COMPONENT, GL_FLOAT, windowDepth);
user942502
  • 111
  • 1
  • 7

1 Answers1

1

You are drawing to a depth texture. The appropriate function to call to read a texture into client memory is glGetTexImage (...).

Now, since there is no glGetTexSubImage (...), you need to allocate enough client storage to hold an entire LOD of the depth texture. Something like this will probably do the trick:

GLuint w = fboWidth, h = fboHeight;
GLfloat windowDepth [w * h];

glBindTexture (GL_TEXTURE_2D, m_depthTexture);
glGetTexImage (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, windowDepth);

Keep in mind that unlike glReadPixels (...), glGetTexImage (...) does not perform pixel transfer conversion. That is, your format and data type must be an exact match with the types used when the texture was created, the GL will not convert your data.


With that out of the way, can I ask why you are reading the depth buffer into client memory in the first place? You appear to be using deferred shading, so I can see why you need a depth texture, but it is less clear why you need a copy of the depth buffer outside of shaders. You will have a hard time achieving interactive frame rates if you copy the depth buffer each frame.

Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • Thank you very much for your answer. I am not trying to copy complete z buffer in client memory but i query the depth of one pixel where my mouse or finger is. Here i have another question. I am doing this for both orthographic and perspective projections. The result what i get from getteximage2d is window depth if i am correct. I have seen in some blog that i have to linearize the depth in perspective projection. Should i linearize the window depth or something else? And what else i would need to to convert this window depth to eye space z. Please help. – user942502 Nov 11 '13 at 05:32