Sie sind auf Seite 1von 55

5 Ingeniera Informtica

Informtica Grfica

Capitulo 2:

Introduccin a OpenGL

Montserrat Mateos Snchez

Introduccin OpenGL
2.1. INTRODUCCIN ...................................................................................................................... 3 2.2 RESEA HISTRICA ............................................................................................................... 4 2.3. QU ES OPENGL? .................................................................................................................. 5 2.3.1. CARACTERSTICAS DE OPEN GL .............................................................................................. 5 2.4. APLICACIONES ........................................................................................................................ 8 2.5. LIBRERAS RELACIONADAS CON OPENGL ................................................................. 11 2.5.1 GLUT (O PENGL UTILITY TOOLKIT) ..................................................................................... 12 2.5.1.1. Caractersticas .............................................................................................................. 12 2.5.1.2. Funciones de GLUT...................................................................................................... 12 2.5.2 LIBRERA AUX ...................................................................................................................... 23 2.5.2.1. Caractersticas .............................................................................................................. 23 2.5.2.2. Funciones ...................................................................................................................... 24 2.6. PROGRAMACIN CON OPENGL PARA WINDOWS. WIGGLE ................................. 27 2.6.1. FUNCIN W INMAIN .............................................................................................................. 28 2.6.2. FUNCIN W NDPROC ............................................................................................................. 30 2.6.3. DIBUJAR EN UNA VENTANA DE WINDOWS............................................................................. 32 2.7. USAR OPENGL ........................................................................................................................ 38 2.7.1. DIBUJAR EN 3D..................................................................................................................... 38 2.7.1.1. Dibujar Objetos ............................................................................................................ 38 2.7.2. TRANSFORMACIN DE COORDENADAS ................................................................................. 43 2.7.3. COLOR Y SOMBRAS............................................................................................................... 46 2.7.4. LUCES Y LMPARAS ............................................................................................................. 48 2.7.5. GRFICOS P LANOS EN OPENGL ............................................................................................. 51 2.7.5.1. Mapas de bits ................................................................................................................ 51 2.7.5.2. Mapas de pxeles ........................................................................................................... 53 2.7.6. TEXTURAS............................................................................................................................. 54 2.8. CONCLUSIONES ..................................................................................................................... 54 2.9. BIBLIOGRAFA....................................................................................................................... 55

2. Introduccin OpenGL
2.1. Introduccin
Utilizar informacin grfica se ha convertido en el mundo de la computacin en un recurso habitual para la comunicacin entre los ordenadores y los usuarios. Este tipo de informacin no solo se usa para la gestin de las aplicaciones a travs de la utilizacin de mens y ventanas, sino que cada vez se usa ms para la representacin grfica de imgenes reales. Las imgenes reales o con efectos realistas se consiguen aproximando al mximo la representacin grfica que se genera en la pantalla del ordenador a las imgenes que percibe el ser humano con la vista. Para dar realismo a las imgenes por ordenador se utilizan tcnicas de sombreado, brillo, nieblas, transparencias etc.

El empleo de imgenes tridimensionales o con realismo grfico es un recurso ms, dentro de los que se dispone para el desarrollo de cualquier aplicacin informtica.

El uso de manera eficiente de todos estos recursos, as como, la estandarizacin de los procedimientos de generacin de grficos por computador, se abordaron por primera vez con las libreras de grficos OpenGL.

El que todas las aplicaciones que presentan grficos por computador sigan los mismos patrones, representa una importante ventaja en cuanto a la portabilidad entre sistemas diferentes. Si adems esos patrones se ajustan a modelos y mtodos avanzados y eficientes para la representacin grfica por ordenador, entonces se tiene la herramienta ideal.

Todo esto lo cumple la librera OpenGL, compatibilidad y versatilidad. Pocos efectos grficos quedan fuera de las capacidades que tienen las OpenGL y cada vez ms sistemas permiten la ejecucin de aplicaciones basadas en OpenGL.

En ste capitulo de introduccin a OpenGL, primero se explicar que es OpenGL, junto sus caractersticas ms destacadas, posteriormente se explicarn de forma muy rpida algunas de las libreras relacionadas con sta y por ltimo y de forma rpida se mostrarn algunas de las funciones de OpenGL. 3

2.2 Resea Histrica


OpenGL, se puede considerar como una norma industrial. Su antecesora fue GL (Graphics Library) desarrollada por Silicon Graphics, Inc. (lder mundial en grficos y animaciones por ordenador) en 1982. Iris GL fue la primera API (Aplication Programing Interface) de programacin para las

estaciones grficas IRIS de alto rendimiento de la compaa. Estas mquinas, contaban con un hardware optimizado para la visualizacin de grficos. Con ste hardware, se poda entre otras cosas, realizar transformaciones matriciales muy rpidas, adems proporcionaban soporte grafico para el buffer de profundidad y otras prestaciones.

Las subrutinas de GL hacen uso directo de las tarjetas grficas instaladas en las estaciones de trabajo; los grficos GL normalmente se refieren a grficos hardware, en oposicin a grficos X Windows, que se refieren a grficos software. Cuando se realiza renderizacin software, la imagen grfica es creada va el software que est corriendo en la mquina. La imagen renderizada es entonces visualizada en una ventana llamada X. Con el renderizado por hardware, la mayor parte del trabajo de crear la imagen la hace la tarjeta grfica.

GL incluye soporte para conseguir desde dispositivos la entrada de datos, crear y dibujar en ventanas, configuracin y control del buffer y renderizado 3D bsico y avanzado.

GL fue elegido por IBM como el API para soportar los adaptadores grficos que fueron instalados en las estaciones de trabajo de la serie RS/6000, y fue usado por mas de 1500

aplicaciones incluyendo IBM Data Explorer, AVS, Grass, (www.ats.ucla.edu)

Pero, IRIS GL no era portable a otras plataformas hardware con lo que se trabaj sobre ello y apareci OpenGL.

Este nuevo lenguaje, deba ofrecer la potencia de GL y a la vez, ser ms abierto para su adaptacin tanto a otras plataformas hardware as como a otros sistemas operativos.

El 1 de Julio de 1992 se present la versin 1.0 de la especificacin de OpenGL. Poco despus, en la sala de exhibicin de empresas se expuso la proyeccin de secuencias de pelculas 4

como Terminator 2, El juicio final y algunas aplicaciones mdicas grficas creadas con OpenGL, y esto tuvo un gran impacto.

En 1995 se aprob la especificacin final de la versin 1.1 de OpenGL. (Sweet, M. et all)

Actualmente, existe la Plataforma para Revisiones de la Arquitectura OpenGL (ARB), est formada por SGI, DEC , IBM, Intel, Microsoft, se rene dos veces al ao y es la que decide las mejoras de OpenGL. Estas reuniones o encuentros, son de carcter pblico y puede asistir cualquier compaa aunque solo tienen derecho a voto las anteriores.

2.3. Qu es OpenGL?
OpenGL, es una interfaz software para grficos por hardware. Es una biblioteca de trazado de grficos de alto rendimiento, fcil de usar, intuitivo, portable, en el que el programador describe las llamadas necesarias a funciones y comandos para conseguir una escena, apariencia o efecto. Consta de 120 comandos o funciones distintos que tienen la misma sintaxis; e stas funciones, se pueden usar para especificar objetos y las operaciones necesarias para desarrollar aplicaciones grficas interactivas 2D y 3D; Los algoritmos que utiliza Silicon Graphics. (Neider, J. et all). fueron desarrollados y optimizados por

2.3.1. Caractersticas de OpenGL OpenGL es por diseo independiente del hardware, sistema operativo o sistema de ventanas. Las funciones de OpenGL trabajan de la misma forma en cualquier plataforma, es decir, se pueden llamar a las funciones de OpenGL desde un programa escrito y obtener los mismos resultados independientemente del lugar donde el programa se este ejecutando. Esto hace que sea portable y la programacin sea ms fcil con OpenGL que con un API integrado en el sistema de ventanas. Para conseguir la independencia del hardware, OpenGL no incluye ninguna funcin para la gestin de ventanas, interactividad con el usuario ni manejo de ficheros. Cada sistema operativo tiene sus propias funciones para realizar estas tareas, por lo que, los programas creados con OpenGL deben interactuar con el sistema de ventanas de la plataforma donde o l s grficos sern visualizados ya que los grficos, son normalmente visualizados en una ventana. Hay varias 5

herramientas y libreras para el manejo de ventanas que han sido desarrolladas para trabajar con OpenGL. (www.linuxfocus.org)

Est diseado para trabajar eficientemente en un entorno cliente/servidor; Existe un protocolo para mover por la red los comandos de OpenGL entre el servidor y el cliente. De esta forma el ordenador que visualiza los grficos no es el mismo que ejecuta el programa de grficos, es decir, el programa o aplicacin que produce los grficos puede correr en otra maquina distinta en la que se estn visualizando los grficos, e incluso el cliente y el servidor no tienen porque ejecutarse en el mismo tipo de plataforma o sistema operativo. (www.ats.ucla.edu)

