gluProject将3D坐标转换为2D坐标不会正确转换2D Y坐标

时间:2014-11-05 10:22:54

标签: java opengl lwjgl glu

经过两个小时的谷歌搜索(hereherehereherehere以及其他一些我不打扰的其他人我觉得我终于学会了将3D坐标转换为2D坐标的理论。但它不起作用。我们的想法是将船舶的3D坐标转换为屏幕上的2D坐标,以呈现控制该船舶的玩家的用户名。

但是,文本呈现在错误的位置: enter image description here

文字是"测试|| 2DXCoordinate || 2DZCoordinate&#34 ;.

这是我的getScreenCoords() - 将3D坐标转换为2D。

public static int[] getScreenCoords(double x, double y, double z) {
    FloatBuffer screenCoords = BufferUtils.createFloatBuffer(4);
    IntBuffer viewport = BufferUtils.createIntBuffer(16);
    FloatBuffer modelView = BufferUtils.createFloatBuffer(16);
    FloatBuffer projection = BufferUtils.createFloatBuffer(16);
    GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelView);
    GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projection);
    GL11.glGetInteger(GL11.GL_VIEWPORT, viewport);
    boolean result = GLU.gluProject((float) x, (float) y, (float) z, modelView, projection, viewport, screenCoords);
    if (result) {
        return new int[] { (int) screenCoords.get(0), (int) screenCoords.get(1) };
    }
    return null;
}

screenCoords.get(0)返回一个完美的X坐标。但是,screenCoords.get(1)会根据我离船的距离而变高或变低。经过几个小时的调试,我把它缩小到这条线是不正确的:

GLU.gluProject((float) x, (float) y, (float) z, modelView, projection, viewport, screenCoords);

然而,我不知道出了什么问题。船的X坐标很好......为什么不是Y?

根据BDL的回答,我正在提供错误的矩阵"到gluProject()。但我不知道这是怎么可能的,因为我在渲染我的船之后立即调用了这个方法(这显然是在任何矩阵中划出船只)。

我无法理解错误。

注意:BDL的答案是完全足够的,除了它没有解释为什么Y坐标不正确。

注意:这个问题过去时间更长,更模糊。经过数小时的调试后,我已在上面发布了我的缩小问题。

2 个答案:

答案 0 :(得分:7)

您必须在gluProject中使用与渲染船舶相同的投影矩阵。在您的情况下,使用透视投影渲染船只,但是当您调用gluProject时,会使用正交投影。

关于OpenGL坐标系的一般理论

在大多数情况下,场景中模型的几何体(例如船舶)在模型坐标系中给出。这是顶点坐标存在的空间。现在将模型放置在场景中时,我们将模型矩阵应用于每个顶点以获得船舶在场景中的坐标。该坐标系称为世界空间。当从给定视点和观察方向观察场景时,再次需要变换场景以使得视点位于原点(0,0,0)并且视图方向沿着负z轴。这是视图坐标系。最后一步是将视图坐标转换为ndc,这是通过投影矩阵完成的。

总的来说,我们将顶点转换为屏幕:

 v_screen = Projection * View * Model * v_model

在古老的OpenGL中(当你使用它时)视图和模型一起存储在ModelView矩阵中。

(我在这里略过了一些问题,因为视角的分歧,但它应该足以理解这个问题。)

您的问题

您已经在船舶的世界空间(x,y,z)中占有一席之地。因此,模型的转换已经发生。剩下的是

v_screen = Projection * View * v_worldspace

为此我们看到,在我们的例子中,输入到gluProject的ModelView矩阵必须完全是View矩阵。

我无法告诉您在代码中获取视图矩阵的位置,因为我不知道您的代码的这一部分。

答案 1 :(得分:0)

我找到了问题的答案!

我用过

font.drawString(drawx - offset, drawy, (sh.username + " || " + drawx + " | " + drawy), Color.orange);

什么时候应该

font.drawString(drawx - offset, Display.getHeight() - drawy, (sh.username + " || " + drawx + " | " + drawy), Color.orange);