我有这个视图集:
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
我通过鼠标点击获得屏幕位置(sx,sy)。
给定 z 值,我如何从 sx 和 sy 计算 3d 空间中的 x 和 y?
你应该使用gluUnProject
:
首先,计算到近平面的“非投影”:
GLdouble modelMatrix[16];
GLdouble projMatrix[16];
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
GLdouble x, y, z;
gluUnProject(sx, viewport[1] + viewport[3] - sy, 0, modelMatrix, projMatrix, viewport, &x, &y, &z);
然后到远平面:
// replace the above gluUnProject call with
gluUnProject(sx, viewport[1] + viewport[3] - sy, 1, modelMatrix, projMatrix, viewport, &x, &y, &z);
现在,您在世界坐标中得到了一条线,可以追踪您可能点击过的所有可能点。所以现在你只需要插值:假设你得到了 z 坐标:
GLfloat nearv[3], farv[3]; // already computed as above
if(nearv[2] == farv[2]) // this means we have no solutions
return;
GLfloat t = (nearv[2] - z) / (nearv[2] - farv[2]);
// so here are the desired (x, y) coordinates
GLfloat x = nearv[0] + (farv[0] - nearv[0]) * t,
y = nearv[1] + (farv[1] - nearv[1]) * t;
最权威的来源OpenGL 的网站最好地回答了这个问题。
这实际上取决于投影矩阵,而不是模型视图矩阵。 http://www.toymaker.info/Games/html/picking.html应该可以帮助您——它以 D3D 为中心,但理论是一样的。
但是,如果您要进行基于鼠标的选择,我建议您使用选择渲染模式。
编辑:请注意,模型视图矩阵确实起作用,但是由于您的身份是身份,所以这不是问题。
libqglviewer有一个很好的选择框架,如果那是你正在寻找的