我正在尝试使用glunproject将windows坐标转换为world坐标。
我不想在模拟器或旧的android系统(使用opengl es v1.0)中获得工作示例,这不是gl功能可用性的问题。我正在尝试使用opengl es 1.1和glget函数在实际设备上返回非零结果。
有样本:

public Vector3 translateScreenCoordsToWorld(Vector2 screenCoords) {
gl.glLoadIdentity();

final Matrix4x4 modelViewMatrix = new Matrix4x4();
final Matrix4x4 projectMatrix = new Matrix4x4();

int[] viewVectorParams = new int[4];
gl.glGetIntegerv(GL11.GL_VIEWPORT,viewVectorParams,0);
gl.glGetFloatv(GL11.GL_MODELVIEW_MATRIX,modelViewMatrix.buffer,0);
gl.glGetFloatv(GL11.GL_PROJECTION_MATRIX,projectMatrix.buffer,0);

float[] output = new float[4];
GLU.gluUnProject(
    screenCoords.x, screenCoords.y, 0,
    modelViewMatrix.buffer, 0,
    projectMatrix.buffer, 0,
    viewVectorParams, 0,
    output, 0);

return new Vector3(output[0],output[1],output[2]);

}

matrix4x4只是float[]缓冲区的包装器;
使用这个函数,我试图创建一个平面来填充所有屏幕或检测当前投影矩阵的最大世界坐标,但它根本不起作用,因为我不确定这些函数是否正确使用。
例如,当我尝试运行translateScreencoordStoworld(new vector2(480800))时,它返回非常小的坐标值vector3(0.27f,0.42f,-1.0f)。
任何人都可以提供良好的样品使用glunproject为gl_投影模式与一个定位相机。
更新
谢谢你的好链接。但对我来说还是不管用(
现在我的功能是:
public Vector3 translateScreenCoordsToWorld(Vector2 screenCoords) {

float winX = screenCoords.x, winY = screenCoords.y, winZ = 0;
winY = (float)currentViewVectorParams[3] - winY;

float[] output = new float[4];
GLU.gluUnProject(
    winX, winY, winZ,
    currentModelViewMatrix.buffer, 0,
    currentProjectMatrix.buffer, 0,
    currentViewVectorParams, 0,
    output, 0
);

Vector3 nearPlane = new Vector3(output[0],output[1],output[2]);
winZ = 1.0f;
GLU.gluUnProject(
    winX, winY, winZ,
    currentModelViewMatrix.buffer, 0,
    currentProjectMatrix.buffer, 0,
    currentViewVectorParams, 0,
    output, 0
);
Vector3 farPlane = new Vector3(output[0],output[1],output[2]);

farPlane.sub(nearPlane);
farPlane.div( nearPlane.length());

float dot1, dot2;

Vector3 pointInPlane = new Vector3(), pointPlaneNormal = new Vector3(0,0,-1);
pointInPlane.sub( nearPlane );

dot1 = (pointPlaneNormal.x * pointInPlane.x) + (pointPlaneNormal.y * pointInPlane.y) + (pointPlaneNormal.z * pointInPlane.z);
dot2 = (pointPlaneNormal.x * farPlane.x) + (pointPlaneNormal.y * farPlane.y ) +(pointPlaneNormal.z * farPlane.z);

float t = dot1/dot2;
farPlane.mul(t);

return farPlane.add(nearPlane);
}

这就是我的相机配置的地方:
public void updateCamera() {
Camera camera = scene.getCamera();
GLU.gluLookAt(gl,
    camera.position.x, camera.position.y, camera.position.z,
    camera.target.x, camera.target.y, camera.target.z,
    camera.upAxis.x, camera.upAxis.y, camera.upAxis.z
);

    gl.glGetIntegerv(GL11.GL_VIEWPORT,currentViewVectorParams,0);
    gl.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, currentModelViewMatrix.buffer,0);
    gl.glGetFloatv(GL11.GL_PROJECTION_MATRIX,currentProjectMatrix.buffer,0);
}

摄像机配置有以下坐标:
camera.position = { 0, 0, 65 };
camera.target = { 0, 0, 0 }
camera.upAxis = { 0, 1, 0 }

最佳答案

好吧,通常当使用glunproject时,你会试图得到屏幕上像素的世界空间坐标。您需要三条信息(矩阵除外)放入glunproject,一个screen x坐标,一个screen y坐标,以及对应于该像素的深度缓冲值。过程通常如下:
画一个框架,这样所有的深度缓冲信息都准备好了。
抓取视区/矩阵/屏幕坐标
反转屏幕Y坐标。
读取给定像素处的深度值。这实际上是一个标准化的z坐标。
在glunproject中输入x、y和z。
最终得到给定像素片段的世界空间坐标。可以找到更详细的指南here。不管怎样,我可以在你的代码中看到两个可能的错误。第一种是通常必须反转y屏幕坐标(关于链接详细说明原因的教程),第二种是始终将0作为z值传递给glunproject。执行此操作时,将顶点取消投影,就像它在近平面上一样。这就是你想要的吗?
不管怎样,如果我看错了你的问题,请原谅我。

07-27 18:06