Acerca de
Tutoriales
Comunidad
Actualidad
Enlaces





En MacProgramadores
En Internet

Tutorial 1: Preparación del entorno


Vamos a empezar viendo cómo podemos acceder a OpenGL utilizando como herramienta a REALbasic.

El IDE de REALbasic ya dispone de un engine para trabajar con 3D, en este caso basado en la tecnología QuickDraw3D de Apple (que discontinuó al aparecer Mac OS X, pero que ha sido retomada por un grupo de usuarios y programadores entusiastas, resurgiendo cual Ave Fénix con el nombre de Quesa), pero OpenGL está tan extendido en todo tipo de plataformas e implementado en tantos lenguajes de programación distintos que bien merece la pena echarle un vistazo. Vamos a seguir de cerca los excelentes tutoriales publicados en Nehe. En particular, este texto cubre su Tutorial 1.

Para poder trabajar desde REALbasic con OpenGL, necesitamos de un plugin que extienda sus capacidades. Una de las características de REALbasic que lo hacen muy interesante es que permite no solo usar los métodos y las funciones propias, si no que también permite hacer llamadas a las rutinas que residen en el interior de nuestro sistema operativo. No obstante, programar con OpenGL de esta manera nos obligaría a realizar un gran esfuerzo, pues deberíamos escribir las definiciones de esas llamadas de manera repetitiva en diferentes lugares, con la consiguiente merma de claridad y eficiencia. Sin embargo, a través de un plugin que realice este trabajo, nuestra programación es más transparente y nos permite centrarnos en el cómo y el porqué. De esta manera, en lo que es el código OpenGL propiamente dicho, la implementación es muy parecida a la de otros lenguajes, el C por ejemplo, y lo que aprendamos con REALbasic lo podremos transportar si se tercia a otros entornos de desarrollo con pocas modificaciones.

El plugin que necesitamos afortunadamente ya está hecho y es gratuito, y lo podemos encontrar en http://people.vanderbilt.edu/~doug.holton/ en particular, el archivo es el OpenGL Plugin 1.1.2 que encontramos en la sección de software. La documentación es breve pero valiosa, trae abundantes ejemplos y lo que es más importante, nos funciona con cualquier versión de REALbasic que dispongamos. Eso sí, sólo para procesadores PowerPC. Para la elaboración y el testeo de los proyectos hemos usado un PowerPC G3 a 466 Mhz, con 192 Mb y con la versión 4 de REALbasic. Una vez descargado el plugin, el archivo OpenGL Plugin debes situarlo en la carpeta Plugins de la carpeta de REALbasic, como puedes leer en las correspondientes instrucciones de instalación.

Así mismo, y a parte del propio plugin, encontraremos un módulo que contiene ya predefinidas una gran cantidad de constantes de OpenGL útiles para nuestros proyectos. Deberemos siempre arrastrar este módulo, OpenGL Constants Module, sobre la ventana de listado del proyecto en el que queramos trabajar.

Lo primero que hemos de hacer es, pues, esto. Lanza REALbasic y una vez que se haya creado el proyecto por defecto, localiza el módulo .... y arrástralo sobre la ventana. Puedes, si lo deseas, hacer doble click sobre el módulo y echarle un vistazo a las constantes a las que acabamos de aludir.

Ahora abre la ventana que se ha creado con tu proyecto (se llamará Window1, cámbiale el nombre si lo deseas) haciendo doble click sobre ella. Para poder añadir código OpenGL y que éste genere objetos 3D en ella, debemos añadir un control. En la barra de herramientas, si hemos instalado bien el plugin, tendremos a nuestra disposición uno que tiene un icono con un círculo verde y que al pasar el ratón por encima suyo muestra el nombre OGL Plugin. Debemos seleccionarlo y arrastralo sobre la ventana (en la siguiente captura, el icono del plugin es el que está realzado en azul).

Cuando soltemos el ratón, el cuadro del control quedará de color negro, que es el color por defecto de fondo. Ésta y otras propiedades se pueden cambiar en el momento del diseño (es decir, ahora) gracias al panel de propiedades. Algunas de ellas pueden incluso cambiarse en tiempo real, cuando el programa se está ejecutando, como ya veremos en su momento.

