gluUnProject Android OpenGL ES 1.1的使用

gluUnProject Android OpenGL ES 1.1的使用,android,opengl-es,Android,Opengl Es,我正在尝试使用gluUnProject将windows coords转换为world coords。 我并没有试图在emulator或旧的Android系统(使用OpenGLESV1.0)中获得工作示例,这不是关于GL函数可用性的问题。我正在尝试使用OpenGL ES 1.1和glGet函数在真实设备上工作,这些函数返回非零结果 有以下示例: public Vector3 translateScreenCoordsToWorld(Vector2 screenCoords) { gl.glLoad

我正在尝试使用gluUnProject将windows coords转换为world coords。 我并没有试图在emulator或旧的Android系统(使用OpenGLESV1.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(newVector2(480800))时,它返回非常小的坐标值Vector3(0.27f,0.42f,-1.0f)

任何人都可以提供良好的样本使用gluUnProject为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,屏幕x坐标、屏幕y坐标以及对应于该像素的深度缓冲区值。过程通常如下所示:

  • 绘制一个帧,以便所有深度缓冲区信息都准备就绪
  • 抓取视口/矩阵/屏幕坐标
  • 反转屏幕y坐标
  • 读取给定像素处的深度值。这实际上是一个标准化的z坐标
  • 将x、y和z输入glUnProject
  • 这最终给出了给定像素片段的世界空间坐标。可以找到更详细的指南。无论如何,我可以在您的代码中看到两个可能的错误。第一个错误是,通常您必须反转y屏幕坐标,(链接教程详细说明了原因),第二个是,您总是将0作为z值传递给gluUnProject。这样做会像在近平面上一样取消投影顶点。这是您想要的吗


    无论如何,如果我误读了你的问题,请原谅。

    谢谢!这篇文章很好。但是OpenGL ES(Android)中没有GL_DEPTH_组件支持。我不能称之为glReadPixels(winX,winY,1,1,GL_DEPTH_组件,GL_FLOAT,&winZ);:(有解决办法吗?你是对的,我可能应该记得。有两种解决办法,第一种是在近平面和远平面之间创建光线,并运行手动相交测试,(这可能非常棘手),第二个是创建一个帧缓冲区对象,并从中读取深度缓冲区值。或者,您可以跳过gluUnProject并尝试执行拾取。再次执行感兴趣的链接。谢谢!我尝试实现手动相交,但仍然不起作用:(请查看更新。)