我在使用 gluUnProject 时遇到了一些麻烦,因为我正在检索不准确的 Z 坐标。
所涉及的程序本质上是一个 3d 查看器。我实现了一个小功能,允许用户单击加载的模型并检索两点之间的距离。
这是代码:
// Declare variables for viewport, modelview and projection matrix
int viewport[] = new int[4];
float modelview[] = new float[16];
float projection[] = new float[16];
// GL y-coordinate position
int realY;
// Returned [wx, wy, wz, 1] coordinates
float worldCoordinates[] = new float[4];
gl2.glGetIntegerv(GL2.GL_VIEWPORT, viewport, 0);
gl2.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, modelview, 0);
gl2.glGetFloatv(GL2.GL_PROJECTION_MATRIX, projection, 0);
// Retrive the Y coordinate, note viewport[3] is height of window in pixels
realY = viewport[3] - click.y - 1;
// Allocate a buffer to store the result
FloatBuffer fb = FloatBuffer.allocate(1);
// Retrieve the Z coordinate, read a block of pixels from the frame buffer
gl2.glReadPixels(click.x, realY, 1, 1, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, fb);
System.out.println("Depth: "+fb.get(0));
// Avoid centering if the click is on nothing
if (fb.get(0) == 1.0f) {
return null;
}
// Map window coordinates to object coordinates, retrieve the world coordinates
glu.gluUnProject(click.x, realY, fb.get(0), modelview, 0, projection, 0,
viewport, 0, worldCoordinates, 0);
当我测量位于垂直于用户的表面上的两点之间的距离时,一切正常。如果我们想象一个 3 轴系统,z 指向用户,y 指向顶部,这两个点位于 XY 平面上。无论围绕 Z 旋转如何,它都可以工作。
例如,在这里我创建了一个小正方形平面,两个点的高度相同(一个被标签遮挡):
世界坐标 P1: (0.019062456, 0.03357359, 0.08333321, 1)
世界坐标P2:(0.025983132, 0.028048635, 0.08333321, 1)
但是,如果我在全局 X 轴上旋转整个场景,则检索到的 Z 坐标会发生变化:
X 和 Y 坐标无关紧要,重要的是 Z 坐标。它不再是 0.08333321。
世界坐标 P1: (0.026863147, 0.027185505, 0.0831252, 1)
世界坐标 P2: (0.020072304, 0.034560144, 0.08312501, 1)
此外,在全局 X 上旋转后,缩放也会影响点的 Z 坐标。
Ps:我正在使用JOGL。通过放大/缩小 glOrtho 平行六面体来执行放大和缩小。glReadPixels 生成的 Z 深度 fb.get(0) 包含在 [0, 1] 中。
我哪里错了?