|
|
Artículo realizado por Tras las transformaciones
homogéneas para nuestra geometría ya somos capaces de modelar
y situar objetos a lo largo y ancho de nuestro mundillo virtual. ¿Pero
cómo hacer que aparezcan en nuestra magnífica ventana 800
x 600 del S.O. ?...esa ventana es 2D y en cambio me está enseñando
mi geometría 3D dándome la sensación de que hay profundidad.
Tenemos que proyectar
la geometría en un plano de proyección. Como plano
es obviamente 2D y suele situarse por convención en Z = 0 (plano
XY). La idea es proyectar primero para "discretizar" después.
Por discretizar entendemos pasar del mundo real (float o double) al entero
(integer) que es el de los pixeles de nuestro monitor. Un pixel lo iluminas
o no lo iluminas, es binario...o cero o uno pero nada de medias tintas.
Nada de decimales.
Tipos de proyección
No os comentaré
todas las existentes pues no lo considero necesario. Nos centraremos en
las proyecciones planares. En éstas se define una dirección
de visión (viewing) que va desde el observador hasta
el objeto en cuestión. Esta dirección se establece por medio
de proyectores (líneas) que cortan el plano de proyección
generando así la imagen 2D que finalmente aparecerá en pantalla.
Como primera gran clasificación de las proyecciones planares podemos
hablar de:
Proyección
ortográfica
Como proyección
paralela que es, cuenta con proyectores paralelos entre ellos. El centro
de proyección (COP) se encuentra en el infinito. En el
caso de la ortográfica, los proyectores son perpendiculares al plano
de proyección. Lo observamos mejor en la figura:
Oscar García "Kokopus".
Capitulo 7
Proyecciones. La cámara
Nosotros nos centraremos
en dos de estas proyecciones. La ortográfica y la perspectiva de
un sólo punto.

Este tipo de proyección no preserva las dimensiones reales de los objetos según la distancia hasta ellos. Con eso quiero decir que aún acercándote / alejándote de ellos no se producen cambios de tamaño con lo cual el realismo no es total. Se utiliza tradicionalmente en proyectos de ingeniería del tipo de programas CAD/CAM. Quién no ha visto una herramienta de modelación 3D (AutoCAD, 3DSMax, Maya...) sin las 3 correspondientes vistas ortográficas desde ambos laterales y desde arriba. La cuarta vista suele ser una perspectiva que comentaré a continuación.
Los parámetros a especificar son las dimensiones de la caja (Xmin, Xmax, Ymin, Ymax, Zmin, Zmax). A los valores MAX y MIN también se les denomina FAR o BACK y NEAR o FRONT.
En OpenGL la podemos definir de la siguiente forma (ya lo habiamos medio visto en algunos ejemplos de artículos anteriores):
glMatrixMode(GL_PROJECTION);la última función puede reemplazarse por:
glLoadIdentity();
glOrtho(x_min, x_max, y_min, y_max, z_min, z_max);
gluOrtho2D(x_min, x_max, y_min, y_max);si se aceptan los valores por defecto de Zmin = -1.0 y Zmax = 1.0.
Proyección perspectiva
Esta es la que definitivamente
utilizaremos para dotar del mayor realismo a nuestras aplicaciones. Las
proyecciones perspectiva preservan las dimensiones reales de los objetos
si nos acercamos / alejamos de ellos. Por tanto el efecto visual es justo
el que necesitamos en casos de apariencia real. La tenéis en la
figura:

