从摄像机坐标计算世界坐标
我有一个用2D渲染的世界,我从顶部看它。 Tjat看起来像这样(地砖没有纹理,只有随机的绿色):
在渲染我的实体之前,我像这样变换模型视图矩阵(当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 ,尽管您可能需要应用一些额外的变换(它从窗口映射到对象坐标)。