从摄像机坐标计算世界坐标

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

2D看世界

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

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

现在我想计算相机当前位置的世界坐标。 我正在尝试用glPushMatrix创建一个新矩阵,然后以与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.我是否以某种方式误用了矩阵? 是否有一种“平滑”的方式从眼睛坐标获取世界坐标?

问题在于你调用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 ,尽管您可能需要应用一些额外的变换(它从窗口映射到对象坐标)。