Anuncios Google

Practica_29 Impostores


Práctica Nº 29 - Impostores.

¿Qué son los Billboards, Carteleras o Impostores? Son la misma cosa, un objeto 2D representado en un entorno 3D, hablando claro, los “Sprites” de toda la vida solo que ahora los pintamos en un mundo en tres dimensiones. Con esta técnica conseguimos ahorrar mucho tiempo de proceso usando “Sprites” a la hora de dibujar árboles, hierba, humo, partículas, explosiones, tiros, rótulos,  etc. Para los que no sepan que es un “Sprite”,  es una imagen o sucesión de imágenes de un tamaño dado que se dibujan en una zona de la pantalla como si fueran pegatinas, esta técnica es la usada comúnmente en los videojuegos en 2D.

Una imagen normal y corriente tiene 2D ancho (x) y alto (y), en un entorno 2D no hay problema alguno basta con definir la posición x e y donde pegar la imagen. Pero en un entorno 3D además tenemos la profundidad (z) que nos afectará al tamaño aparente de la imagen, pero el problema real no es la profundidad sino el hecho de poder trasladarnos en 3D y hacer rotaciones en 3D. ¿Que pasaría si nos posicionamos o rotamos una imagen 2D hasta verla de canto? Como no tiene dimensión (z), o lo que es lo mismo (z = 0 ), seria tan fina que no se vería. Imagínate un árbol visto de frente, entonces empiezas a rodearlo y este se va estrechando hasta hacerse invisible cuando pasas por su lado, luego vuelve a agrandarse hasta quedar invertido en (x) cuando nos coloquemos detrás. Esto sería una buen guión para la teleserie “Más allá de la realidad” pero una auténtica chapuza para un videojuego.

Es evidente que necesitamos ver siempre de frente la imagen, este tipo se denomina “Impostor Esférico” porque nos pongamos donde nos pongamos siempre veremos de frente la imagen. Pero si queremos dibujar por ejemplo un árbol tal vez queramos respetar el eje vertical  (y), este tipo se llama “Impostor Cilíndrico”. Por defecto un impostor siempre apuntará a la cámara, pero podemos hacer que apunte a cualquier punto que queramos como por ejemplo a la posición de una luz para crear el efecto gira sol. Vista la teoría ahora falta la práctica, ¿Y cómo se hace todo esto?

La clave está en la Matriz de Modelado, la podemos capturar en cualquier momento con la función “glGetFloatv();”. Esta contiene cuatro vectores clave:

float M1[16]; glGetFloatv( GL_MODELVIEW_MATRIX, M1 );
Vector que apunta a la derecha -> M1[0] , M[1],  M1[2]
Vector que apunta arriba       -> M1[4] , M[5],  M1[6]
Vector que apunta a la cámara  -> M1[8] , M[9],  M1[10]
Posición Actual                -> M1[12], M[13], M1[14]

 

Para conseguir un “Impostor Cilíndrico” tan solo tenemos que actualizar esta matriz por la siguiente:
M1[0] = 1.0f; M1[4] = 0.0f; M[8]  = 0.0f;
M1[1] = 0.0f; M1[5] = 1.0f; M[9]  = 0.0f;
M1[2] = 0.0f; M1[6] = 0.0f; M[10] = 1.0f;
glLoadMatrixf( M1 );

 

Para conseguir un “Impostor Cilíndrico” omitimos el vector arriba:
M1[0] = 1.0f; M1[4] = 0.0f; M[8]  = 0.0f;
M1[2] = 0.0f; M1[6] = 0.0f; M[10] = 1.0f;
glLoadMatrixf( M1 );

 

La cosa se complica un poco cuando queremos hacer que apunte a un punto dado, para un “Impostor Esférico” los pasos son los siguientes:
1 - Calcular la posición real del punto multiplicándolo por la Matriz de Modelado.
2 - Calcular la posición actual multiplicando la Matriz de Modelado por un vector nulo.
3 - Calcular el vector normalizado de dirección restándole al punto la posición actual.
4 - Calcular el vector normalizado derecha haciendo el producto vectorial de los vectores arriba y dirección. El vector arriba lo tomamos de la matriz.
5 - Calcular el vector normalizado arriba haciendo el producto vectorial de los vectores dirección y derecha.
6 - Cargar la matriz de modelado con los vectores derecha, arriba y dirección.

Para calcular un “Impostor Cilíndrico” que apunte a un punto dado es lo mismo pero omitiendo el paso número cinco.

Y por último, como modificamos la matriz de modelado es evidente que hay que guardarla previamente para poder restaurarla después de usar un impostor. Los pasos resultantes de toda la operación serían los siguientes:
  glPushMatrix();          // Guardar la Matriz de Modelado.
  glTranslatef( x, y, z ); // Posicionarse en el espacio 3D.
  Impostor();              //Activar el tipo de Impostor adecuado;
  Dibujar un cuadrado u rectángulo de 2 Dimensiones con textura;
  glPopMatrix();           // Restaurar la Matriz de Modelado.

También en esta práctica he implementado el uso del ratón usando las siguientes funciones y estados de SDL:
  - SDL_Event evento.button.button
  - SDL_MOUSEBUTTONDOWN
  - SDL_BUTTON_WHEELUP
  - SDL_BUTTON_WHEELDOWN
  - raton_boton = SDL_GetMouseState( &raton_x, &raton_y );
  - SDL_GetRelativeMouseState( &raton_xrel, &raton_yrel );
Ahora se puede girar y moverse por el entorno 3D usando solo el ratón, la ruedecilla y sus botones izquierdo y derecho. No es tema de estudio el uso del ratón con SDL, pero os recuerdo que entre SDL y OpenGL el eje Y está invertido.

Una posibilidad muy útil es seleccionar un objeto 3D con el ratón, para esto hay muchas formas, pero una muy simple es obtener la profundidad Z_DEPTH del puntero del ratón antes y después de dibujar los objetos que nos interesen. Si esta profundidad es menor es por que se ha dibujado un objeto donde está el puntero del ratón. Para ello hay que usar la función “glReadPixel();” os vuelvo a recordar que el eje Y está invertido:

glReadPixels( raton_x, V_Alto - raton_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z_depth );

 

DESCARGA: Practica 29 Impostores.

 


Anuncios Google