Android OpenGL ES 2,0 coordenadas de la pantalla a las coordenadas del mundo

Estoy construyendo una aplicación para Android que usa OpenGL ES 2.0 y me he encontrado con una pared. Estoy tratando de convertir coordenadas de pantalla (donde el usuario toca) a las coordenadas del mundo. He intentado leer y jugar con GLU.gluUnProject, pero lo estoy haciendo mal o simplemente no lo entiendo.

Este es mi intento ….

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]; } 

Los números que estoy recibiendo no parecen correctos, ¿es esta la forma correcta de utilizar este método? ¿Funciona para OpenGL ES 2.0? ¿Debería hacer que la matriz de modelos una matriz de identidad antes de estos cálculos (Matrix.setIdentityM (mModelMatix, 0))?

Como un seguimiento, si esto es correcto, ¿cómo elegir la salida Z? Básicamente, siempre sé a qué distancia quiero que las coordenadas del mundo estén, pero el parámetro Z en GLU.gluUnProject parece ser algún tipo de interpolación entre el plano cercano y el plano lejano. ¿Es sólo una interpolación lineal?

Gracias por adelantado

 /** * 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; } 

El algoritmo es explicado aquí.

Espero que mi pregunta (y respuesta) le ayude:

Cómo encontrar la posición absoluta del clic mientras ampliado

No sólo tiene el código, sino también diagramas y diagramas y diagramas que lo explican 🙂 Tomó años para entenderlo también.

IMHO uno no necesita volver a implementar esta función … Experimenté con la solución de Erol y funcionó, así que muchas gracias por Erol. Además, jugué con

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

Y funciona bien también en mi pequeño ejemplo de noob 2D OpenGL ES 2.0 proyecto:

  • Public void onSurfaceChanged (GL10 no utilizado, int width, int height) {…
  • ¿Por qué glReadPixels da resultados faltados en algunos dispositivos Android más antiguos?
  • Uso de SurfaceTexture en Android
  • LibGDX: ¿Cómo determinar si el contexto opengl se perdió?
  • ¿Cómo manejar la limitación de memoria de la GPU para el procesamiento de imágenes de alta resolución en la GPU?
  • Bajo rendimiento al ejecutar eglSwapBuffer y eglMakeCurrent
  • GLES2.0: Usar GL_TEXTURE_EXTERNAL_OES a través de glEGLImageTargetTexture2DOES
  • Dibujo Triángulo con OpenGl, no aparece?
  • Varias cámaras en libgdx (probablemente similar en otros marcos)
  • For-loop en código de sombreado que trabaja con un número codificado pero no con una variable uniforme
  • Matrices OpenGL - no pueden figurar las correctas
  • GLSurfaceView con contexto de OpenGL ES 3.1
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.