2011-12-13 19 views
11

Estoy haciendo un juego en OpenGL donde tengo algunos objetos dentro del espacio mundial. Quiero hacer una función donde pueda tomar la ubicación de un objeto (3D) y transformarlo a la ubicación de la pantalla (2D) y devolverlo.C++/OpenGL convierte coords mundiales para coords de pantalla (2D)

Sé que el la ubicación 3D de la matriz objeto, matriz de protección y ver en los siguientes varibles:

Matrix projectionMatrix; 
Matrix viewMatrix; 
Vector3 point3D; 

Respuesta

29

Para hacer esta transformación, primero debe tomar sus posiciones modelo de espacio y transformarlas para recortar -espacio. Esto se hace con multiplicaciones de matriz. Voy a utilizar el código de estilo GLSL para que sea obvio lo que estoy haciendo:

vec4 clipSpacePos = projectionMatrix * (viewMatrix * vec4(point3D, 1.0)); 

Observe cómo puedo convertir su vector 3D en un vector 4D antes de la multiplicación. Esto es necesario porque las matrices son 4x4 y no se puede multiplicar una matriz 4x4 con un vector 3D. Necesitas un cuarto componente.

El siguiente paso es transformar esta posición del espacio de recorte al espacio de coordenadas del dispositivo normalizado (espacio NDC). El espacio NDC está en el rango [-1, 1] en los tres ejes. Esto se hace dividiendo las tres primeras coordenadas en el cuarto:

vec3 ndcSpacePos = clipSpacePos.xyz/clipSpacePos.w; 

Obviamente, si clipSpacePos.w es cero, usted tiene un problema, por lo que debe comprobar que de antemano. Si es cero, significa que el objeto está en el plano de proyección; su profundidad del espacio de visión es cero. Y tales vértices son recortados automáticamente por OpenGL.

El siguiente paso es transformar de este espacio [-1, 1] a coordenadas relativas a la ventana. Esto requiere el uso de los valores que pasó a glViewport. Los primeros dos parámetros son el desplazamiento desde la esquina inferior izquierda de la ventana (vec2 viewOffset), y los segundos dos parámetros son el ancho/alto del área de la ventana gráfica (vec2 viewSize). Dado esto, la posición del espacio de la ventana es:

vec2 windowSpacePos = ((ndcSpacePos.xy + 1.0)/2.0) * viewSize + viewOffset; 

Y eso es todo lo que tienes que hacer. Recuerde: el espacio de ventana de OpenGL es relativo a abajo a la izquierda de la ventana, no a la esquina superior izquierda.

+0

¿Cómo puedo lograr esto sin utilizar un programa de sombreado? Quiero decir, ¿simplemente funciones de OpenGL? – mr5

+0

La mejor respuesta que encontré después de buscar en Google por un tiempo y la única que he encontrado que menciona tener que dividir por clipSpacePos.w. –

+2

Nota: si el espacio de la ventana es relativo a la esquina superior izquierda de la ventana, entonces 'windowSpacePos' debe ser ' vec2 (((ndcSpacePos.x + 1.0)/2.0) * viewSize.x + viewOffset.x, ((1.0 - ndcSpacePos.y)/2.0) * viewSize.y + viewOffset.y) ' –

Cuestiones relacionadas