Las funciones de OpenGL como ya se coment anteriormente, estn diseadas para permitir crear grficos 2D y 3D con especial nfasis en 3D. OpenGL tiene funciones o primitivas con las que se podr realizar modelado 3D, transformaciones, utilizacin de color e iluminacin, sombras, mapeado de texturas, animacin, movimiento borroso....

Para conseguir rendimiento no tiene comandos para describir modelos complejos (mapas, pjaros, molculas, etc) sino que tiene primitivas que permiten dibujar puntos, lneas y polgonos, y es el programador el que tendr que construir objetos ms complejos.

Con OpenGL cualquier comando es ejecutado inmediatamente. Cuando en un programa se especifica que dibuje algo, lo hace inmediatamente. Pero existe la opcin de poner comandos en Display Lists. Una display list es una lista no editable de comandos almacenados para una ejecucin posterior y se puede ejecutar ms de una vez. Por ejemplo, se pueden usar para redibujar el grafico cuando el usuario cambia el tamao de la ventana, tambin se puede utilizar para dibujar la misma forma mas de una vez si esta se repite como un elemento de un grafico.

Todos los comandos de OpenGL utilizan la misma sintaxis. Todos ellos usan el prefijo gl y despus la palabra que forma el comando con la primera letra en mayscula. Tambin en algunos comandos va seguido como sufijo un numero y una letra, que indican el nmero de parmetros del comando y el tipo de sus argumentos. As por ejemplo, glColor3f(1.0,1.0,1.0) ste comando es de OpenGL y permite cambiar el color activo (Color) y tendr 3 parmetros de tipo float.

Adems, algunos comandos pueden llevar la letra v al final que indica que el parmetro de la funcin es un puntero a un array o vector.

OpenGL se puede considerar como una mquina de estados. Las aplicaciones se pueden poner en varios estados que permanecen en efecto hasta que se cambian. Por ejemplo el color, se puede poner un color y dibujar un objeto, y ese color seguir activo hasta que se ponga otro color. Igual que ocurre con el color, OpenGL tiene otra variables de estado para otros controles tales como la vista actual y transformacin de proyecciones, posiciones y caractersticas de luces y propiedades del material que los objetos estn siendo dibujados. Algunas de estas variables de estado se pueden habilitar o deshabilitar con los comandos glEnable() o glDisable(). Cada variable de estado tiene un valor por defecto y el programador podr preguntar el valor actual de cada una de estas variables. Adems, tambin se podr almacenar el valor de estas variables de estado para posteriormente recuperarlo. Las funciones que permiten hacer esto son glPushAttrib() y glPopAttrib().

OpenGL ha sido diseado para ser llamado por C, C++, Fortran, Ada, Java. Aunque todos los manuales y documentacin de opengl vienen con C. Otros lenguajes de programacin como Visual Basic que pueden invocar a funciones de C, tambin podrn hacer uso de OpenGL.

Con OpenGL se debe seguir un o rden para la realizacin de las operaciones graficas necesarias para renderizar una imagen en la pantalla, lo primero que se debe hacer es construir formas desde la primitivas geomtricas, despus disponer los objetos en el espacio tridimensional y seleccionar la posicin deseada para ver la composicin, posteriormente calcular el color para todos los objetos y por ltimo convertir la descripcin matemtica de los objetos y su informacin de color asociada a pxeles en la pantalla (rasterizacin).

OpenGL t iene sus propios tipos de datos para as hacer el cdigo mas fcilmente portable, aunque estos tipos de datos corresponden con los tipos de datos de C, y por tanto se podrn utilizar unos u otros indistintamente. Pero si es importante tener en cuenta que si se utilizan los tipos de datos de C, dependiendo del compilador y entorno habr unas reglas para planificar el espacio de memoria de varias variables. As que, para evitar esto se deben utilizar los tipos de Opengl.

Todos los tipos de opengl tienen el sufijo gl y a continuacin el tipo de C correspondiente. La siguiente tabla nos lo muestra:

Tipo de dato en OpenGL Glbyte Glshort GLint, Glsizei GLfloat, GLclampf Gldouble, GLclampd GLubyte, GLboolean Glushort GLuint, GLenum, Glbitfield
Tabla 2.1: Tipos de OpenGL

Definicin como tipo C

Representacin interna

Char con signo Short Long Float Double Unsigned char Unsigned short Unsigned long

Entero de 8 bits Entero de 16 bits Entero de 32 bits Coma flotante de 32 bits Coma flotante de 64 bits Entero de 8 bits sin signo Entero de 16 bits sin signo Entero de 32 bits sin signo

(Huescar M. et all)

2.4. Aplicaciones
OpenGL es la API para grficos 3D ms utilizada para aplicaciones grficas, tanto profesionales como de consumo, as como para juegos y se usa para una amplia variedad de fines. Se pueden distinguir las siguientes categoras:

Software para modelado, rendering y efectos animados. Algunas aplicaciones podran ser: ? ? Carrara, modelado, rendering, construccin de escenas y animaciones ? ? Inferno, crear efectos visuales 3d para pelculas ? ? 3Space Publisher, para crear grficos y animaciones 3D para la web

Aplicaciones CAD para diseo, ingeniera y arquitectura: ? ? SoftCAD ? ? Kinetix ? ? Actify

Herramientas y librerias para el desarrollo de aplicaciones y juegos. 8

? ? 3D Charting Toolkit ? ? 3D MasterSuite ? ? AllegroGL ? ? 3D game engine scene composer & player ? ? Surrender

Juegos ? ? Azteroids ? ? Diablo II ? ? Quake II ? ? Star Trek Voyager Elite Force ? ? Ultimate Golf

Realidad virtual ? ? VRWave ? ? V-Realm Builder ? ? Envision

Salvapantallas ? ? Physical Toy screen saber ? ? Screensaver fighter game

Aplicaciones de simulacin y visualizacin ? ? Amira, visualizacin 3D para medicina ? ? HiQ, visualizacin de datos de laboratorio ? ? SimFUSION , Simulador y generador de imgenes

Aplicaciones cientficas, mdicas y de anlisis de datos ? ? Momol, modelado molecular ? ? Functor, anlisis grficos de funciones algebraicas ? ? MapRender3D ? ? Solar System Simulation

(www.opengl.org) 9

Algunos ejemplos sencillos de escenas que se pueden hacer con OpenGL podran ser los siguientes:

Figura 2.2: Figuras geomticas Figura 2.1: Animacin

10

Figura 2.5: Perspectiva Figura 2.6: Perspectiva

Figura 2.7: Sombras

Figura 2.8: Texturas

2.5. Libreras relacionadas con OpenGL


Hay que destacar que la API de OpenGL est divida en tres libreras distintas: AUX, (denominada tambin librera de recursos, glaux.lib, glaux.h) . Es una librera que proporciona una estructura de trabajo independiente de la plataforma para invocar a las funciones de opengl. Todas las funciones comienzan con el sufijo aux . Funciones que definen OPENGL (es la propia librera, opengl32.dll, gl.h). La librera glu32.dll, y su cabecera glu.h. Esta librera contiene funciones tiles que hacen el trabajo diario ms sencillo, como el dibujo de esferas, discos, cilindros. Esta escrita usando funciones y comandos de opengl. 11

Otro aspecto a tener en cuenta a la hora de hablar de las libreras relacionadas con OpenGL, es que la especificacin de OpenGL se aisl de cualquier dependencia de un sistema de ventanas concreto, y por tanto, es el sistema de ventanas nativo el encargado de abrir y trazar ventanas. Por eso OpenGL debe comunicarse con el sistema nativo a travs de librerias adicionales auxiliares, como por ejemplo GLX (interaccin entre OpenGL y el sistema Windows), GLUT, y otras.

2.5.1 GLUT (OpenGL Utility Toolkit) 2.5.1.1. Caractersticas GLUT ofrece una interfaz comn para mltiples plataformas para el manejo de ventanas, buffers, renderizacin de texto, entrada por teclado y mens, por lo que, los desarrolladores podrn usar un interface comn para el sistema de ventanas independiente de la plataforma, es decir, las aplicaciones de OpenGl que usan GLUT se pueden portar entre plataformas sin tener que introducir muchos cambios en el cdigo fuente.

Es un interfaz de programacin con enlaces para ANSI C y FORTRAN que, permitir e scribir programas OpenGL independientes del sistema de ventanas.

Al igual que OpenGL, utiliza una serie de variables de estado que duran toda la ejecucin de la aplicacin, y luego el programador podr modificar el valor de dichas variables para ajustarlas.

Es pequeo y fcil de aprender. Las funciones de GLUT son simples, tienen pocos parmetros y no manejan punteros excepto los punteros a cadenas de caracteres y manejadores de fuentes que se le pasan a algunas funciones.

2.5.1.2. Funciones de GLUT Las funciones de GLUT se pueden dividir o clasificar segn su funcionalidad: ?? Inicializacin

12

Antes de empezar a GLUT.

trabajar

hay que inicializar el estado de la mquina de estados de

Todas las funciones de inicializacin comienzan por glutInit

Dentro de este grupo de funciones tendramos las siguientes:

glutInit (int **argcp, char **argv ) Modifica las variables de estado de Glut y negocia una sesin con el sistema de ventanas. Los parmetros que se le pasan son las variables argc y argv de la funcin main de C respectivamente.