Como podemos ver, a parte de las propiedades típicas de todos los controles, las encontramos bajo dos epígrafes denominados Renderer (indican cómo se ha de generar el render, es decir, cómo se han de generar las imágenes 3D en la ventana) y FullScreen Options (permiten que el mundo 3D que estamos tratando de generar en vez de en la ventana, se haga a pantalla completa). Ya las iremos viendo a medida que las necesitemos, ahora sólo señalaremos la primera, Accelerated, que, como es evidente, al seleccionarla hace que si es posible se use nuestra tarjeta 3D para acelerar la visualización de los gráficos. También aquí podemos dimensionar adecuadamente el tamaño del control OGL. Generalmente lo ajustaremos en estos tutoriales al tamaño de la ventana para que la ocupen por completo. Lo más cómodo que podemos hacer, para no estar siempre pendientes del tamaño de ésta, es hacerlo mediante código en el evento 'Open' del control. Haz doble click sobre éste y escribe el siguiente código:

Por supuesto, como es usual en REALbasic, me se refiere al propio control y self se refiere a la ventana que lo contiene, de ahí que los tamaños, después del código anterior, coincidan.

Ya estamos en condiciones de incializar lo que es código OpenGL propiamente dicho. Esto no es necesario que lo hagamos en el propio control OGL ya que las llamadas que haremos modifican los valores globales de visualización y son capturados directamente por el plugin. Por ello vamos a elegir el evento Open de la ventana que lo contiene (de esta manera, separamos por claridad los dos fragmentos breves de código que hemos escrito). La manera más elegante de hacerlo es escribir allí la llamada a un método que inicialice OpenGL, para luego implementar el método a parte. De esta manera, según lo que queramos hacer sólo tendremos que modificar el método y dejar todo lo demás igual. Haz click, pues, en Events y en Open y escribe lo siguiente:

Sub Open()
// Inicializa el mundo OpenGL

InitGL
End Sub

Ahora elige en el menú Edit el item New Method... (o bien pulsa Opción+Comando+M) y en el cuadro de diálogo resultante escribe como nombre del método InitGL (sin las comillas, claro):

Y a continuación, implementemos el método de inicialización de OpenGL:

Sub InitGL()
glShadeModel GL_SMOOTH
glClearColor 0.0,0.0,0.0,0.0
glClearDepth 1.0
glEnable GL_DEPTH_TEST
glDepthFunc GL_LESS
End Sub

Estas son nuestras primeras instrucciones, nuestras primeras cábalas en el lenguaje de OpenGL. Vamos a tratar de esplicarlas una a una. Lo primero que debes notar es que todas las rutinas de OpenGL definidas en el plugin empiezan por gl. Así es cómo las encontrarás en los libros. Los valores numéricos que se les pasan unas veces son coordenadas y otras son constantes predefinidas también en el plugin (siempre a imagen del estándar, igual que en el resto de las plataformas). Éstas últimas empiezan siempre por GL. Los nombres de las rutinas y funciones empiezan por minúscula y cuando son nombres compuestos (en inglés) la inicial se pone en mayúscula. También en mayúsculas se escriben las constantes. Naturalmente, REALbasic no distingue entre mayúsculas y minúsculas, pero si nos acostumbramos a ello ganaremos claridad y coherencia con todas las publicaciones sobre el tema.

Con glShadeModel le decimos cómo debe hacer el sombreado de color de los polígonos al renderizar las escenas. El valor que le pasamos, GL_SMOOTH, indica que debe hacerlo de manera suave y elegante. Con glClearColor indicamos el color con el que se limpiará el fondo de la escena al producirse un borrado. Los valores que encontramos a continuación son colores. Éstos se indican en modo RGB, es decir, el primero es la cantidad de rojo (Red), el segundo de verde (Green) y el tercero de azul (Blue). Han de estar comprendidos entre 0 y 1 según sea nada del color correspondiente o todo. Así, 1,0,0 sería un rojo brillante mientras 0.5,0,0 sería un rojo más oscuro. Nosotros hemos puesto 0,0,0, o lo que es lo mismo, color negro. ¿Y el cuarto cero? Es el valor del parámetro alfa. Más adelante veremos de qué se encarga, por el momento lo dejaremos como está.

Ahora tenemos glClearDepth 1.0, que debemos verlo conjuntamente, pues se refieren a lo mismo, con las dos líneas siguientes, glEnable GL_DEPTH_TEST y glDepthFunc GL_LESS. Todas afectan a cómo debe funcionar el llamado buffer de profundidad que es quien se encarga de llevar la cuenta de cómo de lejos (profundos) se encuentran los diferentes objetos que tenemos en la escena 3D que tratamos de generar. La primera instrucción inicializa el buffer, la segunda activa el test o comprobación de profundidad y la tercera indica el tipo de test que debe usar para ello. Veremos más detalles de ésto más adelante.

