无法从附加到FBO的深度纹理中读取深度值

时间:2013-11-10 15:29:27

标签: opengl textures depth fbo glreadpixels

我无法使用glreadpixels函数从深度纹理中读取正确的深度值。 FBO状态已完成。在对另一个FBO进行blitting之后,其他渲染目标看起来也很好。

代码段:

    // 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);

1 个答案:

答案 0 :(得分:1)

您正在绘制深度纹理。调用将纹理读入客户端内存的适当函数是glGetTexImage (...)

现在,由于没有glGetTexSubImage (...),您需要分配足够的客户端存储来保存深度纹理的整个 LOD。像这样的东西可能会成功:

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);

请注意,与glReadPixels (...)不同,glGetTexImage (...)不执行像素传输转换。也就是说,您的格式和数据类型必须与创建纹理时使用的类型完全匹配,GL不会转换您的数据。


有了这个,我可以问一下你为什么要首先将深度缓冲区读入客户端内存?您似乎正在使用延迟着色,因此我可以看到为什么需要深度纹理,但不太清楚为什么需要在着色器外部使用深度缓冲区的副本。如果每帧复制深度缓冲区,则很难实现交互式帧速率。