2011-09-15 9 views
5

Estoy tratando de usar gluUnProject para convertir coords de Windows a coords mundiales. No estoy tratando de obtener muestras de trabajo en el emulador o en sistemas Android anteriores (con OpenGL ES v1.0) y esto no es una cuestión de disponibilidad de la función GL. Estoy tratando de trabajar en el dispositivo real con OpenGL ES 1.1 y las funciones glGet devuelven resultados distintos de cero.gluUnProject Android OpenGL ES 1.1 Uso

No es la Muestra:

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 es sólo un envoltorio para el tampón flotador [];

Con esta función intento crear un plano para llenar toda la pantalla o detectar coords mundiales máximos para la matriz de proyección actual, pero no funciona en absoluto porque no estoy seguro de estar usando estas funciones correctamente.

Por ejemplo cuando estoy tratando de ejecución translateScreenCoordsToWorld (nueva Vector2 (480800)) devuelve las coordenadas valores muy pequeños Vector3 (0.27f, 0.42f, -1.0f).

¿Alguien podría proporcionar un buen uso de muestra gluUnProject para el modo GL_PROJECTION con una cámara posicionada?

Actualizado Gracias por los buenos enlaces. Pero todavía no' trabajar para mí :( Ahora mi función será similar a:

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

y aquí es donde mi cámara configuración:

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

La cámara se configura con las siguientes coordenadas:

camera.position = { 0, 0, 65 };  
camera.target = { 0, 0, 0 } 
camera.upAxis = { 0, 1, 0 } 

Respuesta

3

Bien, normalmente cuando se utiliza gluUnProject, se intenta obtener la coordenada espacial mundial de un píxel en la pantalla. Se necesitan tres piezas de información (distintas de las matrices) para poner int o glUnProject, una coordenada x de pantalla, una coordenada y de pantalla, y el valor del búfer de profundidad correspondiente a ese píxel. El proceso normalmente es así:

  1. Dibuje un marco, por lo que toda la información del búfer de profundidad está lista.
  2. Grab viewport/matrices/screen coords
  3. Invierte la coordenada y de la pantalla.
  4. Lea el valor de profundidad en un píxel determinado. Esto es efectivamente una coordenada z normalizada.
  5. Ingrese x, y y z en glUnProject.

Esto termina dando la coordenada espacial mundial del fragmento dado de un píxel. Se puede encontrar una guía mucho más detallada here. De todos modos, puedo ver dos posibles errores en tu código. La primera es que normalmente tiene que invertir la y la pantalla coord (el tutorial en el enlace detalla por qué), la segunda es que siempre está pasando en 0 como el valor z a gluUnProject. Al hacer esto, des-proyecta el vértice como si estuviera en el plano cercano. ¿Es esto lo que quieres?

De todos modos, perdónenme si leí mal su pregunta.

+0

Gracias! Es un buen artículo de NeHe. Pero no hay soporte GL_DEPTH_COMPONENT en OpenGL ES (Android).No puedo llamar glReadPixels (Winx, vinoso, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); :( ¿Hay alguna solución solución? – abdolence

+3

Tienes razón, probablemente debería haber recordado eso. Hay dos arounds de trabajo, la primero es crear un rayo entre el plano cercano y el plano lejano y ejecutar una prueba de intersección manual, (que puede ser bastante complicado), [aquí] (http://softwareprodigy.blogspot.com/2009/08/gluunproject-for- iphone-opengl-es.html), el segundo es crear un objeto de búfer de cuadro y leer los valores de búfer de profundidad a partir de eso. Alternativamente, podría omitir gluUnProject e intentar implementar picking. [Consulte aquí] (http: // stackoverflow. com/questions/7364693/how-to-get-object-in-webgl-3d-space-from-a-mouse-click-coordinate) –

+0

Enlaces interesados ​​de nuevo. Gracias! Traté de implementar intersección manual, pero todavía no está trabajando :(Por favor mira la actualización mi – abdolence

Cuestiones relacionadas