glutInitWindowPosition(int x, int **y) Indica mediante x e y la posicin en la pantalla en pxeles de la ventana.

glutInitWindowsSize(int width, int **height) Indica mediante width, height ventana el ancho y alto respectivamente en pixeles de la

glutInitDisplayMode(unsigned int mode) Indica mediante mode el modo de display, este valor puede ser entre otros

GLUT_RGBA, GLUT_RGB, GLUT_INDEX, GLUT_SINGLE, GLUT DOUBLE GLUT_LUMINANCE..

El siguiente trozo de cdigo nos muestra como inicializar la mquina de estados,

glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGBA); glutInitWindowPosition(0,0); glutInitWindowSize(500,500);


Listado 2.1: Inicializacin con Glut el sistema de ventanas

13

En este ejemplo se utiliza doble buffer. El doble buffer se utiliza para animaciones, porque as se puede eliminar el parpadeo cuando cambia la imagen en la secuencia de animacin.

?? Gestin de ventanas Para abrir una ventana, o enviar la orden de abrir una ventana para la aplicacin al sistema de ventanas subyacente se hace con,

int glutCreateWindow(char **name) donde name es el nombre de la ventana, nos devolver el identificador de la ventana

Adems de sta funcin existen otras funciones para el manejo de ventanas, a lgunas de ellas son las siguientes:

glutSetWindow(int winId) Establece la ventana con el identificador winId como ventana actual

glutGetWindow(void) Solicita el identificador de la ventana actual

glutDestroyWindow(int winId) Cierra la ventana especificada por winId

glutPostRedisplay(void) Solicita que la ventana sea redibujada

glutPositionWindow(int x, int y) Solicita un cambio de posicin de la ventana a la posicin indicada por x e y

glutReshapeWindow(int width, int height) Solicita un cambio en el tamao de la ventana, el nuevo tamao vendr dado por width y height

glutFullScreen() 14

Solicita que la ventana actual sea cambia a tamao completo

glutShowWindows(void) Solicita que la ventana sea mostrada

glutHideWindows(void) Solicita que la ventana se oculte

glutIconifyWindow(void) Solicita que la ventana se minimice

glutSetWindowTitle(char *name) Pone la barra de ttulo en la ventana.

glutSetIconTitle(char *name) Pone el ttulo en la ventana. Minimizada.

15

El listado 2.1 nos muestra como crear una ventana y como crear un dibujo en ella.

#include <GL/glut.h> void pintar(void) { glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glPointSize(50); glBegin(GL_POINTS); glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(-0.25,-0.25); glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(0.25,0.25); glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(-0.25,0.25); glColor3f(0.5f, 0.5f, 0.5f); glVertex2f(0.25,-0.25); glEnd(); glFlush(); };

int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(0,0); glutInitWindowSize(500,500); glutCreateWindow("Mi primera ventana"); glutDisplayFunc(pintar); glutMainLoop(); return 0; }

Listado 2.2: Creacin y dibujado de ventanas

16

La ejecucin de ste pequeo programa nos mostrar una ventana como la siguiente,

Figura 2.9: Ventana creada con Glut.

?? Usar subventanas

A la hora de crear subventanas tenemos que tener en cuenta los siguientes aspectos:

Cuando se crea una ventana, hay que guardar el identificador de la ventana; el identificador es un entero devuelto por la funcin glutCreateWindow

Solo puede haber una funcin callback idle() en una aplicacin, y esta funcin es global para todas las ventanas de la aplicacin, por lo tanto, a la hora de implementar esta funcin tendr que estar implementado el refresco para todas las ventanas.

Para crear una subventana, hay que proporcionar el identificador de la ventana superior y las coordenadas para la subventana y el ancho y el alto para la subventana.

17

Cuando Glut abre una subventana, le proporciona un contexto completo, con lo que hay una perdida de rendimiento porque el driver de la tarjeta de video tiene que refrescar la memoria para cada una de las ventanas.

Para la creacin de una subventana se utiliza la siguiente funcin, int glutCreateSubWindow(int winId, int x, int y, int width, int height)

?? Procesado de Eventos

GLUT esta dirigido por eventos, es decir, hay un bucle continuo que comienza despus de la inicializacin y va procesando todos los eventos. Los eventos pueden ser por ejemplo un botn del ratn que se pulsa, una ventana que se abre, se redimensiona, se cierra, una tecla del teclado que se ha pulsado...

Los eventos se registran como rutinas de registro callback .

Despus de registrar todos los eventos en el programa hay que llamar a la funcin de procesado de eventos que es glutMainLoop()

Funciones de registro de callback:

glutDisplayFunc(void * void) Registra la funcin de display para la ventana actual, como parmetro se le pasa la funcin que se ejecutar cuando se produzca el evento de visualizar la ventana.

glutReshapeFunc(void *void( int width, int height)) Registra la funcin de cambio de tamao para la ventana actual, como parmetro se le pasa la funcin que llamara cuando se cambie de tamao y el nuevo tamao.

glutIdleFunc(void * void) Registra la funcin idle, esta funcin es llamada cuando no hay entradas de usuario, como parmetro se le pasa la funcin que se ejecutar. 18

glutKeyboardFunc(void *void, unsigned charkey, int x, int y) Registra la funcin de pulsado de teclado para la ventana actual.

Otra rutina til en animaciones es: glutSwapBuffers() Intercambia los buffers, mostrando en la ventana de golpe todo lo que se ha dibujado. ?? Uso de teclado

En el momento de pulsar una tecla en el teclado, el driver de proceso de eventos de GLUT registra un evento de teclado. Estos eventos son manejados por las funciones callback de teclado. La funcin asociada de callback toma como argumentos el cdigo ASCII asociado con la tecla y la posicin x,y del cursor. La generacin de callbacks de teclado se puede deshabilitar con la funcin

glutKeyBoardFunc() y pasndole el valor NULL. ?? Trazar texto en una ventana OpenGL

La librera OpenGL no tiene funciones para manejar el trazado de texto, solo tiene unas directivas muy primitivas para el trazado de bitmaps, por lo que cada uno tiene que hacerse su propia librera de bitmaps para cada carcter. GLUT proporciona unas funciones que permiten dibujar un carcter en una posicin especificada: GlutBitmapCharacter GlRasterPos

Con el siguiente programa se puede ver gran parte de estas funciones como son crear una subventana, trazar texto, dibujar en una ventana, tratar el evento de pulsacin de teclado o cambiar el tamao de la ventana.

19

#include <string.h> #include <stdio.h> #include <GL/glut.h> #include <GL/gl.h> int IdMain; int IdSub;

static double tiempo = 0.0; static double angulo = 0.0; static char label[100]; void pintarcadena (char *s) { unsigned int i; for (i = 0; i < strlen (s); i++) glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24, s[i]); };

void pintarventana(void) { glutSetWindow (IdMain); glClearColor(1.0F, 1.0F, 1.0F,1.0F); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity (); glPushMatrix (); glRotatef (angulo, 0.0, 0.0, 1.0); glBegin (GL_POLYGON); glColor3f (1.0F, 0.0F, 0.0F); glVertex2f(0.0F, 0.5F); glColor3f (0.0F, 1.0F, 0.0F); glVertex2f(0.5F,0.5F); glColor3f (0.0F, 0.0F, 1.0F); glVertex2f(0.5F,0.0F); glColor3f (1.0F, 0.0F, 0.0F); glVertex2f(0.0F,0.0F); glEnd (); glPopMatrix (); glutSwapBuffers (); };

