Android OpenGL ES 2.0屏幕坐标到世界坐标

我正在构build一个使用OpenGL ES 2.0的Android应用程序,而且我已经遇到了一堵墙。 我试图将屏幕坐标(用户触摸的位置)转换为世界坐标。 我试过阅读和玩弄GLU.gluUnProject,但我要么做错了,或只是不明白。

这是我的尝试….

public void getWorldFromScreen(float x, float y) { int viewport[] = { 0, 0, width , height}; float startY = ((float) (height) - y); float[] near = { 0.0f, 0.0f, 0.0f, 0.0f }; float[] far = { 0.0f, 0.0f, 0.0f, 0.0f }; float[] mv = new float[16]; Matrix.multiplyMM(mv, 0, mViewMatrix, 0, mModelMatrix, 0); GLU.gluUnProject(x, startY, 0, mv, 0, mProjectionMatrix, 0, viewport, 0, near, 0); GLU.gluUnProject(x, startY, 1, mv, 0, mProjectionMatrix, 0, viewport, 0, far, 0); float nearX = near[0] / near[3]; float nearY = near[1] / near[3]; float nearZ = near[2] / near[3]; float farX = far[0] / far[3]; float farY = far[1] / far[3]; float farZ = far[2] / far[3]; } 

我得到的数字似乎不正确,这是利用这种方法的正确方法? 它是否适用于OpenGL ES 2.0? 在这些计算(Matrix.setIdentityM(mModelMatix,0))之前,我应该将模型matrix作为单位matrix吗?

作为后续,如果这是正确的,我如何select输出Z? 基本上,我总是知道我希望世界坐标处在什么距离,但GLU.gluUnProject中的Z参数似乎是近平面和远平面之间的某种插值。 它只是一个线性插值?

提前致谢

Solutions Collecting From Web of "Android OpenGL ES 2.0屏幕坐标到世界坐标"

 /** * Calculates the transform from screen coordinate * system to world coordinate system coordinates * for a specific point, given a camera position. * * @param touch Vec2 point of screen touch, the actual position on physical screen (ej: 160, 240) * @param cam camera object with x,y,z of the camera and screenWidth and screenHeight of the device. * @return position in WCS. */ public Vec2 GetWorldCoords( Vec2 touch, Camera cam) { // Initialize auxiliary variables. Vec2 worldPos = new Vec2(); // SCREEN height & width (ej: 320 x 480) float screenW = cam.GetScreenWidth(); float screenH = cam.GetScreenHeight(); // Auxiliary matrix and vectors // to deal with ogl. float[] invertedMatrix, transformMatrix, normalizedInPoint, outPoint; invertedMatrix = new float[16]; transformMatrix = new float[16]; normalizedInPoint = new float[4]; outPoint = new float[4]; // Invert y coordinate, as android uses // top-left, and ogl bottom-left. int oglTouchY = (int) (screenH - touch.Y()); /* Transform the screen point to clip space in ogl (-1,1) */ normalizedInPoint[0] = (float) ((touch.X()) * 2.0f / screenW - 1.0); normalizedInPoint[1] = (float) ((oglTouchY) * 2.0f / screenH - 1.0); normalizedInPoint[2] = - 1.0f; normalizedInPoint[3] = 1.0f; /* Obtain the transform matrix and then the inverse. */ Print("Proj", getCurrentProjection(gl)); Print("Model", getCurrentModelView(gl)); Matrix.multiplyMM( transformMatrix, 0, getCurrentProjection(gl), 0, getCurrentModelView(gl), 0); Matrix.invertM(invertedMatrix, 0, transformMatrix, 0); /* Apply the inverse to the point in clip space */ Matrix.multiplyMV( outPoint, 0, invertedMatrix, 0, normalizedInPoint, 0); if (outPoint[3] == 0.0) { // Avoid /0 error. Log.e("World coords", "ERROR!"); return worldPos; } // Divide by the 3rd component to find // out the real position. worldPos.Set( outPoint[0] / outPoint[3], outPoint[1] / outPoint[3]); return worldPos; } 

这里进一步解释algorithm。

希望我的问题(和答案)能够帮助你:

如何在放大时find点击的绝对位置

它不仅有代码,而且还有图解和图表解释它:)花了我很多时间来弄清楚。

恕我直言,一个不需要重新实现这个function…我试用了Erol的解决scheme,它的工作,所以非常感谢Erol。 而且,我玩了

  Matrix.orthoM(mtrxProjection, 0, left, right, bottom, top, near, far); 

而且在我的微小noob示例2D OpenGL ES 2.0项目中也可以正常工作:

  • public void onSurfaceChanged(GL10 unused,int width,int height){…