glReadPixels获得的深度缓冲区始终为1

Phi*_*ang 5 opengl opengl-3

我正在使用glReadPixels来获取选择像素的深度值,但是我总是得到1,我该如何解决呢?这是代码:

    glEnable(GL_DEPTH_TEST);
    ..
    glReadPixels(x, viewport[3] - y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, z);
Run Code Online (Sandbox Code Playgroud)

我想念什么吗?我的渲染部分如下所示。我使用不同的着色器绘制场景的不同部分,因此如何正确地从缓冲区读取深度值?

void onDisplay(void)
{
// Clear the window and the depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// calculate the view matrix.
GLFrame eyeFrame;
eyeFrame.MoveUp(gb_eye_height);
eyeFrame.RotateWorld(gb_eye_theta * 3.1415926 / 180.0, 1.0, 0.0, 0.0);
eyeFrame.RotateWorld(gb_eye_phi * 3.1415926 / 180.0, 0.0, 1.0, 0.0);
eyeFrame.MoveForward(-gb_eye_radius);
eyeFrame.GetCameraMatrix(gb_hit_modelview);
gb_modelViewMatrix.PushMatrix(gb_hit_modelview);

// draw coordinate system
if(gb_bCoord)
{
    DrawCoordinateAxis();
}

if(gb_bTexture)
{

    GLfloat vEyeLight[] = { -100.0f, 100.0f, 150.0f };
    GLfloat vAmbientColor[] = { 0.2f, 0.2f, 0.2f, 1.0f };
    GLfloat vDiffuseColor[] = { 1.0f, 1.0f, 1.0f, 1.0f};

    glUseProgram(normalMapShader);
    glUniform4fv(locAmbient, 1, vAmbientColor);
    glUniform4fv(locDiffuse, 1, vDiffuseColor);
    glUniform3fv(locLight, 1, vEyeLight);
    glUniform1i(locColorMap, 0);
    glUniform1i(locNormalMap, 1);
    gb_treeskl.Display(SetGeneralColor, SetSelectedColor, 0);
}
else
{
    if(!gb_bOnlyVoxel)
    {
        if(gb_bPoints)
        {
            //GLfloat vPointColor[] = { 1.0, 1.0, 0.0, 0.6 };
            GLfloat vPointColor[] = { 0.2, 0.0, 0.0, 0.9 };
            gb_shaderManager.UseStockShader(GLT_SHADER_FLAT, gb_transformPipeline.GetModelViewProjectionMatrix(), vPointColor);
            gb_treeskl.Display(NULL, NULL, 1);
        }
        if(gb_bSkeleton)
        {
            GLfloat vEyeLight[] = { -100.0f, 100.0f, 150.0f };
            glUseProgram(adsPhongShader);
            glUniform3fv(locLight, 1, vEyeLight);
            gb_treeskl.Display(SetGeneralColor, SetSelectedColor, 0);
        }
    }
    if(gb_bVoxel)
    {
        GLfloat vEyeLight[] = { -100.0f, 100.0f, 150.0f };
        glUseProgram(adsPhongShader);
        glUniform3fv(locLight, 1, vEyeLight);
        SetVoxelColor();
        glPolygonMode(GL_FRONT, GL_LINE);
        glLineWidth(1.0f);
        gb_treeskl.DisplayVoxel();
        glPolygonMode(GL_FRONT, GL_FILL);
    }
}
//glUniformMatrix4fv(locMVP, 1, GL_FALSE, gb_transformPipeline.GetModelViewProjectionMatrix());
//glUniformMatrix4fv(locMV, 1, GL_FALSE, gb_transformPipeline.GetModelViewMatrix());
//glUniformMatrix3fv(locNM, 1, GL_FALSE, gb_transformPipeline.GetNormalMatrix());
//gb_sphereBatch.Draw();
gb_modelViewMatrix.PopMatrix();

glutSwapBuffers();
Run Code Online (Sandbox Code Playgroud)

}

dat*_*olf 2

好吧,您错过了代码中真正相关的部分。此外,深度测试单元的状态对 glReadPixels 提供的内容没有影响。您也发布您的渲染代码怎么样?

更新

缓冲区交换后,SwapBuffers后台缓冲区的内容未定义,帧缓冲区读取的默认状态是从后台缓冲区读取。从技术上讲,双缓冲仅发生在颜色组件上,而不发生在深度和模板组件上。但您可能会遇到驱动程序问题。

我建议进行两项测试来排除这些情况:

  • SwapBuffersglReadBuffer(GL_BACK);之前读取深度缓冲区。

  • glReadBuffer(GL_FRONT);选择用于在 SwapBuffers 之后读取的前缓冲区

另请指定当此问题发生时您在哪个上下文(程序,而不是 OpenGL,以及后来的程序)中执行了 glReadPixels。还要检查您是否可以正确读取颜色值。