|
Una vez que vimos en el tutorial anterior cómo debíamos
preparar el entorno para tenerlo listo para empezar a trabajar
con OpenGL, ha llegado el momento de realizar nuestros primeros
pinitos.
Lo que vamos a hacer es muy sencillo por dos razones. La
primera es que simplemente vamos a dibujar un triángulo
y un cuadrado, lo que no requiere mayores complicaciones y
de esta manera, por una parte vamos aumentando muy poquito
a poquito la dificultad y, por otra y a pesar de todo, comprenderemos
conceptos OpenGL muy útiles listos para ser empleados
en los demás tutoriales. De hecho, el presente tutorial
corresponde a los números 2 y 3 de Nehe.
La segunda razón de la simplicidad
de nuestro siguiente proyecto es que la mayor parte del trabajo,
¡ya la tenemos hecha!. En efecto, creado el esqueleto
de toda aplicación simple OpenGL en el tutorial anterior,
ahora sólo queda decirle qué queremos que dibuje;
es decir, implementar el método DrawGLScene.
Por lo tanto sólo tendremos que modificar su código.
Miremos cómo nos quedó dicho
código en el tutorial anterior:

Todo lo que tenemos que hacer es añadir
lo que creamos pertinente detrás de ese glLoadIdentity,
que recordemos que lo que hacía era resetear la matriz
del modelo. En particular nos interesa saber cómo nos
ha dejado respecto de la escena. Como puede imaginarse, tras
ese glLoadIdentity, en el
centro de la imagen está el origen de coordenadas (hacia
el que estamos mirando), con el eje X dirigido
hacia la derecha, el eje Y hacia arriba y
el eje Z hacia nosotros (es decir, estamos
mirando a lo largo de la dirección -Z).
Es exactamente la misma situación que con el control
3D que incorpora el propio REALbasic. Visualmente:

Vamos ahora a dibujar el triángulo.
Para empezar, debemos decidir dónde. Tenemos que hacerlo
algo a la izquierda de la pantalla para dejar sitio al cuadrado
que también queremos dibujar, y un poco más
lejos que el origen de coordenadas pues si no lo tendremos
en nuestras propias narices. La situación semeja un
poco al viejo lenguaje gráfico Logo.
Allí se tenía una tortuga (que llevaba un lápiz)
a la que debía decirse cómo moverse por la pantalla
y, por tanto, había que tener encuenta en todo momento
cuál era su posición. Aquí ocurre lo
mismo, siempre tenemos que conocer cual es nuestra posición
actual, por decirlo de algún modo. Allí tendrán
lugar todas las instrucciones gráficas OpenGL que usemos.
Tras el glLoadIdentity dicha
posición es el origen de coordenadas o (0,0,0). Añadamos
en primer lugar lo siguiente al método DrawGLScene:
glTranslatef
-1.5,0.0,-6.0
Precisamente la instrucción glTranslate
tiene como misión cambiar esa posición actual
a la que hacíamos alusión. Si nos fijamos en
sus parámetros, el valor -1.5
indica que nos hemos de desplazar 1.5 unidades hacia la izquierda
(eje X), el 0.0 indica que no
nos hemos de mover en la dirección vertical de la pantalla
(eje Y) y el -6.0 nos dice que
debemos avanzar 6 unidades en la dirección hacia el
monitor (eje Z). Así mismo, podemos apreciar otra característica
y es que muchas funciones (por ejemplo nuestro glTranslate)
pueden tener añadido un sufijo. Éste puede ser
una f o una d,
entre otros. Su misión es indicar el tipo de valor
numérico que viene detrás, ya que OpenGL tiene
diferentes rutinas optimizadas según sean dichos valores.
Así la f indica float,
que es el tipo de valor numérico que REALbasic llama
Single, mientras que la d
indicaría double, término que
también emplea REALbasic. Nosotros hemos elegido glTranslatef
de acuerdo a la elección del Tutorial 2 de Nehe,
pero volveremos a ello más adelante.
Una vez que nos hemos separado del centro,
ya estamos en disposición de dibujar el triángulo.
Las figuras sencillas se construyen en OpenGL indicando el
tipo que deseas crear. Como siempre, esto es para optimizar
el resultado y para que las tarjetas gráficas lo realicen
rápida y eficientemente (en definitiva, muchas de estas
tarjetas se dedican a dibujar simplemente triángulos
a una velocidad vertiginosa). Cuando queramos dibujar una
figura de tres puntos (como un triángulo), debemos
usar la constante GL_TRIANGLES;
si son cuatro puntos (cuadrado) GL_QUADS;
y si son más GL_POLYGON.
La siguiente porción de código es, de esta forma,
glBegin GL_TRIANGLES
glVertex3f 0.0,1.0,0.0
glVertex3f -1.0,-1.0,0.0
glVertex3f 1.0,-1.0,0.0
glEnd
En este bloque, la primera instrucción
y la última definen el comienzo de la construcción
de un triángulo y su finalización; todas estas
estructuras deben empezar con un glBegin
y terminar con un glEnd.
Por su parte, como podemos ver, los tres vértices del
triángulo se indican con glVertex3f, en primer lugar
el vértice superior, luego el inferior izquierdo y
finalmente el inferior derecho. Y recordemos que todas sus
medidas numéricas son con respecto a la posición
actual: Las coordenadas de todos esos puntos son 0, indicando
que no se desplazan más en el eje Z, sin cambiar el
valor actual que era el -6 (¿recuerdas?). Debemos cuidar
de que halla tres líneas en el interior del bloque,
o más excatamente un múltiplo de tres si es
que queremos dibujar más triángulos. De la misma
manera, si estamos usando GL_QUADS
tendremos 4 líneas o un múltiplo suyo, mientras
que no hay restricciones en el número de líneas
para GL_POLYGON.
Si ahora ejecutamos el proyecto veremos,
quizá para nuestra sorpresa, lo siguiente:

