Tarea 3. Iluminación y perspectiva en 3D

Oliver Fernando Cuate González

ocuate@computacion.cs.cinvestav.mx

29 de Octubre de 2013

Problema

Realizar la misma escena de la Tarea 2, con iluminación y en perspectiva.

Escena

La aplicación en Qt y OpenGl debe realizar lo siguiente:

  1. El cuadricóptero debe estar subiendo y bajando.
  2. Las flechas del teclado controlan la inclinación del cuadricóptero.
  3. Con la tecla 'escape' las aspas rotan y dejan de rotar, como en la Tarea 1.
  4. Debe ponerse algunos widgets para situar al visor, a donde mira y el vector de arriba. Todo esto para visualizar la escena desde cualquier punto.
  5. El cuadricóptero debe rotar ahora sobre su mismo plano de sustentación.

Análisis

El análisis para resolver este problema es similar al anterior (Tarea 2. Transformaciones en 3D: Cuadricóptero 3D), en relación a las transformaciones que se necesitarán para mover el cuadricóptero a la posición deseada. El cambio se da en el uso de perspectiva para la visualización la escena, en el uso de iluminación para el aspecto de los objetos en 3D y en el movimiento extra de rotación sobre el eje de sustentación.

Para el uso de la perspectiva se utilizará la función de OpenGL glPerpective(fobia, aspecto, z_cerca, z_lejos). Hay que tener en cuenta lo que significa cada parámetro:

En la siguiente figura se muestra el uso de glPerspective.

Perspective

Para el uso de la iluminación en OpenGl necesitamos definir tanto las propiedades de la luz, como las propiedadces del material. Además por la forma en que se utizan estas funciones es necesario definir correctamente los vectores normales a cada vétice de nuestros objetos.

Se definen cinco características fundamentales para un material:

OpenGL soporta en principio hasta 8 luces simultaneas en un escenario. Las luces cuentan con nombre propio del estilo GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, etc. Para activar/desactivar una de ellas usamos respectivamente: glEnable( GL_LIGHT0 ) o glDisable( GL_LIGHT0 ).

También podemos activar y desactivar todo el cálculo de iluminación con: glEnable( GL_LIGHTING ) y glDisable( GL_LIGHTING ).

Para las propiedades de luz tenemos lo siguiente:

La iluminación requiere que nuestros objetos tengan definida una normal en cada vértice, esto se logra con glNormal3fv() o glNormal3f(). Esto es porque el uso de la iluminación utiliza el ángulo de incidencia entre estas normales y las fuentes de luz para realizar la iluminación.

También se utilizarán las trasnformaciones báscias en 3D y así como el manejo de gluLookAt() explicadas en la tarea anterior.

La incorporación de la iluminación hace indispensable el uso de primitivas que definan (vértices y normales) y dibujen objetos base ubicados en el origen para después, con el uso de las transformaciones, utilizarlos para crear el mundo y el cuadricóptero. Las primitivas usadas son:

Con estas primitivas y las transformaciones debe dibujarse el cuadricóptero y el mundo que lo rodea. La escena debe además contar con perspectiva, manejo de la cámara e ilumiación.

Lo que se desea es llevar al cuadricóptero, que inicialmente tendrá su centro en (0, 0, 0) y no estará inclinado, a una determinada posición (0, y, 0) con cierta inclinación, además para dar la impresión de que las aspas rotan es necesario que se tenga un ángulo de rotación para ellas. Para esto definiremos las siguientes variables:

Se describen a continuación las transformaciones y definición incial de cada elemento del cuadricóptero utilizadas para la resolución del problema:

Ahora que se sabe que hacer se muestra acontinuación los detalles de la implementación en Qt y OpenGL.

Alternativa de Solución en Qt y OpenGL

Para implementar el diseño discutido anteriormente con Qt y OpenGL, necesitamos definir los eventos del teclado y los widgets necesarios para obtener la funcionalidad deseada.

La flechas del teclado Arriba y Abajo, aumentarán y disminuirán la variable θz respectivamente y actualizarán el dibujo cada que se presionen. Lo anterior es para controlar inclinación del cuadricóptero, se se limitará a 50° en cada dirección. De manera análoga las flechas Arriba y Abajo tendrán un control sobre la variable θx.

La tecla "r" controlará la rotación del cuadricóptero sobre el eje y a través de la variable θy, no se tiene una restricción de giro para este ángulo.

Para activar las aspas mediante la tecla ESC, definimos un timer y una variable de control booleana que nos indicará si las aspas deben girar o no. El timer siempre esta activo y cada que se actualiza, verifica la variable de control de giro, en caso que deba girar aumenta el ángulo de giro de las aspas y si no no hace nada. También se incluye en el timer la verificación de otras variables de control que se activan con diiferentes teclas, esto permite apreciar los movimientos por separado del cuadricóptero.

La tecla "v" activa y desactiva el movimiento vertical del cuadricóptero.

La tecla "g" activa y desactiva el giro automático sobre el eje de sustentación del cuadricóptero.

La tecla "e" estabiliza el cuadricóptero si este está inclinado respecto al eje x o z.

Por último, para el control de la cámara de incluyen widgets de tipo QTextEdit para editar los valores (xeye, yeye, zeye), (xcen, ycen, zcen) y (xup, yup, zup) definidos con anterioridad. El mundo está dibujado en un cubo que se dfeine por los puntos (-20, -20, -20) y (20, 20, 20) para que los cambios en la vista se vean adeuadamente se define una perspectiva y posición de la cámara que permite la correcta visualización de los elemetos. Los valores de inicio son:

gluPerspective(75.0, factor, 10.0, 80.0); donde factor es el largo sobre el ancho de la pantalla.

gluLookAt(-2.0, 20, 40, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

Las transformaciones se controlan con glPushMartix() y glPopmatrix, con esto y lo anterior un esquema de solución es el siguiente:

  1. Inicializar ventana con los widgets adecuados para el control de la cámara.
  2. Definir perspectiva.
  3. Defnir propiedades de iluminación (luz y materiales).
  4. Arrancar el timer para el control de las variables que definen el estado del cuadricóptero.
  5. Dibujar objeto de la siguiente manera:

Estos son los detalles a grandes rasgos de la implementación. Por último se agregan un par de imágenes con diferente perspectiva y el link de descarga del código fuente del programa:

vista1 vista2

vista3

Descargar Archivo