关于OpenGL:GlunProject()的世界协调问题

World-Coordinate Issues with gluUnProject()

我现在从一个游戏循环调用trace(方法如下)。现在我要做的就是从屏幕鼠标中获取世界坐标,这样我就可以在世界空间中移动物体了。然而,我从沮丧中得到的价值观却让我困惑。

我使用glreadPixel(…)来获取z值,但在我绘制的对象中几乎没有移动,结果向量最终与我的相机位置相同(除了鼠标移动导致的小小数更改),所以我决定取消调用,将z值替换为1。

我的问题是:下面的代码对您合适吗?我看到的每一个例子都是相同的或者非常相似的,但是我似乎不能产生正确的结果,即使我锁定了Y轴。如果代码是正确的,那么我猜我只是没有正确地使用结果向量。我应该不能直接用结果向量画出一个对象或点,还是必须用它做些其他的事情,比如规范化?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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,它给出了一个更合理的向量,但绘制的点仍然与鼠标不匹配。我发现视图[3]的值是384,这对于我使用的视区是正确的,但是我用768(实际窗口大小)替换了它,并且点跟随鼠标100%。进一步的实验表明,我不能使用这些坐标在透视世界空间中围绕三维对象移动,但是在正交空间中围绕三维对象移动会很好。


gluUnprojectwinz参数指定了从相机"拾取"点的深度。正如您所说,这个坐标应该在[0,1]范围内。

像Nehes这样的一些教程会从深度缓冲区中读取z坐标,这样您就可以在正确的深度"选择",当然,为了使这项工作正常进行,您必须在渲染完所有其他内容后进行沮丧的处理。

无论如何,如果您将winz设置为0.5或其他值(不是0或1或该点将最终位于近或远剪辑平面上,并可能被剔除),请执行以下操作:

1
2
3
4
5
6
7
gluUnProject(cursorX, view[3]-cursorY, 0.5, m, p, view, &objX, &objY, &objZ);
//Do something useful here???
glPointSize(10);
glBegin(GL_POINTS);
glColor3f(1, 0, 0);
glVertex3f(objX, objY, objZ);
glEnd();

您应该在鼠标指针处出现一个红色的斑点(前提是此后没有任何其他透支,并且您没有任何有趣的渲染状态来使该点不可见)。


只是一个想法,但是如果第三个关于glunproject的论点是z到相机的距离,你在那个位置画的点不是在你截锥的近裁剪平面上吗?最好让z值再高一点。