gluUnProject正在工作,然后停止工作

时间:2014-04-11 00:57:11

标签: opengl glut freeglut

当我使用从opengl nvidia示例下载的过剩时,此功能正常工作

void gl_select(int x, int y)
{
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;

    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
    glGetDoublev(GL_PROJECTION_MATRIX, projection);
    glGetIntegerv(GL_VIEWPORT, viewport);

    winX = (float)x;
    winY = (float)viewport[3] - (float)y;
    glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

    gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);


    printf("%f %f %f\n", posX, posZ, posY);

    glutPostRedisplay();
}

然后我转向免费过剩,现在它不起作用,有人可以告诉我为什么吗?

1 个答案:

答案 0 :(得分:0)

好的,我想我可以猜出你的问题:你可能从输入事件处理程序调用{​​{1}}。现在就是这样:当您从主帧缓冲区读取像素时,您实际上可能永远不会得到任何合理的值。为什么?因为操作系统可能决定"呃,那部分无论如何都是不可见的,所以为什么还要加工它" (这称为像素所有权测试)。此外,主帧缓冲的内容可能随时丢失(损坏事件)。

好吧,然后gl_select从选择阅读的帧缓冲区中读取。如果这是后台缓冲区,并且在缓冲区交换后访问它,则内容也是未定义的(对于颜色)。帧缓冲区的深度组件也会被交换破坏。

所以,如果glReadPixels如此不可靠,您可能会想,如何使用它?它不是glReadPixels不可靠,它只是窗口缓冲区的易变性。所以你不应该使用它。相反,如果要进行像素空间深度选择,则应首先渲染到FBO,然后将其复制到主窗口帧缓冲区。声称FBO的内容不会丢失。因此,您可以随时阅读FBO,确保获得您所要求的内容。

此外,当你致电glReadPixels时,你不应该依赖于矩阵堆栈中的内容。相反,您应该在显示代码中制作投影和模型视图矩阵的快照副本,其状态代表它们应用于选择的转换。

相关问题