void pintarsubventana () { glutSetWindow (IdSub); glClearColor (1.0, 1.0, 1.0, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f (0.0F, 0.0F, 0.0F); glBegin (GL_LINE_LOOP); glVertex2f (0.0F, 0.0F); glVertex2f (0.0F, 0.99F); glVertex2f (0.999F, 0.99F); glVertex2f (0.999F, 0.0F); glEnd ();

20

glColor3f (1.0F, 0.0F, 1.0F); sprintf (label, " Subventana "); glRasterPos2f (0.40F, 0.70F); pintarcadena (label); sprintf (label, " de OpenGL creada con GLUT "); glRasterPos2f (0.33F, 0.35F); pintarcadena ( label); glutSwapBuffers (); };

void tamanoventana (int w, int h) { glViewport (0, 0, w, h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D (-1.0F, 1.0F, -1.0F, 1.0F); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glutSetWindow (IdSub); glutReshapeWindow (w - 10, h / 10); glutPositionWindow (5, 5); glutSetWindow (IdMain); }; void tamanosubventana (int w, int h) { glViewport (0, 0, w, h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D (0.0F, 1.0F, 0.0F, 1.0F); }; void teclado (unsigned char key, int x, int y) { static int info_banner = 1; switch (key) { case 'i': case 'I': if (info_banner) { glutSetWindow (IdSub); glutHideWindow (); } else { glutSetWindow (IdSub); glutShowWindow (); }; info_banner = !info_banner; break; case 'q': case 'Q': exit (0); break; };

21

}; void idle (void) { angulo += 5.0; tiempo += 0.1; glutSetWindow (IdMain); glutPostRedisplay (); glutSetWindow (IdSub); glutPostRedisplay (); }; int main (int argc, char **argv) { glutInit (&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition (20, 20); glutInitWindowSize (600, 600); IdMain = glutCreateWindow ("Ventana con subventanas"); glutDisplayFunc (pintarventana); glutReshapeFunc (tamanoventana); glutKeyboardFunc (teclado); glutIdleFunc (idle); IdSub = glutCreateSubWindow (IdMain, 20, 20, 600 - 10, 600 / 10); glutDisplayFunc (pintarsubventana); glutReshapeFunc (tamanosubventana); glutMainLoop (); return 0; };
Listado 2.3: Crear ventanas y subventanas con Glut

El ejemplo anterior nos dara la siguiente salida,

Figura 2.10: Ventana que contiene una subventana creada con Glut.

22

?? Mens

Una forma ms de comunicacin entre el usuario y una aplicacin es el uso de mens, por lo tanto, es una cuestin importante a tener en cuenta cuando se realizan aplicaciones. GLUT tambin dispone una serie de funciones para la creacin de mens. Algunas de ellas seran:

int glutCreateMenu(void (f*) (int)) mainMenu(int) subMenu(int) glutAddMenuEntry(char *s, int nr) glutAddSubMenu(char *s, int nr) glutAttachMenu()

(www.linuxfocus.org, 1998), (Kilgard, M., 1996)

2.5.2 Librera AUX 2.5.2.1. Caractersticas Esta librera no forma parte de la especificacin de OpenGL, pero aparece en todas las plataformas a las que se porta opengl. Fue creada principalmente para facilitar el aprendizaje de OpenGL, olvidndose de los detalles de la plataforma y sistema operativo. Se utiliza para probar cosas programadas en OpenGL, pero no para escribir aplicaciones serias, por lo tanto no se debe utilizar demasiado. Las funciones de la librera son rudimentarias y permiten gestionar la creacin y manipulacin de ventanas, las entradas de usuario, dibujar figuras 3D completas.... AUX, tambin tiene funciones para operaciones especificas del sistema, como pueden ser intercambio de buffers y apertura de imgenes, entre otras. Internamente la librera AUX hace uso de la API nativa del entorno para estas funciones. Las funciones de la librera son iguales en todas las plataformas.

(Sweet, M.)

23

Al igual que la librera GLUT tiene funciones para la inicializacin, el manejo de ventanas, el procesado de eventos, aunque la librera AUX es menos completa que GLUT.

2.5.2.2. Funciones ?? Inicializacin Las funciones utilizadas para la inicializacin son: auxInitDisplayMode(Glbitfield mascara) Inicializa el modo de visualizacin en la ventana. Es la primera funcin a la que hay que llamar. El parmetro indicar las caractersticas de la ventana.

auxInitPosition(GLint x, GLint y, Glsizei ancho, Glsizei alto) Especifica la posicin en la pantalla y el tamao de la ventana. ?? Gestin de ventanas Para crear e inicializar la ventana de dibujo se utiliza la funcin auxInitWindow

auxInitWindow(Glbyte *cadenatitulo) Inicializa y muestra la ventana de generacin de OpenGL. El parmetro ser el ttulo que aparecer en la barra de la ventana.

El siguiente ejemplo muestra como inicializar el sistema y la creacin de una ventana.


#include <gl\glaux.h> #include <gl\gl.h> void CALLBACK nada() { }; void main(void) { auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0,0,350,350); auxInitWindow("Mi ventana creada con la librera AUX"); glClearColor(1.0F, 1.0F, 1.0F, 1.0F); glClear(GL_COLOR_BUFFER_BIT); glFlush(); auxMainLoop(nada); }
Listado 2.4: Crear ventanas con la librera Aux

24

?? Rellamada Ests funciones, son muy similares a las que tiene GLUT para el procesado de eventos, es decir, son funciones que se propia librera llamar cuando se necesite, por ejemplo, cuando se cambie de tamao una ventana, cuando se pulse una tecla o un botn del ratn, cuando se necesite redibujar la ventana.... Para declarar e implementar funciones que son llamadas por estas funciones de rellamada se debe poner delante la sentencia CALLBACK.

Las principales son las siguientes: auxMainLoop(AUXMAINPROC func) Permite especificar la funcin que debe usarse para actualizar la ventana OpenGL. El parmetro ser la funcin que se llamar cuando hay que refrescar la ventana.

auxReshapeFunc(AUXRESHAPEPROC func) Permite especificar la funcin que debe llamarse cuando se cambie de tamao la ventana.

auxIdleFuncion(AUXIDLEPROC func) Permite especificar la funcin de rellamada que debe llamarse cuando no hay otra actividad pendiente.

auxKeyFunc(GLint tecla, void (*funcion(void)) Permite especificar la funcin de rellamada cuando se pulse la tecla tecla que se le pasa como parmetro.

auxMouseFunc(int boton, int modo, AUXMOUSEPROC func) Permite especificar la funcin de rellamada con la actividad de los botones del ratn. ?? Otras funciones Hay otras funciones tiles que se pueden utilizar como son, auxSwapBuffers(void) Ocasiona el intercambio del buffer empleado para dibujar con el de pantalla.

auxWireTeapot(Gldouble tamao) Dibuja una tetera almbrica. El parmetro especificar el tamao de la tetera. 25

auxSolidTeapot(Gldouble tamao) Dibuja una tetera slida. El parmetro especificar el tamao de la tetera.

El siguiente cdigo nos muestra como crear y dibujar en una ventana.

#include <windows.h> #include <gl\gl.h> #include <gl\glaux.h> void CALLBACK tamanoventana(GLsizei w, GLsizei h) { if(h == 0) h = 1; glViewport(0, 0, w, h); glLoadIdentity(); if (w <= h) glOrtho (-100.0f, 100.0f, -100.0f, 100.0f*h/w, -100.0, 100.0); else glOrtho (-100.0f, 100*w/h, -100.0f, 100.0f, -100.0, 100.00); } void CALLBACK pintarventana(void) { glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glRotatef(1.0f,0.0f,0.0f,1.0f); glBegin (GL_POLYGON); glColor3f (1.0F, 0.0F, 0.0F); glVertex2f(30.0F, 75.0F); glColor3f (0.0F, 1.0F, 0.0F); glVertex2f(75.0F,75.0F); glColor3f (0.0F, 0.0F, 1.0F); glVertex2f(75.0F,30.0F); glColor3f (1.0F, 0.0F, 0.0F); glVertex2f(30.0F,30.0F); glEnd (); glFlush(); auxSwapBuffers(); }

void CALLBACK idle (void) { pintarventana(); }; void CALLBACK teclado (void) { exit (0); };

26

void main(void) { auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA); auxInitPosition(50,50,300,300); auxInitWindow("Ventana creada con la librera AUX"); auxReshapeFunc(tamanoventana); auxKeyFunc(81, teclado); auxKeyFunc(113, teclado); auxIdleFunc(idle); auxMainLoop(pintarventana); }

Listado 2.5: Crear y dibujar una ventana con la librera Aux

Como se puede observar en la siguiente figura la ejecucin del programa produce casi la misma salida que el ejemplo creado con la librera Glut.

Figura 2.11: Ventana creada con la librera Aux, que contiene un dibujo geomtrico.

(Neider, J.) (Sweet, M.)

2.6. Programacin con OpenGL para Windows. WIGGLE


Como ya se ha dicho anteriormente, OpenGL no tiene funciones para la interaccin con el usuario, la gestin de la pantalla, la asociacin de comandos de dibujo de OpenGL a una ventana, seleccin del modo de buffer, etc. Para todas estas tareas se pueden utilizar algunas librerias que son independientes de la plataforma como las explicadas en el apartado anterior, o bien, utilizar las

27

propias funciones que nos da el sistema, es decir, el lenguaje de programacin anfitrin es el que tiene que asumir, y por lo tanto tener funciones para todas esas tareas. Microsoft Windows ofrece seis funciones que son aadidas a OpenGL para realizar estas tareas, estas funciones son las llamadas funciones wiggle; adems de estas seis hay otras cinco aadidas al GDI de Windows.

Por lo tanto es importante ver como se trabaja en un entorno Windows.

Para la creacin y gestin de las ventanas Windows el programador deber realizar algunas tareas, como son, describir la ventana WinMain, el registro de las clases de windows, crear la ventana y gestionar o controlar la ventana con WndProc.

Para esto se utilizaran dos funciones WinMain y WndProc.

2.6.1. Funcin WinMain El prototipo de sta funcin es:

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) Esta funcin es igual que la funcin main, pero en un entorno Windows. Los parmetros que se le pasan sern: hInstance, para es el handle del programa en uso. hPrevInstance, indica el nmero de veces que se activa el mismo programa lpszCmdLine, es una cadena para indicar todos los parmetros de la lnea de comandos que se pasan al programa. nCmdShow, permite especificar como se mostrara la ventana inicial (normal, maximizada, minimizada).

Las caractersticas de una ventana Windows se indican mediante la estructura WNDCLASS, y ser dentro de la funcin winMain donde se le darn valores a todos los atributos de la estructura WNDCLASS.

Typedef struct_WNDCLASSW{ UINT style; WNDPROC lpfnWndProc; 28

int cbClsExtra; int cbWndExtra; HISTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCWSTR lpszMenuName; LPCWSTR lpszClassName; } WNDCLASS Los campos o atributos de esta estructura son: style: permite especificar las caractersticas de redibujado de la ventana. ipfnWndProc: puntero a una funcin que est relacionada con la clase ventana. CbClsExtra , cbWndExtra: estos dos valores definen la clase y las extensiones de la ventana. hInstance: permite asociar la clase ventana al programa asociada. hIcon: permite especificar el icono asociado a la aplicacin hCursor: permite especificar el cursor asociado a la aplicacin hbrBackground: para determinar el pincel de colores que se utilizara para el fondo de la ventana de aplicacin. lpszMenuName: para indicar la clase de men que se va a utilizar con la ventana. LpszClassName: para asignar nombre a la ventana.

Despus de dados los valores a la estructura tenemos que registrar la ventana con la funcin: RegisterClass(&wc) donde wc es de tipo WNDCLASS

Posteriormente se crea la ventana con la funcin CreateWindow: hWnd CreateWindow( LPCTSTR lpszClassName, LPCTSTR lpzWindowName, DWORD dwStyle, int nX, int nY, int nWidth, int nHeight, HWND hwndParent, HMENU hmenu, HANDLE hinst, LPVOID lpvParam ); 29

Los parmetros que se le pasan a sta funcin seran los siguientes: lpszClassName: es el nombre que se utiliz en la clase anterior para registrar la clase de ventana. lpzWindowName: es el ttulo de la ventana dwStyle: permite especificar detalles de la ventana. (Si se puede minimizar, maximizar, si tiene scroll..) nX , nY: permite especificar la posicin inicial de la ventana. nWidth , nHeight : permite especificar el tamao de la ventana. hwndParent: para indicar el handler de la ventana padre. men: para indicar el handler del men inst : para indicar el handler de la aplicacin en uso. LpvParam: siempre a NULL

2.6.2. Funcin WndProc El prototipo de la funcin es:

LONG WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); Con esta funcin, se pueden controlar y gestionar los eventos que se produzcan en el programa, es donde se especifica como debe actuar el programa segn el tipo de evento que se produzca.

Hay muchos eventos o mensajes que se pueden controlar, como pueden ser: WM_PAINT (para dibujar la ventana), WM_DESTROY (cuando se cierra la ventana), WM_CREATE (cuando se crea la ventana), WM_SIZE (Cuando se cambia de tamao), etc.

El siguiente cdigo mostrar el esqueleto para crear una ventana para una aplicacin:

30

#include <windows.h> #include <gl\gl.h> #define WIDTH #define HEIGHT HDC ghDC; HGLRC ghRC; HINSTANCE hInst; LONG WINAPI WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { LONG lRet = 1; RECT rect; PAINTSTRUCT ps; HDC hdc; static HINSTANCE hInstance; switch (msg){ case WM_PAINT: BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; case WM_DESTROY: if (ghRC) wglDeleteContext(ghRC); if (ghDC) ReleaseDC(hWnd, ghDC); PostQuitMessage (0); break; default: lRet=DefWindowProc(hWnd,msg,wParam,lParam); break; } return lRet; } int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { static char szAppName[] = "W1"; static char szTitle[]="Ventana creada con GDI de Windows"; WNDCLASS wc; MSG msg; HWND hWnd; wc.style = 0; wc.lpfnWndProc = (WNDPROC)WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon (hInstance,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.lpszClassName = szAppName; if (!RegisterClass(&wc )) return (FALSE); 600 500

31

hWnd = CreateWindow( szAppName, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL ); if (!hWnd) return(FALSE); ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); while (GetMessage(&msg,NULL,0,0)) { TranslateMessage( &msg ); DispatchMessage( &msg ); } return( msg.wParam ); }