Es decir, nada. ¿Qué ha sucedido?
Algo muy sencillo. Hemos creado la escena, pero no le hemos
dicho a OpenGL que la muestre. Si nos fijamos en las propiedades
del control OGL, veremos que hay una propiedad booleana que
por defecto es verdadera; se trata de DoubleBuffered:

El doble buffer significa
que toda la escena OpenGL se genera a parte de la escena que
actualmente se muestra en pantalla. Eso tiene ventajas a la
hora de hacer animaciones más suaves o para controlar
con mayor detalle el aspecto que va a tener la imagen final.
Cuando nos interesa mostrarla, una vez que ya la tengamos
construída, sólo debemos volcar el buffer en
la pantalla. Eso se consigue intercambiando los buffers con
la siguiente instrucción que es la que hemos de añadir
a continuación de lo anterior:
aglSwapBuffers
De esta manera, el resultado que tendremos
una vez compilado el proyecto es el siguiente:

Bien, ya tenemos dibujado el triángulo.
Ahora sólo tenemos que desplazarnos hacia la derecha
una distancia conveniente y hacer lo propio con el cuadrado.
Para ello, añadamos el siguiente código al final
del método pero antes de la última línea
que hemos puesto, es decir, antes de aglSwapBuffers:
glTranslatef 3.0,0.0,0.0
glBegin GL_QUADS
glVertex3f -1.0,1.0,0.0
glVertex3f 1.0,1.0,0.0
glVertex3f 1.0,-1.0,0.0
glVertex3f -1.0,-1.0,0.0
glEnd
Con la primera línea conseguimos movernos
hacia la derecha (eje positivo de las X, primera coordenada)
3 unidades. Una vez allí comenzamos el bloque que define
un cuadrado, haciéndolo a partir de sus vértices
en las cuatro líneas siguientes. Se trata, respectivamente,
del vértice superior izquierdo, el superior derecho,
el inferior derecho y el inferior izquierdo. Para terminar,
cerramos el bloque que define el cuadrado con glEnd.
Podemos hacer ya la prueba final; ejecutamos
el proyecto y obtenemos la escena deseada:
¿Le damos color a la escena? Para
hacerlo debemos usar simplemente la instrucción OpenGL
glColor3f. Como podemos
adivinar de su nombre, para especificar el color precisa de
tres parámetros, al estilo del color RGB que ya nos
resultará familiar si hemos manejado REALbasic; el
primero indica la cantidad de rojo, el segundo la de verde
y el tercero la de azul. En este caso, los valores que demos
deben estar comprendidos entre 0.0 (ausencia) y 1.0 (color
puro). Así, (1.0,0.0,0.0) es un rojo brillante puro
y (0.5, 0.5, 1.0) es una mezcla de color más bien azulada.
Debemos tener en cuenta que en cuanto usemos esta instrucción,
todo lo que dibujemos se hará en el color indicado.
Cambiemos a este último color el cuadrado
blanco. Para ello bastará que escribamos lo siguiente
justo antes de la definición del cuadrado, es decir,
antes del glBegin GL_QUADS:
glColor3f 0.5,0.5,1.0
Pero no sólo podemos conseguir colores
solidos, también gradientes. Eso lo podemos llevar
a la práctica con el triángulo; bastará
con que le asignemos un color distinto a cada vértice
para que OpenGL rendere la imagen con el gradiente de color
resultante entre ellos (fijémonos que estamos con lo
que se denomina, color suave). La nueva construcción
del triángulo quedará así:
glBegin GL_TRIANGLES
glColor3f 1.0,0.0,0.0
'color rojo
glVertex3f 0.0,1.0,0.0
glColor3f 0.0,1.0,0.0
'color verde
glVertex3f -1.0,-1.0,0.0
glColor3f 0.0,0.0,1.0
'color azul
glVertex3f 1.0,-1.0,0.0
glEnd
El resultado de la coloración de la
escena es la siguiente:

Puedes descargarte el código
fuente del proyecto de este tutorial haciendo
click aquí. Lo próximo que haremos
será añadir movimiento a nuestro mundo, que
por el momento es estático y algo aburrido.
|