I have a world that is rendered in 2D and I'm looking at it from the top. Tjat looks like this (the floor tiles have no texture and only random green color yet):
我有一个用2D渲染的世界,我从顶部看它。 Tjat看起来像这样(地砖没有纹理,只有随机的绿色):
Before rendering my entities, I transform the model-view matrix like this (while position
is the position and zoom
the zoom of the camera, ROTATION
is 45):
在渲染我的实体之前,我像这样变换模型视图矩阵(当位置是位置并缩放相机的缩放时,ROTATION为45):
glScalef(this.zoom, this.zoom, 1);
glTranslatef(this.position.x, this.position.y, 0);
glRotatef(ROTATION, 0, 0, 1);
Now I want to calculate the world coordinates for the current position of my camera. What I'm trying is to create a new matrix with glPushMatrix
, then transform it the same way that the camera is transformed, and then get the matrix and multiply the given camera coordinate with it:
现在我想计算相机当前位置的世界坐标。我正在尝试使用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);
}
The problem now is: this works for the x
coordinate, but the y
coordinate is wrong and always 0. Have I misused the matrix somehow? Is there a "smoother" way of getting the world coordinates from the eye coordinates?
现在的问题是:这适用于x坐标,但y坐标是错误的并且总是0.我是否以某种方式误用了矩阵?是否有一种“平滑”的方式从眼睛坐标获取世界坐标?
1 个解决方案
#1
The problem is with the way you're calling getFloat()
. When you call it with an index on a ByteBuffer
, the index is the number of bytes into the buffer at which to start reading the float, not the number of floats. You need to multiply each of your indices by 4:
问题在于你调用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);
However given that x is working for you already, I suspect you might also need to transpose your matrix co-ordinates, and so the correct code is:
但是假设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);
(By a co-incidence, transposing the first row of the matrix into the first column gives indices that are 4 times as great, so the 2 bugs cancel each other out in the case of x but not y).
(通过共同发生,将矩阵的第一行转置到第一列中得到的索引是4倍大,因此在x但不是y的情况下,2个错误相互抵消)。
If you're looking for a smoother way of doing it, look into using gluUnProject, although you may have to apply some additional transforms (it maps from window to object co-ordinates).
如果您正在寻找更顺畅的方法,请查看使用gluUnProject,尽管您可能需要应用一些额外的变换(它从窗口映射到对象坐标)。
#1
The problem is with the way you're calling getFloat()
. When you call it with an index on a ByteBuffer
, the index is the number of bytes into the buffer at which to start reading the float, not the number of floats. You need to multiply each of your indices by 4:
问题在于你调用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);
However given that x is working for you already, I suspect you might also need to transpose your matrix co-ordinates, and so the correct code is:
但是假设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);
(By a co-incidence, transposing the first row of the matrix into the first column gives indices that are 4 times as great, so the 2 bugs cancel each other out in the case of x but not y).
(通过共同发生,将矩阵的第一行转置到第一列中得到的索引是4倍大,因此在x但不是y的情况下,2个错误相互抵消)。
If you're looking for a smoother way of doing it, look into using gluUnProject, although you may have to apply some additional transforms (it maps from window to object co-ordinates).
如果您正在寻找更顺畅的方法,请查看使用gluUnProject,尽管您可能需要应用一些额外的变换(它从窗口映射到对象坐标)。