Listado 2.5: Esqueleto de un programa para con el sistema de ventanas propio de Windows

2.6.3. Dibujar en una ventana de Windows Hasta ahora se ha visto como crear una ventana Windows, pero ahora debemos aprender a dibujar en ella. Para dibujar en una ventana se puede hacer sin usar OpenGL y por lo tanto se utilizaran las funciones del GDI (Interfaz Grfica de Dispositivos) de Windows, en cuyo caso, habra que tener en cuenta el concepto de Contexto de Dispositivo, o bien, tener en cuenta el concepto de Contexto de Generacin. utilizar OpenGL y entonces hay que

32

Contexto de Dispositivo Cada ventana, tiene un contexto de dispositivo que recibe la salida de grficos, y cada funcin GDI toma un contexto de dispositivo como argumento para indicar a que ventana queremos que afecte la funcin. Podemos tener mltiples contextos de dispositivo, pero slo uno para cada ventana.

Contexto de Generacin El concepto de contexto de generacin no es de OpenGL sino de la API de Windows para soportar OpenGL. Antes de ejecutar ningn comando de OpenGL hay que indicar la ventana de generacin, es decir, en que ventana se va dibujar. Puede haber varios contextos de generacin, pero solo uno puede ser el actual. Al activar un contexto de generacin, se asocia con una ventana particular. Para poder trabajar con el contexto de generacin tenemos las funciones WIGGLE, que no son funciones propias de la especificacin de OpenGL, sino que se aadieron para soportar todo este tipo de cosas propias de Windows.

Algunas de las funciones relacionadas con el contexto de generacin que ms se utilizan son: HGLRC wglCreateContext(HDC hDC) Crea un contexto de generacin adecuado para dibujar en el contexto de dispositivo especificado en el parmetro hDC

BOOL wglDeleteContext(HGLRC hrc) Borra un contexto de generacin. El contexto de generacin se debe borrar despus que la aplicacin no lo necesita

BOOL wglMakeCurrent(HDC hDC, HGLRC hrc) Activa el contexto de generacin que se le pasa como parmetro hrc y lo asocia con el contexto de dispositivo especificado tambin como parmetro hDC

Para la creacin de un contexto de generacin debemos crear primero un contexto de dispositivo con la funcin GetDc(HWND hwnd), esta funcin devuelve el contexto de dispositivo para la ventana que se e l pasa como parmetro, y posteriormente crear el contexto de generacin con la funcin HGLRC wglCreateContext(HDC hDC) anteriormente expuesta, pasndole como 33

parmetro el contexto de dispositivo creado y por ltimo asignar el contexto de dispositivo con el contexto de generacin mediante la funcin BOOL wglMakeCurrent(HDC hDC, HGLRC hrc).

Estas operaciones normalmente se harn con el evento o mensaje WM_CREATE, que es el momento de creacin de la ventana.

El contexto de generacin debe borrarse y normalmente se borrar cuando se cierre la ventana, es decir, cuando se produzca el mensaje WM_DESTROY. Para borrarlo se har con la funcin anterior BOOL wglDeleteContext(HGLRC hrc)

Para poder dibujar con OpenGL en una ventana hay que tener en cuenta otros dos aspectos, uno de ellos es el estilo de la ventana y el otro es el formato de Pxel. Para que OpenGL pueda dibujar en una ventana, la ventana no podr tener el estilo CS_PARENTDC y deber crearse con los estilos WS_CHIPCHILDREN y WS_CLIPSIBLINGS. El formato de Pxel tambin hay que especificarlo a la hora de dibujar en una ventana con OpenGL. El formato de pxel no viene con la especificacin de OpenGL, si no que es una extensin a la API Win32 para soportar la funcionalidad de OpenGL. El formato de pxel debe seleccionarse para un contexto de dispositivo antes de que este se use en un contexto de generacin. En el formato de pxel se seleccionan caractersticas tales como si la ventana tiene doble buffer, color, profundidad, etc.

Para

seleccionar

el

formato

de

pxel

utilizaremos

la

estructura

PIXELFORMATDESCRIPTOR, en el que le daremos valor a los campos de esta estructura dependiendo del tipo de ventana que se quiera, y las funciones:

int ChoosePixelFormat(HDC hDC, PIXELFORMATDESCRIPTOR *ppfd) Esta funcin se usa para determinar el mejor formato de pxel disponible para el contexto de dispositivo hDC basado en las caractersticas deseadas descritas en la estructura ppfd.

BOOL SetPixelFormat(HDC hDC, int iPixelFormat, PIXELFORMATDESCRIPTOR *ppfd) Selecciona el formato de pxel para un contexto de dispositivo.

34

Ahora que ya se ha visto como crear ventanas y como dibujar en ellas, veamos un ejemplo:
void tamanoventana(GLsizei w, GLsizei h) { if(h == 0) h = 1; glViewport(0, 0, w, h); glLoadIdentity(); if (w <= h) glOrtho (-100.0f, 100.0f, -100.0f, 100.0f*h/w, -100.0, 100.0); else glOrtho (-100.0f, 100*w/h, -100.0f, 100.0f, -100.0, 100.00); } void pintarventana(void) { glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glRotatef(1.0f,0.0f,0.0f,1.0f); glBegin (GL_POLYGON); glColor3f (1.0F, 0.0F, 0.0F); glVertex2f(30.0F, 75.0F); glColor3f (0.0F, 1.0F, 0.0F); glVertex2f(75.0F,75.0F); glColor3f (0.0F, 0.0F, 1.0F); glVertex2f(75.0F,30.0F); glColor3f (1.0F, 0.0F, 0.0F); glVertex2f(30.0F,30.0F); glEnd (); glFlush(); } void IdleFunction(void) { pintarventana(); } void SetDCPixelFormat(HDC hDC) { int nPixelFormat; static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 8, 0,0,0,0,0,0, 0,0, 0,0,0,0,0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0,0,0 };

