/*Este tutorial cubre los primeros conceptos previos a la
creación de aplicaciones con OpenGL y en general a la
creación de contenido 3d. Es necesario aclarar que el
tutorial, por simplicidad y extensión se enfoca sobre la
especificación 1.1 de OpenGL, es decir, solo se menciona la
funcionalidad de la llamada “Fixed Pipeline” (ahora con la
entrada de OpenGL 2.0 y la introducción de los shader al
estándar, la estructura cambio).
En el tutorial se mencionan algunas palabras en ingles,
acompañadas de su traducción al español, solo para conservar
el término original (en ingles) y facilitar la búsqueda
posterior del término, tanto en español, como en inglés.
¿Qué es OpenGL? : OpenGL (Open Graphics Library) es un API
(de Aplication Programming Interface, Interfaz de
Programación de Aplicaciones) libre, multiplataforma,
orientado a la creación de contenido 3d. A un nivel más
simple se puede decir que es una librería que permite hacer
software con gráficos 3d sin preocuparse por el hardware en
que se va a ejecutar y que tiene un gran soporte en diferentes
sistemas operativos como Windows, OS/2, UNIX, FreeBSD , Linux,
etc.
Hay que hacer una diferencia clara, OpenGL no es un lenguaje
de programación, pero se puede trabajar con él desde
diferentes lenguajes como c++, c#, java y Visual Basic.
¿Para que puedo usar OpenGL? : OpenGL puede ser usado para
todo tipo de aplicaciones que necesiten visualización 3d en
tiempo real de alto rendimiento y calidad, en esto están
incluido los videojuegos, CAD, aplicaciones científicas,
médicas, militares, simuladores, etc.
¿Qué necesito para utilizar OpenGL en mis programas? Es buena
idea utilizar un IDE como Visual Studio, Eclipse o DevCpp
para realizar los programas, ya que facilita mucho el trabajo,
adicionalmente, en los archivos fuente donde se utilicen
funciones de OpenGL es necesario incluir las bibliotecas de
prototipos gl.h y glu.h, que generalmente se encuentran
preinstaladas no solo en Visual Studio, sino en otros entornos
donde se soporta el uso de OpenGL. También es necesario hacer
un link con las librerías binarias, en Visual Studio las dos
cosas se verían como:
*/
//Inclusión de las librerías prototipo
#include <gl/gl.h>
#include <gl/glu.h>
//Link con las librerías binarias
#pragma comment(lib, “opengl32.lib”)
#pragma comment(lib, “glu32.lib”)
/*es necesario pasar a algunos conceptos fundamentales del 3d.
SISTEMAS DE COORDENADAS
Para trabajar gráficos bien sea 2d o 3d es necesario tener una
forma de describir la posición de un objeto cualquiera en el
espacio. Para esto es necesario establecer un patrón de
referencia, lo cual se hace generalmente a través de un
sistema de coordenadas y el sistema al que mas estamos
acostumbrados es el de coordenadas cartesianas, en el cual un
punto puede ser expresado como una distancia a través uno (x),
dos (x,y) o tres ejes (x,y,z) mutuamente perpendiculares que
se intersecan en el punto (0,0) en el caso de dos dimensiones
y (0,0,0) en el caso de tres.
OpenGL maneja los sistemas 2d y 3d, aunque el sistema de 2d
sobre píxeles en pantalla es bastante ineficiente, por lo que
en la mayoría de los casos mejor utilizar 3d y simular el 2d
con una proyección ortográfica de la escena.
Si bien la forma en que se representan las coordenadas
cartesianas en matemáticas es bastante estándar (‘x’ positivo
a la derecha y ‘y’ positivo arriba), en los sistemas de dibujo
en el computador hay variaciones dependiendo del sistema de
dibujo sobre el cual se esté trabajando y el caso del 3d es
totalmente dependiente de desde donde, hacia donde y que es
“arriba”. Esto quiere decir que las coordenadas del sistema
abstracto no tienen que ser concordantes con el sistema de
coordenadas sobre la pantalla, por lo que se deber realizar
un proceso llamado mapeo de coordenadas. En este caso el
mapeo debe hacerse del sistema abstracto de coordenadas de
OpenGL al sistema de coordenadas en ventana del sistema
operativo (window, UNIX, linux, mac, etc). El siguiente
esquema muestra tres posibles formas de realizar el mapeo de
coordenadas
El grafico muestra tres de las posibles formas de realizar el
mapeo las coordenadas. En el Modo 1, el punto (0,0) en
coordenadas de dibujo es el correspondiente al extremo
inferior izquierdo de la ventana y el punto (200,200) estará
en el extremo superior derecho. Tal vez es uno de los modos
que parece más “natural”
En el Modo 2, el punto (0,0) en coordenadas de dibujo es el
centro de la ventana y los puntos extremos estarán situados en
los cuatro cuadrantes, en (100,100) superior derecha,
(-100,100) superior izquierda, (-100.-100) inferior izquierda
y (100,-100) inferior derecha. Este modo es similar a la forma
en que lo muestra la cámara por defecto de OpenGL, con el
agregado del eje ‘z’ positivo “saliendo” de la pantalla.
En el Modo 3, el punto (0,0) en coordenadas de dibujo se
encuentra en el extremo superior izquierdo de la ventana y el
punto (200,200) corresponde al extremo inferior derecho. Hay
que notar, que en este modo el eje ‘y’ positivo se encuentra
“cabeza abajo”, es decir, cuando un punto aumenta su
coordenada ‘y’ va hacia abajo, no hacia arriba. Este modo es
usado generalmente por los dispositivos de hardware y es la
forma por defecto de GDI.
Estas son solo algunas formas de mapeo de coordenadas y en
cualquier caso y con un poco de matemáticas (matrices de
transformación) se puede pasar de cualquier modo de mapeo a
otro.
PROYECCION
Los monitores actuales de PC, los televisores, las pantallas
de PDA, de celulares y consolas portátiles son todos
dispositivos bidimensionales, la percepción 3d sobre estos
dispositivos se debe a un conjunto de “trucos” para engañar al
ojo humano y hacerle ver objetos “tridimensionales” sobre un
dispositivo bidimensional, el primero de estos trucos es la proyección. La proyección consiste en generar una imagen bidimensional de una escena tridimensional, algo así como sacarle una foto, o pintar un cuadro de la escena. Tal vez las dos mas conocidas y las que permite trabajar OpenGL directamente son la ortográfica y la perspectiva.
Proyección Ortográfica: En este tipo de proyección se trazan rayos paralelos al plano de proyección (son paralelos porque se considera la fuente de “luz”o centro de proyección en el infinito) y la imagen se forma con aquellos rayos que intersequen al objeto. Esto se ve mas claro en el diagrama
Proyección en Perspectiva: La fuente de rayos en este caso no
se encuentra en el infinito, sino que es un punto localizado
llamado punto de fuga. Los rayos que parten del punto de
fuga e intersecan al objeto son entonces los que formaran la
imagen sobre el plano de proyección
En la proyección en perspectiva los objetos sufren una
deformación por la distancia, a medida que los objetos se
alejan del plano de proyección “disminuyen” su tamaño justo de
la forma en que ocurre cuando un objetos se aleja de nuestros
ojos ( en la figura se muestra como los dos objetos a pesar de
ser de diferentes tamaños producen una imagen casi del mismo
tamaño sobre el plano de proyección, debido a la diferencia de
distancias), es por eso, que esta perspectiva es la mas
utilizada para dar una sensación de realismo, como la que se
necesitan en los juegos, simulaciones y animaciones.
En el caso de OpenGL, tanto en el modo de perspectiva como en
el ortográfico se limita la región del espacio sobre la que se
realizan los cálculos, a esta región se le llama volumen de
vista o volumen de recorte (clipping volume) y en el caso de
la perspectiva también se la llama frustrum por la forma que
tiene. Dicha región se especifica, ya que los objetos por
fuera de este campo a derecha o izquierda no aparecerán en
pantalla y aquellos muy lejanos generarán pocos rasgos, por lo
que de calcularse consumirían recursos innecesariamente (la
consideración de “lejano” depende del programador).
En el caso de la proyección ortográfica el volumen de vista
tiene forma de caja rectangular, por lo que se determina
fácilmente mediante 6 medidas: near, far, top, bottom, left,
right (cerca, lejos, arriba, abajo, izquierda, derecha) y en
el caso de proyección, tiene forma de pirámide truncada de
base rectangular, que puede ser determinada por el field of
view (campo de visión), el aspect ratio ( el alto del plano
mas cercano dividido el ancho), near y far.
Hay que anotar que ambos volúmenes se calculan a partir de la
posición del observador, que en el caso de OpenGL es la cámara.
También hay que observar que las dimensiones del plano más
cercano a la cámara pueden ser mayores o menores a las de la
ventana, por lo el mapeo de las condenadas no será con
relación uno a uno, adicionalmente OpenGL permite definir el
viewport (vista), es decir la región sobre la ventana en la
que se va a realizar el dibujado, que puede ser menor al
tamaño de la ventana.
Hasta este punto el tutorial ha mostrado algunos conceptos
básicos relacionados con la forma en que OpenGL trabaja los
gráficos tridimensionales, conceptos que posteriormente se
verán reflejados en las primeras aplicaciones que se realicen
con OpenGL. Es importante tomar en cuenta que un buen manejo
del álgebra lineal, los TDA como las pilas y conocimientos en
un lenguaje de programación como c++ permitirán avanzar más
rápidamente en el aprendizaje del API OpenGL