En la figura tenemos una proyección perspectiva con un sólo COP o punto de fuga. Todos los proyectores emanan de él y se dirigen hasta el objeto intersectando el plano de proyección. Como podéis observar los proyectores no son paralelos entre ellos tal y cómo ya os comenté anteriormente.
En OpenGL la podemos definir así:
glMatrixMode(GL_PROJECTION);Los parámetros que tenemos que especificar son:
glLoadIdentity();
gluPerspective( FOV en grados, Relación de Aspecto, z_near, z_far);
Podemos definir también una proyección perspectiva usando la función:FOV en grados. Es el "field of view" o campo visual. Se refiere al ángulo de abertura vertical. Relación de Aspecto o "aspect ratio". Es el cociente entre la anchura (width) y la altura (height) del plano de proyección deseado. Los valores NEAR y FAR del volúmen de visualización perspectiva. Idem que en ortográfica.
glFrustrum(x_min, x_max, y_min, y_max, z_min, z_max);En este caso OpenGL calculará el "frustrum piramidal", es decir, el volúmen de visualización perspectiva más idóneo. Son simplemente dos maneras distintas de acabar creando lo mismo. A cada uno con su elección, la que os parezca más intuitiva y cómoda.
Las distancias NEAR y FAR son siempre positivas y medidas desde el COP hasta esos planos, que serán obviamente paralelos al plano Z = 0. Dado que la cámara apunta por defecto en la dirección negativa de Z, el plano de front (near) estará realmente situado en z = -zmin mientras que el de back (far) estará en z = -zmax.
Lo he dado más o menos por asumido pero lo voy a recordar. Pensad que no hay que proyectar toda la geometría existente sinó tan sólo la que vé la cámara desde su posición y orientación. Tenemos que acotar en este sentido y es por eso que además de definir un plano de proyección y una forma de proyectar, creamos un volúmen de visualización finito con unas fronteras bién marcadas. Todo aquello que no se encuentre dentro del volúmen será rechazado y no proyectado dado que no debe verse. Para tenerlo más claro pensad en vuestros ojos. ¿Lo véis todo a vuestro alrededor?...no...tenéis una cierta apertura visual, de unos 60º a 80º y más allá de eso nada de nada.
No somos como las palomas con los ojos en los laterales de la cabeza o como una lente gran angular de una cámara. De hecho tan sólo variando la apertura visual (FOV) observaremos como es más o menos la cantidad de escena que entra en pantalla.
La Cámara
La cámara son nuestros ojos virtuales. Todo lo que ella vea será proyectado, discretizado y finalmente mostrado en nuestra ventanita del sistema operativo. Podemos imaginar que de la cámara emana el volúmen de visualización de forma que se traslada con ella. Los parámetros a definir en cuanto a la cámara son:
gluLookAt(eyeX, eyeY, eyeZ, atX, atY, atZ, upX, upY, upZ);Esta es la función que determina dónde y cómo está dispuesta la cámara. Cuidado que la posición de la cámara no tiene nada que ver con el tipo de proyección que hayamos definido. La proyección se define sólo una vez, típicamente al principio del programa en una función inicializadora, mientras que la cámara se mueve continuamente según nos interese y más en un arcade 3D !!!. Añadir a esto que la matriz que se modifica al llamar a esta función no tiene que ser GL_PROJECTION sinó GL_MODELVIEW. OpenGL calculará todas las transformaciones que aplicará al mundo 3D para que manteniendo la cámara en el origen de coordenadas y enfocada en la dirección negativa de las Z's nos dé la sensación de que lo estamos viendo todo desde un cierto lugar. Para ello recordad siempre activar esta matriz antes de llamar a gluLookAt de esta forma:
glMatrixMode(GL_MODELVIEW);En cuanto a los parámetros que demanda la función son los siguientes:

Espero haber acertado con la figura. Aquí véis una cámara con trípode y todo...;)...y los tres parámetros a los que me vengo refiriendo. Notad el hecho de que moviendo el vector de UP cambiariamos la orientación de la cámara aunque esta siguiera mirando hacia el mismo punto y situada en idéntica posición.
Pensad en lo siguiente y esto ya os lo dejo a vuestra propia iniciativa en cuanto a experimentación. Si gluLookAt altera la matriz GL_MODELVIEW y esta es la que guarda el estado de todo nuestro sistema en cuanto a transformaciones (recordad el artículo anterior), mejor controlar la situación con los gl_push y gl_pop que ya conoceis para no desmontarlo todo....y quizás tengais que limpiar la matriz antes de tocar la cámara usando para ello una identidad.....pensad en ello un poco...8)
Si partimos de que por defecto la cámara se encuentra en el orígen, mirando hacia las Z's negativas y con el vector de UP definido como el eje Y, podríamos dejar de utilizar esta función y acumular transformaciones con las funciones del capítulo anterior para que todo se posicionara de tal manera que nos diera la sensación de estarlo viendo desde otro punto de vista!!!....¿lo véis?
Creo que ya hemos llegado a un nivel lo suficientemente digno de conocimientos como para que seáis capaces de crear algo más que simples figuras. Por ahora el "render" será simple pues aún no conocemos la iluminación, ni las texturas ni las curbas y superfícies. Aún siendo simple podemos jugar adecuadamente con los colores creando bonitos escenarios virtuales. Os invito a programar algo de ese estilo. Un laberinto 3D con muros que seamos capaces de recorrer a voluntad usando las teclas y el raton. Pintad las caras de los muros (cubos escalados) con diferentes tonalidades del mismo color para emular sombras. Programad dos vistas del mismo escenario: una frontal perspectiva para el personaje que movéis y otra ortográfica y superior de todo el escenario. Necesitareis definir dos cámaras, una para cada ventana de GLUT. Vamos a ello que tenéis los conocimientos y la imaginación para hacerlo!!!
En la próxima
edición inauguraré un tema muy nuevo: la iluminación.
Dotaremos a nuestras composiciones del mayor realismo posible gracias a
la luz...y a las sombras...
ÚLTIMA REVISIÓN EN JULIO DE 1999
|
|