35

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; WNDCLASS wc; HWND hWnd; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = lpszAppName; if(RegisterClass(&wc) == 0) return FALSE; hWnd = CreateWindow( lpszAppName, lpszAppName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 300, 300, NULL, NULL, hInstance, NULL); if(hWnd == NULL) return FALSE; ShowWindow(hWnd,SW_SHOW); UpdateWindow(hWnd); while( GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HGLRC hRC; static HDC hDC; switch (message) { case WM_CREATE: hDC = GetDC(hWnd); SetDCPixelFormat(hDC); hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); SetTimer(hWnd,101,1,NULL); break;

36

case WM_DESTROY: KillTimer(hWnd,101); wglMakeCurrent(hDC,NULL); wglDeleteContext(hRC); if(hPalette != NULL) DeleteObject(hPalette); PostQuitMessage(0); break; case WM_SIZE: tamanoventana(LOWORD(lParam), HIWORD(lParam)); break; case WM_TIMER: { IdleFunction(); InvalidateRect(hWnd,NULL,FALSE); } break; case WM_PAINT: { pintarventana(); SwapBuffers(hDC); ValidateRect(hWnd,NULL); } break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return (0L); }

Listado 2.6: Dibujar ventanas con el sistema de ventanas propio de Windows

Lo que nos muestra este pequeo programa es el mismo objeto o dibujo que nos mostraba en los ejemplos anteriores con la librera Glut y Aux, pero la forma de crear, dibujar en la ventana y el procesado de eventos o mensajes es diferente como se puede apreciar en el cdigo. (Huescar, J.M., 1999)

37

2.7. Usar OPENGL


Hasta este momento se ha visto para que sirve OpenGL, que aplicaciones la utilizan, que se puede hacer con esta librera y como trabajar y preparar las ventanas dependiendo del sistema y plataforma para visualizar escenas hechas con OpenGL. Ahora y de una forma rpida, ya que posteriormente se har ms hincapi en cada uno de las cuestiones, se expondr como usar OpenGL.

2.7.1. Dibujar en 3D Antes de enumerar las diferentes primitivas para la creacin de objetos hay que tener en cuenta como se comporta OpenGL a la hora de dibujar. Dibujar con OpenGL es distinto a trabajar con otras libreras o funciones; con OpenGL lo que se hace es definir un volumen de visualizacin y para dibujar objetos las c oordenadas no se indican en pixeles, ni en coordenadas fsicas si no con lo que se denomina coordenadas posicinales en el volumen de visualizacin. Por lo que para poder trabajar con OpenGL despus de crear la ventana de la aplicacin,

debemos definir la ventana de visualizacin o volumen de visualizacin donde dibujaremos los objetos geomtricos, tomando como referencia coordenadas posicinales.

2.7.1.1. Dibujar Objetos Despus de definir el rea de visualizacin, se pueden comenzar a dibujar objetos. Para dibujar objetos las funciones que se utilizan son las siguientes:

glVertexXX() Se usa para especificar las coordenadas de un vrtice. Se pueden definir vrtices en dos y tres dimensiones, dependiendo del nmero de coordenadas que se pasen como parmetros a la funcin. OpenGL trabaja normalmente en coordenadas homogneas representadas por cuatro componentes, (x, y, z, h), por lo tanto cuando estamos definiendo puntos en dos dimensiones el valor z coge el valor 0 y h el valor 1, en tres dimensiones h coge el valor 1. El tipo especificado de coordenadas viene determinado a partir de los sufijos que siguen a la funcin glvertex. Los sufijos que pueden seguir a la funcin sern, d (double), indica que las coordenadas deben especificarse en valores double, f (float), 38

i (integer) y finalmente s (short), por lo tanto las coordenadas debern indicarse con valores que correspondan al sufijo. Existe la posibilidad de definir un punto mediante un vector que contenga las coordenadas, para ello deberemos utilizar el sufijo v indicando que es un vector de coordenadas.

glBegin(GLenum modo) glEnd() Estas funciones se utilizan juntas, y permiten delimitar los vrtices de la primitiva pasada como parmetro. El valor de modo indicar la primitiva a dibujar y podr tomar distinto valores como puede ser GL_POINTS, GL_LINES, GL_POLYGON...

El formato para utilizar estas funciones ser el siguiente:


glBegin(modo); glVertex(x,y,z); glVertex(x,y,z); ... glEnd();

donde modo es el identificador del tipo a dibujar en la pantalla y glVertex es la descripcin de un punto de la pantalla.

?? Dibujar Puntos

La primitiva para dibujar puntos es GL_POINTS. Este es el parmetro que llevar la funcin glBegin() y posteriormente se indicarn los puntos mediante la funcin glVertex().

El tamao de los puntos a dibujar se puede cambiar utilizando la funcin, glPointSize(GLfloat tamano) ?? Dibujar Lneas

Para poder dibujar una lnea hay que definir dos puntos en el rea de visualizacin. Por lo que, entre los comandos glBegin y glEnd hay que especificar al menos dos vrtices con glVertex . 39

A la hora de dibujar lneas tenemos varias opciones dependiendo de la primitiva indicada en la funcin glBegin Las primitivas disponibles para dibujar lneas son las siguientes:

GL_LINES Genera una serie de lneas que no se conectan entre s. Las lneas se definen mediante los pares de puntos sucesivos, por lo tanto el nmero de vrtices debe ser par, en el caso de que fuera impar se ignorara

GL_LINE_STRIP Genera una serie de lneas pero que se conectan entre s, es decir el punto final de una lnea es el punto inicial de la siguiente. Con este modo se pueden generar figuras cerradas si el punto inicial coincide con el final.

GL_LINE_LOOP Genera una serie de lneas conectadas entre s, es parecido al modo anterior pero este modo conecta automticamente el punto inicial con el punto final.

Tambin se le podra cambiar el tipo de lnea o patrn, para que sea punteada, a rayas, con puntos y rayas, etc.. Para ello, y habra que habilitar especificar el el patronaje patrn con con la la funcin funcin

glEnable(GL_LINE_STIPPLE) glLineStipple(patron). ?? Dibujar Polgonos

posteriormente

El dibujado de polgonos es la base de composicin de objetos de OpenGL. Con lo visto hasta ahora se pueden dibujar, puntos, lneas e incluso formas cerradas, pero no superficies slidas. Para ello hay un conjunto de primitivas especificas. Las primitivas para polgonos seran las siguientes:

GL_POLYGON Genera un simple polgono relleno con los vrtices especificados

40

GL_TRIANGLES Genera una serie de tringulos rellenos que no se conectan entre s. El nmero de vrtices debe ser mltiplo de 3, si el total de vrtices es menor de tres, OpenGL ignora los vrtices que no forma un tringulo.

GL_TRIANGLE_STRIP Genera una serie de tringulos rellenos conectados entre s, y dos de los vrtices de un tringulo son los vrtices del siguiente tringulo. Debemos saber que con N vrtices se pueden crear N-2 tringulos. De igual forma que anteriormente el nmero de vrtices debe ser mltiplo de tres, si no lo es se ignora aquellos que sobran.

GL_TRIANGLE_FAN Genera un conjunto de tringulos rellenos conectados entre s, con la caracterstica de que todos los tringulos tiene un vrtice en comn. El primer tringulo define el vrtice comn a todos los tringulos. De igual forma que los anteriores el nmero de vrtices debe ser mltiplo de 3, si no lo es se ignora aquellos vrtices que sobran.

GL_QUADS Genera un conjunto de cuadrilteros rellenos sin conectar entre ellos. El nmero de vrtices que se requiere es mltiplo de cuatro, si no se verifica esto entonces OpenGL ignora los vrtices que sobran. Cada cuatro vrtices se describe un cuadriltero.

GL_QUAD_STRIP Genera un conjunto de cuadrilteros rellenos que se conectan entre s, es decir dos vrtices de un cuadrado se utilizan para generar el siguiente cuadriltero. Hay que tener en cuenta que si tenemos un total de N vrtices podremos obtener un total de N/2-1 cuadrados. El n mero de vrtices debe ser mltiplo de cuatro, si no se verifica entonces los vrtices que sobran son ignorados.

A la hora de dibujar polgonos debemos tener en cuenta dos reglas: Todos los polgonos deben ser planares. Los polgonos deben ser convexos.

41

El siguiente cdigo es un ejemplo muy sencillo que muestra como utilizar estas primitivas para crear dibujos u objetos.

