OpenGL坐标向世界的转换

OpenGL Coordinate Transformation Sceen to World

本文关键字:转换 世界 坐标 OpenGL      更新时间:2023-10-16

我正在编写一个使用OpenGL的MFC c++应用程序。该程序允许在三维中绘制和操纵对象。现在,我想在屏幕上单击鼠标的任何地方,在绘制对象的同一坐标空间中找到坐标。

到目前为止,我一直在使用glReadPixels和gluUnProject的组合,它一直在工作,但只有当我在已经绘制对象的地方单击鼠标时。如果我点击对象之外的任何地方,获得的坐标都会完全关闭。

所以我想知道如何更改我的代码,这样我就可以在屏幕上的任何地方找到我的对象所在的坐标空间中的坐标。这是我一直在使用的代码:

GLint viewport[4];
GLdouble ox, oy, oz;//the coordinates I need
GLfloat winZ = 0.0;
::glGetIntegerv(GL_VIEWPORT, viewport);
::glGetDoublev(GL_PROJECTION_MATRIX,    projectionMatrix);
::glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix);
GLfloat winX = (float)point.x;//point.x and point.y are the mouse coordinates
GLfloat winY = (float)viewport[3] - (float)point.y;
::glReadPixels( winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject((GLdouble)winX, (GLdouble)winY, (GLdouble)winZ, modelviewMatrix, projectionMatrix, viewport, &ox, &oy, &oz);

gluUnProject获取窗口空间坐标,并使用世界视图投影视口变换的逆变换来取消投影。它不知道坐标是否对应于现有对象。

当您清除深度缓冲区时,它在所有位置都会初始化,其值使用glReadPixels读取为1.0。

当绘制对象的可见片段时,它们将通过深度测试,并将用与这些片段相交的每个像素的较小值覆盖深度值。

这意味着,每次读取深度缓冲区中值为1.0的像素时,这意味着在该像素中没有绘制任何可见的内容,而这正是您获得的结果完全关闭的地方。