Ya hemos escrito una gran cantidad del esqueleto de nuestro proyecto OpenGL. Podemos añadirle todavía un par de cosas, hacer sitio para una rutina que se encargue del dibujado de la escena (a la que llamaremos DrawGLScene) y otra que entre en funcionamiento si cambiamos el tamaño de la ventana (ResizeGLScene). Observa que los nombres de los métodos los escribimos en inglés, por conservar la notación de los tutoriales Nehe.

Vamos a ello. Crea un nuevo método, llámalo DrawGLScene y escribamos el siguiente código:

Sub DrawGLScene()
glClear GL_COLOR_BUFFER_BIT
glClear GL_DEPTH_BUFFER_BIT
glLoadIdentity
End Sub

Aquí es donde pondremos todo el código encargado del dibujado de la escena. En este tutorial de configuración simplemente hemos puesto unas cuantas instrucciones que realizan un limpiado general. En particular, la primera línea, glClear GL_COLOR_BUFFER_BIT indica que limpie la pantalla (con el color que previamente hayamos seleccionado), la segunda glClear GL_DEPTH_BUFFER_BIT borra el buffer de profundidad y la tercera, glLoadIdentity resetea la matriz de visiualización del modelo. ¿Qué significa esto último? En OpenGL hay una serie de matrices que se encargan de llevar el seguimiento de diferentes aspectos. Uno de ellos es la matriz de visualización del modelo (en inglés, ModelView Matrix) y todo lo que debemos saber por el momento es que la instrucción 'glLoadIdentity' lo que hace es poner a cero todos sus elementos. Observa por tanto que todavía no hemos realizado aquí ningún dibujado, tan sólo hemos puesto las cosas a cero, dejándolas listas para empezar.

Algo parecido vamos a hacer con el otro método, ResizeGLScene. En primer lugar volvemos a cambiar el tamaño del control OGL para que se ajuste al nuevo tamaño de la ventana (fíjate que al estar el código fuera del control, en este caso me representa a la ventana y por tanto al control lo hemos de llamar por su nombre, que por defecto es OGLPlug1; si usas otra versión del plugin, este nombre puede cambiar... para evitar este problema, en los próximos tutoriales le cambiaremos el nombre por otro a nuestra elección):

Sub ResizeGLScene()
OGLPlug1.width=me.width
OGLPlug1.height=me.height

A continuación le hemos de decir a OpenGL que ha cambiado el tamaño de la zona en la que se debe hacer el render de la escena, el llamado ViewPort; le decimos que dicha zona empieza en la esquina superior izquierda (0,0) y que tiene las nuevas anchura y altura de la ventana:

glViewPort 0,0,me.width,me.height

Ahora hemos de cambiar la matriz activa. En este caso activamos la matriz de proyección, la que se encarga de que los objetos más lejanos se vean más pequeños y los más cercanos, más grandes. De esta manera, las dos instrucciones siguientes operan sobre ella. La primera, nuestra conocida glLoadIdentity, resetea la matriz; la segunda establece el tipo de proyección. Para ello le indicamos que use un ángulo de visión de 45 grados (primer parámetro) y que la proporción del campo de visión es la correspondiente a la de la ventana, con su anchura y su altura (segundo parámetro, el cociente entre ambas). Los últimos dos parámetros, 0.1 y 100, son dónde se sitúan el primer plano y el fondo de la escena, respectivamente. Nada más cerca del primer valor ni más lejos del segundo se dibujará. Se corresponden con las propiedades Hither y Yon del control View3D implementado en REALbasic.

glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 45.0,me.width/me.height,0.1,100.0

Finalmente, escribimos un código que ya conocemos, el reseteo de la matriz de visualización del modelo, y para ello activamos dicha matriz con la primera instrucción que tenemos a continuación:

glMatrixMode GL_MODELVIEW
glLoadIdentity
End Sub

Ya está. Sólo nos queda hacer las llamadas pertinentes a estos métodos en los lugares adecuados. Como es lógico, serán el evento Paint del control OGL y el evento Resized de la ventana. Selecciónalos y escribe lo siguiente:

Sub Paint(g as Graphics)
// Dibuja la escena OpenGL

DrawGLScene
End Sub

y

Sub Resized()
// Cambia el tamaño de la escena OpenGL

ResizeGLScene
End Sub

Puedes descargarte el código fuente del proyecto de este primer tutorial haciendo click aquí. Observa que no hemos dibujado en realidad nada. Lo que hemos hecho ha sido preparar el camino para el próximo tutorial, en donde veremos aparecer las primeras imágenes.