根据摄像机坐标计算世界坐标

时间:2015-05-06 10:07:33

标签: java opengl math matrix lwjgl

我有一个用2D渲染的世界,我从顶部看它。 Tjat看起来像这样(地砖没有纹理,只有随机的绿色):

2D look on the world

在渲染我的实体之前,我会像这样变换模型视图矩阵(而position是位置,而zoom是相机的缩放,ROTATION是45):

glScalef(this.zoom, this.zoom, 1);
glTranslatef(this.position.x, this.position.y, 0);
glRotatef(ROTATION, 0, 0, 1);

现在我想计算相机当前位置的世界坐标。我尝试的是创建一个带有glPushMatrix的新矩阵,然后以与变换相同的方式对其进行变换,然后获取矩阵并将给定的摄像机坐标与其相乘:

private Vector2f toWorldCoordinates(Vector2f position) {

    glPushMatrix();

    // do the same as when rendering
    glScalef(this.zoom, this.zoom, 1);
    glTranslatef(this.position.x, this.position.y, 0);
    glRotatef(ROTATION, 0, 0, 1);

    // get the model-view matrix
    ByteBuffer m = ByteBuffer.allocateDirect(64);
    m.order(ByteOrder.nativeOrder());
    glGetFloatv(GL_MODELVIEW_MATRIX, m);

    // calculate transformed position
    float x = (position.x * m.getFloat(0)) + (position.y * m.getFloat(4)) + m.getFloat(12);
    float y = (position.x * m.getFloat(1)) + (position.y * m.getFloat(5)) + m.getFloat(13);
    System.out.println(x + "/" + y);

    glPopMatrix();
    return new Vector2f(x, y);
}

现在的问题是:这适用于x坐标,但y坐标错误且始终为0.我是否以某种方式误用了矩阵?有没有更顺畅的"从眼睛坐标获取世界坐标的方法?

1 个答案:

答案 0 :(得分:1)

问题在于您调用getFloat()的方式。当您使用ByteBuffer上的索引调用它时,索引是进入缓冲区的字节数,开始读取浮点数,而不是浮点数。您需要将每个索引乘以4:

float x = (position.x * m.getFloat(0)) + (position.y * m.getFloat(16)) + m.getFloat(48);
float y = (position.x * m.getFloat(4)) + (position.y * m.getFloat(20)) + m.getFloat(52);

但是考虑到x已经为你工作,我怀疑你可能还需要转置矩阵坐标,所以正确的代码是:

float x = (position.x * m.getFloat(0)) + (position.y * m.getFloat(4)) + m.getFloat(12);
float y = (position.x * m.getFloat(16)) + (position.y * m.getFloat(20)) + m.getFloat(28);

(通过共同发生,将矩阵的第一行转置到第一列中得到的索引是4倍大,因此在x但不是y的情况下,2个错误相互抵消。

如果您正在寻找更顺畅的方法,请查看使用gluUnProject,尽管您可能需要应用一些额外的变换(它从窗口映射到对象坐标)。