当我使用从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();
}
然后我转向免费过剩,现在它不起作用,有人可以告诉我为什么吗?
答案 0 :(得分:0)
好的,我想我可以猜出你的问题:你可能从输入事件处理程序调用{{1}}。现在就是这样:当您从主帧缓冲区读取像素时,您实际上可能永远不会得到任何合理的值。为什么?因为操作系统可能决定"呃,那部分无论如何都是不可见的,所以为什么还要加工它" (这称为像素所有权测试)。此外,主帧缓冲的内容可能随时丢失(损坏事件)。
好吧,然后gl_select
从选择阅读的帧缓冲区中读取。如果这是后台缓冲区,并且在缓冲区交换后访问它,则内容也是未定义的(对于颜色)。帧缓冲区的深度组件也会被交换破坏。
所以,如果glReadPixels
如此不可靠,您可能会想,如何使用它?它不是glReadPixels
不可靠,它只是窗口缓冲区的易变性。所以你不应该使用它。相反,如果要进行像素空间深度选择,则应首先渲染到FBO,然后将其复制到主窗口帧缓冲区。声称FBO的内容不会丢失。因此,您可以随时阅读FBO,确保获得您所要求的内容。
此外,当你致电glReadPixels
时,你不应该依赖于矩阵堆栈中的内容。相反,您应该在显示代码中制作投影和模型视图矩阵的快照副本,其状态代表它们应用于选择的转换。