gluUnProject()的世界协调问题

时间:2009-12-02 17:52:12

标签: opengl graphics

我正在从游戏循环中调用Trace(下面的方法)。现在我所要做的就是从屏幕鼠标获取世界坐标,这样我就可以在世界空间中移动物体。然而,我从gluUnProject获得的值是;令我困惑的是。

我正在使用glReadPixel(...)来获取Z值,但是在我绘制的对象中产生很少甚至没有移动,结果向量最终与我的相机位置相同(除了微小的十进制变化)由于鼠标移动),所以我决定摆脱调用并用1替换Z值。

我的问题是:以下代码是否适合您?我见过的每一个例子都是相同的或非常相似但我似乎无法产生正确的结果,即使我锁定了Y轴。如果代码是正确的,那么我猜我只是没有正确使用结果向量。我是否应该无法直接使用生成的向量绘制对象或点,还是必须对其进行其他操作,例如normalize?

当前的渲染模式是GL_RENDER,我使用glZrustum,其NearZ值为1,FarZ值为2048,以创建透视图。还有一系列与剪刀一起创建的视口,尺寸和宽度为512x768,位于1024x768窗口的每个角落。在渲染左上视口之间调用跟踪(...),并且是唯一的透视投影,而其他视口是正交的。 FOV设置为45。

void VideoWindow::Trace(int cursorX, int cursorY)
{
    double objX, objY, objZ;//holder for world coordinates
    GLint view[4];//viewport dimensions+pos
    GLdouble  p[16];//projection matrix
    GLdouble  m[16];//modelview matrix
    GLdouble z;//Z-Buffer Value?

    glGetDoublev (GL_MODELVIEW_MATRIX, m);
    glGetDoublev (GL_PROJECTION_MATRIX,p);
    glGetIntegerv( GL_VIEWPORT, view );

    //view[3]-cursorY = conversion from upper left (0,0) to lower left (0,0)
    //Unproject 2D Screen coordinates into wonderful world coordinates
    gluUnProject(cursorX, view[3]-cursorY, 1, m, p, view, &objX, &objY, &objZ);

    //Do something useful here???
}

有什么想法吗?

编辑:我已经将winZ值更改为0.5而不是1,这样可以使矢量更合理但绘制点仍然与鼠标不匹配。我发现view [3]的值是384,这对我正在使用的视口是正确的,但我用768(实际窗口大小)替换它,并且点跟随鼠标100%。进一步的实验表明,我无法使用坐标在透视世界空间中使用这些坐标移动3D对象,但在正交空间中移动3D对象可以正常工作。

2 个答案:

答案 0 :(得分:4)

winz的{​​{1}}参数指定了您“选择”点数的相机深度。如您所述,此坐标应位于[0,1]范围内。

NeHes等一些tutorials从深度缓冲区中读出z坐标,以便您在正确的深度“选择”,当然为了实现这一点,您必须在渲染后执行gluUnproject其他一切。

无论如何,如果将gluUnproject设置为0.5或其他(不是0或1,或者该点将在近或远剪裁平面上结束,并且可能被剔除)并执行以下操作:

winz

你最后应该在鼠标指针上留下一个红色斑点(之后没有其他任何东西透支它,你没有任何有趣的渲染状态,这使得该点不可见)。

答案 1 :(得分:0)

只是一个想法,但如果gluUnProject的第三个参数是到摄像机的z距离,那么你在该位置绘制的任何点都不会 on 的近剪裁平面你的视锥体? 更好地使z值更高。