void RenderScene(void) { GLfloat y; GLint factor = 1; GLushort pattern = 0x5555; GLfloat x,z, angle; glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glBegin(GL_POLYGON); glVertex2f(-80.0, -80.0); glVertex2f(-55.0, -80.0); glVertex2f(-55.0, -55.0); glVertex2f(-80.0, -55.0); glEnd(); glEnable(GL_LINE_STIPPLE); for(y = 20.0f; y < 60.0f; y += 5.0f) { glLineStipple(factor,pattern); glBegin(GL_LINES); glVertex2f(40.0f, y); glVertex2f(80.0f, y); glEnd(); factor++; } glBegin(GL_POINTS); z = 10.0f; for(angle = 0.0f; angle <= (2.0f*GL_PI)*3.0f; angle += 0.1f) { x = 15.0f*sin(angle); y = 15.0f*cos(angle); glVertex3f(-x, -y, z); z += 0.5f; } glEnd();

glPopMatrix(); glFlush(); }
Listado 2.7 : Uso de primitivas para crear objetos geomtricos

42

El cdigo anterior producir la siguiente salida,

Figura 2.12: Puntos, lineas y polgonos

2.7.2. Transformacin de Coordenadas Los dibujos o grficos estn compuestos de las formas explicadas anteriormente, pero, para que todas estas formas se conviertan en una escena coherente hay que colocarlas con relacin a otras formas y al observador, por esta razn habr que saber m over, rotar o cambiar de tamao los objetos, o mejor dicho, el sistema de coordenadas. Cuando se mueve el sistema de coordenadas el efecto que produce es que se mueve el objeto, es decir, se vuelve a redibujar con el nuevo sistema de coordenadas. Esto es lo que se denomina transformacin.

Hay varios tipos de transformacin: Transformacin del observador: especifica la localizacin del observador o de la cmara. sta transformacin debe ser la primera en especificarse ya que ser la que cambie el sistema de coordenadas oculares.

43

Transformacin del modelado: permite manipular tanto el modelo como los objetos que contiene. Es decir, permitir trasladar, rotar o escalar un objeto.

Transformacin del modelador: describe la dualidad de las transformaciones de m odelado y vista.

Entre las dos transformaciones anteriores en realidad no hay ninguna diferencia ya que da igual que se mueva el objeto hacia arriba o que se desplace el eje de coordenadas hacia abajo. Las funciones que nos permitirn este tipo de transformacin sern: glTranslate(GLdouble x, GLdouble y, GLdouble z) glRotatef(Gldouble angulo, GLdouble x, GLdouble y, GLdouble z) glScale(GLdouble x, GLdouble y, GLdouble z) que permitirn respectivamente trasladar, rotar y escalar objetos.

Transformaciones de la vista: esta transformacin se refiere al mapeado de la escena a coordenadas fsicas de la ventana. La funcin que nos permite definir este tipo de transformacin es: gluLookAt(GLdouble ojos, GLdouble ojoy, GLdouble ojoz, GLdouble centrox, GLdouble centroy, GLdouble centroz, GLdouble arribax, GLdouble arribay, GLdouble arribaz)

Transformacin de la proyeccin: define y dimensiona el volumen de visualizacin. Hay dos tipos: - Ortogonal. Con este tipo de perspectiva los objetos se dibujan con las dimensiones especificadas. - Perspectiva. Con este tipo de perspectiva la imagen parece ms real, ya que se tienen en cuenta las distancias de los objetos.

Las funciones que permiten definir estas perspectivas son,

void glOrtho(GLdouble izquierda, GLdouble derecha, GLdouble abajo, GL arriba, GLdouble cerca, GLdouble lejos)

44

Esta funcin se utiliza para especificar una proyeccin ortogrfica. Este tipo de proyeccin define un volumen de vista rectangular, es decir, define un paraleleppedo de tamao infinito, por lo que se debe definir una serie de planos de corte para detallar con exactitud el volumen de visualizacin. Los seis argumentos definen la ventana de visualizacin y los planos de corte tanto cercano como lejano. Para definir la ventana de visualizacin es suficiente definir las coordenadas de dos esquinas de la ventana, con estos dos valores queda totalmente definida. Los valores de pcerca y plejos representan el plano cercano y el plano lejano. Hay que tener en cuenta que el objeto a visualizar debe encontrarse dentro de ambos planos, si sobrepasan automticamente. estos dos planos el objeto se recortar

void glFrustum(GLdouble izquierda, GLdouble derecha, GLdouble abajo, GLdouble arriba, GLdouble cerca, GLdouble lejos) Esta funcin se utiliza para definir una proyeccin perspectiva, y por tanto

define como volumen de visualizacion una pirmide; el objeto a visualizar tiene un aspecto mucho ms realista. Igual que en la proyeccin ortogonal se definen los planos de corte para limitar el volumen de vista, que en este caso al ser una proyeccin perspectiva definir un tronco piramidal.

gluPerpespective GLdouble zlejos)

