我正在绘制z = 0的纹理,如下图所示:
我的近平面和远平面设置为0.001和120.0。我可以使用键盘四处移动并放大和缩小。
我想要的是在使用gluunproject时识别鼠标光标位置的世界位置(例如图像中的红色)。
问题:结果posX,posY和posZ有些接近但不正确。例如。对于可见视图的中心(蓝色)我得到posX = 8.90000和posY = 53.80000。但是,如果我将鼠标向左移动,我会得到posX = 8.89894(应该是3.xx)。如果我将光标向右移动,我得到8.90103而不是大约。 14-16。
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
perspectiveGL(65.0,(GLdouble)width()/(GLdouble)height(), 0.001, 120.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Go to current World-Position
glTranslated(-m_posWorld.x(), -m_posWorld.y(), -m_posWorld.z());
// Try to project Screen(Mouse)-Coordinates to World Coordinates
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );
winX = (float)m_lastPos.x(); // m_lastPos is a Point storing the last Mouse Cursor Position within the OpenGL-Widget (without borders)
winY = (float)viewport[3]-(float)m_lastPos.y();
winZ = -m_posWorld.z();
GLdouble posX, posY, posZ;
int success = glhUnProjectf( winX, winY, -m_posWorld.z(), modelview, projection, viewport, &posX, &posY, &posZ);
这可能是什么问题?
答案 0 :(得分:2)
x
,y
和 z
。 m_posWorld.z
几乎肯定不在窗口空间。
窗口空间z
是深度缓冲区存储的值,它是[ 0.0 , 1.0 ]之间的值(假设默认深度范围)。因为深度缓冲区为您提供了这个值,所以您可以通过在(winX, winY)
处读取深度缓冲区来轻松找出它(尽管性能会受到影响)。
vec4 posClip = projectionMatrix * viewMatrix * m_posWorld; // Project to clip-space
vec4 posNDC = posClip / posClip.w; // Perspective Divide
float winZ = (posNDC * vec4 (0.5) + vec4 (0.5)).z; // Adjust for Depth Range
上面讨论的方法会更快,但需要一些矩阵数学。您目前完全依赖OpenGL来为您进行矩阵数学运算,如果您想继续这样做,您唯一的选择就是读取深度缓冲区:
GLfloat winZ;
glReadPixels (winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);