(GLdouble

angulo,

GLdouble

aspecto,

GLdouble

zCerca,

Esta funcin es muy parecida a la funcin glFrustum, la diferencia entre ambas est en la forma de definir la ventana de visualizacin. La funcin glFrustum define los dos vrtices necesarios de la ventana y en la sentencia glPerpestive solamente se definir el ngulo de apertura de la cmara y la relacin entre el largo y ancho del plano cercano de corte.

45

Cada una de las transformaciones explicadas puede describirse como la multiplicacin de dos o ms matrices.

Todos los cambios de perspectiva que se realicen son acumulativos, es decir, si por ejemplo se rota un objeto y posteriormente se traslada, sta traslacin se hace sobre la posicin que tomo despus de la rotacin. Pero habr ocasiones que necesitemos hacer operaciones sobre la situacin anterior, o bien, poder volver a la situacin anterior. Para ello se pueden utilizar las siguientes funciones: glMatrixMode glLoadIdentity glPushMatrix glPopMatrix

2.7.3. Color y Sombras El aspecto de las aplicaciones grficas tiene gran influencia a la hora de evaluar y decidirse por una aplicacin concreta. Por lo que el color es muy importante a la hora de realizar este tipo de aplicaciones.

El color en los ordenadores se genera especificando intensidades separadas de las componentes roja, verde y azul. Por esta razn los monitores se fabrican para producir estos tres tipos de luz. Para especificar un color utilizamos tres valores positivos (que seran las tres componentes). Por lo que, s un ordenador utiliza 24 bits para el almacenamiento de este tipo de informacin, entonces tendramos ocho bits para cada componente y por tanto cada componente de color se podra especificar con valores entre 0 y 255.

De sta forma se podra modelar los colores disponibles como un volumen llamado espacio de color. Si se forma un cubo a partir del espacio anterior, se obtiene un cubo con todos los colores posibles.

46

OpenGL soporta dos modos de color: RGBA, se expresa un color de forma precisa con sus tres componentes (roja, verde y azul) Modo de color indexado, se elige un color especificando un ndice en una matriz de colores (paleta). En la paleta se especifica el color exacto que se quiere seleccionando las intensidades de las componentes roja, verde y azul. ?? Seleccin de un Color

La funcin de seleccin de un color es: void glColorXT(GLX rojo, GLX verde, GLX azul)

Cuando se utiliza este comando, todos los objetos dibujados a partir de ese m omento tendrn el mismo color hasta que se especifique otro color. ?? Sombreado

Otro aspecto importante a la hora de dibujar es lo que se denomina sombreado, que sera la transicin suave entre un color y el siguiente, es decir, si al dibujar una lnea especificamos en un vrtice un color y en el otro vrtice otro color, el color de la lnea que se dibujar ir variando.

El sombreado puede ser de dos tipos: - Suave, se produce una transicin suave. - Plano, no se produce ninguna transicin, normalmente con este d egradado el color es el del ltimo vrtice especificado.

Para cambiar el sombreado se har con , void glShadeModel (Glenum modo) donde modo puede tomar los valores GL_SMOOTH (suave) o GL_FLAT (plano).

Dentro de Color y Sombras otra cuestin importante sera la definicin y creacin de paletas de colores para ajustar o elegir los colores necesarios en un momento dado para una aplicacin.

47

?? Cambiar el Color de Fondo

Cuando se habla de color es importante explicar como se puede cambiar el color de fondo de una ventana.

Segn el tipo de aplicacin que se quiera crear habr que modificar el color de fondo de la ventana.

Para modificar el color de fondo de la ventana se utiliza la siguiente funcin:

void glClearColor (GLclampf rojo, GLclampf verde, GLclampf azul, GLclampf alfa) Define el color de fondo que se aplicar, utiliza los valores de RGB; Cada argumento corresponde a la intensidad del color, Rojo, Verde y Azul, el rango de estos valores debe ir comprendido entre el valor 0.0; El cuarto p armetro corresponde al valor alpha del color que se utiliza para determinar informacin referente a la transparencia del color.

Despus de definido el color de fondo hay que utilizar la funcin glClear para borrar la pantalla con el color que se haba definido

2.7.4. Luces y Lmparas Los objetos en el mundo real no aparecen como un color slido y OpenGL permite hacer una aproximacin de los objetos dibujados al mundo real utilizando las funciones de iluminacin. Anteriormente, se ha visto como darle color a los objetos, pero el color de un objeto puede variar dependiendo de la luz que incida sobre l, por lo que hay que tener en cuenta este aspecto a la hora de seleccionar el color.

Un objeto, excepto que emita su propia luz, est iluminado por tres tipos de luz diferentes: Luz ambiente, es la luz que no viene de ninguna direccin particular. Luz difusa, esta luz viene de alguna direccin particular, pero es suavemente reflejada por una superficie (como ejemplo puede ser un fluorescente)

48

Luz especular, es direccional, pero no se refleja ntidamente es una direccin particular (como ejemplo se puede decir el sol)

Al igual que un color esta compuesto por tres componentes, una fuente de luz est compuesta por tres componentes de luz tambin: ambiente, difusa y especular. Y as ser la forma de especificar la luz.

Para implementar y especificar la iluminacin en los objetos hay que tener en cuentas aspectos tales como que propiedades reflectivas tienen los materiales de los objetos, calcular los efectos de la luz ambiente y los efectos de difusin y reflexin. Por lo tanto par aadir luz a la escena lo primero que hay que hacer es activar la iluminacin con, glEnable (GL_LIGHTTING)

Posteriormente, hay que configurar y seleccionar el modelo de iluminacin. glfloat luzambiente[]={1.0f, 1.0f, 1.0f, 1.0f} glLightModelfv(GL_LIGHT_MODEL_AMBIENT, luzambiente)

Y por ltimo especificar o definir las propiedades de los materiales mediante las funciones, glEnable(GL_COLOR_MATERIAL) glColorMaterialfv(GLenum, cara, GLenum modo)

El uso de la luz ambiente es sencillo y tiene sus aplicaciones, pero para darle ms realidad a una escena se deben especificar varias fuentes de luz.

A la hora de especificar fuentes de luz habr que definir adems de la intensidad y color, la localizacin de la fuente y la direccin. Para indicar la posicin y el color de la luz se utiliza la misma funcin y se cambiar el valor de los parmetros. La funcin es la siguiente: glLight(GLenum luz, GLenum pnombre, GLfloat param)

En el siguiente ejemplo se ve el efecto que produce la luz que incide sobre el cilindro dibujado.

49

#include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> void inicializar(void) // Inicializacion de los parametros de OpenGL { GLfloat mat_difuso[] = {1.0,.0,1.0,1.0}; GLfloat posicion_luz[] = {1.0,1.0,1.0,0.0}; // Luz direccional glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glMaterialfv(GL_FRONT,GL_DIFFUSE ,mat_difuso); glLightfv(GL_LIGHT0,GL_POSITION,posicion_luz); } void CALLBACK cambiartamano(GLsizei w, GLsizei h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0*(GLfloat)w/(GLfloat)h,1.0,200.0); gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void CALLBACK dibujar(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); auxSolidCylinder(1.0,1.0); glFlush(); auxSwapBuffers(); } int main(int argc, char* argv[]) { auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA|AUX_DEPTH); auxInitPosition(0,0,500,500); auxInitWindow("LUCES"); inicializar(); auxReshapeFunc(cambiartamano); auxMainLoop(dibujar); return 0; }

Listado 2.8: Efecto que produce una luz difusa sobre un objeto

50

La imagen que se produce con el cdigo anterior es la siguiente,

Figura 2.5: Luces

2.7.5. Grficos Planos en Opengl Hasta ahora se ha visto que se pueden y como dibujar puntos, lneas, formas geomtricas, etc., pero tambin es importante hablar de los mapas de bits y mapas de pxeles.

2.7.5.1. Mapas de bits Los mapas de bits son imgenes bicolor y se representan mediante arrays de dos dimensiones rellenado con ceros y unos que permitir crear la imagen deseada. Los mapas de bits se suelen utilizar para crear fuentes. Para crear mapas de bits se utilizar la funcin,

glBitmap(GLsizei ancho, GLsizei alto, GLfloat xorig, GLfloat yorig, GLfloat xmov, GLfloat ymov, const GLubyte *bits) Permite dibujar el mapa de bits que vendr dado por *bits, que ser la matriz que contiene el mapa de bits. 51

Antes de dibujar la imagen con glBitmap hay que indicar la posicin donde colocarlo (posicin raster) con la funcin glRasterPos() El siguiente trozo de cdigo nos muestra como mostrar la letra E utilizando bitmaps.
#include <windows.h> #include <GL/gl.h> #include <GL/glaux.h> GLubyte ees[24]= { 0xff, 0xc0, 0xff, 0xc0, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xff, 0xc0, 0xff, 0xc0 };

void init(void) { glPixelStorei(GL_UNPACK_ALIGNMENT,1); glClearColor(1.0, 1.0, 1.0, 1.0); } void CALLBACK dibujar(void) { int i; float pos=0.0; float pos1=500.0; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 1.0); for (i = 0; i < 10; i ++) { glRasterPos2i(pos+i*50, pos+i*50); glBitmap(10, 12, 0.0, 0.0, 12.0, 0.0, ees); glRasterPos2i(pos+i*50, pos1-i*50); glBitmap(10, 12, 0.0, 0.0, 12.0, 0.0, ees); }; glFlush(); } void CALLBACK cambiotamano(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, w, 0, h, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); } void main(int arg, char** argv) { auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0, 0, 500, 500); auxInitWindow("Mapa de bits"); init(); auxReshapeFunc(cambiotamano); auxMainLoop(dibujar); }

52

Listado 2.9: Uso de bitmaps El cdigo anterior producir la siguiente salida,

Figura 2.6: Bitmaps

2.7.5.2. Mapas de pxeles Los mapas de pxeles son como los mapa de bits, pero la imagen tendr mas de dos colores. Estos se utilizan como imgenes de fondo. En OpenGL los mapas de pxeles pueden ser imgenes de 8 bits indexadas, o bien, imgenes RGB de 24 bits. La funcin utilizada para dibujar mapas de pxeles es: glDrawPixels(GLsizei ancho, GLsizei alto, GLenum formato, GLenum tipo, const GLvoid *pxeles)

A la hora de trabajar con mapas de bits y de pxeles se puede hablar de los ficheros .BMP de Windows. Trabajar con estos ficheros desde programas OpenGL es muy sencillo. Para ello se utilizarn las estructuras BITMAPFILEHEADER y BITMAPINFOHEADER, que se encuentran dentro de cualquier fichero .BMP al comienzo de ste. Despus de estas dos estructuras vendran ya los datos de la imagen.

53

2.7.6. Texturas Poner texturas en los grficos es uno de los avances ms importantes en los grficos 3D. El mapeado de texturas es como poner papel pintado en una pared. Es decir, permite cubrir los polgonos que forman el dibujo con imgenes. El mapeado de texturas se utiliza para conseguir imgenes ms reales. Se pueden mapear texturas en una, dos y tres dimensiones. Los pasos para utilizar el mapeado de texturas son,

Definir una imagen para textura antes de que se puedan dibujar con polgonos con textura. glTextImage?d(GLenum objetivo, GLint nivel, GLint componentes, GLsizei ancho, GLint borde, GLenum formato, GLenum tipo, cons GLvoid *pxeles)

Despus hay que habilitar el mapeado de texturas con la funcin, glEnable(GL_TEXTURE_?D)

Por ltimo, habr que mapear la textura, es decir, cuando se dibuja el objeto, hay que indicar que posicin de la textura la corresponde en cada vrtice, glTextCoord??(Type *s)

2.8. Conclusiones
Depus de ver en sta introduccin las caractersticas de OpenGL y algunas de la operaciones que se pueden realizar con sta librera, se puede observar que es muy potente y fcil de usar, adems de tener las ventajas de portabilidad y estandarizacin, y por tanto OpenGL es una buena eleccin para producir efectos visuales y escenas e imgenes realistas. De hecho est librera se esta utilizando en gran cantidad de aplicaciones como ya se comento anteriormente y es muy probable que se siga utilizando en muchas otras.

54

2.9. Bibliografa
Neider J., Davis T., Woo M. (1993) OpenGL Programming Guide. The official guide to learning OpenGL, Release 1. Addison-Wesley Publising Company.

Richard S. Wright Jr., Sweet M. Programacin en OpenGL. Anaya Multimedia

Kilgard M. (1996) The OpenGL Utility Toolkit (GLUT). Programing Interface. API Version 3. Silicon Graphics, Inc.

Segal M., Akely K (1999). The OpenGL Graphcis System: A Specification (Version 1.2.1). Silicon Graphics, Inc.

Segal M., Akely K (1994). The Design of the OpenGL Graphcis Interface. Silicon Graphics, Inc.

Using OpenGl to Create 2D and 3D Graphics . UCLA Academic Technology Services. (http://www.ats.ucla.edu/at/software/scivis/Scientific OpenGL to Create 2D and 3D Graphics.htm) Visualization Software Using

Huescar J.M., Serra J.C., Bennasar A.F. (1999/2000). Manual de OpenGL

Seplveda M.A. (1988) Qu es OpenGL? . http://www.linuxfocus.org/Castellano/January1998/article15.html

Seplveda M.A. (1988) Programando OpenGL: Trazado de Polgonos Simples. http://www.linuxfocus.org/Castellano/January1998/article17.html

Seplveda M.A. (1988) Programando OpenGL: Ms sobre lneas http://www.linuxfocus.org/Castellano/March1998/article28.html

Seplveda M.A. (1988) Programacin OpenGL: Escenas 3D. http://www.linuxfocus.org/Castellano/May1998/article46.html

55

Das könnte Ihnen auch gefallen