Sunteți pe pagina 1din 185

OpenGL

Renderizado Bsico con C++

OpenGL

Renderizado Bsico con C++

Primera Edicin
Diciembre 2011

Karina I. Batista A.
Angel A. Gonzlez P.
Mayoli M.Gonzlez
Guadalupe del C. Prez De La R.
Jos Luis Prez P.
Jos Carlos Rangel O.
Rosmely R. Rodriguez R.
Juan Antonio Santana G.

Universidad Tecnolgica de Panam


Santiago, Veraguas
2011


Este Libro se elabor como proyecto final en la Asignatura Computacin Grfica II, la cual fue impartida por la Profesora Milka de Gracia, en el II Semestre 2011.

Realizado por los estudiantes de Ingeniera de Sistemas y Computacin de IV ao del Centro Regional de Veraguas. Est dirigido especficamente a los estudiantes del curso de Computacin Grfica II y
a cualquier persona interesada en entrar al mundo de la programacin
con OpenGL. Basado en el contenido de la Asignatura cuyo cdigo es
8465, del plan de Estudio de la carrera Licenciatura en Ingeniera de
Sistemas y Computacin (2007).

Sigue el esquema y la separacin de los temas segn el libro
Computacin Grfica: Manejo de Grficos con OpenGL, desarrollado
por el Dr. Euclides Samaniego Gonzlez

A Jos Manuel Diaz Zaid (q.e.p.d), amigo y


compaero.

Contenido

Prefacio

xii

Introduccin a Visual C++ 2010 con OpenGL


1.

Introduccin a Visual C++ con OpenGL

1.1 Qu es OpenGL?

1.2 Cmo funciona OpenGL?

1.3 Libreras relacionadas con OpenGL

1.4 Bibliotecas y Encabezados

1.5 Sintaxis de una orden OpenGL

1.6 Estudio de las partes de una orden OpenGL

1.7 Tipos de datos de una orden OpenGL

1.8 Estructura de un programa OpenGL

1.8.1 Manejo de ventanas.

1.8.2 Funciones de visualizacin.

1.8.3 Ejecucin del programa.

1.8.4 Gestin de eventos.

1.8.5 Gestion de ventos en segundo plano.

1.8.6 Funciones de primitivas.

1.9 Microsoft Visual 2010 C++ y las Libreras Graficas de OpenGL

1.9.1 Instalacin de las libreras Graficas de Open GL.

1.9.2 Pasos para iniciar un proyecto con Visual C++ y libreras de OpenGL

1.9.2.1 Nuevo Proyecto 

1.9.2.2 Aplicacin de consola

10

1.9.2.3 Seleccin de Proyecto Vacio

11

1.9.2.4 Aadir Archivo de cdigo fuente C++

12

1.9.2.5 Compilacin, vinculacin y ejecucin de proyectos

14

1.10 Recomendaciones para crear un proyecto con Visual C++ y


1.11 Entorno de programacin de OpenGL

OpenGL

14
15

1.11.1 Inclusin tpica de encabezamiento inicial.

15

1.11.2 El cuerpo del programa de una aplicacin en OpenGL

15

1.11.3 Modo de presentacin de la Ventana OpenGL

16

vii

1.11.4 Creacin de la ventana Open en pantalla

16

1.11.5 Establecer la devolucin de llamada que dibuja el contenido de la ventana.


16
1.11.6 Configurando el estado a interpretacin.

16

1.11.7 Bucle a la espera de eventos.

16

1.11.8 Llamadas de grficos OpenGL

17

1.11.9 Limpiando el bfer de color, borra todos los pixeles.

17

1.11.10

Limpiando la cola y los bufers de comando OpenGL

18

Referencias

18

Taller N 1

18

Taller N 2

19

Taller N 3

20

Ejercicio N 1

21

Conceptos Fundamentales de OpenGL

23

Primitivas Geomtricas Bsicas

24

2.

2.1 Sistemas De Coordenadas

24

2.2 Describiendo Puntos, Lneas Y Polgonos

26

2.2.1 Puntos

26

2.2.2 Lneas

26

2.2.3 Polgonos

27

2.2.4 Rectngulos

28

2.2.5 Curvas y superficies curvas

28

2.3 Especificando Vrtices

29

2.4 Dibujando Primitivas En OpenGL

30

2.4.1 Restricciones sobre el uso de glBegin y glEnd

31

2.4.2 Utilizando glBegin, glEnd() y glVertex para dibujar primitivas

32

2.5 Gestin De Caractersticas De Estados OpenGL

34

2.6 Desplegando Puntos, Lneas Y Polgonos 

35

2.6.1 Detalles de puntos

35

2.6.2 Detalles de lneas

35

2.6.3 Detalles de polgonos 

37

Referencias

40

viii

Taller N 4

41

Taller N 5

44

Ejercicio N 2

47

Ejercicio N 3

47

OpenGL Bsico en 3D


3.

48

OpenGL Bsico en 3D

49

3.1 Mens desplegables

49

3.2 Creacin de una animacin sin parpadeo, eliminacin de caras traseras

50

3.3 Definir, situar y colocar la cmara que usa OpenGL

52

3.4 La Proyeccin en OpenGL

54

3.5 Visibilidad: Ocultacin de objetos (Z-Buffer)

57

3.6 Las Transformaciones en OpenGL

58

Referencias 

61

Taller N 6

61

Taller N 7

65

Ejercicio N 4

66

Color, Materiales e Iluminacin


4.

68

Color, Materiales e Iluminacin

69

4.1 Especificacin de un normal en OpenGL

69

4.2 Estableciendo el Modelo de Sombreado

70

4.3 Estableciendo las Propiedades del Material

72

4.4 Estableciendo el Modelo de Iluminacin

74

4.4.1 Luz Ambiente

74

4.4.2 Luz Posicional

76

4.4.3 Luz Direccional

77

4.5 Gestin de un Foco de Luz

79

4.6 Gestin de la atenuacin de la intensidad de la luz

80

Referencias

81

Taller N 8

81

Ejercicio N 5

84

Trazado del Mapa de Textura

86

ix

5.

Trazado del Mapa de Texturas

87

5.1 Texturas 2D para polgonos 

87

5.2 Filtrado de Una Textura 

93

5.3 Aplicacin de texturas 2D sobre Primitivas GLUT

95

Referencias

105

Taller N 9

106

Taller N 10

108

Ejercicio N 6

111

Aspectos avanzados de OpenGL


6.

112

Aspectos Avanzados de OpenGL

113

6.1 Geometras de las primitivas de los dibujos eficientes

113

6.2 Lista de Visualizacin

114

6.3 Especificacin de eliminacin de caras traseras

121

6.4 El efecto fusin en OpenGL

122

6.5 Uso de GlutIdleFunc y glutTimerFunc

124

6.5.1 Funcin GlutIdleFunc

124

6.5.2 Funcin GlutTimerFunc

125

6.6 Definicin de varias reas de dibujo.

125

6.7 Tratamiento de imagines en OpenGL: Guardar y recuperar imagines.

126

6.8 Especificacin de los vectores de vrtice en OpenGL.

131

6.9 Niebla 

135

6.10 Cargar modelos .OBJ 

140

Figura. Resultado de la ejecucin 

142

Referencias 

143

Taller N 11

143

Taller N 12 

146

Ejercicio N 7

147

OpenGL con otros Lenguajes 


7.

149

OpenGL con otros Lenguajes 

150

7.1 Implementacin con C# 

150

7.1.1 OpenTK

150

7.1.2 Comenzar un nuevo proyecto

150

7.1.3 Primera Aplicacin con OpenTK

151

7.1.4 Windows Form y GLControl

158

7.2 Implementacin con Java 

164

7.2.1 Instalacin de los complementos 

165

7.2.2 Una aplicacin JOGL

167

Referencias 

169

xi

Prefacio

l mundo ha cambiado enormemente en las ltimas dcadas, estos cambios


han sido propiciados en gran parte por un elemento comn, la computadora, la cual desde su aparicin ha tenido un gran desarrollo. Parte de este
desarrollo es la infografa o grficos por computadora desde la aparicin de interfaces que hacen ms sencillo el trabajo con el equipo, hasta los actuales avances
en animacin que van dirigidos al entretenimiento. En comparacin con los inicios
de la computacin grfica donde el proceso de dibujar se basada en complicados
clculos matemticos y el ensayo y error, hasta la actualidad donde existen gran
cantidad de programas para el diseo grfico se ha progresado mucho lo cual augura un futuro prometedor en cuanto a esta rea de la computacin. Inmerso en
este desarrollo se encuentra OpenGL el cual fue desarrollado en Silicon Graphics
Inc. a inicios de la dcada del 90. Esta es una herramienta que permite la creacin
de grficos en 2D y 3D, al igual que animaciones; creaciones las cuales pueden
interactuar con los usuarios a travs de los diversos dispositivos de entrada.

OpenGL Renderizado Bsico en C++, incluye los conceptos bsicos para
aprender a programar grficos con OpenGL en C++, presenta un contenido cargado de ejemplos para aclarar lo ms posible los conceptos presentados, as como
tambin talleres y ejercicios para estimular la capacidad creativa de los estudiantes.
Los contenidos del libro por captulo se pueden resumir de la siguiente manera:

En el captulo 1 se presenta una descripcin de que es OpenGL, definiendo
los conceptos y reglas que rigen el lenguaje, como funciona, que elementos y libreras se requieren y en que carpetas deben ser copiadas, para la construccin de
una aplicacin o programa en Visual C++ 2010 utilizando las libreras grficas de
OpenGL. Adems se mostraran los pasos para realizar la ejecucin de un proyecto
con Visual C++ 2010 utilizando OpenGL y los mtodos para compilar y ejecutar
una aplicacin.

En el captulo 2 se describen las primitivas geomtricas en funcin a sus vrtices, a los cuales se les asocian coordenadas, que son las que definen los puntos
de inicio y fin de un segmento de lnea o bordes de un polgono. En este captulo
explicaran como se dibujan primitivas mediante la especificacin de un conjunto de
vrtices; y mostrar las funciones de OpenGL que permiten el dibujo de lneas aplixii

cando los patrones de lneas y los patrones de relleno para los polgonos.

En el captulo 3 mostraremos las diferentes funciones y mtodos bsicos
que nos ofrece OpenGL para trabajar grficos en 3D, as como las distintas formas
de aplicar los mismos para obtener el resultado deseado en las diversas tareas a
realizar que se nos presenten en el camino.

En el captulo 4, aprenderemos a implementar el uso de colores, materiales, sombras as como tambin la iluminacin (llamase luces), que se le puede
aplicar a los objetos creados para una mejor proyeccin de lo que se est realizando. Describiremos las funciones adecuadas para dicho fin, a la vez, detallando los
cambios y la manera, en que se debe implementar dichas funciones para obtener
un buen resultado.

En el captulo 5 se presentan las funciones necesarias para aplicar texturas a una primitiva (polgono, triangulo, etc.). Se muestran tambin los parmetros
necesarios para la utilizacin de dichas funciones, y a la vez se pueden realizar
algunos talleres en los que se puede practicar como se utilizan estas funciones en
aplicaciones de C++ con OpenGL.

En el captulo 6 se muestran conceptos avanzados de OpenGL como las
listas de visualizacin, eliminacon de caras traseras, niebla, definicin de reas de
dibujo, entre otras. Estos conceptos combinados con los explicados en los captulos anteriores enriquecen, los conocimientos sobre OpenGL, lo cual permite crear
una gran variedad de aplicaciones diferentes.

En el captulo 7 se presenta una introduccin al trabajo con OpenGL en otros
lenguajes como lo es C#, explicando la manera de trabajar con este en el entorno
Visual Studio. Tambin se aborda la implementacin de OpenGL en Java con el
entrono NetBeans.

xiii

<1>

C a p t u l o

Introduccin a Visual C++ 2010


con OpenGL
OBJETIVOS:

Conocer los conceptos fundamentales de


OpenGL para visualizar grficos 3D en
una aplicacin.

numerar las ventajas


E
de utilizar OPenGL al
aislarnos del hardware disponible.

escribir las libreras


D
y el conjunto de comandos
utilizados
para las aplicaciones
con OpenGl.

onocer la estructura
C
de un programa que
utilice OpenGL.

resentar el cdigo
P
de una aplicacin utiliozando OpenGL que
permita observar la
forma implementada
en la utilizacin de
esta herramienta.

DESCRIPCIN:
En este captulo se tratara sobre la introduccin a OpenGL, como interface de programacin para crear graficos 3D. se describir que es OpenGL, como funciona, que
elementos requiere, sus libreras graficas:
glut.dll, glut32.dll, glut32.lib, glut.lib,
glut.h.
Adems se presentaran los aspectos a considerar para la creacin de un proyecto en
OpenGL.

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

1.

Introduccin a Visual C++ con OpenGL

1.1

Qu es OpenGL?

Se define como una interface de programacin de aplicacin para crear grficos


3D. bsicamente se trata de una librera de funciones que permiten visualizar grficos 3D en una aplicacin, adems de que es una herramienta de programacin
con grficos portable, que ofrece una gran disponibilidad usando interfaces de programacin de aplicaciones para grficos 2D e imgenes, y gran potencia en el
manejo de grficos 3D de manera fcil y rpida.

Consta de unas 120 funciones distintas, que especifican los objetos y las operaciones necesarias para producir aplicaciones interactivas en las que intervienen
grficos en tres dimensiones.

Esta diseado de forma completamente independiente del hardware por
lo que puede implementarse en plataformas muy diversas (PC, SGI, Digital, Sun,
etc. El precio que hay que pagar en aras de esta portabilidad, es que OpenGL no
incluye comandos para gestionar el sistema de ventanas, ni para capturar rdenes
de los usuarios, ya sea por ratn o por teclado. En lugar de esto, debemos trabajar con la ayuda de cualquier sistema de ventanas que se utilice en la mquina en
concreto en la que estemos trabajando. En nuestro caso utilizaremos el sistema de
ventanas de Windows.

1.2

Cmo funciona OpenGL?

Al trabajar con OpenGl se deben realizar una serie de pasos tales como llamadas
a los comandos de OpenGL que se necesitan para conseguir cierto aspecto, apariencia o efecto; en vez de escribir la escena y como debe aparecer. Estos comandos son utilizados para dibujar primitivas graficas en 3D(puntos, lneas, polgonos);
transformacin de primitiva, atencin a eventos de teclado, raton y ventana; trazado de texturas; filtrado, definicin de materiales, iluminacin, sombreados; fusin;
menus despegables; transpariencia; niebla, animacin y otros muchos eventos y
opciones especiales.

Cabe destacar que OpenGL funciona para muchas propiedades como una
mquina de estados. Es decir si a una propiedad se le asigna un valor determinado,
todo lo que se haga a partir de ese momento se ver afectado por ese valor, hasta
que este se modifique o desactive de forma explcita.

Por ejemplo, una de esas propiedades es el color actual, con el que se pintan los objetos. De esta forma, si asignamos a la propiedad color actual por ejemplo
el valor ROJO, todos los puntos, lneas y polgonos que se dibujen a continuacin
sern de color rojo, hasta que se modifique este valor de forma explcita, mediante
la funcin adecuada.
2

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

Las propiedades que funcionan de esta forma son:

Color actual.

Punto de vista.

Transformaciones de proyeccin.

Estilo de lneas y polgonos.

Modos de dibujar polgonos.

Convenciones de empaquetado de bits.

Posicin y caractersticas de las fuentes de iluminacin.

Propiedades de los materiales de los objetos.

1.3

Libreras relacionadas con OpenGL

Las libreras relacionadas con OpenGl se han desarrollado con el fin de simplificar
las tareas de programacin.
Se divide en tres partes funcionales:

La librera OpenGL, que proporciona todo lo necesario para acceder a las funciones de dibujado de OpenGL.

a librera GLU (OpenGL Utility Library), una librera de utilidades


L
que proporciona acceso rpido a algunas de las funciones ms
comunes de OpenGL., a travs de la ejecucin de comandos de
ms bajo nivel, pertenecientes a la librera OpenGL propiamente
dicha.

LX (OpenGL Extension to the X Window System) proporciona un


G
acceso a OpenGL para poder interactuar con un sistema de ventanas X Window, y est incluido en la propia implementacin de
OpenGL (su equivalente en Windows es la librera WGL, externa a
la implementacin de OpenGL).


Adems de estas tres libreras, la librera GLUT (OpenGL Utility Toolkit) proporciona una interfaz independiente de plataforma para crear aplicaciones de ventanas totalmente portables.

1.4

Bibliotecas y Encabezados

OpenGL es una biblioteca de programacin que posee muchas implantaciones. La


compatibilidad que ofrece Microsoft Windows para OpenGL es como un interpretador de software.

opengl32.dll. Es una librera del software de Microsoft, de de3

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

sarrollo, biblioteca de vnculo dnmco, en la que se encuentra


la implantacin del software de Microsoft, y est localizada en el
directorio del sistema Windows (C:\Windows\System32).

gl.h: Es el archivo encabezado que contiene todos los prototipos


de funciones, tipos y superficies.

glut.h. Es el archivo de encabezado que contiene todas las funciones de la biblioteca de utilidades.


Estos 2 ltimos archivos se encuentran localizados en un directorio especial
en la ruta de acceso include (C:\Program Files\Microsoft Visual Studio 10.0\VC\
include).

1.5

Sintaxis de una orden OpenGL

Una orden OpenGL maneja un conjunto de prefijos y sufijos a identificar de datos o


el nmero de parmetros con el que trabaja, entre otros. La sintaxis de una orden
OpenGl es:
<Prefijo de Biblioteca> <Comando Raiz> <Numero de Argumentos> <Tipo de Argumentos> gl<orden> [234] [dsi] [v] (args)

l. El identificar de cada orden de OpenGL inicia siempre con el


g
prefijo gl.

<orden>: Es el comando raz de OpenGL.

Los sufijos definen el numero de parmetro de la orden(2,3 o 4) y


el tipo de dato(doubl, short, int, float, )

1.6

Estudio de las partes de una orden OpenGL

Las partes de la funcin OpenGL indican de que la biblioteca es la funcin, la


cantidad y tipos de argumentos que acepta la funcin. Cada una de las funciones
OpenGL tienen una raz que representa el comando OpenGL correspondiente.
Ejemplo
glVertex2i ()

gl: funcin de la librera OpenGLglut

vertex: comando raz

2: cantidad de argumentos que se envan.

I: tipo de argumentos enteros.

glColor3f ()

gl: Prefijo que representa a la biblioteca GL.


4

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

Color: comando bsico que tiene la raz color.

3: sufijo que indica el numero de argumentos.

F: sufijo que indica tipo de argumentos flotante.

1.7

Tipos de datos de una orden OpenGL

OpenGl define sus propios tipos de datos que facilitan la portabilidad del cdigo
OpneGl de una plataforma a otra.

A continuacin, mostraremos el significado de los sufijos utilizados para especificar los distintos tipos:
Sufijo literal
en C

Tipo de dato

Definicin como
tipo C

Tipo de datos
OpenGL

Entero de 8 bits

signed char

GLbyte

Entero de 16 bits

short

GLshort

GLint, GLsizei
Entero de 32 bits
int o long
Coma flotante 32
GLfloat, GLclampf
float
bits
Coma flotante 64
GLdouble, GLclampd
double
bits
Entero de 8 bits
GLubyte, GLboolean
unsigned char
sin signo
Entero de 16 bits
GLushort
unsigned short
sin signo
Entero de 32 bits
GLuint, GLenum,
unsigned int
GLbitfield
sin signo
Tabla Sufijos de instrucciones OpenGL

f
d
ub
us
ui

1.8

Estructura de un programa OpenGL

OpenGl es una librera grafica que permite el uso de ms de doscientas rdenes


para la generacin de aplicaciones interactivas. Las principales acciones que se
pueden realizar mediante rdenes OpenGL incluyen las especificaciones de los
objetos y las operaciones necesarias para producir aplicaciones interactivas en 3D.

La librera OpenGL est formada por seis grupos de funciones: manejo de
ventanas, funciones de visualizacin, ejecucin del programa, gestin de eventos,
gestin de eventos en segundo plano y funciones primitivas.
5

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

1.8.1 Manejo de ventanas.


Este grupo de funciones permiten la inicializacin del sistema para que abra una
ventana grafica para dibujar. Forman parte de estas funciones:

glutInit(int *argc, char **argv); Inicializa las utilidades de

glutInitDisplayMode(unsigned int mode); Selecciona el modo


glutInitWindowPosicion(int x, int y);Posiciona la ventana en

glutInitWindowSize(int width, int size); Selecciona el tamao

lutCreateWindow(char *cadena); Abre la ventana. Esta funcin es


g
la que crea una ventana de visualizacin habilitada para OpenGL y
el parmetro es el nombre o titulo de la misma, es decir, la funcin
acta poniendo el titulo indicado en la barra superior de la ventana.

OpenGL. Esta funcin es la que inicializa la GLUT, y negocia con


el sistema de ventana para abrir una. Adems sus argumentos
son los estndares para pasar informacin sobre los comandos de
lnea.
pantalla. Define el modo en el que debe dibujar la ventana. Es
decir, especifica el modo de visualizacin. Los parmetros se definen como flags o mascaras de bits.
la pantalla. Especifica la posicin de la ventana. Posicin x e y de
la esquina superior izquierda de la nueva ventana con respecto al
escritorio que se trate.
de la ventana. Especifica el ancho y alto de la nueva ventana.

1.8.2 Funciones de visualizacin.


Define la funcin que se llamara para visualizar la escena, y la que permite forzar
esta llamada. Verbigracia, cuando se produce un cambio en la escena.

glutDisplayFunc(void (*func)(void)); Especifica la funcin que

glutPostRedisplay(void); Actualiza la ventana actual. Esta funcin

dibuja la escena. Esta funcin establece la funcin de devolucin


de llamada de la presentacin para la venta actual.
informa a la GLUT que la ventana actual necesita actualizarse, es
decir, refresca el dibujo de la escena.

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

1.8.3 Ejecucin del programa.


La funcin de este grupo comienza la ejecucin del programa, visualiza todas las
ventanas creadas, permite el envi de rdenes y gestiona los eventos que se generan.

glutMainLoop(); Desencadena la ejecucin del programa, inicia el

proceso de bucle principal del GLUT. La funcin sede el control del


flujo del programa a la GLUT.

1.8.4 Gestin de eventos.


El grupo de funciones de la gestin de eventos especifican las rutinas que se ejecutan cuando se produce un evento determinado.

glutReshapeFunc (void (*func(int anc, int alt))); Gestion de


lutKeyboardFunc(void(*func (unsigned char tecla, int x, int


g
y))); Gestion de eventos del teclado. Funciona cuando se pulsa

evento de redimensionamiento de la ventana.

una tecla.

lutMouseFunc(void (*func (int botn, int estado, int x, int


g
y))); Gestin de eventos del raton. Funciona cuando se pulsa un

botn del raton.

glutMotionFunc( void(*func (int x, int y))); Gestion de eventos


deraton. Funciona cuando se mueve el raton con un botn pulsado.

1.8.5 Gestion de ventos en segundo plano.


La funcin de la gestin de eventos en segundo plano especifica la rutina que se
ejecuta cuando no hay otros eventos pendientes, se utiliza comnmente para realizar animaciones.

glutldleFunc(void( *func(void));

1.8.6 Funciones de primitivas.


Este grupo perimite visualizar las primitivas de objetos prdefinidos de dibujos mas
completjas que las que incluyen OpenGL.

glutWireCone(base,

glutWireCube(size), glutSolidCube(size)

glutWireDodecahedron(void), glutSolidDodecahedron(void)

heigth,
height, slices, stacks)

stacks),

glutSolidCone(base,

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

glutWirecosahedron(void), glutSolidcosahedron(void)

glutWireOctahedron(void), glutSolidOctahedron(void)

glutWireSphere(radius, slices, stacks), glutSolidSphere(radius,


slices, stacks)

glutWireTeapot(void), glutSolidTeapot(void)

glutWireTetrahedron(void), glutSolidTetrahedron(void)

Cono

Cubo

Dodecaedro

Octaedro

Icosaedro

Esfera

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

Tetraedro

Torus

Tetera

1.9

Microsoft Visual 2010 C++ y las Libreras Graficas de OpenGL

En esta parte se explicara cmo crear un proyecto utilizando OpenGL y GLUT en


Visual C++.
1.9.1 Instalacin de las libreras Graficas de Open GL.
Para poder trabajar con OpenGL. Se deben instalar los siguientes archivos:
Archivos
glut.dll glut32.dll
glut32.lib glut.lib
glut.h

Direccion de las carpetas


C:\Windows\System32
C:\Program Files\Microsoft Visual Studio 10.0\VC\lib
C:\Program Files\Microsoft Visual Studio 10.0\VC\include

Estos archivos se pueden obtener de la siguiente direccin http://www.xmission.


com/~nate/glut/glut-3.7.6-bin.zip.
1.9.2 Pasos para iniciar un proyecto con Visual C++ y libreras de OpenGL
Los pasos a seguir son los siguientes:
1.9.2.1

Nuevo Proyecto

Para crear un nuevo proyecto del tipo Aplicacin de Consola Win32 se debe seleccionar Archivo Nuevo Proyecto , como se indica en la figura 1.
9

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

Figura 1. Nuevo Proyecto


1.9.2.2

Aplicacin de consola

Estando la ventana Nuevo Proyecto activa, seleccionar la opcion Aplicacin de


Consola Win32. Indique el nombre del nuevo proyecto y el lugar donde se desea
guardar.

Figura 2. Aplicacin de Consola


10

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

1.9.2.3

Seleccin de Proyecto Vacio

Al seleccionar aceptar en la ventana de Nuevo Proyecto (Figura 2) aparecera la


ventana del Asistente para Aplicaciones Win32 (Figura 3), en este seleccionamos
siguiente, con lo cual aparecera las opciones de configuracin de la aplicacin del
asistente(Figura 4), en esta seleccionamos proyecto vacio.

Figura 3. Asistente para Aplicaciones Win32

11

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

Figura 4 Configuracin de la Aplicacin


Recuerde que a partir de ahora, estamos trabajando con los espacios de trabajo
(Workspoce), por lo tanto para seguir trabajando debemos abrir siempre el espacio
de trabajo.
1.9.2.4

Aadir Archivo de cdigo fuente C++

Para aadir un archivo de cdigo fuente C++ se debe seleccionar ProyectoAgregar


Nuevo Elemento como se indica en la Figura 5.

12

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

Figura 5. Aadir Nuevo Elemento



Luego aparecera la ventana de Agregar nuevo elemento (Figura 6), donde
seleccionamos Archivo C++ (.cpp) e indicamos el nombre para nuestro archivo.

Figura 6. Ventana de Agregar nuevo elemento

13

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

El archivo que agreguemos se ubicara bajo la carpeta Archivos de cdigo fuente,


en el explorador de soluciones de Visual C++ 2010 (Figura 7).

Figura 7. Ubicacin del elemento agregado


1.9.2.5

Compilacin, vinculacin y ejecucin de proyectos

Para compilar podemos utilizar cualquiera de estos mtodos:



Compilar (Compile)
Generar
Iniciar sin Depurar
Iniciar Depuracin

Ctrl + F7
F7
Ctrl + F5
F5

1.10 Recomendaciones para crear un proyecto con Visual C++


OpenGL
Es importante tomar en cuenta los siguientes puntos:

Ahorro de espacio en la unidad de disco.

Ahorro de tiempo al evitar tener que crear un proyecto nuevo con


cada practica.

Solo sern por tanto necesario tener almacenado un proyecto


prototipo y los distintos ficheros correspondientes a los cdigos
fuentes de cada practica.
14

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

1.11 Entorno de programacin de OpenGL


Para ir familiarizndose un poco con la aplicacin, tenemos este cdigo ejemplo:
#include<Windows.h>
#include<gl\GL.h>
#include<gl\glut.h>
Void Mostrar(void)
{
glClear(GL_COLOR_BUFFER_BIT)
glfrush();
}
Void Iniciar(void)
{
glClearColor(0.0, 1.0, 0.0, 1.0)
int main(int argc, char **argv)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_
glutCreateWindows(Mi primer programa);
glutDisplayFunc(Mostrar);
Iniciar();
glutMainLoop();
return 0;
}
1.11.1 Inclusin tpica de encabezamiento inicial.
#include<Windows.h>
#include<gl/GL.h>
#include<glut.h>
1.11.2 El cuerpo del programa de una aplicacin en OpenGL
Int main (int argc, char **argv)
{
}

15

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

1.11.3 Modo de presentacin de la Ventana OpenGL


glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
//Selecciona el modo
pantalla

Sintaxis: void glutInitDisplayMode (unsigned int mode)

Propsito: Inicializa el modo de presentacin de la ventana OpenGL


de la biblioteca GLUT.

Parmetros: Mode: indica una marcara o combinacin de mascaras de bits que describen las caractersticas de la ventana.

1.11.4 Creacin de la ventana Open en pantalla


glutCreateWindows(Mi primer Programa)
// Abre la ventana

Sintaxis: int glutCreateWindows(Char *name)

Propsito: crea una ventana GLUT de alto nivel habilitada para


OpenGL, que ers considerada ventana actual.

Parmetros: Name: titulo o nombre de la ventana.

1.11.5 Establecer la devolucin de llamada que dibuja el contenido de la ventana.


glutDisplayFunc(mostrar)
//Registra la funcin redibujar.

Sintaxis: void glutDisplayFunc(void(*func)(void));

Propsito: indica a GLUT que debe llamar siempre que se tenga


que dibujar el contenido de la ventana.

Parmetros. Func: nombre de la funcin que ejecutaba la interpretacin.

1.11.6 Configurando el estado a interpretacin.


La lnea de cdigo Iniciar (); es la funcin que establece el contexto a seguir
y que realiza cualquier iniciacin de OpenGL que debera ejecutarse antes de la
interpretacin.
1.11.7 Bucle a la espera de eventos.
glutMainLoop();

Sintaxis: void glutMainLoop(void)

Propsito: esta funcin inicia el proceso de evento principal de


GLUT es el lugar donde se procesan todos los mensajes.
16

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

1.11.8 Llamadas de grficos OpenGL


glClearColor(0.0, 0.0, 0.0, 1.0);

Sintaxis: void

Propsito: establece los valores de relleno que se utilizan cuando


se borren los buferes de ojo, verde, azul y transparencia.

Parmetros:

glClearColor(GLclampf
Glclampf blue, GLclampf alpha)

red,

GLclampf

green,

GLclampf red, componente rojo del valor de relleno


GLclampf green, componente verde del valor de relleno
Glclampf blue, componente azul del valor de relleno
GLclampf alpha, componente transparencia del valor de relleno
COLOR COMPUESTO
Amarillo
Azul
Blanco
Can
Gris claro
Gris oscuro
Magenta
Marrn
Naranja calabaza
Negro
Prpura
Rojo
Rosa Pastel
Verde

COMPONENTE
ROJO
VERDE
1
0
0
0
1
1
0
1
0.75
0.75
0.25
0.25
1
0
0.6
0.4
0.98
0.625
0
0
0.6
0.4
1
0
0.98
0

0.04
1

AZUL
0
1
1
1
0.75
0.25
1
0.12
0.12
0
0.7
0
0.7
0

Tabla Algunos colores comunes y sus valores de componente


1.11.9 Limpiando el bfer de color, borra todos los pixeles.
glClear(GL_COLOR_BUFFER_BIT);
La lnea de cdigo GLUT establece que OpenGL, para usar el color verde de borrado es la orden glClear.
17

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

La funcin borra un bufer o una combinacin determinada, la sintaxis de la funcin


es: void glClear(Glbitfdield mask). Limpia los buffers especficos asignndoles
los valores actuales. El argumento mask puede tener los siguientes valores:

Buffer
De color
De fondo
De acumulacin
De patron
1.11.10

Nombre
GL_COLOR_BUFFER_BIT
GL_DEPTH_BUFFER_BIT
GL_ACCUM_BUFFER_BIT
GL_STENCIL_BUFFER_BIT

Limpiando la cola y los bufers de comando OpenGL

La lnea de cdigo: glFlush(); es la encargada de realizar la limpieza y el borrado


de los bferes de comando OpenGL.

Este comando hace que se ejecute cualquier comando que est esperando
a ejecutarse. Por lo general, los comandos OpenGL se aplican en la cola y se ejecutan en secuencias de comando para optimizas el rendimiento.

La funcin glFlush(); indica a OpenGL que debe proceder con las instrucciones de dibujo suministrada hasta el momento antes de esperar cualquier otro
comando de dibujo.
Referencias
Agenjo, J. (30 de Agosto de 2009). SegmentationFault. Recuperado el 25 de
Agosto de 2011, de OpenGL y GLUT en Visual C++: http://www.segmentationfault.
es/2009/08/opengl-glut-visual-cpp/
Samaniego Gonzlez, E. Computacin Grfica: Manejo de Grficos con OpenGL.
Panam.
Taller N 1
Indicaciones:
Para inicializar el sistema, crear la ventana de dibujo y comenzar el bucle de gestin
de eventos se debe utilizar cdigo que se muestra a continuacin.
Int main(int numParametros; char **ListaParametros)
{
/*Inicializacion y creacin de venta */
//Inicializa toolkit
glutInit(&numParametros, ListaParametros);
//Selecciona el modo pantalla
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
18

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

//Selecciona el tamao de la ventana


glutInitWindowSize(anchoVentana, altoVentana);
//Posiciona la ventana en la pantalla
glutInitWindowPosition(posicionVentanax, posicionVentanay);
//Abre la ventana
glutCreateWindow(ListaParametros[0]);
glutDisplayFunc(dibuja);
//Registra la funcin de redibuja
//Bucle a la espera de eventos.
glutMainLoop();

La funcin Dibuja realiza el dibujo de la escena.


Taller N 2
Ahora se presenta un programa que genera una ventana de trabajo y dibuje primitivas bsicas sobre la misma. Este cdigo trata acerca de la creacin de una ventana usando la librera GLUT y Visual C++. Escriba el siguiente cdigo y ejecute el
programa:
#include<Windows.h>
#include<gl/GL.h>
#include<gl/glut.h>
Void Mostrar(void)
{
//Limpia la pantalla. Borra los pixeles
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0); //Establece el color a dibujar
glBegin(GL_POLYGON);
//Vrtices
glVertex3f(0.25, 0.25, 0.0);
glVerter3f(0.75, 0.25, 0.0);
glVerter3f(0.75, 0.75, 0.0);
glVerter3f(0.25, 0.75, 0.0);
glEnd();
}
Void iniciar(void)
//Mi inicio
{
//Selecciona el color de limpieza del fondo de la ventana
glClearColor(0.0, 0.0, 0.0, 0.0);
19

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

//Inicializacin de los valores de visualizacin.


glMatrizMode(GL_PROJECTION);
glLoadIdentify();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 10.0);
}
Int main(int argc, char **argv)
{
glutInit(&argc, argv);
//Inicializa toolkit
//Selecciona el modo pantalla
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
//Selecciona el tamao de la ventana.
//Proporciona la ventana en la pantalla.
glutInitWindowPosition(100, 100);
//Abre la ventana
glutInitCreateWindow(Ejemplo Guia Crear Ventana);
iniciar();
glutDisplayFunc(Mostrar); //Registra la funcin de redibujar.
glutMainLoop();
//Bucle a la espera de eventos.
return 0;
}
Taller N 3
Aplicacin de los comandos bsicos de OpenGL.
1.

iga los pasos para iniciar un proyecto con Visual C++ y utilizando las
S
libreras de OpenGL y cree un proyecto denominado Prueba1.

2.

Utilizando el cdigo suministrado en la seccin de reforzamiento. Realizar los siguientes cambios, compilar y ejecutar mediante Build <
execute e indique que sucede.

Cambiar el argumento de la orden, glColor3f, por:

(0.0, 0.0, 1.0); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

(0.0, 1.0, 0.0); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

(0.0, 1.0, 1.0); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

(1.0, 0.0, 0.0); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

(1.0, 0.0, 1.0); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

(1.0, 1.0, 0.0); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

20

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

Cambiar el argumentos de la orden, glutCreateWindow, por:

Mi primera Ventana; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Programa Prueba 1; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Cambiar el argumento de la orden, glutInitWindowSize, por:

(800, 800); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

(400, 800); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

(400, 100); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Ejercicio N 1
Comandos bsicos para escribir un programa con OpenGL.
1.

Cul es el funcionamiento de la orden glutMainLoop(void)?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
2.

Cul es la orden que indica al sistema que rutina se debe ejecutar?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
3.

encione la orden de OpenGL a la que le pasa como parmetro la


M
rutina que se ejecuta cada vez que sea necesario redibujar la escena.

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
4.

Qu rol juega la orden glutPostRedisplay(void)?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
21

Captulo 1 - Introduccin a Visual C++ 2010 con OpenGL

5.

Cules son los pasos para iniciar un proyecto con Visual C++ y las
libreras OpenGL?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
6.

Cules son las principales acciones que se pueden realizar mediante


rdenes OpenGL?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
________________________________________________________________
7.

Qu elementos estn presentes en la estructura de un programa


OpenGL?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
______________________________________________________________
8.

Cules son los grupos que estn presentes en un programa OpenGL?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_______________________________________________________________

22

<2>

C a p t u l o

Conceptos Fundamentales de
OpenGL
OBJETIVOS:

Definir el rea de trabajo de en OpenGL.


Describir las funciones bsicas que
hacen el llamado
a las utilidades del
OpenGL para abrir
una ventana grfica
para dibujar.

Conocer las herramientas de OpenGL que


permiten el dibujo de
primitivas, as como
tambin mostrar las
funciones de OpenGL
que
permiten
el
dibujo de lneas aplicando los patrones de
lneas y rellenado de
polgonos.

Definir la sintaxis de
las instrucciones que
cambian los valores
por defecto del grosor
de los puntos y lneas
que se dibujan en
OpenGL.

DESCRIPCIN:
En este captulo se dar a conocer el rea
de trabajo en OpenGL. Donde se har una
descripcin de funciones bsicas que son
empleadas en Microsoft C++ para hacer el
llamado a las utilidades del OpenGL para
abrir una ventana grfica para dibujar. Se
conocern las herramientas de OpenGL que
permiten el dibujo de primitivas bsicas, el
dibujo de lneas aplicando patrones de lneas,
el dibujo de polgonos, rectngulos y el relleno de polgonos.

23

Captulo 2 - Conceptos Fundamentales de OpenGL

2.

Primitivas Geomtricas Bsicas

En esta seccin se explicara cmo se describen las primitivas en OpenGL. Todas


las primitivas geomtricas son descritas en funcin a sus vrtices, a los cuales se
le asocian coordenadas que son las que definen los puntos de inicio y terminacin
de un segmento de lnea o bordes de un polgono.

2.1

Sistemas De Coordenadas

Para comenzar a utilizar OpenGL hay que estar claro con el funcionamiento de las
diversas funciones que vamos a utilizar muy a menudo.

Primero es necesario seleccionar un sistema de coordenadas cartesianas
adecuado, denominado sistema de coordenadas de referencia del mundo, que
puede ser bidimensional o tridimensional. Despus se describen los objetos de la
imagen proporcionando sus especificaciones geomtricas en trminos de la posicin dentro de las coordenadas del mundo.

Fragmento de cdigo necesario para establecer el sistema de coordenadas
del mundo:
glViewport(0, 0, 50.0, 50.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 50.0, 0.0, 50.0);

Figura 1: sistema de coordenada establecido


glViewport()

Establece el puerto o punto de vista.


24

Captulo 2 - Conceptos Fundamentales de OpenGL

glMatrixMode()

Es el modo matriz donde decidimos que tipo de matriz vamos a modificar ya sea la
matriz de proyeccin (GL_PROJECTION) o la matriz de visualizacin/modelado (GL_
MODELVIEW).

glLoadIdentity()

Funcin para cargar la matriz identidad como matriz activa, esta funcin trabaja en
conjunto con glMatrixMode().
gluOrtho()

Este es el modo de proyeccin donde podemos especificar como va a afectar la


posicin de un objeto a su visualizacin. Tenemos dos maneras de visualizar el espacio: con una proyeccin ortogrfica, o con una proyeccin perspectiva:

La proyeccin ortogrfica: La proyeccin ortogrfica nos permite visualizar todo aquello que se encuentre dentro de un cubo,
delimitado por los parmetros de la funcin glOrto(). A la hora de
visualizar, la distancia al observador solo se tiene en cuenta para
determinar si el objeto est dentro o fuera del cubo.

Figura 2: Proyeccin Ortogrfica

La proyeccin perspectiva: La proyeccin perspectiva delimita


un volumen de visualizacin dado por un ngulo de cmara, y
una relacin alto/ancho. La distancia al observador determinar el
25

Captulo 2 - Conceptos Fundamentales de OpenGL

tamao con el que un objeto se visualiza.

Figura 3: Proyeccin perspectiva

2.2

Describiendo Puntos, Lneas Y Polgonos

2.2.1 Puntos
Un punto est representado por un numero punto flotante que es llamado vrtice.
En OpenGL todos los clculos internos son hechos como si los vrtices estuvieran
en tres dimensiones, y cuando el usuario especifica las coordenadas del punto,
solo lo hace trabajando en dos dimensiones, con solo las coordenadas x, y. y la
coordenada z es igualada a cero por OpenGL.

f
Figura 4: Serie de puntos.
2.2.2 Lneas
En OpenGL, el trmino de lnea se refiere a un segmento de lnea, permitiendo que
haya ms facilidad cuando se quiere especificar una serie de segmentos de lneas
26

Captulo 2 - Conceptos Fundamentales de OpenGL

conectadas, o un plano cerrado, ver Figura 5. Pero aunque las lneas conforman
las series conectadas, estas se consideran como un segmento de lneas independientes, y especificadas en trminos de sus vrtices.

Figura 5: Serie conectada de segmentos de lnea


2.2.3 Polgonos
Los polgonos son reas cerradas formadas solo por segmentos de lneas entrelazadas. Donde los segmentos de lneas estn especificados por los vrtices de
sus puntos finales. Los polgonos tpicamente estn dibujados con los pixeles los
cuales rellanan su interior, pero tambin se puede dibujar solo los bordes o poner
los solo los puntos del polgono.

En general los polgonos pueden ser complicados, as que OpenGL impone
algunas restricciones de cmo debe estar conformado una primitiva de polgono.

Primero, los bordes de los polgonos en OpenGL no pueden interceptarse entre s.

Segundo, los polgonos de OpenGL deben de ser convexos, con


esto nos referimos que no puede tener aberturas.

Tercero, Todos los polgonos deben ser planares.


Vea la figura 6 para algunos ejemplos de polgonos vlidos e invlidos.
OpenGL, de cualquier modo no restringe el nmero de segmentos de lneas usadas
para crear el lmite del polgono convexo. Fjese que los polgonos con huecos no
pueden ser vlidos.

27

Captulo 2 - Conceptos Fundamentales de OpenGL

Figura 6: Poligonos vlidos e invlidos



La razn por la que OpenGL tiene restricciones sobre los polgonos es
porque sencillamente provee rapidez al momento del renderizado, puesto que un
polgono sencillo puede ser renderizado rpidamente. Pero los difciles son complicados de detectar rpidamente, y para el mximo rendimiento OpenGL asume que
los polgonos son simples.
2.2.4 Rectngulos
Desde que los rectngulos son comunes en la aplicaciones grficas, OpenGL
provee la funcin para dibujar rectngulo plano, glRect*(). Pero puedes dibujar
un rectngulo como un polgono, como se describir ms adelante, pero por su
particular implementacin OpenGL, con la funcin glRect*() optimiza el dibujado
de los rectngulos.

Figura 7: Rectngulo dibujado con la funcion glRect*()


2.2.5 Curvas y superficies curvas
Cualquier lnea o superficie circular puede ser el aproximado de cualquier grado
de exactitud arbitrario, por cortos segmentos de lneas o pequeas regiones poligonales. De esta manera subdividiendo la lneas y superficies curvas suficientemente
y entonces aproximndolos con los segmentos de lnea recta o polgonos planos se
crean las curvas ver figura 8.

28

Captulo 2 - Conceptos Fundamentales de OpenGL

Figura 8: Segmentos de lineas conectados para formar curvas

2.3

Especificando Vrtices

En OpenGL, cada objeto geomtrico es descrito como un conjunto de vrtices ordenados. Para esto se utiliza la funcin glVertex*() donde se especifica los vrtices
del objeto a dibujar.
void glVertex[234]{sifd}(TIPO coords);
void glVertex[234]{sifd}v(const TIPO* coords);

[2, 3, 4]: sufijos que especifican el nmero de parmetros de la


orden.

[s, i, d, f]: especifica el tipo de dato: short, int , double, float.

[v]: matriz de valores que contienen los dos, tres o cuatros valores
necesarios para especificar el vrtice.

Ejemplo: Segmento de cdigo utilizando glVertex*()


glVertex2s(4, 5);
glVertex3d(0.0, 0.0, 3.1416);
glVertex4f(2.3, 1.0, -2.2, 2.0);
GLdouble dvect[3] = {5.0, 9.0, 1992.0};
glVertex3dv(dvect);

Se emplea la funcin glVertex*() para especificar coordenadas para las
posiciones de los puntos. De esta forma, se utiliza una misma funcin para los puntos, las lneas y los polgonos; en la mayora de los casos, se emplean recubrimientos poligonales para describir los objetos de una escena.

29

Captulo 2 - Conceptos Fundamentales de OpenGL

2.4

Dibujando Primitivas En OpenGL

Despus de haber visto como se especifican los vrtices con la funcin glVertex*(), se necesita conocer como se le dice a OpenGL que cree un conjunto de
puntos, una lnea, o un polgono a partir de esos vrtices. Para hacer esto, usted
tiene que colocar cada conjunto de vrtices entre la funcin glBegin() y al funcin
glEnd().

El argumento de glBegin() determina qu clase de primitiva
se construir con los vrtices.

geomtrica

void glBegin(GLenum modo);


Seala el comienzo de una lista de vrtices que se utilizaran para definir la
primitiva. El tipo de primitiva se indica en modo que pueden ser cualquier valor de la
tabla 1.
void glEnd(void);

Seala el fin de una lista de vrtices.

TIPO
GL_POINTS
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
GL_QUADS
GL_QUAD_STRIP
GL_POLYGON

DESCRIPCIN
Crea puntos individuales.
Crea segmentos de lnea individuales, para cada
par de vrtices.
Crea una serie de segmentos de lneas conectados.
Crea segmentos de lnea conectados y cerrados.
Crea un tringulo donde cada tres vrtices se interpreta como un nuevo triangulo.
Entrelazado de tringulos.
Enlaza un abanico de tringulos.
Cada cuatro vrtices se interpreta como un
cuadrado.
Entrelazado de cuadrados.
Crea un polgono convexo.
Tabla 1: Tipos de primitivas.

30

Captulo 2 - Conceptos Fundamentales de OpenGL

Ejemplo: fragmento de cdigo donde se utilizamos glBegin() y glEnd().


glBegin(GL_POINTS);
glColor3f(0.0, 1.0,
glColor3f(1.0, 0.0,
glVertex(...);
glColor3f(1.0, 1.0,
glColor3f(0.0, 0.0,
glVertex(...);
glVertex(...);
glEnd()

0.0);
0.0);
0.0);
1.0);

2.4.1 Restricciones sobre el uso de glBegin y glEnd


La informacin ms importante de los vrtices son sus coordenadas, que son definidas con la funcin de glVertex*(). Pero adems se puede aadir informacin
adicional para cada vrtice que sea especificado, como color, un vector normal,
coordenadas de textura, o cualquier combinacin de estas, usando comandos especiales.

Los comandos validos entre la funcin glBegin y glEnd, son los que aparecen en la tabla 2:
Tabla.2: lista de comandos vlidos entre glBegin() y glEnd().
COMANDO
glVertex*()
glColor*()
glIndex*()
glSecondaryColor*()
glNormal*()
glMaterial*()
glFogCoord*()
glTexCoord*()
glMultiTexCoord*()
glVertexAttrib*()
glEdgeFlag*()

OBJETIVO DEL COMANDO


Conjunto de las coordenadas utilizadas
para los vrtices.
Establece un color RBGA.
Establece el ndice de color.
Establece un color secundario, para el texturizado de la aplicacin.
Establece las coordenadas de un vector
normal.
Establece las propiedades de material.
Establece coordenadas para el modo niebla.
Establece las coordenadas de textura.
Establece las coordenadas de textura para
el multi-texturizado.
Establece un atributo genrico para el vrtice.
Para el control de dibujo de bordes.
31

Captulo 2 - Conceptos Fundamentales de OpenGL

Extrae vrtices de un arreglo de datos.


glArrayElement()
glEvalCoord*(), glEvalPoint*() Genera coordenadas.
Ejecuta un despliegue de lista(s).
glCallList(), glCallLists()
Tabla 2: Continuacion de lista de comandos validos entre glBegin() y glEnd().

2.4.2 Utilizando glBegin, glEnd() y glVertex para dibujar primitivas


En los siguentes fragmentos de cdigos, se muestra como dibujar primitivas utilizando las funciones glBegin() y glEnd. Para esto se utilizada la funcion glVertex()
que es para definir los vrtices de las primitivas. El tipo de primitiva que se dibujar
va a depender del parmetro asignado a glBegin().
Dibujando polgono
glBegin(GL_POLYGON);
glVertex2f(0.0, 0.0);
glVertex2f(0.0, 3.0);
glVertex2f(4.0, 3.0);
glVertex2f(6.0, 1.5);
glVertex2f(4.0, 0.0);
glEnd();
Dibujando puntos
glBegin(GL_POINTS);
glVertex2i(0, 0);
glVertex2i(0, 3);
glVertex2i(4, 3);
glVertex2i(6, 1);
glVertex2i(4, 0);
glEnd();
Dibujando un triangulo
glBegin(GL_TRIANGLES);
glVertex2i(0, 0);
glVertex2i(5, 0);
glVertex2i(3, 5);
glEnd();

32

Captulo 2 - Conceptos Fundamentales de OpenGL

Dibujando un cuadriltero
glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(4, 0);
glVertex2i(0, 4);
glVertex2i(4, 4);
glEnd();

Figura 9: Tipo de primitivas.


33

Captulo 2 - Conceptos Fundamentales de OpenGL

2.5

Gestin De Caractersticas De Estados OpenGL

OpenGL mantiene muchos estados y variables de estado. Un objeto puede ser


renderizado con iluminacin y texturarizado, eliminando la superficie oculta, niebla,
y otros estados que afectan su apariencia.

Por defecto, muchos de esos estados estn inicialmente inactivos, ya que
estos estados afectan al proceso de renderizacin al momento de ser activados,
puesto que si a una primitiva se le coloca textura, niebla o iluminacin, el proceso
de renderizacin se vuelve lento, y el tiempo de renderizacin depender del
rendimiento del sistema.

Pero de cualquier modo la imagen mejorara en calidad y tendr una apariencia ms realista. Debido al aumento de su capacidad grfica.

Para habilitar y deshabilitar estos estados, se utilizan nicamente dos comandos:
Void glEnable( GLenum caracterstica );
Void glDisable (GLenum caracterstica );
glEnable(): Es la funcin que habilita una caracterstica de estado de OpenGL.
glDisable(): Deshabilita una caractersticas de estado de OpenGL.

En la tabla 3 se muestra una lista de caractersticas de estados OpenGL,
que pueden ser habilitados y deshabilitados con estas funciones.
Tabla 3: Caractersticas de estados de OpenGL.
ESTADOS
GL_FOG
GL_COLOR_SUM
GL_LIGHTING
GL_BLEND
GL_LIGHTi
GL_POINT_SMOOTH
GL_TEXTURE_CUBE_MAP
GL_SCISSOR_TEST
GL_DITHER
GL_LINE_SMOOTH
GL_LINE_STIPPLE

DESCRIPCIN
Habilita el modo niebla.
Habilita la suma de color.
iluminacin.
Fundido de color.
Nmero de luz i.
Suavizado de punto.
Mapa de textura de cubo.
Recorte habilitado.
Tramado.
Suavizado de lnea.
Puntero de lnea.
34

Captulo 2 - Conceptos Fundamentales de OpenGL

GL_CULL_FACE
GL_POLYGON_SMOOTH
GL_POLYGON_STIPPLE
GL_TEXTURE_xD
GL_STENCIL_TEST
GL_DEPTH_TEST

Seleccionar polgono.
Suavizado de polgono.
Puntero de polgono.
Textura de xD(1, 2, 3).
Prueba de Plantilla.
Prueba detallada.

Tabla 3: Continuacin de las caractersticas de estados de OpenGL.

2.6

Desplegando Puntos, Lneas Y Polgonos

Por defecto, en OpenGL un punto se dibuja como un simple pixel en la escena, una
lnea como un slido de un pixel de ancho, y los polgonos son dibujados como un
slido rellenado.

En esta seccin se discutir los detalles de cmo se cambian los modos de
desplegar los puntos, lneas y polgonos.
2.6.1 Detalles de puntos
Se puede controlar el tamao de los puntos con la funcin glPointSize(), a la cual se
le suministran el tamao deseado en pixeles como argumento de la funcin.
void glPointSize (GLfloat size)

Modifica la anchura de los puntos.


Ejemplo: fragmento de cdigo para cambia el grosos del punto a tamao 4.
glPointSize(4.0) // modificamos el tamao del punto.
glBegin(GL_POINTS);
glVertex2f(0, 0); // Coordenadas del vrtice.
glEnd();
2.6.2 Detalles de lneas
OpenGL tiene funciones que te permiten modificar y controlar el grosor de las lneas,
as como tambin para crear patrones de lneas. Estas funciones son:
void glLineWidth(GLfloat width)

La finalidad de esta funcin es establecer el ancho en pixeles de las lneas
dibujadas con cualquier primitiva basada en lneas.
Ejemplo: fragmento de cdigo para cambiar el ancho de la lnea a un valor de 8.
glLineWidth(8.0);

// modificamos el tamao de la lnea a 8


35

Captulo 2 - Conceptos Fundamentales de OpenGL

glBegin(GL_LINES);
// Dibujamos una lnea
glVertex3f(-0.6,-0.2,0.0); // Coordenadas del primer vrtice
glVertex3f(0.6,-0.2,0.0); // Coordenadas del segundo vrtice
glEnd();
// Terminamos de dibujar
Void glLineStipple(GLint factor, GLushort pattern)
Esta funcin es para crear un patrn con lneas, ya sea punteado o guiones a lo
cual se le denominara patrn.Ver la figura 10 donde se muestra ejemplos de patrones de lneas.

Factor: Especifica un multiplicador que determina cuantos pixeles

Pattern: Establece el patrn del puntero de 16 bits.

se vern afectados por cada bit en el parmetro pattern. El valor


predeterminado es 1 y el mximo es 225.


Para usar esta funcin es necesario que se habilite la caracterstica de estado GL_LINE_STIPPLE. Este estado es habilitado con la funcin glEnable() y deshabilitada con glDisable().

Figura 10: Patrones de lnea.


Ejemplo: fragmento de cdigo para crear un patrn de lnea con un factor de
1 y un pattern de0x00FF.
glLineStipple(1, 0x00FF);
glEnable(GL_LINE_STIPPLE);
tado GL_LINE_STIPPLE
glBegin(GL_LINES);
glVertex3f(-0.6,-0.2,0.0);
glVertex3f(0.6,-0.2,0.0);

// se establece el patrn de la lnea


//se habilita la caracterstica de es// Dibujamos un tringulo
// Coordenadas del primer vrtice
// Coordenadas del segundo vrtice
36

Captulo 2 - Conceptos Fundamentales de OpenGL

glEnd();
// Terminamos de dibujar
glDisable(GL_LINE_STIPPLE); //se deshabilita la caracterstica de
estado GL_LINE_STIPPLE
2.6.3 Detalles de polgonos
OpenGL tiene una funcin que nos permite cambiar la forma en la que visualizamos
los polgonos que se despliegan en una escena, as como tambin para crear patrones de rellenos para los polgonos. Estas funciones son:
voidglPolygonMode(GLenum face, GLenum mode)

face: especifica la cara del polgono que se ver afectado por el


cambio de modo.los parmetros que puede tener son: GL_FRONT,
GL_BACK, GL_FRONT_AND_BACK.

mode: especifica el nuevo modo de dibujo. Los parmetros para


mode son: GL_FILL generan los polgonos relleno, GL_LINE genera
los esquemas del polgono, GL_POINT traza los puntos de los vr-

tices.


La finalidad de esta funcin es cambiar la forma en la que se describen los
polgonos, haciendo que los polgonos no solo sean rellenos, sino que tambin se
dibuje los vrtices de este, o las lneas de su contorno.
Ejemplo: fragmento de cdigo para crear un polgono al que se le cambia la
forma de visualizarlos.
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
// se establece el modo en que se ver afectado el polgono
glBegin(GL_POLYGON);
//dibuja el polgono
glColor3f(1.0,0.0,0.0);
glVertex3f(0.0, 0.0, 0.0);//coordenadas del primer vrtice
glColor3f(0.0,1.0,0.0);
glVertex3f(0.0, 0.3, 0.0); //coordenadas del primer vrtice
glColor3f(0.0,0.0,1.0);
glVertex3f(0.4, 0.3, 0.0); //coordenadas del primer vrtice
glColor3f(0.0,1.0,1.0);
glVertex3f(0.6, 0.15, 0.0); //coordenadas del primer vrtice
glColor3f(1.0,0.0,1.0);
glVertex3f(0.4, 0.0, 0.0); //coordenadas del primer vrtice
glEnd();
// Terminamos de dibujar
37

Captulo 2 - Conceptos Fundamentales de OpenGL

void glPolygonStipple(const GLubyte *mask)



Esta funcin es utilizada para rellanar un polgono de acuerdo a un patrn,
para hacer el patrn de relleno se crea un bitmap de 32x32 de tamao organizado
por filas, cual ser de tipo GLubyte.

Esta bitmap es el que ser usada como patrn de relleno para el polgono,
este bitmap ser rellenado de 1s y 0s. Esto nos dice que cuando aparece un 1,
este corresponder a un pixel que ser dibujado en el polgono, y cuando aparece
un 0 no se dibuja nada.

Para habilitar y deshabilitar el patrn de relleno del polgono, se utiliza el


glEnable () y el glDisable (), donde habilitaremos la caracterstica de estado
GL_POLYGON_STIPPLE.

Ejemplo: cdigo para hacer un patrn de relleno para polgonos. Utilizando la


funcin glPolygonStipple().
void mostrar(void)
{
glClearColor(0.0,0.0,0.0,0.0); // Color de fondo: negro
glClear(GL_COLOR_BUFFER_BIT); // Boramos la pantalla
glViewport(0, 0, 500.0, 500.0);
glMatrixMode(GL_PROJECTION); // Modo proyeccin
glLoadIdentity(); // Cargamos la matriz identidad
gluOrtho2D(0.0,500.0, 0.0, 500.0);
tro del cubo sealado

// Proyeccin ortogrfica, den-

glMatrixMode(GL_MODELVIEW); // Modo de modelado


GLubyte estilo[] = {
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xff,
0xff,
0xff,
0xff,
0x00,
0x00,

0x00,
0x00,
0x00,
0x00,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,

0x00,
0x00,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,

0x00,
0x00,
0xff,
0xff,
0x00,
0x00,
0x10,
0x10,
0x10,
0x10,
0x00,
0x00,

0x00,
0x00,
0xff,
0xff,
0x00,
0x00,
0x10,
0x10,
0x10,
0x10,
0x00,
0x00,

0x00,
0x00,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
38
0xff,

0x00,
0x00,
0x00,
0x00,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,

0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xff,
0xff,
0xff,
0xff,
0x00,
0x00,

Captulo 2 - Conceptos Fundamentales de OpenGL

0x00,
0x00,
0x00,
0x00,

0x00,
0x00,
0x00,
0x00,

0xff,
0xff,
0x00,
0x00,

0xff,
0xff,
0x00,
0x00,

0xff,
0xff,
0x00,
0x00,

0xff,
0xff,
0x00,
0x00,

0x00,
0x00,
0x00,
0x00,

0x00,
0x00,
0x00,
0x00};

glEnable (GL_POLYGON_STIPPLE); // habilita el patrn de relleno


glPolygonStipple (estilo); // especifica el patrn de relleno
glBegin(GL_POLYGON); //dibuja el polgono
glColor3f(1.0,0.0,0.0);
glVertex3f(100.0, 100.0, 0.0);//coordenadas del primer vrtice
glColor3f(0.0,1.0,0.0);
glVertex3f(100.0, 400, 0.0); //coordenadas del segundo vrtice
glColor3f(0.0,0.0,1.0);
glVertex3f(400, 400, 0.0); //coordenadas del tercero vrtice
glColor3f(0.0,1.0,1.0);
glVertex3f(400, 100.0, 0.0); //coordenadas del cuarto vrtice
glEnd(); // Terminamos de dibujar
glDisable (GL_POLYGON_STIPPLE);
glFlush();
}
int main(intargc, char * argv)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(20,20);
glutInitWindowSize(500,500);
glutCreateWindow(patrones de relleno);
glutDisplayFunc(mostrar);
glutMainLoop();
return 0;
}

39

Captulo 2 - Conceptos Fundamentales de OpenGL

Figura 11: Resultado de la ejecucin.


Referencias
Dave Shreiner, T. K. (Julio 2009). OpenGL Programming Guide (Seventh Edition
ed.). Pearson Education, Inc. .
Gonzlez, D. E. Computacin Grfica: Manejo de Grficos con OpenGL. Panam,
Panam.
Hearn, D., & Baker, M. P. (2006). Graficos por Computadora con OpenGL (Tercera
Edicin ed.). Madrid: Pearson Educacin S.A.
40

Captulo 2 - Conceptos Fundamentales de OpenGL

Taller N 4
Dado el siguiente cdigo, vea lo que genera el programa y despus realice las
modificaciones que se le indique en los diferentes puntos.
#include
#include
#include
#include

<windows.h>
<stdio.h>
<stdlib.h>
<glut.h>

voidmostrar(void)
{
glClearColor(0.0,0.0,0.0,0.0); // Color de fondo: negro
glClear(GL_COLOR_BUFFER_BIT);
// Borramos la pantalla
glMatrixMode(GL_PROJECTION);
// Modo proyeccin
glLoadIdentity();
// Cargamos la matriz identidad
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0); // Proyeccin ortogrfica,
dentro del cubo sealado
glMatrixMode(GL_MODELVIEW);

// Modo de modelado

glBegin(GL_TRIANGLES); // Dibujamos un tringulo


glColor3f(1.0,0.0,0.0); // Color del primer vrtice: rojo
glVertex3f(0.0,0.8,0.0); // Coordenadas del primer vrtice
glColor3f(0.0,1.0,0.0); // Color del segundo vrtice: verde
glVertex3f(-0.6,-0.2,0.0); // Coordenadas del segundo vrtice
glColor3f(0.0,0.0,1.0); // Color del tercer vrtice: azul
glVertex3f(0.6,-0.2,0.0); // Coordenadas del tercer vrtice
glEnd(); // Terminamos de dibujar
glFlush(); // Forzamos el dibujado
}
int main(int argc, char * argv)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(20,20);
glutInitWindowSize(500,500);
glutCreateWindow(TALLER 1);
glutDisplayFunc(mostrar);
glutMainLoop();
return 0;
41

Captulo 2 - Conceptos Fundamentales de OpenGL

1.

Modifique las instrucciones del recuadro que aparce en el programa


con el siguiente cdigo:

glBegin(GL_POLYGON);
glColor3f(1.0,0.0,0.0);
glVertex3f(0.0, 0.0, 0.0);
glColor3f(0.0,1.0,0.0);
glVertex3f(0.0, 0.3, 0.0);
glColor3f(0.0,0.0,1.0);
glVertex3f(0.4, 0.3, 0.0);
glColor3f(0.0,1.0,1.0);
glVertex3f(0.6, 0.15, 0.0);
glColor3f(1.0,0.0,1.0);
glVertex3f(0.4, 0.0, 0.0);
glEnd();

42

Captulo 2 - Conceptos Fundamentales de OpenGL

Cul es la salida del programa ahora?


________________________________________________________
________________________________________________________
2.

Modifique las instrucciones del recuadro que aparce en el programa


con el siguiente cdigo:

glBegin(GL_POINTS);
glColor3f(1.0,0.0,0.0);
glVertex3f(0.0, 0.0, 0.0);
glColor3f(0.0,1.0,0.0);
glVertex3f(0.0, 0.3, 0.0);
glColor3f(0.0,0.0,1.0);
glVertex3f(0.4, 0.3, 0.0);
glColor3f(0.0,1.0,1.0);
glVertex3f(0.6, 0.1,0.0);
glColor3f(1.0,0.0,1.0);
glVertex3f(0.4, 0.0, 0.0);
glEnd();
Cul es la salida del programa ahora?
________________________________________________________
________________________________________________________

3.

Modifique las instrucciones del recuadro que aparce en el programa


con el siguiente cdigo:

glBegin(GL_QUADS);
glVertex3f(0.0, 0.0,
glVertex3f(0.4, 0.0,
glVertex3f(0.0, 0.4,
glVertex3f(0.4, 0.4,
glEnd();

0.0);
0.0);
0.0);
0.0);

Cul es la salida del programa ahora?


________________________________________________________
________________________________________________________
43

Captulo 2 - Conceptos Fundamentales de OpenGL

Taller N 5
Dado el siguiente cdigo, vea lo que genera el programa y despus realice las
modificaciones que se le indique en los diferentes puntos.

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <glut.h>
void mostrar(void)
{
glClearColor(0.0,0.0,0.0,0.0); // Color de fondo: negro
glClear(GL_COLOR_BUFFER_BIT); // Borramos la pantalla
glMatrixMode(GL_PROJECTION); // Modo proyeccin
glLoadIdentity(); // Cargamos la matriz identidad
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0); // Proyeccin ortogrfica,
dentro del cubo sealado
glMatrixMode(GL_MODELVIEW); // Modo de modelado
glLineWidth(1.0);// definimos el ancho de la lnea
glLineStipple(2, 0x00FF);// especificamos el patrn deesado
glEnable(GL_LINE_STIPPLE);// habilitamos la caracterstica de estado
glBegin(GL_LINES); // Dibujamos un tringulo
glColor3f(0.0,1.0,0.0); // Color del segundo vrtice: verde
glVertex3f(-0.6,-0.2,0.0); // Coordenadas del segundo vrtice
glColor3f(0.0,0.0,1.0); // Color del tercer vrtice: azul
glVertex3f(0.6,-0.2,0.0); // Coordenadas del tercer vrtice
glEnd(); // Terminamos de dibujar
glDisable(GL_LINE_STIPPLE);// deshabilitamos la caracterstica de
estado
glFlush(); // Forzamos el dibujado
}
int main(int argc, char * argv)
{
44

Captulo 2 - Conceptos Fundamentales de OpenGL

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(20,20);
glutInitWindowSize(500,500);
glutCreateWindow(TALLER 2);
glutDisplayFunc(mostrar);
glutMainLoop();
return 0;
}
Figura 13: Resultado de la ejecucin.

1.

Modifiquele el parmetro factor de la funcin glLineStipple(factor,


pattern); con los siguientes parmetros:

Factor = 4

Factor = 6

Factor = 8

Factor = 10

45

Captulo 2 - Conceptos Fundamentales de OpenGL

Qu efecto se produce con las modificaciones hechas al programa?


________________________________________________________
________________________________________________________
2.

Modifique el parmetro pattern de la funcin glLineStipple(factor,


pattern); con los siguientes parmetros:

Pattern = 0x0001

Pattern = 0x0101

Pattern = 0x1010

Pattern = 0xAAAA

Pattern = 0xFFFF

Qu efecto se produce con las modificaciones hechas al programa?


________________________________________________________
________________________________________________________
3.

Modifique el parmetrowidth de la funcin glLineWidth(width) con los


siguientes parmetros:

Width = 3

Width = 4

Width = 5

Width = 8

Qu efecto se produce con las modificaciones hechas al programa?


________________________________________________________
________________________________________________________

46

Captulo 2 - Conceptos Fundamentales de OpenGL

Ejercicio N 2
Hacer un programa que dibuje un polgono de cuatro vrtices, donde cada vrtice
sea de un color diferente.
Ejercicio N 3
Con el programa del ejercicio 1, utilice la funcin glPolygonMode (face, mode). Y
asgnele los siguientes parmetros:

face: GL_FRONT_AND_BACK

mode: GL_LINE

Haga una breve descripcin de lo que le sucede al polgono al momento de aadirle


la funcin.

47

<3>

C a p t u l o

OpenGL Bsico en 3D
OBJETIVOS

Conocer la estructura
de un programa que
utilice OpenGL para
la creacin de mens
desplegables.

Presentar la sintaxis
grafica de las librerias
de OpenGL para la
generacin de aplicaciones interactivas en
3D.

Describir la orden
OpenGL que permite
determinar el rea
en pantalla donde se
proyectaran las imgenes.

Explicar las funciones


que se requieren para
la definicin, ubicacin y orientacin
de la cmara que usa
OpenGL.

DESCRIPCIN:
En esta seccin se presentar la estructura
que debe seguir un programa que utilice las
libreras grficas de OpenGL para la creacin
de mens desplegables; se presentar la
sintaxis que se requieren para la generacin
de aplicaciones interactivas en 3D; se explicar la funcionalidad de los comandos de
OpenGL para la creacin de una animacin
sin parpadeo. Adicionalmente, se indicarn
cules son las instrucciones encargadas de
realizarlas tareas necesarias para la creacin
de una ventana y se describir la funcin de
OpenGL que permite determinar el rea en
pantalla donde se proyectarn las imgenes
y cules son las funciones que se requieren
para la definicin, ubicacin y orientacin
de la cmara que usa OpenGL. Finalmente,
se dar a conocer las instrucciones que se
emplean en OpenGL para la ocultacin de
objetos y los comandos de OpenGL para realizar transformaciones en la construccin de
aplicaciones 3D.

48

Captulo 3 - OpenGL Bsico en 3D

3.

OpenGL Bsico en 3D

3.1

Mens desplegables

Para poder incluir mens desplegables en la aplicacin se necesitan dos pasos.


Primero la definicin de la estructura de mens con la asignacin del evento de
despliegue y, segundo, la asignacin a cada opcin de men del cdigo que se
debe ejecutar al pulsar esa opcin.

La definicin de la estructura de mens se puede realizar dentro de las funciones init() o main() de la siguiente forma:
void init();
{
glutCreateMenu(menuapp);
glutAddMenuEntry(Borrar Pantalla,1);
glutAddMenuEntry(Salir,2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}


La Liberia GLUT incorpora un conjunto de instrucciones que ayudan de una
manera fcil a que se aadan mens desplegables en una aplicacin. Las funciones bsicas para crear un men desplegable con OpenGl son:

Funcin que crea un men desplegable: int


(void(*funcin) (int valor));

glutCreateMenu

glutCreateMenu crea un nuevo men emergente y devuelve un identificador nico

entero pequeo. La gama de asignar identificadores empieza a la una. El rango de


identificador de men es independiente de la gama de identificador de ventana.

Implcitamente, el men actual se establece en el men de nueva creacin.
Este identificador de men se puede utilizar cuando se llama a glutSetMenu.

Cuando la devolucin de llamada del men es llamado por una entrada del
men es seleccionado para el men, el men actual es implcitamente establecido
en el men con la entrada seleccionada antes de la devolucin de llamada se hace.

Funcin que asigna al men actual a un botn concreto del ratn:


void glutAttachMenu (int boton);

glutAttachMenu concede un botn del ratn para el actual ventana para el identificador el men actual, glutDetachMen desprende un botn conectado a la corriente

ventana. Al colocar un identificador de men a un botn, el men llamado se apareci cuando el usuario presiona el botn especificado.
El botn debe ser uno de:
49

Captulo 3 - OpenGL Bsico en 3D

GLUT_LEFT_BUTTON botn izquierdo


GLUT_MIDDLE_BUTTON

botn medio

GLUT_RIGHT_BUTTON botn derecho

Tenga en cuenta que se asocia el men del botn de identificacin, no por de referencia.

Funcin que aade una opcin al men: void glutAddMenu Entry


(char *nombre, int valor);

glutAddMenuEntry aade una entrada de men en la parte inferior del men actual.


El parametro denominado nombre se aade al menu actual y se identifica
por el parametro valor. Este parametro es el que se utiliza para distinguir unas opciones de otras.

Con lo visto hasta ahora ya es posible crear un menu con un conjunto de
opciones. una posibilidad mas es que una opcion del menu a su vez sea otro menu:
es lo que se llama un submenu. un submenu se crea igual que un menu, es decir,
con la orden glutCreatreMenu vista anteriormente

Funcin que aade un nuevo men como una opcin: void


glutAddSubMenu (char *nombre, int menu);

glutAddSubMenu aade un disparador de sub-men de la parte inferior del men

actual. El nombre de la cadena se muestra para el recin agregado sub-men de


disparo. Si el gatillo sub-men es introducido, el men numerado del sub-men se
mostrara en cascada, lo que permite sub-men mostrar las opciones de men a
elegir.

3.2 Creacin de una animacin sin parpadeo, eliminacin de caras


traseras
La animacin es una de las aplicaciones ms importantes de la computacin grfica. En OpenGL el mtodo que se utiliza para crear una animacin es similar al
utilizado en la proyeccin de una pelcula. Por ejemplo las pelculas se graban
empleando una secuencia de imgenes fijas que son proyectadas en la pantalla a
una velocidad de 24 imgenes por segundo dando una sensacin de continuidad.

El procedimiento que se emplea para la proyeccin de una pelcula inicia
cuando se pone cada imagen delante del proyector, luego se abre el foco y la imagen se visualiza. Posteriormente, se cierra el foco momentneamente, se pone la
siguiente imagen delante del proyector y se vuelve a abrir el foco, y asi 24 veces por
segundo.

El algoritmo que se utiliza para visualizar un milln de imgenes en una computadora es el siguiente:
50

Captulo 3 - OpenGL Bsico en 3D

Abrir_Ventana();
For(i=0;i<1000000;i++)
{
Borrar_Ventana();
Dibujar_Ventana(i);
Proyeccion_de_una_pelicula();
}


Esta alternativa presenta un problema, al no mostrar las imgenes que fueron terminadas, sino que el dibujo es visualizado mientras se est generando. Por
tal razn es que en este tipo de aplicaciones aparece el efecto de parpadeo.

Las ltimas versiones de los sistemas OpenGL usan un sistema de doble
buffer que permite que se dibuje en un buffer sea visualizado en otro, y al terminarse de dibujar se intercambian. De esta forma, se logra que en un cuadro solo
sea visualizado cuando est completamente dibujado y, con ello desaparece el
parpadeo. El algoritmo que ayuda a la eliminacin del parpadeo, se muestra en el
siguiente cdigo:
Abrir_Ventana();
For(i=0;i<1000000;i++)
{
Borrar_Ventana();
Dibujar_Ventana(i);
Cambiar_Buffer();
}


En un programa de OpenGL en el que se desea eliminar el parpadeo, se
utilizan las siguientes funciones:
glutInitDisplayMode establece el modo de visualizacin inicial.

El modo de visualizacin inicial se utiliza al crear ventanas de nivel superior,
sub-ventanas y revestimientos para determinar el modo de visualizacin de la ventana de OpenGL a-ser-creado o superposicin.

Tenga en cuenta que GLUT_RGBA selecciona el modelo de color RGBA, pero
no solicita ningn bit de la alfa (a veces llamado un buffer de alfa alfa o destino) se
asignarn. Para solicitar alfa, especifique GLUT_ALPHA. Lo mismo se aplica a GLUT_
LUMINANCE.

glutSwapBuffers intercambia los buffers de la ventana actual si buffer doble.


glutSwapBuffers Realiza un intercambio de buffer en la capa de uso de la ventana
actual. En concreto, glutSwapBuffers promueve el contenido del bfer trasero de la

capa en el uso de la ventana actual para convertirse en el contenido del bfer frontal. El contenido del bfer de aquel entonces convertido en indefinido. La actualizacin suele tener lugar durante el refresco vertical del monitor, y no inmediatamente
51

Captulo 3 - OpenGL Bsico en 3D

despus glutSwapBuffers se llama.



Un glFlush implcita se hace glutSwapBuffers antes de que vuelva. Los
siguientes comandos de OpenGL pueden ser emitidos inmediatamente despus de
llamar glutSwapBuffers, pero no se ejecutan hasta que el intercambio de buffer se
ha completado.
Si la capa de uso no es el doble buffer, glutSwapBuffers no tiene ningn efecto.

glutIdleFunc establece la devolucin de llamada ociosa mundial para funciones por lo que un programa de GLUT se pueden realizar tareas de procesamiento en segundo plano o una animacin continua en los eventos del sistema de
ventanas no se estn recibiendo. Si se activa, el callback idle est continuamente
llamado cuando los acontecimientos no se estn recibiendo. La rutina callback no
tiene parmetros. La ventana y men actual no ser cambiado antes de la devolucin de llamada de inactividad. Programas con mltiples ventanas y / o mens debe
establecer explcitamente la ventana actual y / o actuales del men y no depender
de su configuracin actual.

El monto de la computacin y la prestacin hecha en un callback idle debera reducirse al mnimo para no afectar la respuesta interactiva del programa. En
general, no ms de un solo marco de la prestacin debe hacerse en un callback
idle.

Pasar NULL a glutIdleFunc desactiva la generacin de la devolucin de
llamada de inactividad.
glutPostRedisplay marca el plano normal de la ventana actual como la
necesidad de volver a mostrar. La siguiente iteracin a travs de glutMainLoop, la

devolucin de llamada de la ventana de visualizacin se llama para volver a mostrar


plano normal de la ventana. Varias llamadas al glutPostRedisplay ante la posibilidad de devolucin de llamada pantalla siguiente slo genera una devolucin de
llamada vuelve a mostrar una sola. glutPostRedisplay puede ser llamado dentro
de la presentacin de una ventana o de devolucin de llamada superposicin de
pantalla para volver a marcar la ventana para volver a mostrar.

Lgicamente, la notificacin normal de dao de avin para una ventana es
tratado como un glutPostRedisplay en la ventana daada. A diferencia de los daos
reportados por el sistema de ventanas, glutPostRedisplay no se establece en verdadero estado daado el plano normal (devuelto por glutLayerGet (GLUT_NORMAL_DAMAGED)).

3.3

Definir, situar y colocar la cmara que usa OpenGL


Definicin y colocacin de la cmara

Una vez hemos definido toda nuestra escena en coordenadas mundo, tenemos que
hacerle la foto. Para ello, tenemos que hacer dos cosas: colocar la cmara en el
mundo (o sea, en la escena) y definir el tipo de proyeccin que realizar la cmara.
52

Captulo 3 - OpenGL Bsico en 3D

Posicin de la cmara

Tenemos que definir no slo la posicin de la cmara (o donde est), sino tambin
hacia dnde mira y con qu orientacin (no es lo mismo mirar con la cara torcida
que recta aunque veamos lo mismo).

Para hacer esto, basta con modificar la matriz ModelView para mover toda la
escena de manera que parezca que hemos movido la cmara. El problema de este
sistema es que tenemos que pensar bastante las transformaciones a aplicar. Es por
ello que la librera GLU viene al rescate con la funcin gluLookAt.
Su sintaxis es la siguiente:
void gluLookAt( eyeX, eyeY, eyeZ, cenX, cenY, cenZ, vp_X, vp_Y, vp_Z);

donde eye corresponde a la posicin de la cmara, cen corresponde al punto hacia


donde mira la cmara y vp es un vector que define la orientacin de la cmara. No
podemos llamar a gluLookAt en cualquier momento, puesto que tiene postmultiplicar la matriz ModelView (por tanto, conviene llamarla lo primero de todo). El vector vp no puede ser paralelo al vector formado por eye y cen, es ms, debera serle
perpendicular. Si no, el resultado es impredecible.

53

Captulo 3 - OpenGL Bsico en 3D

3.4

La Proyeccin en OpenGL

En esta parte analizaremos como definir la matriz de proyeccin que tambin afecta
a los vrtices de la escena. Es importante recordar que de forma previa a la especificacin de la matriz de proyeccin es necesario activar dicha matriz e inicializarla
mediante las rdenes OpenGL:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();


La proyeccin define el volumen del espacio que va a utilizarse para formar
la imagen; en el caso de la proyeccin perspectiva este volumen es una pirmide
truncada o frustum. Por lo tanto, en esta proyeccin se produce un efecto tamao distancia (los objetos aparecen ms pequeos cuanto ms alejados estn del punto
de vista) y es la proyeccin ms usada en animacin por ordenador o simulacin
visual, donde se requiere un alto grado de realismo. El frustum de visualizacin se
define en OpenGL de la forma siguiente:
void glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble

54

Captulo 3 - OpenGL Bsico en 3D

top, GLdouble near, GLdouble far) dnde los parmetros left, right, bottom, top,

near y far definen el frustum tal y como se muestra en la figura siguiente:


Tal y como se muestra en la figura, el frustum no tiene porqu ser simtrico
respecto al eje Z, ya que es posible utilizar valores distintos para left y right, o para
bottom y top.

La especificacin de una proyeccin perspectiva mediante glFrustum puede
resultar complicada debido a que la forma de definicin no resulta intuitiva. En lugar de esta orden, podemos utilizar la rutina de la librera de utilidades de OpenGL
gluPerspective. Esta rutina permite especificar el volumen de la vista de forma diferente, utilizando el ngulo de visin sobre el plano XZ (fovy) y el ratio de la anchura
respecto a la altura (aspect). Mediante estos parmetros es posible determinar el
volumen de la vista, tal y como se muestra en la figura siguiente:


Esta forma de definir la proyeccin resulta ms intuitiva. La sintaxis de la
rutina gluPerspective es la siguiente:
void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble near, GLdou-

55

Captulo 3 - OpenGL Bsico en 3D

ble far);


Cuando utilicemos la rutina gluPerspective tendremos que tomar precauciones con respecto a los valores de fovy y near. Una mala eleccin de dichos
valores puede producir deformaciones en la imagen similares a las aberraciones
pticas habituales en las lentes fotogrficas (v.g. efecto ojo de pez).

Otra forma de definir la manera en que una cmara sinttica observa una
escena es mediante dos posiciones en el espacio: la del punto de inters o punto
al que la cmara est enfocando, y la del punto de vista o punto dnde se encuentra situada la cmara. Esta forma de definir la transformacin de la vista es la que
utiliza la orden de la librera de utilidades de OpenGL gluLookAt. La sintaxis de la
orden es la siguiente:
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble
upz);

donde los parmetros eyex, eyey, eyez indican la posicin del punto de vista;
centerx, centery, centerz especifican el punto de inters y upx, upy, upz la direccin
tomada como arriba, o inclinacin de la cmara

La proyeccin ortogrfica define un volumen de la vista cuya geometra es la
de un paraleleppedo rectangular (o informalmente, una caja). A diferencia de la
proyeccin perspectiva, la distancia de un objeto a la cmara no influye en el tamao final del mismo en la imagen. Este tipo de proyecciones son comunes en aplicaciones de diseo asistido por ordenador, ya que las medidas sobre la imagen son
proporcionales a las reales de acuerdo a un determinado factor de escala. Entre las
proyecciones ortogrficas ms comunes en este tipo de sistemas cabe destacar la
proyeccin ortogrfica (planta, alzado y perfil) y la proyeccin isomtrica. La caja de
visualizacin se define en OpenGL de la forma siguiente:
void glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
dnde los parmetros left, right, bottom, top, near y far definen la caja tal y como se
muestra en la figura siguiente:

56

Captulo 3 - OpenGL Bsico en 3D

3.5

Visibilidad: Ocultacin de objetos (Z-Buffer)

El enunciado del problema es el siguiente: Dado un conjunto de objetos 3D y una


especificacin de la vista, se desea conocer las superficies de los objetos visibles
desde la posicin del observador, para evitar dibujar las ocultas.

De los algoritmos existentes para resolver dicho problema, uno de lo ms
importantes es el algoritmo del Z-buffer, por ser uno de los ms simples de implementar (implementacin hardware). Para su funcionamiento necesita definir una
matriz de profundidad (Z-buffer) con un nmero de entradas igual al de pixels en la
ventana de visualizacin. Esta matriz almacena las coordenadas z de los puntos de
la superficie del objeto a iluminar y debe inicializarse con el menor valor de z.

Durante el proceso de visualizacin de los objetos, si el punto del objeto que
iluminar el pixel (x, y) tiene un valor profundidad (coordenada z) mayor que el que
se encuentra almacenado en el Z-buffer, se iluminar el pixel y se reemplazar el
antiguo valor de z por el nuevo. En caso contrario no es necesario iluminar ningn
pixel pues el objeto en ese punto est oculto.
Z-buffer en OpenGL

Los pasos a seguir para utilizar el Z-buffer en OpenGL son los siguientes:

Creacin de la ventana de la aplicacin incluyendo el Z-buffer.


La creacin de la ventana de la aplicacin incluye el parmetro AUX_DEPTH para
garantizar que se aplica ocultacin por Z-buffer.
auxInitDisplayMode(AUX_SINGLE | AUX_RGBA | AUX_DEPTH)
Activar el Z-buffer y definir el tipo de comparacin de profundidad.
La llamada a glEnable con parmetro GL_DEPTH_TEST activa la ocultacin por ZBuffer. La funcin glDepthFunc define la forma en que se realiza la comparacin
con el buffer de profundidad de OpenGL (ocultacin de superficies). Por ejemplo
57

Captulo 3 - OpenGL Bsico en 3D

utilizando el argumento GL_LEQUAL se iluminarn los pixels de pantalla cuando sean


menores o iguales a los ya dibujados.
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
Inicializar el Z-buffer.
La orden glClear debe borrar tanto la ventana de la aplicacin (GL_COLOR_BUFFER_
BIT) como el buffer de profundidad o Z-Buffer (GL_DEPTH_ BUFFER_BIT).
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

3.6

Las Transformaciones en OpenGL

Las funciones disponibles en OpenGL para especificar transformaciones en 3D


son: traslacin, rotacin y escalado. Estas rutinas actan sobre la matriz de Modelo / Vista, por lo que sern de utilidad tanto para aplicar transformaciones a los
distintos objetos de la escena, como para definir las transformaciones asociadas al
posicionamiento de dicha escena en el volumen de la vista.

OpenGL utiliza dos matrices distintas durante el proceso de visualizacin,
la matriz de Modelo / Vista y la matriz de proyeccin. Para distinguir sobre cual de
dichas matrices van a actuar las distintas rutinas de transformacin se utiliza la
siguiente funcin OpenGL:
void glMatrixMode (GLenum mode);

donde el parmetro mode especifica la matriz a utilizar en las transformaciones


siguientes mediante las constantes GL_MODELVIEW, GL_PROJECTION o GL_TEXTURE.
Independientemente de la matriz que vayamos a utilizar, la primera operacin que
deberemos realizar siempre ser inicializar dicha matriz a la identidad. Para ello
utilizaremos la funcin OpenGL:
void glLoadIdentity (void);

Transformaciones del modelo


Las tres rutinas que proporciona OpenGL para definir transformaciones son glTranslate*, glRotate* y glScale*. La rutina de traslacin
void glTranslate{fd} (TYPE x, TYPE y, TYPE z);

multiplica la matriz actual por una matriz de traslacin con desplazamientos indicados por x, y, z. La rutina de giro
void glRotate{fd} (TYPE angle, TYPE x, TYPE y, TYPE z);

multiplica la matriz actual por una matriz que gira el objeto en el sentido contrario a
las agujas del reloj (sentido de la mano derecha o dextrogiro) alrededor del eje que
va desde el origen al punto indicado por x, y, z. Lo ms habitual es girar sobre los
58

Captulo 3 - OpenGL Bsico en 3D

ejes de coordenadas, por lo que los valores de los parmetros sern:


Giro sobre X: x = 1.0, y = 0.0, z = 0.0
Giro sobre Y: x = 0.0, y = 1.0, z = 0.0
Giro sobre Z: x = 0.0, y = 0.0, z = 1.0
Por ltimo, la rutina de escalado
void glScale{fd} (TYPE x, TYPE y, TYPE z);

multiplica la matriz actual por una matriz que amplia o reduce el objeto con respecto
a los ejes coordenados. Cada coordenada (x, y, z) del objeto se multiplica por el
argumento correspondiente x, y, z. Valores de estos parmetros inferiores a 1.0
reducen el objeto, mientras que valores superiores a 1.0 lo amplan.
Respecto al orden en que se aplican las transformaciones, supongamos que ejecutamos la siguiente porcin de cdigo OpenGL:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(1.0, 1.0, 1.0);
glScalef(2.0, 2.0, 2.0);

Inicialmente, la matriz contiene la identidad, a la que llamaremos I. La orden

gLTranslatef multiplica la identidad por una matriz de traslacin a la que llamare-

mos T. Posteriormente, la orden gLScalef multiplica la matriz resultado por una


matriz de escalado a la que llamaremos S. Por tanto, despus de ejecutar el cdigo
la matriz de Modelo / Vista contiene el producto ITS. Cuando se aplique esta
matriz a los distintos vrtices del modelo tendremos:
v = ITSv = I(T(Sv)))
es decir, primero se aplicar el escalado y posteriormente la traslacin, por lo que
podemos concluir que las transformaciones siempre se aplicarn en orden inverso
al que han sido definidas en OpenGL.
Transformacin de la vista
La transformacin de la vista cambia la posicin y orientacin del punto de vista. Si
recordamos la analoga con una cmara analizada con anterioridad, la transformacin de la vista ajusta el trpode, enfocando la cmara hacia la escena. Dado que
movemos la cmara hasta la posicin deseada y despus la giramos para enfocar
la escena, la transformacin de la vista puede realizarse mediante una composicin
de operaciones de giro y traslacin. Es importante mencionar que para conseguir
una cierta disposicin de la escena en la imagen final, es equivalente mover la
cmara para que enfoque a los objetos, o mover estos ltimos para que queden
dentro del campo de visin de la cmara. Esta ltima aproximacin es la que utili59

Captulo 3 - OpenGL Bsico en 3D

zaremos en informtica grfica.



Los parmetros que se pueden utilizar por ejemplo para definir la transformacin de la vista de la cmara sinttica se muestran en la figura siguiente:


Por tanto, la transformacin de la cmara realizar las transformaciones 3D
necesarias para llevar la cmara a la posicin de observacin (situada en el origen
de coordenadas y enfocando hacia el eje Z negativo). Estas transformaciones son
las siguientes:
Girar sobre Y un ngulo para llevar la cmara al plano YZ.
Girar sobre X un ngulo para llevar la cmara al eje Z.
Trasladar en Z un desplazamiento -dist para llevar la cmara al origen.
Manejo avanzado de transformaciones
En este apartado analizaremos algunas rutinas incorporadas en OpenGL que
pueden considerarse como rutinas avanzadas de manejo de transformaciones. Entre estas rutinas, estudiaremos las que permiten la aplicacin jerrquica de transformaciones y la rutina utilizada para definir la transformacin de la vista.
Aplicacin jerrquica de transformaciones
A menudo, la definicin de una escena requiere la construccin de objetos complejos que se crean a partir de otros ms simples. En estos casos es necesario
poder aplicar transformaciones de forma jerrquica a los objetos. Veamos un ejemplo. Supongamos que estamos construyendo el modelo de un coche: podemos
definir un modelo simple de una tuerca y utilizarla para crear una rueda que utiliza
cuatro tuercas. Una vez definida la rueda, el coche la utilizar cuatro veces en su
60

Captulo 3 - OpenGL Bsico en 3D

definicin. En la construccin del coche, cada pieza bsica definida en su sistema


de coordenadas local se transforma a un nuevo sistema externo, el cual a su vez
puede transformarse nuevamente.

Para permitir la aplicacin jerrquica de transformaciones, OpenGL utiliza
una pila de matrices en la que puede almacenar estados anteriores del proceso. La
pila de matrices se maneja mediante las ordenes OpenGL glPushMatrix y glPopMatrix, cuya sintaxis se muestra a continuacin:
void glPushMatrix(void);
void glPopMatrix(void);


La orden glPushMatrix mueve todas las matrices en la pila una posicin
hacia abajo, dejando en la cabeza de la pila una copia de la matriz cabeza de la pila
anterior. Por tanto, despus de ejecutar una orden glPushMatrix, la primera y segunda matriz de la pila contienen los mismos valores. Si se efectan ms ordenes
glPushMatrix de las permitidas, se produce un error.

La orden glPopMatrix elimina la matriz cabeza de la pila, moviendo el resto
de matrices almacenadas en la pila una posicin hacia arriba. Si la pila contiene
una nica matriz, al ejecutar glPopMatrix se produce un error.

El uso conjunto de glPushMatrix y glPopMatrix permite almacenar estados
intermedios de la transformacin en la pila y recuperarlos posteriormente. El efecto
de la orden glPushMatrix puede entenderse como recuerda dnde ests y el de
glPopMatrix como vuelve a dnde estabas.
Referencias
Jordi Linares Pellicer (2003). Prcticas Grficos por Computador
Jos Ribelles Miguel (2003). Open GL en fichas: una introduccin prctica. Universitat Jaume I. Espaa
Cristina Caero Morales. Apuntes de OpenGL y GLUT
Informatica Grfica 2006-2007. (s.f.). Recuperado el 30 de Septiembre de 2011, de
http://trevinca.ei.uvigo.es/~vluzon/Tutorial/
PyOpenGL 2.0.1.04 Man Pages. (s.f.). Recuperado el 10 de Octubre de 2011, de
http://pyopengl.sourceforge.net/documentation/manual/index.xml

Taller N 6
Detalles de Poligonos y Menu Desplegable
Objetivos:

oner en practica el uso de las funciones para mostrar los diferP


entes modos de los polgonos.
61

Captulo 3 - OpenGL Bsico en 3D

erificar el orden de aparicin de los vrtices de los polgonos en


V
pantalla.

Instrucciones Iniciales: Escriba el siguiente cdigo y responda las interrogantes


planteadas en esta sesion.
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
static int menu, cara, sentido, modo;
void variables()
{
if(modo==1)
{
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}
else if(modo==2)
{
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
}
if(sentido==3)
{
glFrontFace(GL_CW);
}
else if(sentido==4)
{
glFrontFace(GL_CCW);
}
if(cara==4)
{
glCullFace(GL_FRONT);
}
else if(cara==5)
{
glCullFace(GL_BACK);
}
else if(cara==6)
{
glCullFace(GL_FRONT_AND_BACK);
}
}
void Dibuja()
{
glClear(GL_COLOR_BUFFER_BIT);
62

Captulo 3 - OpenGL Bsico en 3D

glColor3f(0.4,0.6,0.0);
glEnable(GL_CULL_FACE);
variables();
glBegin(GL_POLYGON);
glVertex2f(-35,-35);
glVertex2f(-35,35);
glVertex2f(35,35);
glVertex2f(35,-35);
glEnd();
glFlush();
glutSwapBuffers();
}
void eventoVentana(GLsizei ancho,GLsizei alto)
{

glViewport(0,0,ancho,alto);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-50,50,-50,50,-1,1);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();
}
void popupMenu(int m)
{

switch(m)
{

case 1:

modo=1;

break;

case 2:

modo=2;

break;

case 3:

sentido=3;

break;

case 4:

sentido=4;

break;

case 5:

cara=5;

break;

case 6:

cara=6;

break;

case 7:
63

Captulo 3 - OpenGL Bsico en 3D

cara=7;

break;

case 8:

exit(0);
}

glutPostRedisplay();
}
void prepararMenu()
{

menu=glutCreateMenu(popupMenu);

glutAddMenuEntry(Contorno GL_LINE,1);

glutAddMenuEntry(Slido GL_FILL,2);

glutAddMenuEntry(Sentido Horario GL_CW,3);

glutAddMenuEntry(Sentido Antihorario GL_CCW,4);

glutAddMenuEntry(Descartar GL_FORNT,5);

glutAddMenuEntry(Descartar GL_BACK,6);

glutAddMenuEntry(Descartar GL_FORNT_AND_BACK,7);

glutAddMenuEntry(Salir,8);

glutAttachMenu(GLUT_RIGHT_BUTTON);
}
int main(int argc, char* argv[])
{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);

glutInitWindowPosition(0,0);

glutInitWindowSize(500,500);

glutCreateWindow(Detalles_Poligonos/Menu Desplegable);

prepararMenu();

glClearColor(0.0,0.0,0.0,0.0);

glutDisplayFunc(Dibuja);

glutReshapeFunc(eventoVentana);

glutMainLoop();

return 0;
}
1.

Cules son los modos de dibujo de polgonos?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
2.

Qu parmetros indican el sentido en que estn ordenados los


polgonos?
64

Captulo 3 - OpenGL Bsico en 3D

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
3.

Cules son los parmetros para especificar las caras del polgono?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
4.

Cul es la salida que genera el programa?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
Taller N 7
Creacin de un men desplegado con dos opciones.
Objetivo: Crear un men desplegado con dos opciones y un submen con
cinco opciones.
Instrucciones iniciales:
Tomando el cdigo de la seccin anterior, detalles de poligonos y menu desplegable. Crear un men desplegable con dos opciones: (a) Relleno y (b): Rellenos/
Lineas. La segunda opcin debe ser un submen con cinco opciones: Linea Verde,
Relleno Rojo, Relleno Amarillo, Descargar y Salir.
El siguiente cdigo muestra como rear un men desplegado con dos opcones y un
submen con cinco opciones:

menu=glutCreateMenu(popupMenu);

glutAttachMenu(GLUT_RIGHT_BUTTON);
glutAddMenuEntry(Relleno,3);
menuParalelo=glutCreateMenu(popupMenu);
glutAddMenuEntry(Linea Verde,1);
glutAddMenuEntry(Relleno Rojo,2);
glutAddMenuEntry(Relleno Amarillo,5);
glutAddMenuEntry(Descargar,4);
glutSetMenu(menuPrincipal);
glutAddSubMenu(Rellenos yLineas,menuParalelo);

65

Captulo 3 - OpenGL Bsico en 3D

1.

Se debe declarar alguna variable?Explique

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
2.

Qu funciones dentro del programa deben ser alteradas?Sustente

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
3.

En que parte del programa se debe incluir el cdigo proporcionado


para crear el men desplegado con dos opciones y el submen?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
4.

Modofique el programa y agregue dos opciones mas con sus respectivos submenes

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
Ejercicio N 4
Comandos para visualizar grficos 3D en una aplicacin
Objetivos: Evaluar los conocimientos adquiridos para escribir un programa con
OpenGL .
Instrucciones: Coloque a lado de cada funcion de OpenGL la descripcin de la
misma.

glMatrixMode: _____________________________________

glRotate: ________________________________________

glFrusturm: _______________________________________

________________________________________________
________________________________________________
________________________________________________
66

Captulo 3 - OpenGL Bsico en 3D

glOrtho: _________________________________________

glScale: _________________________________________

glLoadIdentity: ____________________________________

glutAddMenuEntry: __________________________________

glutCreateMenu:

glClearColor: _____________________________________

glEnable/glDisable: _________________________________

glutAddSubMenu:

glTranslate: ______________________________________

glutAttachMenu:

gluPerspective: ____________________________________

glPopMatrix: ______________________________________

gluLookAt: ________________________________________

glutSetMenu: ______________________________________

glPushMatrix: _____________________________________

glViewPort: _______________________________________

glutInitDisplayMode: ________________________________

glDepthFunc: ______________________________________

________________________________________________
________________________________________________
_______________________________________________

________________________________________________

___________________________________
_______________________________________________
________________________________________________
________________________________________________

___________________________________
________________________________________________
________________________________________________

___________________________________
________________________________________________
_______________________________________________

________________________________________________
________________________________________________
________________________________________________
________________________________________________
________________________________________________
________________________________________________
________________________________________________

67

<4>

C a p t u l o

Color, Materiales e Iluminacin


OBJETIVOS:

Describir las normales en OpenGL


utilizadas para la iluminacin que indican
la orientacin relativa
de un objeto respecto
a las fuentes de iluminacin.

Presentar los modelos de los de sombreado para darle color a


una superficie en las
aplicaciones creadas
en OpenGL.

Mostrar el uso de
los comandos en
OpenGL para la defincin de las propiedades de material de
un objeto.

Enumerar las funciones que se usarn


en las aplicaciones
de OpneGLpara especificar la luz de una
escena

DESCRIPCIN:
En este captulo se presentsn rutinas que
especifican la normal en OpenGL t que son
utilizadas para la iluminacin, indicando la
orientacin relativa de un objeto respecto a
las fuentes de iluminacin . Se describen los
comandos que permiten darle color a una superficie mediante OpenGL, contemplando las
dos formas de relleno: con color slido, o con
un color combinacin de colores de los vrtices.
Adicionalmente, se muestran las funciones
que definen las propiedades de un objeto y
los comandos que especifican la luz de una
escena; se presentan los comandos empleados en la gestion de la atenuacin de la intensidad de la luz y se explica la funcionalidad de
los comandos para la gestin de un foco de
luz en OpenGL.

68

Captulo 4 - Color, Materiales e Iluminacin

4.

Color, Materiales e Iluminacin

4.1

Especificacin de un normal en OpenGL

Para iluminar una superficie (plano) necesitamos informacin sobre su vector normal asociado. De hecho en el caso de OpenGL, es necesaria la definicin de un
vector normal para cada uno de los vrtices de nuestra geometra.

Supongamos que tenemos un objeto 3D (figura 1). Nos situamos en su cara
superior, la formada por los vrtices A, B, C y D. Encontramos la normal de esta
cara, que por lo tanto es la asociada a cada uno de los vrtices que la forman.

Slo tenemos que calcular dos vectores pertenecientes a la cara y hacer su
producto vectorial (el resultado ser un vector perpendicular a ambos y por lo tanto
una normal del plano, como se ve en la figura 1, en el punto 2).

Figura 1.

A partir de tres vrtices (A, B, C), creo dos vectores que tras su producto
vectorial me generan el vector normal. Este vector ya puede asociarse a la correspondiente cara en 1.

Una vez calculada la normal tenemos que normalizar, es decir, dividir ese
vector por su propio mdulo para que sea unitario. De esta forma tenemos un vector normal de mdulo igual a la unidad que es lo que OpenGL necesita.

Es importante el orden en que multiplicaras, porque de ste depende que el
vector normal apunte hacia fuera o hacia dentro de la cara. Lo que queremos es
que las normales apunten hacia fuera de la cara visible, y as le decimos a OpenGL
que solo dibuje la parte visible de las caras. (FRONT).

OpenGL utilizar la normal asociada a cada vrtice para evaluar la luz que
incide sobre ste. Si un vrtice pertenece a ms de una cara, podemos o bien promediar para obtener unos clculos correctos por parte de OpenGL, o bien repetir
69

Captulo 4 - Color, Materiales e Iluminacin

los vrtices, cada uno con la normal que le corresponde. Para definir normales con
OpenGL , se utilizan las siguientes funciones:
glBegin ( GL_POLYGON ) ;
glNormal3f ( CoordX, CoordY, CoordZ ) ;
glVertex3f ( ... ) ;
glVertex3f ( ... ) ;
glVertex3f ( ... ) ;
glVertex3f ( ... ) ;
glEnd( ) ;
En este caso estamos definiendo un polgono de N vrtices que comparten la normal, es decir, todos tienen la misma. Si no fuera el caso lo podramos hacer as:
glBegin ( GL_POLYGON ) ;
glNormal3f ( CoordX, CoordY, CoordZ ) ;
glVertex3f ( ... ) ;
glNormal3f ( CoordX, CoordY, CoordZ ) ;
glVertex3f ( ... ) ;
glNormal3f ( CoordX, CoordY, CoordZ ) ;
glVertex3f ( ... ) ;
glNormal3f ( CoordX, CoordY, CoordZ ) ;
glVertex3f ( ... ) ;
glEnd( ) ;
Entonces cada vrtice tendra su propia normal asociada.
En el caso de que no se normalice el vector normal, podemos utilizar:
glEnable ( GL_NORMALIZE ) ;
/* Para activar la normalizacin
automtica */
glDisable ( GL_NORMALIZE ) ;
/* Para desactivar la normalizacin
automtica */

Para que OpenGL lo haga automticamente por nosotros. No es para nada
recomendable, pues se carga al sistema con clculos innecesarios que ralentizarn
an ms lo que ya de por s es computacionalmente exigente, es decir, el clculo
automtico de la iluminacin.

4.2

Estableciendo el Modelo de Sombreado

Asumiendo que se puede computar vectores normales, dado un conjunto de fuentes


de luz y un observador, los modelos de luz e iluminacin desarrollados pueden
aplicarse a cada punto de una superficie. Se han visto muchas de las ventajas de
usar modelos poligonales para los objetos. Una ventaja adicional, para polgonos
planos, es que se puede reducir bastante el trabajo requerido para el sombreado.

La mayora de los sistemas grficos, incluyendo OpenGL, explota las posibles eficiencias para polgonos planos, descomponiendo superficies curvas en mu70

Captulo 4 - Color, Materiales e Iluminacin

chos polgonos planos pequeos, cada uno teniendo un vector normal bien definido.
Se considerarn tres maneras de sombrear polgonos:

Sombreado plano o constante

Sombreado interpolativo o Gouraud

Sombreado Phong

Sombreado Plano (Flat)

Los tres vectores, l, n y v, (figura 2), pueden variar segn los puntos sobre una superficie, donde:

Para un polgono plano, n es constante.

Si se asume un observador distante (la bandera GL_DISTANT_VIEWER


en OpenGL), v es constante sobre el polgono.

Si la fuente de luz es distante, l es constante.

Figura 2.

As podemos decir que, DISTANT se puede interpretar como una fuente
o un observador en el infinito; en particular, si los polgonos son pequeos, las
distancias relativas para el infinito no tienen que ser muy grandes. Los ajustes necesarios, como cambiar la ubicacin de la fuente u observador a la direccin de la
fuente u observador, de forma correspondiente, puede hacerse a las ecuaciones de
sombreado y a su implementacin.

Si los tres vectores son constantes, entonces el clculo de sombreado se lleva a cabo una sola vez para cada polgono, y se asignar la misma sombra a cada
punto en el polgono. Esta tcnica se conoce como sombreado plano o constante.
71

Captulo 4 - Color, Materiales e Iluminacin

En OpenGL, se especifica sombreado plano mediante:


glShadeModel(GL_FLAT).


Si se usa sombreado plano, OpenGL usar las normales asociadas con el
primer vrtice de un polgono sencillo para el clculo de sombreado. Para primitivas
como un strip de tringulo, OpenGL usa la normal del tercer vrtice para el primer
tringulo, la normal del cuarto vrtice para el segundo, etc. Reglas similares se aplican para otras primitivas, como strips cuadrilteros.

Sombreado plano mostrar diferencias de sombreado entre los polgonos. Si
las fuentes de luz y el observador estn cerca del polgono, los vectores v y l sern
diferentes para cada polgono.
Sombreado Interpolativo y Gouraud
Si se asigna el modelo de sombreado para que sea suave, mediante
glShadeModel(GL_SMOOTH).


OpenGL interpolar colores para las primitivas, como las lneas. Si se permite sombreado y luz suaves, y se asigna a cada vrtice la normal del polgono
siendo sombreado, se calculara la luz en cada vrtice, determinando el color del
vrtice, usando las propiedades materiales y los vectores v y l se computan para
cada vrtice.

Si la fuente de luz es distante, y el observador es distante o no hay reflexiones especulares, entonces el sombreado interpolativo sombreara un polgono
con un color constante.

Como mltiples polgonos se juntan en vrtices interiores, cada uno teniendo
su propia normal, la normal en los vrtices es discontinua. Aunque esta situacin
pudiera complicar las matemticas, Gouraud se dio cuenta que la normal en el
vrtice de puede definir de manera que se obtenga sombras ms suaves mediante
interpolacin.

Desde la perspectiva de OpenGL, el sombreado Gouraud es deceptivamente
sencillo. Se necesita solamente asignar correctamente las normales de vrtices.
Sombreado Phong
Phong propuso que, en lugar de interpolar intensidades de los vrtices, segn se
hace en el sombreado Gouraud, se interpole normales a lo largo del polgono.

El sombreado Phong producir imgenes ms suaves que con el sombreado Gouraud, pero a un costo computacional mayor. Existen varias implementaciones en hardware para el sombreado Gouraud, pero no as mismo para sombreado Phong.

4.3

Estableciendo las Propiedades del Material


72

Captulo 4 - Color, Materiales e Iluminacin

Para cada polgono de la escena hay que definir un material de forma que su respuesta a la incidencia de luz vare segn sea el caso.

Por tanto tenemos que decirle a OpenGL de qu forma tendr que tratar a
cada trozo de geometra. Se definen cinco caractersticas fundamentales para un
material. Estas componentes son:

Reflexin difusa (diffuse) o color de base, que reflejara el objeto si incidiera sobre l una luz pura blanca.

Reflexin especular (specular), que se refiere a los puntitos


brillantes de los objetos iluminados.

eflexin ambiental (ambient) , define como un objeto (polgono)


R
determinado refleja la luz que no viene directamente de una fuente
luminosa sino de la escena en s.

oeficiente de brillo o shininess. Define la cantidad de punC


tos luminosos y su concentracin. Digamos que variando este
parmetro podemos conseguir un objeto ms o menos cercano al
metal por ejemplo.

oeficiente de emisin (emission) o color de la luz, que emite


C
el objeto.


Las componentes ambiental y difusa son tpicamente iguales o muy semejantes. La componente especular suele ser gris o blanca. El brillo nos determinar
el tamao del punto de mxima reflexin de luz.

Se pueden especificar diferentes parmetros en cuanto a material para cada
polgono. Es una tarea ardua pero lgicamente a ms variedad de comportamientos ms real ser la escena. El funcionamiento es el normal en OpenGL. Cada vez
que se llama a la correspondiente funcin se activan esos valores que no cambiarn hasta llamarla de nuevo con otros. Por tanto todo lo que se renderice a partir
de una llamada heredar esas caractersticas.
Para definir los materiales usaremos la funcin:
glMaterialfv(cara, caracterstica, parmetro)
Los parmetros pueden llevar los siguientes valores:
Cara:

GL_FRONT

GL_BACK

GL_FRONT_AND_BACK

Caracterstica:
73

Captulo 4 - Color, Materiales e Iluminacin

GL_DIFFUSE

GL_AMBIENT

GL_AMBIENT_AND_DIFFUSE

GL_EMISSION

GL_SPECULAR

GL_SHININESS

Parmetro:
Aqu ponemos los valores que queremos para el tipo definido. Tendremos que definir
los valores para RGB, menos para GL_SHININESS que tendr un valor entre 0 y 128.

OpenGL tambin permite definir superficies que tengan componentes emisivos que caracterizan fuente auto luminosas. Este mtodo es til si se quiere que
una fuente de luz aparezca en la imagen.

Este trmino no est afectado por ninguna otra de las fuentes de luz, y no
afecta ninguna otra superficie. Agrega un color fijo a las superficies y est especificada de manera similar a las dems propiedades materiales.
Por ejemplo: GLfloat emission[]={0.0, 0.3, 0.3};
glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emission; define una
pequea cantidad de emisin azul-verde (cian).

4.4

Estableciendo el Modelo de Iluminacin

Con OpenGL podemos manipular la luz y los objetos en una escena para crear
diferentes clases de efectos.

Cuando iluminamos una escena el resultado de la iluminacin depende de
qu luz usamos y como los objetos de la escena reflejan o absorben la luz.
4.4.1 Luz Ambiente
La luz ambiente es aquella que proviene de una fuente que ha sido tan disipada
por el entorno que es imposible determinar su direccin. Cuando una luz ambiente
golpea una superficie, esta es disipada igualmente en todas direcciones.

74

Captulo 4 - Color, Materiales e Iluminacin


Cada fuente de luz puede contribuir a la luz ambiente de la escena. Puede
haber otra luz ambiente que no viene de una fuente en particular. Para especificar
la intensidad RGBA de esa luz global usamos el parmetro:

Para indicar a OpenGL que ha de realizar los clculos de iluminacin: glEnable (GL_LIGHTING)

Para seleccionar el modelo de iluminacin ambiente activo: void

Para establecer el material activo: void glMaterialfv (Glenum

glLightModelfv (GL_LIGHT_MODEL_AMBIENT, GLfloat params[4])


cara, Glenum nombre, GLfloat params[4])

Donde cara, tiene los siguientes parmetros:

GL_FRONT_AND_BACK

GL_BACK

GL_FRONT

Nombre:

GL_SPECULAR

GL_DIFFUSE

GL_AMBIENT


La luz ambiental ilumina los objetos en todas las superficies y en todas las
direcciones. Los objetos son siempre visibles y coloreados (o sombreados) independientes de su rotacin o ngulo de visualizacin.
Se puede interpretar como un factor de brillo global aplicado por una fuente de luz.
Un ejemplo con Luz ambiente sera el siguiente:
// Activar los clculos de iluminacin
glEnable (GL_LIGHTING);
75

Captulo 4 - Color, Materiales e Iluminacin

// Seleccionar la luz ambiente


GLfloat LuzAmbiente[4] = {1.0, 1.0, 0.0, 1.0};
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, LuzAmbiente);
// Seleccionar el material
GLfloat MaterialAmbiente[4] = {1.0, 0.5, 0.5, 1.0};
glMaterialfv (GL_FRONT, GL_AMBIENT, MaterialAmbiente);
// Dibujar el objeto
glBegin (..)
...
Aqu diseamos el objeto, y sus parmetros.
...
glEnd();
4.4.2 Luz Posicional
El segundo tipo referido se conoce como fuente de luz posicional, ya que su posicin exacta dentro de la escena determina el efecto que tiene sobre esta, especficamente, la direccin desde la cual vienen los rayos de luz.

A la funcin glLight*() se le pasa un vector de cuatro valores (x,y,z,w) para
el parmetro GL_POSITION. Si el ltimo valor, w, es distinto de cero, la fuente de luz
correspondiente es de tipo posicional y los valores (x,y,z) especifican la localizacin
de la fuente de luz.

Para luces en el mundo real, la intensidad de la luz decrece a medida que
aumenta la distancia desde la fuente de luz. Ya que una luz direccional est infinitamente lejos, no tiene sentido atenuar su intensidad con la distancia, luego la
atenuacin est desactivada para luz direccional.
OpenGL atena una fuente de luz multiplicando la contribucin de esa fuente por
un factor de atenuacin:

Donde:
d : distancia entre la posicin de la luz y el vrtice
c k : GL_CONSTANT_ATTENUATION
l k : GL_LINEAR_ATTENUATION
q k : GL_QUADRATIC_ATTENUATION

76

Captulo 4 - Color, Materiales e Iluminacin


Una luz posicional irradia en todas las direcciones, pero se puede restringir
esto de forma que se produzca un cono de luz definiendo lo que se conoce como
una luz tipo spotlight (por ejemplo la lmpara, figura 3.).

Por lo tanto, para definir un spotlight hay que determinar la apertura deseada
del cono de luz. (Recordar que, puesto que las spotlights son luces posicionales,
hay que darles una localizacin). Para especificar el ngulo entre el eje del cono y
un rayo a lo largo del borde del cono, usar el parmetro GL_SPOT_CUTOFF.

Figura 3. Significado del parmetro GL_SPOT_CUTOFF



Por defecto el valor del parmetro es 180, es decir, irradia en todas las
direcciones(360). Los valores que puede tomar, a parte del particular 180, estn
comprendidos en el intervalo [0,90].

Tambin hay que especificar la direccin del eje del cono de luz, para lo cual
se utiliza el parmetro GL_SPOT_DIRECTION.
Hay dos formas de controlar la intensidad de la distribucin de la luz dentro del
cono:

ijando el factor de atenuacin descrito anteriormente, el cual es


F
multiplicado por la intensidad de la luz.

ijando el parmetro GL_SPOT_EXPONENT que controla cmo es la luz


F
de concentrada. La intensidad de la luz es ms alta en el centro
del cono. La luz se atena hacia los bordes del cono luz, luego a
mayor exponente resulta en una fuente de luz ms localizada.

4.4.3 Luz Direccional


La luz direccional es la distancia infinita de los objetos donde todos los rayos son
paralelos. Un vector puede ser utilizado para cada punto de la escena, la cual se
ejecuta rpidamente comparndolo con otras luces. La luz direccional imita efectos
luminosos como el sol.

El modelo empleado por OpenGL es el propuesto por Blinn-Phong (Phong


77

Captulo 4 - Color, Materiales e Iluminacin

simplificado). Phong, el componente especular es proporcional al coseno entre el


vector reflexin de la luz y el vector del ojo

L= vector desde la luz hasta el vrtice


N= normal de la superficie
Eye= vector desde el vrtice al ojo/cmara
R= vector reflejado de L con respecto a N

La luz que viene de una direccin y sus rayos son paralelos porque vienen
de una fuente de luz muy lejana (infinitamente lejana). En el mundo real lo ms
parecido es la luz del sol. A OpenGL le indicamos que es una luz direccional cuando
la cuarta coordenada de la posicin de la luz es 0.0 (por ejemplo. GLfloat posicin
[] = { 0.0, -1.0, 0.0, 0.0 };. Las primeras tres coordenadas sern el vector
de direccin hacia donde alumbra (no tiene sentido que sea la posicin si es direccional).

La implantacin de los parmetros para luz direccional sera la siguiente manera:


78

Captulo 4 - Color, Materiales e Iluminacin

GLfloat light_diffuse [4] = {1.0, 1.0, 1.0, 1.0 };


GLfloat light_ambient [4] = {0.2, 0.2, 0.2, 1.0 };
GLfloat light_specular [4]= {1.0, 1.0, 1.0, 1.0 };
GLfloat light_position [4]= { 1.0, 1.0, 1.0, 0.0 };
glLightfv( GL_LIGHT0, GL_AMBIENT, light_ambient );
glLightfv( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
glLightfv( GL_LIGHT0, GL_SPECULAR, light_specular );
glLightfv( GL_LIGHT0, GL_POSITION, light_position );
Donde:

GL_AMBIENT: es la intensidad RGBA amiente de la fuente

GL_DIFFUSE: intensidad RGBA difusa de la fuente

GL_SPECULAR: intensidad RGBA especular de la fuente

GL_POSITION: direccin de la fuente

4.5

Gestin de un Foco de Luz

Las luces se insertan en la escena igual que cualquier elemento geomtrico, estando afectados del mismo modo por las transformaciones geomtricas de modelado
definidas. Esto permite controlar la posicin de la luz, haciendo que permanezca
fija, se mueva, o est ligada a algn objeto de la escena.

La luz se inserta en el modelo cuando se le asigna posicin, siendo la transformacin geomtrica activa en ese punto la que se le aplicara.

Un foco de luz en una escena, permite que una imagen no se vea negra.
Para esto OpenGL ofrece cuatro comandos de luces; dos escalares y dos vectoriales.
Un foco de luz cuenta con:

Luz propia: que es proporcionada por un foco de luz bien situado,


del cual conocemos su ubicacin, y que emite sus rayos de luz de
forma radial o divergente.

Luz impropia: que emite sus rayos de luz desde una ubicacin
muy distante, de forma que podemos considerar sus rayos como
paralelos entre s.

Colocacin de un foco de luz:

Para colocar una fuente de luz en OpenGL: glLightfv (GL_LIGHT0,

Si queremos le podemos dar el efecto foco: Se configura el ngulo


del cono de luz. glLight (GL_LIGHT0, GL_SPOT_CUTOFF, 60.0f);

GL_POSITION,LightPos);

79

Captulo 4 - Color, Materiales e Iluminacin

Configura el brillo del mismo: glLight (GL_LIGHT0, GL_SPOT_EXPONENT, 100.0f);

GL_SPOT_CUTOFF: especifica el mximo ngulo de apertura de la fuente de luz en el

rango [0,90]. Si el valor de cualquier objeto forma un ngulo con la direccin de la


luz superior al ngulo de corte, el objeto no sera iluminado por dicha luz.
GL_SPOT_EXPONENT: especifca la distribucin de intensidad de luz en el rango

[0,128]. Al ser ms alto el rango, ms se concentra la intensidad de la luz en el centro de su rea de proyeccin.
GL_POSITION: aqu se necesitan 4 elementos para especificar la posicin de la luz

en coordenadas homogneas.

Para ver como los focos de luz interaccionan en una escena hay que hablar de:

Iluminacin local: cmo se comporta cada superficie al ser iluminada de forma individual.

Iluminacin global: iluminacin de un determinado objeto en una


escena, teniendo en cuenta los rayos provenientes varias fuentes
de luz y varios objetos.

4.6

Gestin de la atenuacin de la intensidad de la luz

En las fuentes de luz reales, la intensidad de la luz decrece a medida que la distancia desde la fuente de luz se incrementa. Este efecto es conocido como atenuacin.

Debido a que una luz direccional esta infinitamente lejos, no es necesario
atenuar su intensidad respecto a su distancia, entonces la atenuacin estara deshabilitada para una luz direccional. Sin embargo, la atenuacin es importante para
dar realismo con luces posicionales.
En OpenGL la atenuacin de una intensidad de luz. Hay tres tipos de atenuacin:

GL_CONSTANT_ATTENUATION

GL_LINEAR_ATTENUATION

GL_QUADRATIC_ATTENUATION

Las funciones utilizadas para la gestin de atenuacin de intensidad de la luz son:

glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0);

glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0);

glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.5);


Los valores de las contribuciones de luz ambiente, difusa y especular son
atenuados, solo el valor de emisin y luz ambiente global no son atenuados.

Tambin es importante recalcar que al involucrar clculos matemticos adicionales, especialmente divisiones, para cada color, el uso de luces atenuadas
afecta el rendimiento de la aplicacin.
80

Captulo 4 - Color, Materiales e Iluminacin

Referencias
Brian, D. (Octubre de 2008). ANLISIS Y ESTUDIO DE LA ILUMINACIN Y
COLOR EN OPENGL. Recuperado el 2011, de http://repositorio.utn.edu.ec/bitstream/123456789/601/1/An%C3%A1lisis%20y%20Estudio%20de%20la%20
Iluminaci%C3%B3n%20y%20Color%20en%20OpenGL.pdf
Garca, O., & Guevara, A. (2004). Introduccin a la Programacin Grfica con
OpenGL. Recuperado el agosto de 2011
Hearn, D. (2006). Grficos por Computadora con OpenGL. Madrid: Pearson.
Montoya, Y. (2003). Tecnicas Avanzadas de Animacion 3D - OpenGL. Recuperado
el 2011, de http://docentes.umss.edu.bo/fcyt/ymontoya/materias/animacion3D/TextoAnimacion.pdf
Morales, C. (9 de Octubre de 2002). Apuntes de OpenGL y GLUT. Obtenido de
http://dac.escet.urjc.es/docencia/IG/03-OpenGL_Apuntes4.pdf
OpenGL. (s.f.). The Industrys Foundation for High Performance Graphics. Obtenido
de http://www.opengl.org/
Weitzenfeld, A. (Noviembre de 19999). Iluminacin y Sombreado - OpenGL. Recuperado el agosto de 2011, de http://cannes.itam.mx/Alfredo/Espaniol/Cursos/Grafica/Sombreado.pdf
Taller N 8
#include
#include
#include
#include

<windows.h>
<stdio.h>
<stdlib.h>
<glut.h>

void init(void)
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat brillo_specular_fuerte[] = { 5.0 };
GLfloat mat_specular_ninguno[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat lmodel_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat color_difuso_y_ambiente[]={0.1,0.5,0.8,1.0};
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
81

Captulo 4 - Color, Materiales e Iluminacin

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);


glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT,GL_AMBIENT,color_difuso_y_ambiente);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSolidSphere(1.0, 20, 16);
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho(-1.5*(GLfloat)w/(GLfloat)h,
1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}

82

Captulo 4 - Color, Materiales e Iluminacin

Resultado de la ejecucin

Realice los siguientes cambios:


1.

ambiar el argumento glMaterialfv(GL_FRONT, GL_SPECULAR,


C
mat_specular) por glMaterialfv(GL_FRONT, GL_SPECULAR, mat_
specular_ninguno) Qu observa?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
2.

ambiar el argumento glMaterialfv(GL_FRONT, GL_SHININESS,mat_


C
shininess)por glMaterialfv(GL_FRONT, GL_SHININESS,brillo_specular_fuerte ) Qu observa?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
3.

Cambiar el argumento glMaterialfv(GL_FRONT,GL_AMBIENT,color_


difuso_y_ambiente)por
glMaterialfv(GL_FRONT,GL_DIFFUSE,
83

Captulo 4 - Color, Materiales e Iluminacin

color_difuso_y_ambiente ) Qu observa?
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

Ejercicio N 5
1.

Mtodos que se utilizan para sombrear polgonos.

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
2.

Funcin que es utilizada para asignar el modelo de sombreado suave.

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
3.

Caractersticas fundamentales para establecer las propiedades del


material y defina el parmetro de esta funcin.

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
______________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
4.

Como podemos definir una luz ambiente

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
84

Captulo 4 - Color, Materiales e Iluminacin

_________________________________________________________________
_________________________________________________________________
5.

Como podemos definir una luz direccional

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
6.

Como podemos definir una luz posicional

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

85

<5>

C a p t u l o

Trazado del Mapa de Textura


OBJETIVOS:

Presentar los comandos necesarios para


aplicar una textura 2D
sobre un polgono.

Utilizar las funciones


de OpenGL para realizar una repeticin
de textura en los programas que se aplica
una textura 2D sobre
un polgono.

Hacer uso de las rutinas de OpenGL


para lograr el filtrado
de una textura en el
proceso de aplicacin
de una textura 2D sobre un polgono,

Describir las funciones de OpenGL


que establecen los
parmetros de trazado de mapas de texturas.

DESCRIPCIN:
En el captulo se har uso de los tres comandos que dispone OpenGL para aplicar una
textura 2D sobre un polgono, y de los comandos que permiten modificar los distintos
parmetros que se utilizan en el proceso de
aplica una textura 2D sobre un polgono. Adicionalmente, se presentan las funciones de
OpenGL que establecen los parmetros de
trazado de mapas de texturas, se describe el
proceso de filtrado de la textura que dispone
OpenGL y que permite modificar los distintos
parmetros que se utilizan en el proceso de
aplicacin de una textura 2D sobre un polgono.

86

Captulo 5 - Trazado del Mapa de Textura

5.

Trazado del Mapa de Texturas

5.1

Texturas 2D para polgonos

Existen cuatro tipos bsicos de texturas en OpenGL GL_TEXTURE_1D, GL_TEXTURE


_2D, GL_TEXTURE _3D y GL_TEXTURE_CUBE_MAP. Al igual que con iluminacin,
culling y otras propiedades, el texturizado puede ser activado y desactivado va
glEnable() y glDisable(), utilizando cualquiera de los cuatro tipos de textura.

Se puede decir que para mostrar una textura en OpenGL hay que hacer cuatro cosas bsicas:
1.

Cargar la textura desde algn lugar de almacenamiento, lo que implica leerla desde algn tipo de formato (png, bmp, jpg, gif, etc)
y ponerla en memoria.

2.

Configurar las caractersticas de presentacin de la textura, es decir,


como OpenGL debe interpretarla y mostrarla.

3.

Generar un objeto-textura y con esto es necesario obtener un identificador para sta.

4.

Asociar la textura a una o varias primitivas, especificando para cada


caso la forma en que debe ser mapeada.

El cargar una textura en un programa con openGL, se puede hacer por medio de
la funcin:
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type,
void *data);

Los parmetros de la funcin son:

Target: indica el tipo de textura a utilizar. Debe ser GL_TEXTURE_2D

Level: nivel de detalle, permite determinar si el patrn de textura tiene distintas resoluciones. En el caso de utilizar una nica
resolucin, esta debe ser 0.

internalformat: Formato interno de la informacin suministrada


en data.

width: El ancho en pixeles de la textura.

height: La altura en pixeles de la textura.

border: Cantidad de pixeles a agregar horizontal y verticalmente


en los bordes de la imagen, habitualmente es 0.

format: Indica el formato de los elementos de la textura y puede


tomar los valores: GL_COLOR_INDEX, GL_RGB, GL_RGBA, GL_RED, GL_

o GL_PROXY_TEXTURE_2D.

BLUE, GL_ALPHA, GL_LUMINACE_ALPHA.

87

Captulo 5 - Trazado del Mapa de Textura

type: Tipo de representados, indica el tamao de cada componente de color, transparencia y/o luminancia.

data: Es el contenido de la imagen.

Dentro de los tipos posibles a utilizar como target se encuentran:

GL_TEXTURE_2D

GL_TEXTURE_PROXY_2D

GL_TEXTURE_PROXY_CUBE_MAP

O alguna de las seis caras del cube map

GL_TEXTURE_CUBE_MAP_POSITIVE_X

GL_TEXTURE_CUBE_MAP_POSITIVE_Y

GL_TEXTURE_CUBE_MAP_POSITIVE_Z

GL_TEXTURE_CUBE_MAP_NEGATIVE_X

GL_TEXTURE_CUBE_MAP_NEGATIVE_Y

GL_TEXTURE_CUBE_MAP_NEGATIVE_Z


Adicionalmente a estos el soporte para manejar texturas con compresin es
provedo mediante el mecanismo de extensiones, para interpretar formatos particulares. Mediante la funcin glCompressedTexImage2D() se puede crear la textura
gl, que posee los mismos parmetros de la funcin sin compresin, excepto por el
format que no se encuentra y que data debe apuntar a un bloque de memoria que
representa la imagen con la compresin correspondiente a internalformat.

Esta tabla muestra los valores ms comunes de internalformat utilizados,
denominados formatos internos base:
FORMATO INTERNO
GL_ALPHA
GL_DEPTH_COMPONENT
GL_LUMINANCE
GL_LUMINANCE_ALPHA
GL_INTENSITY
GL_RGB
GL_RGBA

VALORES

VALORES

TOMADOS
A
Depth
R
R, A
R
R,G,B

Transparencia
Profundidad
Luminosidad
Luminosidad y transparencia
Intensidad

R,G,B,A

Red, Green, Blue, Alpha (rojo,


verde, azul y transparencia)

Red, Green, Blue (rojo, verde y


azul)


Existe una extensa tabla que muestra todos los posibles valores de bits para
cada una de las combinaciones entre los diferentes formatos base, por ejemplo
GL_RGB8 que indica que las componentes tendrn R-8 bits G-8 bits y B-8 bits.
88

Captulo 5 - Trazado del Mapa de Textura

Mipmaps
Un problema en los principios de la computacin grfica en tiempo real, especialmente en los videojuegos era la pixelacin de las texturas a medida que un observador se acercaba a una primitiva texturizada. En principio esto se puede solucionar utilizando texturas de alta resolucin, pero estas a su vez crean el inconveniente
de requerir mayor tiempo de procesamiento y espacio en memoria utilizar este tipo
de texturas.


La solucin (parcial) entonces es utilizar mipmaps, que bsicamente son
versiones escaladas de una misma textura que se mantienen en memoria, con
el fin de cambiar a texturas ms pequeas (baja resolucin) cuando la vista del
usuario est lejos del objeto texturizado y a mas altas resoluciones cuando este se
encuentra cerca, evitando as la pixelacin y los usos altos de procesamiento, pero
consumiendo mas memoria, aproximadamente un tercio ms que con la imagen de
ms alta resolucin nicamente.

La imagen muestra una serie de mipmaps desde la textura con mas resolucin
hasta la textura con menor resolucin. Los mipmaps deben ser alimentados manualmente cambiando el parmetro level en glTexImage2d(), aunque glu tambin
posee una utilidad para crearlos automticamente mediante gluBuildMipmaps().
Mapeo de texturas

Debido a una textura es una imagen rectangular y una primitiva no necesariamente lo es, se debe especificar la forma en que la textura se acoplar a
la primitiva, esto se hace suministrando la coordenada denominadas s, t (en los
programas de diseo generalmente se denominan u,v ). Estas coordenadas se
suministran para cada vrtice mediante el comando:
glTextureCoord{1234}{sifd}( T coords)
que para el caso de texturas bidimensionales tomara la forma usual de
glTexture2f(GLfloat param1, GLfloat param2); , mientras que los otros parmetros
corresponden a textura 3d (u=0) y escala (w = 0).
89

Captulo 5 - Trazado del Mapa de Textura


La imagen muestra a la izquierda una textura en el espacio (s,t) y a la derecha un tringulo con la textura aplicada, mostrando las coordenadas (s,t) para cada
vrtice de la primitiva. El espacio (s,t) es normalizado, as que la textura sin importar
el tamao siempre va estar contenida entre las coordenadas flotantes (0.0, 0.0) y
(1.0, 1.0). Para asociar las coordenadas de textura basta con dar las (s,t) antes de
las de cada vrtice dentro de los llamados glBegin() glEnd().


Este ejemplo de texturas muestra un cubo texturizado a partir de rectngulos, variando para algunas caras las coordenadas de textura.

Para dibujar un cuadrado 2D definido mediante las coordenadas (0,0), (0,1),
(1,1), (1,0) con una textura. Se asignan a los distintos vrtices del cuadrado coordenadas de textura en el rango [0,3].

90

Captulo 5 - Trazado del Mapa de Textura

glBegin(GL_POLYGON);

glTexCoord2f(0.0, 0.0);

glVertex2f(0.0, 0.0);

glTexCoord2f(0.0, 3.0);

glTexCoord2f(0.0, 0.0);

glVertex2f(0.0, 1.0);

glTexCoord2f(3.0, 3.0);

glVertex2f(1.0, 1.0);

gltexCoord2f(3.0, 0.0);

glVertex2f(1.0, 0.0);
glEnd();

91

Captulo 5 - Trazado del Mapa de Textura

Parmetros de textura
Una vez cargada la textura, es posible ajustar algunos parmetros que modifican
la manera en que ser vista cuando se aplique sobre una primitiva, esto se hace
mediante la funcin:

Void glTexParameterf( enum target, enum pname, enum tparam );
De nuevo target es GL_TEXTURE_2D para el caso que se est tratando, pname corresponde al nombre del parmetro a ajustar y tparam al valor de este parmetro,
una lista de posibles valores se puede observar a continuacin:
Pname

tparam

GL_TEXTURE_WRAP_S

GL_CLAMP, GL_CLAMP_TO_EDGE, GL_REPEAT, GL_


MIRRORED_REPEAT, GL_CLAMP_TO_BORDER
GL_CLAMP, GL_CLAMP_TO_EDGE, GL_REPEAT, GL_
MIRRORED_REPEAT, GL_CLAMP_TO_BORDER
GL_NEAREST, GL_LINEAR, GL_NEAREST_MIMPMAP_
NEAREAST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR
GL_NEAREST, GL_LINEAR

GL_TEXTURE_WRAP_T
GL_TEXTURE_MIN_FILTER

GL_TEXTURE_MAG_FILTER

Texture Wrap
Corresponde a GL_TEXTURE_WRAP_S y GL_TEXTURE_WRAP_T Este parmetro sirve
para determinar la manera en que se ver la textura, si algn parmetro s o t es
mayor a 1.0, los modos son:

GL_CLAMP: Recorta la textura una vez esta supera las coordenadas

GL_CLAMP_TO_EDGE: Similar a clamp, con la diferencia que no muest-

GL_CLAMP_TO_BORDER: Similar a clamp, pero se utiliza el pixel de

GL_REPEAT: Despus de 1.0 bien sea en s y/o t de acuerdo al ajuste,

GL_MIRRORED_REPEAT: Similar a repeat, pero la textura se alterna en

1.0 en (s,t), dependiendo de los ajustes en los estados (se puede


hacer independiente sobre s y t).
rea el texel del borde.

los bordes, con lo que se extiende como textura sobre texels


mayores a 1.0 .
la textura se repite.

coordenadas, por lo que la textura aparece invertida.

92

Captulo 5 - Trazado del Mapa de Textura

5.2

Filtrado de Una Textura

Cuando se aplica una textura a un polgono, y tras realizar la conversin de este


al espacio de pantalla, difcilmente cada pixel en la textura se corresponde con un
pixel de la imagen final obtenida.

Dependiendo de las transformaciones utilizadas y de las coordenadas de
textura definidos, un pixel de la pantalla se corresponder con una porcin de la
textura.

Esta porcin puede abracar desde una pequea parte de un pixel de
textura(magnificacin) hasta una gran coleccin de pixeles(minificacin).
Para obtener el color del pixel en la imagen de la pantalla debern interpolarse
o promediarse los valores de los pixeles de textura implicados. Este proceso se
conoce como filtrado de la textura.
Funcin glTexParameteri
Establece lo parmetros de textura

Cuando la imagen de la textura no se adecua con el tamao de la superficie
que se quiere cubrir, OpenGL utiliza unos filtros de textura para interpolar entre los
pxeles de la imagen y adecuarla a la superficie
Sintaxis
void WINAPI glTexParameteri(
GLenum target,
GLenum pname,
GLint param
);
Parametros
target
La textura objetivo ,que debe ser GL_TEXTURE_1D o GL_TEXTURE_2D.
pname
La constante simbolica de un parmetro de la textura de un solo valor. Los
siguientes smbolos son aceptados en pname.

93

Captulo 5 - Trazado del Mapa de Textura

Valor

Significado
Valor aceptado en param
-La funcin de minificacin
es usada cuando el pixel que
est siendo texturando se
mapen a un rea mayor (elemento de textura). La superGL_NEAREST
ficie a la que se le aplique la
GL_LINEAR
textura es menor que la texGL_NEAREST_MIPMAP_NEARtura que se va a aplicar.

GL_TEXTURE_MIN_
Un pixel de la imagen repreFILTER

EST

senta a muchos del espacio GL_NEAREST_MIPMAP_LINEAR


de texturas.
GL_LINEAR_MIPMAP_NEAREST
Se utiliza cuando el patrn de
texturas deba ser reducido,
para encajar en las coordenadas especificas

GL_LINEAR_MIPMAP_LINEAR

La textura de magnificacin
se utiliza cuando el pixel que
se esta texturando se mapea
a un rea menor (elemento
de textura).
Cuando la superficie a la que
se le aplique la textura sea
mayor que la imagen(textura)
G L _ T E X T U R E _ M A G _ que se va a aplicar . Esta esFILTER
tablece la magnificacin de
textura a GL_NEAREST o GL_
LINEAR

Es utilizada por las rutinas de


texturado cuando una seccin del patrn de texturas
deba agrandarse para encajar en un rango de coordenadas especificas

94

GL_NEAREST
GL_LINEAR

Captulo 5 - Trazado del Mapa de Textura

Para asignar un color a (por ejemplo) el pixel blanco de la figura, se pueden considerar dos estrategias:

Considerar exclusivamente el centro texel ms cercano al pixel, y


usar el color de dicho texel. En la figura, y para el pixel blanco, se
usara el texel que tiene inmediatamente encima y a la derecha.

Considerar los cuatro centros de texels ms cercanos al pixel, y


realizar una mezcla ponderada (segn la distancia) de los cuatro
colores (equivale a una interpolacin lineal). En la figura, y para el
pixel blanco, se usaran los cuatro texel unidos a el con lneas.


La segunda opcin es ligeramente ms costosa en tiempo, pero produce
mejores resultados. OpenGL provee la tcnica conocida como mip-mapping para
mejorar el filtrado de texturas cuando un pixel cubre muchos texels.

La funcin glTexParameter sirve para especificar cul de los dos modos anteriores se usar. Se puede usar un modo para cuando los pixeles son ms grandes
que los texels, y otro (o el mismo) para cuando ocurre lo contrario.

5.3

Aplicacin de texturas 2D sobre Primitivas GLUT


OpenGL incorpora la posibilidad de asignar las coordenadas de textura a los
vrtices evaluando una funcin que depende de las posiciones de los vrtices. Esto
facilita la asignacin de coordenadas de textura, y hace posible la evaluacin de
esta funcin por el hardware grfico, con la consiguiente mejora en el rendimiento.
En este caso, las coordenadas de textura especificadas con glTexCoord2 se igno95

Captulo 5 - Trazado del Mapa de Textura

ran.

Esta funcionalidad (que llamaremos generacin automtica de coordenadas
de textura, GACT) puede activarse (o desactivarse) independiente para cada componente (s o t) del par de coordenadas de textura (s,t), usando la funcin glEnable
(o glDisable) con las constantes GL_TEXTURE_GEN_S (coord. s) y GL_TEXTURE_GEN_T
(coord. t). En nuestro caso, activaremos (o desactivaremos) esta capacidad para
ambas componentes simultneamente).

OpenGL incorpora tres posibles funciones (o modos) para GACT. Cuando
GACT est activada, la seleccin del modo a usar se hace invocando a glTexGen.
Para cada componente (s o t) esta llamada permite elegir una de entre tres posibilidades, usando cada una de las tres constantes que se indican a continuacin

elativo al objeto (GL_OBJECT_LINEAR) :La correspondiente coordeR


nada de textura se calcula como la distancia ms corta desde el
vrtice al que queremos asignarle coordenadas hasta un plano
determinado. Por defecto, para la coordenada S se usa el plano
X=0 (la coordenada de textura S es la coordenada X del vrtice),
y para la coordenada T se usa el plano Y=0 (la coord. de textura T
es la coordenada Y del vrtice). Adems de esto, el plano usado
puede cambiarse dando los coeficientes de su ecuacin implcita
con glTexGen, si bien en esta prctica usaremos los planos por
defecto. La coordenada del vrtice que se usa es la especificada
en glVertex antes de aplicarle las transformacin de instanciacin
(matriz model-view), con lo cual el sistema de coordenadas usado
es el sistema de coordenadas del objeto, lo cual tiene el efecto, en
la prctica, de que la textura se transforma solidariamente con el
polgono y por tanto aparece como fijada al objeto.

elativo al observador (GL_EYE_LINEAR) :Este esquema es similar


R
anterior excepto que se usan las coordenadas del vrtice en el sistema de coordenadas del observador (el eye coordinate system),
es decir, se usa el vrtice despus de aplicarle matriz de transformacin model-view. El efecto es que la textura aparece fija en el
espacio, sin que le afecte la transformacin del objeto.

apa de entorno esfrico (GL_SPHERE_MAP) Este esquema se puede


M
usar para producir imgenes en las que las superficies aparecen
como espejos reflectantes. La textura se usa como un mapa de
entorno (environment map). Esto significa que la textura codifica
la irradiacin entrante desde cualquier direccin posible. Cuando
se usa este modo, OpenGL calcula el vector reflejado r respecto
del vector hacia el observador v (para ello se usa la normal n al
vrtice). El vector r se usa entonces para seleccionar un texel de
la textura. La funcin que permite obtener el texel a partir de r
est diseada de forma que el mapa de entorno pueda obtenerse
96

Captulo 5 - Trazado del Mapa de Textura

directamente de una fotografa de una bola con una superficie especular en la cual se refleje el entorno.
Sintaxis de glTexGen
void glTexGen{ifd}{v}(GLenum coord, GLenum pname, TYPE param);
Parametro

Funcion

Valores posibles

coord,

indicar cul de las coorde- GL_T


nadas de textura debe
GL_R
generarse

GL_S

GL_Q,
GL_TEXTURE_GEN_MODE

pname

GL_OBJECT_PLANE

Si pname

param

es

TURE_GEN_MODE

GL_EYE_PLANE.
GL_OBJECT_LINEAR,
GL_TEX- EYE_LINEAR

GL_

GL_SPHERE_MAP.

Ejemplo
El siguiente ejemolo mustra el uso de las funciones para el trazado de texturas
#include
#include
#include
#include

<math.h>
<stdio.h>
<stdlib.h>
<glut.h>

#ifdef _WIN32
#define floorf(x) ((float)floor((x)))
#endif
static
static
static
#define
#define
void


float transx = 1.0, transy, rotx, roty;


int ox = -1, oy = -1;
int mot = 0;
PAN 1
ROT 2

pan(const int x, const int y) {


transx += (x -ox)/5.;
transy -= (y-oy)/5.;
ox = x; oy = y;
97

Captulo 5 - Trazado del Mapa de Textura

glutPostRedisplay();

void rotate(const int x, const int y) {



rotx += x-ox;

if (rotx > 360.)

rotx -= 360.;

else if (rotx < -360.)

rotx += 360.;

roty += y-oy;

if (roty > 360.)

roty -= 360.;

else if (roty < -360.)

roty += 360.;

ox = x; oy = y;

glutPostRedisplay();
}
void motion(int x, int y) {

if (mot == PAN)

pan(x, y);

else if (mot == ROT)

rotate(x,y);
}
void mouse(int button, int state, int x, int y) {

if(state == GLUT_DOWN) {

switch(button) {

case GLUT_LEFT_BUTTON:

mot = PAN;

motion(ox = x, oy = y);

break;

case GLUT_MIDDLE_BUTTON:

mot = ROT;

motion(ox = x, oy = y);

break;

case GLUT_RIGHT_BUTTON:

break;
}

} else if (state == GLUT_UP)

mot = 0;
}
#define stripeImageWidth 32
98

Captulo 5 - Trazado del Mapa de Textura

GLubyte stripeImage[4*stripeImageWidth];
void makeStripeImage(void) {
int j;
for (j = 0; j < stripeImageWidth; j++) {

stripeImage[4*j] = (GLubyte) ((j<=4) ? 255 : 0);

stripeImage[4*j+1] = (GLubyte) ((j>4) ? 255 : 0);

stripeImage[4*j+2] = (GLubyte) 0;

stripeImage[4*j+3] = (GLubyte) 255;
}
}
void hsv_to_rgb(float h,float s,float v,float *r,float *g,float *b)
{

int i;

float f, p, q, t;


h *= 360.0;

if (s==0) {

*r = v;

*g = v;

*b = v;
}

else {

if (h==360)

h = 0;

h /= 60;

i = floorf(h);

f = h - i;

p = v*(1.0-s);

q = v*(1.0-(s*f));

t = v*(1.0-(s*(1.0-f)));

switch (i) {

case 0 :

*r = v;

*g = t;

*b = p;

break;

case 1 :

*r = q;

*g = v;

*b = p;

break;
99

Captulo 5 - Trazado del Mapa de Textura


case





case





case





case




}
}
}

2 :
*r = p;
*g = v;
*b = t;
break;
3 :
*r = p;
*g = q;
*b = v;
break;
4 :
*r = t;
*g = p;
*b = v;
break;
5 :
*r = v;
*g = p;
*b = q;
break;

GLubyte rainbow[4*stripeImageWidth];
void makeRainbow(void) {

int j;

for (j = 0; j < stripeImageWidth; j++) {

float r, g, b;

hsv_to_rgb((float)j/(stripeImageWidth-1.f), 1.0, 1.0,
&r, &g, &b);

rainbow[4*j] = r*255;

rainbow[4*j+1] = g*255;

rainbow[4*j+2] = b*255;

rainbow[4*j+3] = (GLubyte) 255;
}
}
/* planes for texture coordinate generation */
static GLfloat xequalzero[] = {1.0, 0.0, 0.0, 0.0};
static GLfloat slanted[] = {1.0, 1.0, 1.0, 0.0};
static GLfloat *currentCoeff;
static GLenum currentPlane;
static GLint currentGenMode;
100

Captulo 5 - Trazado del Mapa de Textura

void init(void) {

glClearColor (0.0, 0.0, 0.0, 0.0);

glEnable(GL_DEPTH_TEST);

glShadeModel(GL_SMOOTH);


makeStripeImage();

makeRainbow();

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);


glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_
RGBA, GL_UNSIGNED_BYTE, stripeImage);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

currentCoeff = xequalzero;

currentGenMode = GL_OBJECT_LINEAR;

currentPlane = GL_OBJECT_PLANE;

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);

glTexGenfv(GL_S, currentPlane, currentCoeff);


glEnable(GL_TEXTURE_GEN_S);

glEnable(GL_TEXTURE_1D);

glEnable(GL_CULL_FACE);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);

glEnable(GL_AUTO_NORMAL);

glEnable(GL_NORMALIZE);

glFrontFace(GL_CW);

glCullFace(GL_BACK);

glMaterialf (GL_FRONT, GL_SHININESS, 64.0);
}
void tfunc(void) {

static int state;

if (state = 1) {

glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_
REPEAT);

glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);

glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,
101

Captulo 5 - Trazado del Mapa de Textura

GL_LINEAR);

glTexImage1D(GL_TEXTURE_1D, 0,
GL_RGBA, GL_UNSIGNED_BYTE, rainbow);
}

else {

glTexParameteri(GL_TEXTURE_1D,
REPEAT);

glTexParameteri(GL_TEXTURE_1D,
GL_LINEAR);

glTexParameteri(GL_TEXTURE_1D,
GL_LINEAR);

glTexImage1D(GL_TEXTURE_1D, 0,
GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
}

glutPostRedisplay();
}

4, stripeImageWidth, 0,

GL_TEXTURE_WRAP_S, GL_
GL_TEXTURE_MAG_FILTER,
GL_TEXTURE_MIN_FILTER,
4, stripeImageWidth, 0,

void display(void) {

static GLUquadric *q;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


glPushMatrix();

glTranslatef(0., 0., transx);

glRotatef(rotx, 1.0, 0.0, 0.0);

glRotatef(45.0, 0.0, 0.0, 1.0);

glutSolidTeapot(2.0);
#if 0

if (!q) q = gluNewQuadric();

gluQuadricTexture(q, GL_TRUE);

gluCylinder(q, 1.0, 2.0, 3.0, 10, 10);
#endif

glPopMatrix();

glutSwapBuffers();
}
void reshape(int w, int h) {

glViewport(0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if (w <= h)

glOrtho(-3.5, 3.5, -3.5*(GLfloat)h/(GLfloat)w, 3.5*(GLfloat)h/(GLfloat)w, -3.5, 3.5);
else

glOrtho(-3.5*(GLfloat)w/(GLfloat)h,3.5*(GLfloat)w/(GLfloat)
102

Captulo 5 - Trazado del Mapa de Textura

h, -3.5, 3.5, -3.5, 3.5);



glMatrixMode(GL_MODELVIEW);

glLoadIdentity();
}
/*ARGSUSED1*/
void keyboard (unsigned char key, int x, int y) {

switch (key) {

case e:

case E:

currentGenMode = GL_EYE_LINEAR;

currentPlane = GL_EYE_PLANE;

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);

glTexGenfv(GL_S, currentPlane, currentCoeff);

glutPostRedisplay();

break;

case o:

case O:

currentGenMode = GL_OBJECT_LINEAR;

currentPlane = GL_OBJECT_PLANE;

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);

glTexGenfv(GL_S, currentPlane, currentCoeff);

glutPostRedisplay();

break;

case s:

case S:

currentCoeff = slanted;

glTexGenfv(GL_S, currentPlane, currentCoeff);

glutPostRedisplay();

break;

case x:

case X:

currentCoeff = xequalzero;

glTexGenfv(GL_S, currentPlane, currentCoeff);

glutPostRedisplay();

break;

case t:

tfunc();

break;

case 27:

exit(0);

break;
103

Captulo 5 - Trazado del Mapa de Textura


default:

break;
}
}
int main(int argc, char*argv[]) {

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glutInitWindowSize(512, 512);

glutInitWindowPosition(100, 100);

glutInit(&argc, argv);

glutCreateWindow(argv[0]);

init();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);

glutMouseFunc(mouse);

glutMotionFunc(motion);

glutMainLoop();

return 0;
}
Resultado del Ejemplo
Este ejemplo produce la siguiente imagen, la textura de la imagen se puede cambiar utilizando las teclas e, o, s, x, t. Tambin se puede mover la iluminacin utilizando el botn izquierdo del ratn y moviendo este en el sentido del eje Y.

104

Captulo 5 - Trazado del Mapa de Textura

Referencias
Hearn, D., & Baker, M. (2006). Grficos por Computadora con OpenGL. Madrid:
Pearson Prentice Hall.
Microsoft. (9 de Julio de 2011). MSDN. Recuperado el 8 de Septiembre de
2011, de Microsoft Developer Network: http://msdn.microsoft.com/en-us/library/
dd368641(v=vs.85).aspx
Universidad de Valencia. (s.f.). Recuperado el 5 de Septiembre de 2011, de Departamento de Informatica: http://informatica.uv.es/iiguia/AIG/docs/texturas.htm
Urea, C. (2010). Universidad de Granada. Recuperado el 12 de Septiembre
de 2011, de Departamento de Lenguajes y Sistemas Informaticos.: http://lsi.ugr.
es/~curena/doce/vr/pracs.10-11/04/

105

Captulo 5 - Trazado del Mapa de Textura

Taller N 9
Copie el siguiente cdigo:
#include <stdio.h>
#include <stdlib.h>
#include <glut.h>
#include <GL/gl.h>
GLubyte texArray [32][32][4];
void
{




}

iniciar ()
glClearColor(.5,0.2,0,0);
gluOrtho2D(0,110,0,110);
glFlush();
glutSwapBuffers();

void Dibuja()
{

glClear(GL_COLOR_BUFFER_BIT);

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_
NEAREST);

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_
NEAREST);

glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);

glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

glTexImage2D (GL_TEXTURE_2D, 0, GL_INTENSITY, 32, 32, 1, GL_
RGBA, GL_BYTE, texArray) ;

glEnable (GL_TEXTURE_2D);












glBegin (GL_QUADS);
glColor3f(1,0,1);
glTexCoord2f (0.0,
glVertex2f (100,100);
glColor3f(0,1,0);
glTexCoord2f (1.0,
glVertex2f (100,10);
glColor3f(0,0,1);
glTexCoord2f (1.0,
glVertex2f (10,10);
glColor3f(1,1,0);
glTexCoord2f (0.0,
glVertex2f (10,100);

0.0);
0.0);
1.0);
1.0);
106

Captulo 5 - Trazado del Mapa de Textura

glEnd ( );
glDisable (GL_TEXTURE_2D);


glFlush();

glutSwapBuffers();
}
void almacenarDatosTex ()
{

int x, y, z;

for (z = 0; z < 4; z++){

for (x = 0; x < 32 ; x ++){

for ( y = 0 ; y < 32 ; y++){

if( (x + y + z) % 2 == 0)

texArray[x][y][z] = 55;
else

texArray[x][y][z] = 100;
}
}
}
}
int main( int argc, char *argv[])
{
almacenarDatosTex();
glutInit( &argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize( 500, 500);
glutCreateWindow(Detalles de Texturas);
iniciar();
glutDisplayFunc( Dibuja);
glutMainLoop();
return 0;
}
En el fragmento de cdigo:
glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, 32, 32, 1, GL_RGBA, GL_BYTE,
texArray) ; cambie el valor del elemento GL_INTENSITY por: 3, 4, GL_RGBA, GL_LUMINACE4, GL_RGB12.

Anote sus observaciones


En el fragmento de cdigo:
107

Captulo 5 - Trazado del Mapa de Textura

glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, 32, 32, 1, GL_RGBA, GL_BYTE,


texArray) ;cambie el valor del elemento GL_BYTE por: GL_BITMAP, GL_SHORT,

GL_UNSIGNED_SHORT. Anote sus resultados


En la funcin almacenarDatosTex
Remplace su cdigo por el siguiente:

int x, y, z;
for (z = 0; z < 4; z++){

for (x = 0; x < 32 ; x ++){

for ( y = 0 ; y < 32 ; y++){

if( (x + y + z) % 2 == 0)

texArray[x][y][z] = 0;

if( (x + y + z) % 3 == 0)

texArray[x][y][z] = 25;

if( (x + y + z) % 4 == 0)

texArray[x][y][z] = 50;

if( (x + y + z) % 5 == 0)

texArray[x][y][z] = 75;
else

texArray[x][y][z] = 100;
}
}
}
Anote sus observaciones.
Taller N 10
Copie el siguiente cdigo:
#include
#include
#include
#include
void
{





}

<stdio.h>
<stdlib.h>
<glut.h>
<GL/gl.h>

iniciar ()
//glClearColor(1,0.2,0,0);
glClearColor(0.0,1.0,0.0,1.0);
gluOrtho2D(0,110,0,110);
glFlush();
glutSwapBuffers();

void Dibuja()
108

Captulo 5 - Trazado del Mapa de Textura

{

GLint k;

GLubyte texLine [16]; // Matriz de texturas de 16 elementos.
/* Definir dos elementos verdes para el patrn de textura.
/* Cada color de textura se especifica en cuatro posiciones de la
matriz.
*/

for (k = 0; k <= 2; k += 2){

texLine[4*k] = 0;

texLine
[4*k+1]
= 255;

texLine
[4*k + 2] = 0 ;

texLine
[4*k + 3] =
255;
}
/* Definir dos elementos rojos para el patrn de textura. */

for (k = 1;k<=3;k+=2){

texLine
[4*k] = 255;

texLine
[4*k+1]= 00;

texLine
[4*k + 2]= 0;

texLine
[4*k + 3]= 255;
}

glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_
NEAREST) ;

glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_
NEAREST) ;

glTexImage1D (GL_TEXTURE_1D, 0, GL_RGBA, 4, 0, GL_RGBA, GL_
UNSIGNED_BYTE, texLine);

glEnable (GL_TEXTURE_1D) ;
/* Asignar el rango completo de colores de textura a un segmento
de lnea. */


glLineWidth(40.0);

glBegin (GL_LINES) ;

glTexCoord1f (0.0);

glVertex3f (10,10,0) ;

glTexCoord1f (1.0) ;

glVertex3f (100,100,0) ;

glEnd ( ) ;

glDisable (GL_TEXTURE_1D) ;

glFlush();

glutSwapBuffers();
}
int main( int argc, char *argv[])
109

Captulo 5 - Trazado del Mapa de Textura

{









}

glutInit( &argc, argv);


glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize( 500, 500);
glutCreateWindow(TEXTURAS EN LINEAS);
iniciar();
glutDisplayFunc( Dibuja);
glutMainLoop();
return 0;

Modifique el fragmento de cdigo








glBegin (GL_LINES) ;
glTexCoord1f (0.0);
glVertex3f (10,10,0) ;
glTexCoord1f (1.0) ;
glVertex3f (100,100,0) ;
glEnd ( ) ;

Cada ejercicio inicia con este cdigo

Cambie las lneas glTexCoord1f (0.0); y glTexCoord1f (1.0) ; por


glTexCoord1f (-2.0); y glTexCoord1f (1.0) ;, respectivamente

Cambie las lneas glTexCoord1f (0.0); y glTexCoord1f (1.0) ; por


glTexCoord1f (1.0); y glTexCoord1f (-2.0) ;, respectivamente

Cambie las lneas glTexCoord1f (0.0); y glTexCoord1f (1.0) ; por


glTexCoord1f (0.0); y glTexCoord1f (-16.0) ;, respectivamente

Cambie las lneas glTexCoord1f (0.0); y glTexCoord1f (1.0) ; por


glTexCoord1f (-14.0); y glTexCoord1f (1.0) ;, respectivamente

Anote sus observaciones en cada caso.

110

Captulo 5 - Trazado del Mapa de Textura

Ejercicio N 6
1.

Mencione y explique los 4 aspectos fundamentales para utilizar una


textura en OpenGL:

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
2.

Nombre de la funcin que permite se ajusten los parmetros que modifican y son utilizados en una textura:

_________________________________________________________________

3.

Explique en qu consiste el filtrado de una textura:

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
4.

Mencione las 3 funciones que OpenGL incorpora para GACT:

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
5.

Explique el uso de la funcin glTexParametri:

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

111

<6>

C a p t u l o

Aspectos avanzados de OpenGL


OBJETIVOS:

Presentar los pasos


necesarios para crear
e invocar una lista de
visualizacin.

Definir las funciones


y comandos para la
eliminacin de caras
traseras.

Proporcionar
las
rdenes de OpenGL
para evitar el efecto
escalera o aliasing.

Mostrar los comandos OpenGL que permite la realizacin de


trabajos con varias
reas de dibujo.

Describir los comandos de OpenGL para


guardar el contenido
de la ventana grfica
en un fichero y recuperar imgenes.

DESCRIPCIN:
En el capitulo presentamos las diferentes
primitivas de dibujos que ayudaran a mejorar la eficiencia de nuestras aplicaciones.
Se har uso de una lista de visualizacin,
es decir de un grupo de funciones OpenGL
que han sido almacenadas para su ejecucin
posterior, y que cuando se invoca una lista
de visualizacin las funciones que la forman
se ejecutan en el mismo orden en que fueron almacenadas. Y, la eliminacin de caras
traserasSe presentan los comandos para
definir el efecto escalera o aliasing, las funciones Glutidlefunc y Gluttimer: se hace uso
de las funciones que permiten dividir el rea
de la ventana en varas subreas con el fin de
mostrar a los mismos tiempos distintos vistas
y del conjunto de instrucciones para aadir
mens desplegables a una aplicacin. Se usaran las funciones para guardar el contenido
de la ventana grfica en un fichero, como
mostrar la imagen que contiene en fichero en
una ventana, y la definicin de vectores de
vrtices y niebla.

112

Captulo 6 - Aspectos avanzados de OpenGL

6.

Aspectos Avanzados de OpenGL

6.1

Geometras de las primitivas de los dibujos eficientes

En algunas aplicaciones con OpenGL se requiere dibujar tiras de segmentos de


lneas, lazos de segmentos de lneas, tiras de tringulos, abanicos de tringulos,
tiras de romboides.

Para lograrlo, se usa la funcin de OpenGL void glVertex[2 3 4] {s i d


f} [v] (TYPE coordenadas) que es la que define los vrtices que especifican la
geometra de las primitivas bsicas de OpenGL.


El cdigo que describe la geometra de las primitivas eficientes se especifica
entre llamadas a las funciones, void glBegin(GLenum modo) y void glEnd(void)
donde glEnum modo indica el tipo de primitivas pudiendo ser:

GL_LINE_LOOP: Lazo de segmentos de lneas

GL_LINE_STRIP: Tira de segmento de lnea

GL_QUAD_STRIP: Tira de romboides

GL_TRIANGLE_FAN: Abanico de tringulos


GL_TRIANGLE_STRIP: Tira de tringulos



Se debe tener presente que los segmentos de lnea se dibujan con el ltimo
color seleccionado, el ltimo grosor seleccionado y el ltimo patrn de lneas seleccionado. El segmento de cdigo que se presenta a continuacin indica cmo se
dibuja la geometra de las primitivas eficientes:
void dibuja()
{
Glfloat v[8][2] ={{0.0f,0.0f},{0.1f,1.0f},{0.9f,0.2f},{1.1f,1.1f},{
1.9f,0.3f}{1.8f,0.9f},{2.7f,0.0f},{2.9f,1.2f}};
glPushMatrix();
glTranslate(4.0,2.0,0.0);
glBegin(GL_LINE_LOOP);
glVertex2fv(v[0]); glVertex2fv(v[1];)
glVertex2fv(v[3]); glVertex2fv(v[5];)
glVertex2fv(v[7]); glVertex2fv(v[6];)
glVertex2fv(v[4]); glVertex2fv(v[2];)
glEnd();
glPopMatrix();

glPushMatrix();
glTranslate(2.0,-2.6,0.0);
glBegin(GL_QUAD_STRIP);
glVertex2fv(v[0]); glVertex2fv(v[1];)
glVertex2fv(v[2]); glVertex2fv(v[3];)
113

Captulo 6 - Aspectos avanzados de OpenGL

glVertex2fv(v[4]); glVertex2fv(v[5];)
glVertex2fv(v[6]); glVertex2fv(v[7];)
glEnd();
glPopMatrix();
}

6.2

Lista de Visualizacin

Una lista de visualizacin o display list es un conjunto de comandos que se almacenan para ser ejecutados posteriormente. La mayora de los comandos de
OpenGL se pueden ejecutar de dos maneras:

Modo inmediato: Los comandos se ejecutan conforme se encuentran en el programa. Hasta ahora todos los ejemplos vistos se ejecutan de modo inmediato.

Modo diferido: Los comandos se almacenan en una lista de visualizacin y son ejecutados en otro punto del programa


Los modos de ejecucin no son excluyentes, es decir, en un mismo programa pueden aparecen comandos que se ejecuten en modo inmediato y en modo
diferido.
Para crear una lista de visualizacin utilizamos las funciones:

gl NewList: marca el inicio del conjunto de funciones que se alma-

glEndList: marca el final del conjunto de funciones que se alma-

cenan en la lista

cenan en la lista.


En la funcin, void glNewList (GLuint lista, GLenum modo), la lista es un
entero que identifica a la lista, y debe ser nico, y el modo, que indica el modo de
la lista. Puede ser GL_COMPILE (slo compila la lista) o GL_COMPILE_AND_EXECUTE (la
compila y la ejecuta a la vez). Y la funcin void glEndList (void), indica el final de
la lista de visualizacin.
Ejemplo:
glNewList (1, GL_COMPILE)
glColor3f (1.0, 0.0, 0.0);
glBegin (GL_POLYGON)
glVertex3f (50.0, 100.0, 50.0);
glVertex3f (100.0, 200.0, 10.0);
glVertex3f (10.0, 200.0, 50.0);
glEnd ();
glTranslatef (3.0, 0.0, 0.0);
glEndList ();
114

Captulo 6 - Aspectos avanzados de OpenGL


El uso de listas de visualizacin resulta ms rpido que la ejecucin en modo
inmediato y, por lo tanto, resulta conveniente utilizarlas. Adems, facilitan el encapsulamiento y la reutilizacin de objetos. Creando una lista y ejecutndola donde
necesitemos, estamos realizando un encapsulamiento de las instrucciones que la
componen. La ventaja principal de realizar este encapsulamiento con una lista de
visualizacin en vez de con una funcin, es que las operaciones que incluye se
realizan al compilar la lista.

En el siguiente ejemplo dibujamos un crculo en modo inmediato y utilizando
una lista de visualizacin. El clculo de los vrtices es un proceso computacionalmente costoso debido a las funciones trigonomtricas que aparecen. La versin
con lista de visualizacin resulta mucho ms rpida al ejecutarla, puesto que los
clculos se realizan en tiempo de compilacin.
Ejemplo
// Versin en modo inmediato
dibujarCirculo ()
{
GLint i;
GLfloat coseno, seno;
glBegin (GL_POLYGON);
for (i=0; i<100; i++)
{
coseno = cos (i*2*PI/100.0);
seno = sin (i*2*PI/100.0);
glVertex2f (coseno, seno);
}
glEnd ();
}// Versin con lista de visualizacin
#define LISTA_CIRCULO 1
dibujarCirculo ()
{
GLint i;
GLfloat coseno, seno;
glNewList (LISTA_CIRCULO, GL_COMPILE);
glBegin (GL_POLYGON);
for (i=0; i<100; i++)
{coseno = cos (i*2*PI/100.0);
seno = sin (i*2*PI/100.0);glVertex2f (coseno, seno);}
glEnd ();
glEndList ();
}

115

Captulo 6 - Aspectos avanzados de OpenGL


Despus de a ver creado la lista de visualizacin, podemos ejecutarla en
cualquier lugar del programa, y tantas veces como queramos. La funcin que la
ejecuta es glCallList.

En la funcin void glCallList (GLuint lista), la lista identifica la lista. En
el ejemplo siguiente, aplicamos la funcin glCallList.
Ejemplo
main ()
{
...
// Crear la lista de visualizacin
dibujarCirculo ();
...
// Ejecutar la lista de visualizacin
glCallList (LISTA_CIRCULO);
...
glCallList (LISTA_CIRCULO);
...
}
El incremento en la velocidad de proceso que se produce al utilizar listas de visualizacin, depende de la implementacin concreta de OpenGL y del hardware sobre
el que est instalado. En cualquier caso, como mnimo el uso de listas de visualizacin es tan rpido como el modo inmediato.
Por otro lado, debemos tener en cuenta al utilizar listas de visualizacin, que algunos comandos son sensibles al contexto. Adems, los cambios que se produzcan
en el contexto dentro de la lista, repercutirn a continuacin en los dems comandos, estn dentro de una lista o se ejecuten en modo inmediato.
En el siguiente ejemplo, la instruccin glTranslatef, hace que cada vez que se
ejecuta la lista, se acumule una traslacin en la matriz de modelo y vista y que, por
lo tanto, los objetos que se dibujen a continuacin, incluso la propia lista si se ejecuta de nuevo, sufran esta traslacin. De igual manera, el cambio de color afecta a
todos los objetos que se ejecuten a continuacin.
Ejemplo
void creaTriangulo ()
{
glNewList (1, GL_COMPILE);
glColor3f (1, 0, 0);
116

Captulo 6 - Aspectos avanzados de OpenGL

glBegin (GL_TRIANGLES);
glVertex2f (0, 0);
glVertex2f (1, 0);
glVertex2f (0, 1);
glEnd ();
glTraslatef (1.5, 0, 0);
glEndList ();
}
Para conseguir que no se altere el contexto, debemos utilizar las funciones:

gl PushMat ri x

glPopMatrix

glPushAttrib

glPopAttrib.

Ejemplo
void crearTriangulo ()
{
glNewList (1, GL_COMPILE);
glPushMatrix ();
glPushAttrib (GL_CURRENT_BIT);
glColor3f (1, 0, 0);
glBegin (GL_TRIANGLES);
glVertex2f (0, 0);
glVertex2f (1, 0);
glVertex2f (0, 1);
glEnd ();
glTraslatef (1.5, 0, 0);
glPopAttrib ();
glPopMatrix ();
glEndList ();
}

Debemos destacar que no todas las funciones de OpenGL pueden guardarse en una lista de visualizacin, esto ocurre con las funciones que pasan algn
parmetro por referencia, o que devuelven un valor.
Estas funciones son:

glDeleteList

glFeedbackBuffer

117

Captulo 6 - Aspectos avanzados de OpenGL

glFinish

glFlush

glGenLists

glGet

glIsEnabled

glIsList

glPixelStore

glReadPixels

glRenderMode

glSelectBuffer


Si se incluye alguna de estas funciones, se ejecutar durante la creacin
(compilacin) de la lista, pero no se almacenar en la misma. Es posible crear listas
jerrquicas, es decir, listas que ejecutan otras listas. Las listas jerrquicas son muy
tiles cuando estamos definiendo objetos formados por varias componentes, especialmente si algunas de ellas se repiten varias veces.

En el siguiente ejemplo, empleamos una lista de visualizacin para crear una
bicicleta, suponiendo que creamos otras listas para definir el pedal, el cuadro y las
ruedas.
Ejemplo
#define PEDAL 1
#define CUADRO 2
#define RUEDA 3
#define BICICLETA 4
glNewList (PEDAL, GL_COMPILE);
...
glEndList ();
glNewList (CUADRO, GL_COMPILE);
...
glEndList ();
glNewList (RUEDA, GL_COMPILE);
...
glEndList ();
glNewList (BICICLETA, GL_COMPILE);
glCallList (PEDAL);
glCallList (CUADRO);
glTranslatef (1.0, 0.0, 0.0);
glCallList (RUEDA);
118

Captulo 6 - Aspectos avanzados de OpenGL

glTranslatef (3.0, 0.0, 0.0);


glCallList (RUEDA);
glEndList ()

Los identificadores de las listas de visualizacin deben ser enteros positivos
nicos, lo que implica que debemos tener un especial cuidado es no duplicar ndices.

Cuando se manejan muchas listas de visualizacin puede ser til recurrir
a las siguientes funciones determinadas de OpenGL que proporcionan ndices de
listas de visualizacin no utilizados:

GLuint glGenLists (GLsizei rango): el rango es el nmero de n-

GLboolean glIsList (GLuint indice): el ndice, como su palabra lo

glDeleteLists (GLuint indice, GLsizei rango), el ndice, sera el

dices que queremos obtener. Esta funcin nos proporciona tantos


ndices para listas de visualizacin no usados como indiquemos
con el parmetro rango. Devuelve el primer ndice vaco y ste
junto con los dems, que son correlativos, se marcan como ocupados.
dice, sera el ndice de la lista. Indica si el ndice est usado.

ndice inicial, rango: nmero de ndices que queremos borrar. Esta


funcin borra un conjunto de listas de visualizacin correlativas,
definidas a partir de un ndice inicial y un rango.

Ejemplo
GLuint indiceLista;
indiceLista = glGenLists (1);
if (glIsList (indiceLista))
{
glNewList (indiceLista, GL_COMPILE);
...
glEndList();
}...
glDeleteLists (indiceLista, 1);

OpenGL proporciona tambin la posibilidad de ejecutar varias listas de visualizacin con una nica llamada. Para ello es necesario guardar los ndices en un
array (que puede ser de cualquier tipo) y utilizar las siguientes funciones:

void glCallLists (GLsize n, GLenum tipo, const GLvoid *listas):

119

Captulo 6 - Aspectos avanzados de OpenGL

Donde n, sera el nmero de elementos del array de ndices de listas, el tipo, sera
el tipo de datos del array. Puede ser GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_

UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT, GL_2_BYTES, GL_3_BYTES


o GL_4_BYTES, y las listas, son array de ndices de las listas. Esta funcin ejecuta

un conjunto de listas de visualizacin cuyos ndices se encuentran en el array listas.


void glListBase (GLuint base):

La base es el valor del offset, el cual fija un valor como offset que debe aadirse a
los ndices del array que se ejecuta con glCallLists. La ejecucin de varias listas
con glCallLists se utiliza, por ejemplo, para escribir texto.

En el siguiente ejemplo, tenemos una funcin que crea una lista de visualizacin para cada letra del alfabeto. Una segunda funcin escribe una cadena de
caracteres utilizando llamadas alas listas de visualizacin correspondientes.
Ejemplo
GLuint CrearFuente ()
{
GLuint fuente;
fuente = glGenLists (26);
/* Crear lista para la letra A */
glNewList (fuente, GL_COMPILE);
.
...
glEndList();
/* Crear lista para la letra B */
glNewList (fuente+1, GL_COMPILE);
...
glEndList();
...
return (fuente);
}void EscribirCadena (GLuint fuente, char *cadena)
{
if (fuente == 0 || cadena == NULL)
return;
/* Se pone como base el primer ndice de la fuente y le restamos
65. As,
para la A (cdigo ASCII 65), se mostrar la primera lista, para la
B la
segunda ... */
glListBase (fuente-65);
glCallLists (strlen (cadena), GL_UNSIGNED_BYTE, cadena);
}main ()
120

Captulo 6 - Aspectos avanzados de OpenGL

{
...
GLuint fuente;
fuente = CrearFuente ();
EscribirCadena (fuente, OPENGL);
...

6.3

Especificacin de eliminacin de caras traseras

Dado un conjunto de objetos 3D y una especificacin de la vista, se desea conocer


las superficies de los objetos visibles desde la posicin del observador. Si los objetos que utilizamos estn cerrados, no poseen agujeros, podemos evitar el coste
de dibujar las caras traseras que no son visibles por el observador
La eliminacin de caras posteriores se lleva a cabo mediante las funciones,
glEnable (GL_CULL_FACE);
glCullFace (mode);
donde al parmetro mode se le asigna el valor GL_BACK. De hecho, podemos utilizar
esta funcin para eliminar en su lugar las caras frontales, o podramos incluso eliminar tanto las caras frontales como las posteriores. Por ejemplo, si nuestra posicin
de visualizacin se encuentra dentro de un edificio, entonces lo que queremos es
ver las caras posteriores (el interior de las habitaciones). En este caso, podramos
asignar al parmetro mode el valor GL_FRONT o podramos cambiar la definicin de
qu cara de los polgonos es la frontal utilizando la funcin glFrontFace que se
explica ms adelante. Entonces, si la posicin de visualizacin se desplaza al exterior del edificio, podemos eliminar las caras posteriores de la imagen. Asimismo,
en algunas aplicaciones, puede que slo queramos ver otras primitivas dentro de
la escena, como los conjuntos de puntos y los segmentos de lneas individuales.
En este caso, para eliminar todas las superficies poligonales de una escena, asignaramos al parmetro mode la constante simblica OpenGL GL_FRONT_AND_BACK.

De manera predeterminada, el parmetro mode en la funcin glCullFace
tiene el valor GL_BACK. Por tanto, si activamos la eliminacin de caras posteriores
mediante la funcin glEnable sin invocar explcita-mente la funcin glCullFace, se
eliminarn las caras posteriores de la escena. La rutina de eliminacin se desactiva
mediante,
gIDisable

(GL_CULL_FACE);

La funcin de cara frontal de OpenGL


Aunque, de manera predeterminada, la ordenacin de los vrtices de un polgono
controla la identificacin de las caras frontal y trasera, podemos etiquetar de forma independiente las superficies seleccionadas de una escena como frontales o
traseras con la funcin:
glFrontFace

(vertexOrder);

121

Captulo 6 - Aspectos avanzados de OpenGL


Si cambiamos el argumento vertexOrder a la constante de OpenGL GL_CW,
un polgono definido a continuacin con una ordenacin de sus vrtices en el sentido de las agujas del reloj se considera que es de can frontal. Esta caracterstica
de OpenGL se puede utilizar para intercambiar las caras de un polgono, en el que
hayamos especificado sus vrtices en el orden correspondiente al sentido horario.
La constante GL_CCW etiqueta una ordenacin de los vrtices en sentido contrario a
las agujas del reloj como de cara frontal, que es LA ordenacin predeterminada.


Si definimos esa cara como ABC, el sentido de giro ser como las agujas del
reloj. Si seguimos la regla de la mano derecha, la cara frontal queda hacia dentro
de la pantalla. Si definimos la cara como CBA, ocurre al contrario, la cara frontal es
la que nosotros vemos.

6.4

El efecto fusin en OpenGL

OpenGL provee una serie de funciones que ayudan a evitar el efecto que se produce al asignar a un pixel el color de la primitiva que se est dibujando, sin tener en
cuenta si la primitiva cumple el total o solo parte del pixel.

Para eliminar el efecto fusin, tambin conocido como (efecto escalera o
antialiasing), el proceso utilizado por OpenGL consiste en calcular la superficie de
pixel que verdaderamente estara cubierta por la geometra y, en modo RGBA,
hacer el resto del pixel transparente.

Cabe destacar que para que esto se logre, se requiere habilitar la transparencia y luego iniciar los parmetros necesarios. Los comandos establecidos son
los siguientes:
122

Captulo 6 - Aspectos avanzados de OpenGL

glEnable(GL_BLEND)
glBlendFunc(GLenun sfactor, GLenun dfactor);

La orden glBlendFunc, establece los factores de origen y de destino de la fusin de color.

l primer parmetro de la orden sfactor indica la funcin de la


E
fusin del color origen.

l segundo parmetro, dfactor indica la funcin de fusin del color


E
destino.

dicionalmente, hay que llamar a glEnable(GL_BLEND) para activar


A
la funcin de fusin de color.

Las

configuraciones

predeterminadas

glBlendFunc(GL_ONE, GL_ZERO).

para

la

fusin

son

Ahora mostraremos una lista de factores de fusin validos:

GL_ZERO

GL_ONE

GL_SRC_COLOR

GL_ONE_MINUS_SRC_COLOR

GL_DST_COLOR

GL_ONE_MINUS_DST_COLOR

GL_ONE_SRC_ALPHA

GL_ONE_MINUS_SCR_ALPHA

GL_DST_ALPHA

GL_ONE_MINUS_DST_ALPHA

GL_CONSTANT_COLOR

GL_ONE_MINUS_CONSTANT_COLOR

GL_CONSTANT_ALPHA

GL_ONE_MINUS_CONSTANT_ALPHA

GL_SRC_ALPHA_SATURATE

Es importante tener claro que en el momento que se desea aplicar los factores de
fusin de OpenGL, el primer paso a realizar es habilitarlo con la funcin glEnable,
envindole como parmetros la geometra que se desea suavizar, de esta manera:

123

Captulo 6 - Aspectos avanzados de OpenGL

GL_POINT_SMOOTH,

GL_LINE_SMOOTH,

GL_POLYGON_SMOOTH,

entre otras. Por ejemplo: glEnable(GL_LINE_SMOOTH).


Ahora bien, Para mejorar la calidad del efecto fusin se utiliza la siguiente
rutina que permite controlar la relacin entre calidad de la imagen y velocidad de
dibujo:
Void glHint(GLenum objetivo, Glenum modo);


La funcin glHint permite un control opcional de determinados comportamientos de interpretacin.

El parmetro objeto indica que comportamiento est siendo controlado y
especifica la calidad de la imagen de puntos, lneas y polgonos durante las operaciones del efecto de fusin.
Los valores posibles son:

GL_POINT_SMOOTH_HINT

GL_LINE_SMOOTH_HINT

GL_POLYGON_SMOOTH_HINT

El parmetro modo puede ser:

GL_FASTEST, Para indicar que se elige la opcin ms eficiente.

GL_NICEST, Se elige la opcin de mayor calidad.

GL_DONT_CARE, Para no indicar ninguna referencia.

6.5

Uso de GlutIdleFunc y glutTimerFunc

6.5.1 Funcin GlutIdleFunc


glutIdleFunc establece la devolucin de llamada de espera global.
glutIdleFunc vaco (void (* func) (void));
glutIdleFunc establece la devolucin de llamada de espera global para ser fun-

cional para que en un programa de GLUT se puedan realizar tareas de procesamiento de fondo o una animacin continua en los eventos del sistema de ventanas no
se estn recibiendo. Si est activado, el callback idle est continuamente llamado
cuando los eventos no se estn recibiendo. La rutina callback no tiene parmetros.
La ventana y men actual no ser cambiado antes de la devolucin de llamada
de inactividad. Programas con mltiples ventanas y / o mens debe establecer
explcitamente la ventana actual y / o actuales del men y no depender de su con124

Captulo 6 - Aspectos avanzados de OpenGL

figuracin actual.

El monto de la computacin y la prestacin a cabo en un callback idle debera reducirse al mnimo para no afectar la respuesta interactiva del programa. En
general, no ms que un solo marco de la prestacin debe hacerse en un callback
idle.

Pasando NULL a glutIdleFunc se desactiva la generacin de la devolucin
de llamada de inactividad.
6.5.2 Funcin GlutTimerFunc
glutTimerFunc registra una devolucin de llamada de temporizador que se activa

en un nmero especificado de milisegundos.

glutTimerFunc vaco (unsigned int milisegundos, void (* func) (int valor),


valor);
GlutTimerFunc registra la funcin de devolucin de llamada del temporizador que

se activa por lo menos en milisegundos milisegundos. El parmetro valor a la devolucin de llamada del temporizador ser el valor del parmetro valor a glutTimerFunc. Devoluciones de llamadas de temporizador mltiples, a veces iguales o diferentes pueden ser registradas de forma simultnea.

El nmero de milisegundos es un lmite inferior en el tiempo antes que la
devolucin de llamada se genera y se indica por unsigned int milisegundos. GLUT
intenta entregar el temporizador de devolucin de llamada tan pronto como sea
posible despus de la expiracin del intervalo de tiempo de la devolucin de llamada.

No hay soporte para cancelar una devolucin de llamada registrada. En su
lugar, ignorar una devolucin de llamada en funcin de su valor del parmetro cuando se activa.

6.6

Definicin de varias reas de dibujo.

Es posible realizar tareas donde se quieran visualizar varias sub-reas del dibujo al
mismo tiempo es decir que una misma ventana pueda dividirse mostrando visualizaciones diferentes. Como por ejemplo supongamos que hemos creado un programa de diseo de modelos 3D, sera posible visualizar cada una de sus perspectivas
al mismo tiempo.

El resultado de la proyeccin se fija mediante la llamada a la funcin glViewport. Y el prototipo de esta funcin es la siguiente:
void glViewport (GLint x, GLint y, GLsizei ancho, GLsizei alto)
Los parmetros x e y de esta funcin especifican las esquina inferior izquierda de
la vista dentro de la ventana, y los parmetros ancho y largo especifican las dimensiones en pixeles de dicha rea.

Frecuentemente cuando se llama esta funcin con dos parejas de nmeros


125

Captulo 6 - Aspectos avanzados de OpenGL

especificando el rea de dibujo en la ventana se produce un error, ya que en realidad se trata de las dimensiones en lugar de un segundo punto.

Luego de haber especificado el tipo de proyeccin, dibujada la escena, y
lgicamente definido el rea de dibujo; si lo que se desea es dividir el rea de la
ventana para visualizar varias a la vez se deben seguir los siguientes pasos suponiendo que una misma ventana ser dividida en dos sub-reas:

Definir el rea de dibujo.

Especifica la proyeccin.

Dibuja la escena.

Define el rea de dibujo 2.

Especifica la proyeccin.

Dibuja la escena.

Esto se repite la cantidad de veces que se desea dividir el rea de la ventana.


Para realizar esto se debe considerar lo siguiente:

Al trabajar con una sola rea de dibujo, la funcin glViewport se


llamara dentro de la rutina de eventos de la ventana, con la finalidad de que el rea de dibujo se pueda redimensionar si el tamao
de la ventana lo hace tambin.

uando se trabaja con distintas reas la funcin glViewport se llaC


mara cada vez que haya una rea distinta y cada una de ellas debe
ordenar que se dibuje la escena que le corresponda, por lo que se
deber indicar desde la rutina para dibujar la escena.

6.7 Tratamiento de imagines en OpenGL: Guardar y recuperar imagines.


A lo largo de trabajar en OpenGL nos resulta necesario guardar lo que tenemos en
nuestra ventana grafica en un fichero o mostrar la imagen que contiene en fichero
en una ventana grfica. En OpenGL lo podemos hacer transfiriendo de la memoria
del sistema grfico a la memoria principal o de la memoria principal y luego hacia
la memoria del sistema grfico. Este proceso de transferir los datos realiza en dos
pasos: primero los datos se transfiere de la memoria del sistema grfico a la memoria principal y segundo los datos se transfiere de la memoria principal al archivo.

Las funciones que nos permiten realizan estas tranferencias son glReadPix-

els y glDrawPixels.


Para transferir los datos de la memoria del sistema grfico a la memoria principal se utiliza la orden en OpenGL: void glReadPixels(GLint x, GLint y,

GLsizei ancho, GLsizei alto,

126

Captulo 6 - Aspectos avanzados de OpenGL

GLenum format, GLenum tipo,

GLvoid*pixeles);


Con esta orden podemos definir el rea rectangular de nuestra ventana grfica que deseamos transferir a la memoria principal.
Parmetros

El parmetro x y el parmetro y se utilizan para definir el vrtice


inferior izquierdo en coordenadas de ventana.

Los parmetros alto y ancho indican la altura y ancho del rectngulo de pxeles. Si se escribe en anchurayaltura 1 como parmetros de valor, esto correspondera a un solo pxel.

El parmetro formato nos indica de que elemento est formado un


pixel. Se aceptan estos valores simblicos:
Valor

GL_COLOR_INDEX

GL_STENCIL_INDEX

GL_DEPTH_COMPONENT

Significado
Los ndices de color se leen de la memoria de color seleccionado porglReadBuffer.Cada ndice se convierte en
punto fijo, desplazado hacia la izquierda o derecha, dependiendo del valor y el signo de GL_INDEX_SHIFT, y se
aade a GL_INDEX_OFFSET.Si es GL_MAP_COLOR GL_TRUE,
los ndices son reemplazados por sus asignaciones en el
GL_PIXEL_MAP_I_TO_I.
Stencil valores se leen desde el stencil buffer.Cada ndice
se convierte en punto fijo, desplazado hacia la izquierda
o derecha, dependiendo del valor y el signo de GL_INDEX_
SHIFT, y se aade a GL_INDEX_OFFSET.Si es GL_MAP_STENCIL GL_TRUE, los ndices son reemplazados por sus asignaciones en el GL_PIXEL_MAP_S_TO_S.
Los valores de profundidad se leen en el bfer de profundidad.Cada componente se convierte en punto flotante por
ejemplo que los mapas de profundidad mnima de valor a
0.0 y los mapas de valor mximo de 1,0.Cada componente se multiplica por GL_DEPTH_SCALE, sumado a GL_DEPTH_
BIAS y, finalmente, anclada en el rango [0,1].

127

Captulo 6 - Aspectos avanzados de OpenGL

GL_RED,
GL_GREEN,
GL_BLUE, GL_ALPHA,
GL_RGB,
GL_RGBA,
GL_BGR_EXT,
GL_
BGRA_EXT,
GL_LUMINANCE,
GL_LUMINANCE_ALPHA

Procesamiento difiere dependiendo de si los ndices de


buffers de color almacenar el color o los componentes
RGBA de color.Si los ndices de color se almacenan, se
leen de la memoria de color seleccionado porglReadBuffer. Cada ndice se convierte en punto fijo, dependiendo del valor y el signo de GL_INDEX_SHIFT, y se aade
a GL_INDEX_OFFSET. Los ndices son luego reemplazados
por el rojo, verde, azul y alfa obtenida por la indexacin
de los GL_PIXEL_MAP_I_TO_R, GL_PIXEL_MAP_I_TO_G, GL_
PIXEL_MAP_I_TO_B y tablas GL_PIXEL_MAP_I_TO_A. Si los
componentes de color RGBA se almacenan en el buffer
de color, que se leen de la memoria de color seleccionado
por glReadBuffer . Cada componente de color se convierte a tal punto flotante que los mapas de intensidad.Cada
componente se multiplica por GL_c_SCALE y se aade a
GL_c_BIAS, donde c es GL_RED, GL_GREEN, GL_BLUE y
GL_ALPHA. Por ltimo, si es GL_MAP_COLOR GL_TRUE, cada
componente de color c se sustituye por su asignacin en
la tabla GL_PIXEL_MAP_c_TO_c.

El parmetro tipo se debe especificar de que tipo de elementos


consta cada pixel, debe ser uno de los siguientes valores.

Tipo

ndice de la mscara

1
G L _ U N S I G N E D _ 2161

Componente de conversin
(281)c
[(271)c-1] / 2
1
(2161)c

2151
GL_UNSIGNED_INT_ 2321
GL_INT
2311
GL_FLOAT
ninguno

[(2151)c1] / 2
(2321)c
[(2311)c1] / 2
c

GL_UNSIGNED_BYTE 281
GL_BYTE
271
GL_BITMAP
SHORT
GL_SHORT

Parmetro pixeles es un apuntador a los datos de pixeles en la


imagen.

Funcin glDrawPixels
Es la funcin que escribe en un bloque de pxeles para el framebuffer.
Para utilizarla es con la orden void glDrawPixels (
128

Captulo 6 - Aspectos avanzados de OpenGL

GLsizei ancho,

GLsizei alto,

GLenum formato,

GLenum tipo,

const GLvoid pxeles * );

Parmetros

El parmetro Ancho se utiliza para asignar la dimensin de la anchura del rectngulo de pxeles que se escribir en el uso de este
dispositivo.

El parmetro Alto es usado para asignar una altura al dispositivo.

El parmetro formato se usa para asignar el formato de los datos


en pxeles.Utiliza estas constantes:

Valor
GL_COLOR_INDEX

GL_STENCIL_INDEX

GL_DEPTH_COMPONENT

GL_RGBA

GL_RED

Significado
Cada pixel es un valor nico, un ndice de
color. La funcin glDrawPixels convierte
cada pixel en formato de punto fijo.
Cada pixel es un valor nico, un ndice de la
plantilla.La funcin glDrawPixels convierte
en formato de punto fijo.
Cada pixel es un componente de un solo
fondo. La funcin glDrawPixels convierte
datos de coma flotante directamente a un interno de formato de punto flotante con una
precisin sin especificar.
Cada pixel es un grupo de cuatro componentes en este orden: rojo, verde, azul, alfa.
Convierte valores de punto flotante directamente.
Cada pixel es un componente rojo. La funcin convierte este componente a lo interno
en un punto flotante de la misma manera que
el componente rojo de un pxel es RGBA, y
luego lo convierte en un pixel RGBA con el
conjunto verde y azul, despus se lee como
un pixel RGBA.
129

Captulo 6 - Aspectos avanzados de OpenGL

GL_GREEN

GL_BLUE

GL_ALPHA

GL_RGB

GL_LUMINANCE
GL_LUMINANCE_ALPHA

GL_BGR_EXT

GL_BGRA_EXT

Cada pixel es un componente verde nico.


La funcin convierte este componente a lo
interno en un punto flotante de la misma
manera que el componente verde de un pxel es RGBA, y luego lo convierte en un pixel
RGBA con el conjunto rojo y azul, despus
se lee como un pixel RGBA.
funcin convierte este componente a lo interno formato de punto flotante de la misma
manera que el componente azul de un pxel
es RGBA, y luego lo convierte en un pixel
RGBA con el conjunto rojo y verde. Lafuncin convierte este componente a lo interno
en un punto flotante de la misma manera que
el componente azul de un pxel es RGBA, y
luego lo convierte en un pixel RGBA con el
conjunto rojo y verde, despus se lee como
un pixel RGBA.
Cada pixel es un componente alfa solo.
Cada pixel es un grupo de tres componentes
en este orden: rojo, verde, azul.La funcin
glDrawPixels convierte cada componente
a lo interno formato de punto flotante de la
misma manera que los componentes rojo,
verde y azul de un pxel se RGBA.
Cada pixel es un componente de luminancia
solo.
Cada pixel es un grupo de dos componentes
en este orden: luminancia, la alfa.
Cada pixel es un grupo de tres componentes
en este orden: azul, verde, rojo. GL_BGR_EXT
proporciona un formato que coincida con
el diseo de memoria de Windows, mapas
de bits independientes del dispositivo. Por
lo tanto, las aplicaciones pueden utilizar los
mismos datos con llamadas a funciones de
Windows y las llamadas OpenGL pixel funcin.
Cada pixel es un grupo de cuatro componentes en este orden: azul, verde, rojo, alfa.

El parmetro tipo se utiliza para especificar el formato de cada


130

Captulo 6 - Aspectos avanzados de OpenGL

pixel. Se aceptan los siguientes:


Valor
GL_UNSIGNED_BYTE
GL_BYTE
GL_BITMAP
GL_UNSIGNED_SHORT
GL_SHORT
GL_UNSIGNED_INT
GL_INT
GL_FLOAT

6.8

Significado
Sin signo de 8 bits sin signo
Entero de 8 bits sin signo
Bits individuales de 8 bits sin signo enteros
Sin signo de 16 bits sin signo
Entero de 16 bits sin signo
Sin signo de 32 bits sin signo
Entero de 32 bits
Un solo punto flotante de precisin

Parmetro pixeles es un puntero a los datos en pixeles.

Especificacin de los vectores de vrtice en OpenGL.

Cuando se quiere dibujar primitivas geomtricas en OpenGL, es necesario llamar


a muchas funciones. Por ejemplo para dibujar un polgono de 20 bordes, necesitas
llamar por lo menos a 22 funciones: una para llamar a glBegin(), una funcin para
cada uno de los vrtices, y para terminar la funcin de glEnd(). Y si se le quiere
aadir ms informacin como colores RBGA, ndices de color y normales, para
cada uno de los vrtices; esto puede duplicar o triplicar el nmero de funciones que
se necesitaran llamar, para una solo primitiva geomtrica. Y esto puede impedir la
buena ejecucin del programa y tambin a afectar el rendimiento del sistema.

Pero para evitar esto OpenGL tiene vectores de vrtices que permite especificar un grupo de vrtices relacionados en unos pocos arreglos y accediendo a los
datos de estos. Esto nos da la opcin de llamar a menos funciones.
Hay tres pasos que se utilizan en la especificacin de vectores de vrtice son:
1.

Activar el vector apropiado, existen de diferentes tipos: en la siguiente tabla se muestra la lista de vectores que pueden ser llamados
en OpenGL.

Vector
GL_VERTEX_ARRAY
GL_NORMAL_ARRAY
GL_COLOR_ARRAY
GL_INDEX_ARRAY
GL_FOG_COORD_ARRAY
GL_TEXTURE_COORD_ARRAY

Descripcin
Coordenadas de vrtices
Normales
Colores RBGA
ndice de color
Coordenadas de niebla
Coordenadas de textura
131

Captulo 6 - Aspectos avanzados de OpenGL


GL_EDGE_FLAG_ARRAY

Banderas de aristas de Polgonos

Tabla 1: vectores que pueden ser llamados en OpenGL.


En OpenGL estos vectores son llamados con la funcin glEnableClientState(), y
son desactivados con la funcin de glDisableClientState().
2.

Especificando los datos parta los vectores: hay diferentes funciones


para especificar datos para un vector, una funcin para cada tipo de
vector.

Coordenadas de vrtices.

void glVertexPointer(GLint tamao, GLenum tipo, GLsizei empaquetamiento, const GLvoid *puntero);

Colores RBGA.
void glColorPointer(GLint tamao, GLenum tipo, GLsizei empaquetamiento, const
GLvoid *puntero);

ndice de color.

void glIndexPointer(GLenum tipo, GLsizei empaquetamiento, const


GLvoid *puntero);

Normales.
void glNormalPointer(GLenum tipo, GLsizei empaquetamiento, const
GLvoid *puntero);

Coordenadas de niebla.
void glFogCoordPointer(GLenum tipo, GLsizei empaquetamiento, const
GLvoid *puntero);

Coordenadas de textura.
void glTexCoordPointer(GLint tamao, GLenum tipo, GLsizei empaquetamiento, const GLvoid *puntero);

Banderas de aristas de Polgonos.


void glEdgeFlagPointer(GLsizei empaquetamiento, const GLvoid
*puntero)

Donde:

Puntero es la direccin de memoria donde residen los datos.

Tipo indica el tipo de dato en el vector (GL_SHORT, GL_INT, GL_


FLOAT, GL_DOUBLE).

Tamao indica el nmero de coordenadas por vrtice que pueden


ser 2, 3, o 4.
132

Captulo 6 - Aspectos avanzados de OpenGL

Empaquetamiento indica el espacio, en bytes, entre coordenadas


sucesivas de un vrtice, si es cero, los datos se encuentran uno
tras otro sin ningn tipo espacio adicional entre ellos.

Ejemplo
Fragmento de cdigo para habilitar vectores de vrtices.
static GLint vertices[] = {25, 25,
100, 325,
175, 25,
175, 325,
250, 25,
325, 325};
static GLfloat colors[] = {1.0, 0.2, 0.2,
0.2, 0.2, 1.0,
0.8, 1.0, 0.2,
0.75, 0.75, 0.75,
0.35, 0.35, 0.35,
0.5, 0.5, 0.5};
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(3, GL_FLOAT, 0, colors);
glVertexPointer(2, GL_INT, 0, vertices);
3.

Hacer referencia de la informacin para su utilizacin. Existen varias


forma de referenciar los datos que se encuentran en los vectores,
estas son:

Hacer referencia a un nico elemento del vector, Para esto se utiliza la funcin void glArrayElement(GLint posicin).

Ejemplo
Fragmento de cdigo usando glArrayElement().
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(3, GL_FLOAT, 0, colors);
glVertexPointer(2, GL_INT, 0, vertices);
glBegin(GL_TRIANGLES);
133

Captulo 6 - Aspectos avanzados de OpenGL

glArrayElement(2);
glArrayElement(3);
glArrayElement(5);
glEnd();

Hacer referencia a una lista de elementos del vector, para esto


se pueden utilizar funciones como: glArrayElement(), glDrawElements(), glMultiDrawElements(), glDrawRangeElements().

Ejemplo
Fragmento de cdigo usando glDrawElements().
static GLubyte frontIndices[] = {4, 5, 6, 7};
static GLubyte rightIndices[] = {1, 2, 6, 5};
static GLubyte bottomIndices[] = {0, 1, 5, 4};
static GLubyte backIndices[] = {0, 3, 2, 1};
static GLubyte leftIndices[] = {0, 4, 7, 3};
static GLubyte topIndices[] = {2, 3, 7, 6};
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, frontIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, rightIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, bottomIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, backIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, leftIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, topIndices);
Ejemplo
Fragmento de cdigo usando glMultiDrawElements().
static
static
static
static

GLubyte oneIndices[] = {0, 1, 2, 3, 4, 5, 6};


GLubyte twoIndices[] = {7, 1, 8, 9, 10, 11};
GLsizei count[] = {7, 6};
GLvoid * indices[2] = {oneIndices, twoIndices};

glMultiDrawElements(GL_LINE_STRIP, count, GL_UNSIGNED_BYTE, indices, 2);

Hacer una referencia a una secuencia aleatoria de elementos,


Cuando se desea extraer una secuencia aleatoria de elementos
se pueden utilizar funciones: glArrayElement(), glDrawElements,
glDrawRangeElements() y glDrawArrays().

134

Captulo 6 - Aspectos avanzados de OpenGL

Ejemplo
Fragmento de cdigo usando glDrawArrays().
for (i = 0; i < primcount; i++) {
if (count[i] > 0)
glDrawArrays(mode, first[i], count[i]);
}

6.9

Niebla

La niebla es un efecto especial de fcil uso que dispone OpenGl y que fusiona un
color de niebla que podemos especificar en el elemento geomtrico una vez efectuados los clculos.

La cantidad de color de niebla mezclada con el elemento vara con la distancia desde el origen a la cmara.

Las funciones utilizadas para la niebla son:

Void
Void
Void
Void

glFogf(GLenum
glFogi(GLenum
glFogf(GLenum
glFogi(GLenum

atributo,
atributo,
atributo,
atributo,

GLfloat valor)
GLfloat valor)
GLfloat* valor)
GLfloat *valor)

Donde:

Atributo es el valor enumerado que determina la funcionalidad a


gestionar.

Valor contiene un conjunto de valores que sustituir a los antiguos


atributos.

En la siguiente tabla se muestra la lista de atributos que tiene OpenGL para el


manejo de la niebla.

Atributo
GL_FOG_COLOR
GL_FOG_DENSITY
GL_FOG_END
GL_FOG_INDEX

Descripcin
Especifica exactamente el color que se desea para la niebla.
Especifica la densidad de la niebla.
Especifica la distancia mxima a la que se aplica la niebla.
Determina el ndice de color de niebla.

135

Captulo 6 - Aspectos avanzados de OpenGL

GL_FOG_MODE
GL_FOG_START
GL_FOG_COORD_SRC

Especifica el modo de niebla, que se desea. GL_LINEAR,


GL_EXP, GL_EXP2.
Especifica la distancia a la que se empieza a aplicar la niebla.
Niebla de vrtice interpolado.

Tabla 2: Lista atributos para la niebla en OpenGL.


El uso de la funcin glhint(GL_FOG_HINT,mode) permite el clculo de la niebla con
precisin, donde el parmetro modo indica la precisin deseada por eJ usuario. Las
opciones disponibles son las siguientes:

GL_FASTEST. Emplea el algoritmo de niebla mas eficiente, pero tam-

GL_NICEST. Algoritmo menos eficiente, pero genera resultados con


GL_DONT_CARE. El programador no tiene preferencias. Decide el


bin el mas inexacto.

la mayor calidad posible.


paquete grfico.

Cuando el clculo de niebla por pxel no se soporta eficientemente por la implementacin OpenGL empleada, GL_DONT_CARE o GL_FASTEST usaran una interpolacin lineal por vrtices.

Ejemplo
Cdigo para el manejo de la niebla en OpenGL.
#include
#include
#include
#include
#include

<windows.h>
<stdio.h>
<stdlib.h>
<glut.h>
<gl/gl.h>

static GLint modo_niebla;


static void iniciar(void)
{
GLfloat posicion[] = { 0.5, 0.5, 3.0, 0.0 };
glEnable(GL_DEPTH_TEST);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
{
136

Captulo 6 - Aspectos avanzados de OpenGL

GLfloat mat[3] = {0.1745, 0.01175, 0.01175};


glMaterialfv(GL_FRONT, GL_AMBIENT, mat);
mat[0] = 0.61424; mat[1] = 0.04136; mat[2] = 0.04136;
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat);
mat[0] = 0.727811; mat[1] = 0.626959; mat[2] = 0.626959;
glMaterialfv(GL_FRONT, GL_SPECULAR, mat);
glMaterialf(GL_FRONT, GL_SHININESS, 0.6*128.0);
}
glEnable(GL_FOG);
{
GLfloat color_niebla[4] = {0.5, 0.5, 0.5, 1.0};
Modo_niebla = GL_EXP;
glFogi(GL_FOG_MODE, modo_niebla);
glFogfv(GL_FOG_COLOR, color_niebla);
glFogf(GL_FOG_DENSITY, 0.35);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 1.0);
glFogf(GL_FOG_END, 5.0);
}
glClearColor(0.5, 0.5, 0.5, 1.0); //color de niebla
}
static void renderSphere(GLfloat x, GLfloat y, GLfloat z)
{
glPushMatrix();
glTranslatef(x, y, z);
glutSolidSphere(0.4, 16, 16);
glPopMatrix();
}
//desplegar() dibuja cinco esferas diferentes.
void desplegar (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderSphere(-2., -0.5, -1.0);
renderSphere(-1., -0.5, -2.0);
renderSphere(0., -0.5, -3.0);
renderSphere(1., -0.5, -4.0);
renderSphere(2., -0.5, -5.0);
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
137

Captulo 6 - Aspectos avanzados de OpenGL

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w,
2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho(-2.5*(GLfloat)w/(GLfloat)h,
2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void teclado(unsigned char key, int x, int y)
{
switch (key) {
case f:
case F:
if (modo_niebla == GL_EXP) {
modo_niebla = GL_EXP2;
printf(El modo de niebla es: GL_EXP2\n);
}
else if (modo_niebla == GL_EXP2) {
modo_niebla = GL_LINEAR;
printf(El modo de niebla es: GL_LINEAR\n);
}
else if (modo_niebla == GL_LINEAR) {
modo_niebla = GL_EXP;
printf(El modo de niebla es: GL_EXP\n);
}
glFogi(GL_FOG_MODE, modo_niebla);
glutPostRedisplay();
break;
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
138

Captulo 6 - Aspectos avanzados de OpenGL

glutInitWindowSize(500, 500);
glutCreateWindow(argv[0]);
iniciar();
glutReshapeFunc(reshape);
glutKeyboardFunc(teclado);
glutDisplayFunc(desplegar);
glutMainLoop();
return 0;
}

Figura: Resultado de la ejecucion.

139

Captulo 6 - Aspectos avanzados de OpenGL

6.10 Cargar modelos .OBJ


Para cargar este formato de archivo, el cual puede ser creado en diversos programas de modelado grfico, se requiere la librera glm.h la cual fue desarrollada por
Nate Robin, esta se encuentra en la siguiente direccin : http://www.megaupload.
com/?d=QGWIEZD7. Como primer paso se debe crear un nuevo proyecto en Visual Studio 2010. A este proyecto se le agregaran los archivos glm.cpp y glm.h que
estn en el archivo descargado anteriormente. Para la ejecucin de este programa
es necesario utilizar los archivos virus.obj y virus.mtl los cuales se encuentran en
la siguiente direccin: http://www.megaupload.com/?d=EMHCDLDH, despus de
descomprimirlos los agregaremos a una carpeta que se llamara modelos, en donde hemos guardado nuestro proyecto
Despus se creara un archivo de cdigo fuente en el cual se copiara el siguiente
cdigo.
#include <glut.h>
#include glm.h
#include <math.h>
GLMmodel* objeto;
//////////
GLfloat luzAmbient[4] = {0.0,0.0,0.0,1.0};
GLfloat luzDiff[4] = {1.0, 1.0, 1.0,1.0};
GLfloat luzSpec[4] = {1.0, 1.0, 1.0,1.0};
/////////
//////////
GLfloat matAmbient[4] = {0.11,0.06,0.11,1.0};
GLfloat matDiff[4] = {0.42, 0.0, 0.79,1.0};
GLfloat matSpec[4] = {0.33, 0.33, 0.52,1.0};
GLfloat matEmision[4] = {0.0,0.0,0.0,0.0};
GLint shininess=128;
/////////
void init(){
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
objeto = glmReadOBJ(../modelos/virus.obj);
}
void luz(){
//luces del modelo
glLightfv(GL_LIGHT0, GL_AMBIENT, luzAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, luzDiff);
140

Captulo 6 - Aspectos avanzados de OpenGL

glLightfv(GL_LIGHT0, GL_SPECULAR, luzSpec);

void cambiarTamano(int largo, int ancho) {


// esta funcion resive los parametros largo y ancho del callback que lo llamo
(glutReshapeFunc)
if(ancho==0) ancho=1; // Previene que dividamos por 0
// Afectaciones de vistas o tomas de perspectiva
glMatrixMode(GL_PROJECTION);

//Escojemos la matriz de proyeccion
glLoadIdentity();
// Se resetea la matriz
glViewport(0,0,ancho, largo);
// Se va a usar toda la ventana para mostrar graficos
gluPerspective( 60 , (float)largo/(float)ancho, 1, 260);
glMatrixMode(GL_MODELVIEW);

glLoadIdentity();
gluLookAt(0.0, 0.0, 8.5, 0.0, 0.0, 5.0,1.0, 7.0, 0.0);
}
void dibujar() {
glClearColor (1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

luz();

glTranslatef(0,0,-5);
glRotatef(1,1,1,1);
glmDraw(objeto, GLM_SMOOTH);
glFlush();
}
int main(int argc, char **argv) {







glutInit( &argc, argv);


glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize( 600, 600);
glutCreateWindow(Cargar Modelos .OBJ);
init();
glutDisplayFunc(dibujar);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
glutReshapeFunc(cambiarTamano);
glutMainLoop();
141

Captulo 6 - Aspectos avanzados de OpenGL


glFlush();

return 0;
}
Al ejecutarse se mostrara la siguiente imagen

Figura. Resultado de la ejecucin

142

Captulo 6 - Aspectos avanzados de OpenGL

Referencias
Sanchez, A. (abril de 2009). Scribd. Recuperado el 18 de Noviembre de 2011, de
Lista de Visualizacion.
Hearn, D., & Baker, M. (2006). Grficos por Computadora con OpenGL. Madrid:
Pearson Prentice Hall.
Ortega, A. L. (s.f.). Introduccin a OpenGL (II). Recuperado el 19 de Noviembre de
2011, de http://www.alobbs.com/revistas/opengl2
Kilgard, M. (23 de Febrero de 1996). The OpenGL Utility ToolKit . Recuperado el
21 de Noviembre de 2011, de The OpenGL Utility ToolKit: http://www.opengl.org/
resources/libraries/glut/spec3/node63.html
Dave Shreiner, T. K. (Julio 2009). OpenGL Programming Guide (Seventh Edition
ed.). Pearson Education, Inc. .
Gonzlez, D. E. Computacin Grfica: Manejo de Grficos con OpenGL. Panam,
Panam.
Microsoft. (9 de Julio de 2011). MSDN. Recuperado el 24 de Noviembre de
2011, de Microsoft Developer Network: http://msdn.microsoft.com/en-us/library/
dd374211(v=VS.85).aspx
The Kanetrixs GC. (5 de Octubre de 2009). Recuperado el 28 de Noviembre de
2011, de Grficos por Computador y otras cosas: http://kanetrixgc.wordpress.
com/2009/05/10/modelosobj/#comments

Taller N 11
Copie el Siguiente cdigo
#include < glut.h >
GLfloat angle = 0.0;
GLfloat density = 0.3;
GLfloat fogColor [ 4 ] = { 0.5, 0.5, 0.5, 1.0 } ;
void cube ( void ) {
glRotatef ( angle, 1.0, 0.0, 0.0 ) ;
glRotatef ( angle, 0.0, 1.0, 0.0 ) ;
glRotatef ( angle, 0.0, 0.0, 1.0 ) ;
glColor3f ( 0.4, 1.0, 0.0 ) ;
glutSolidCube ( 2.5 ) ;
}
143

Captulo 6 - Aspectos avanzados de OpenGL

void init ( void ) {


glEnable ( GL_DEPTH_TEST ) ;
glEnable ( GL_FOG ) ;
glFogi ( GL_FOG_MODE, GL_EXP ) ;
glFogfv ( GL_FOG_COLOR, fogColor ) ;
glFogf ( GL_FOG_DENSITY, density ) ;
glHint ( GL_FOG_HINT, GL_NICEST ) ; }
void display ( void ) {
glClearColor ( 1.0,1.0,1.0,1.0 ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
glLoadIdentity ( ) ;
gluLookAt ( 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ) ;
cube ( ) ;
glutSwapBuffers ( ) ;
angle += 0.1 ;
}
void reshape ( int w, int h ) {
glViewport ( 0, 0, ( GLsizei ) w, ( GLsizei ) h ) ;
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ;
gluPerspective ( 60, ( GLfloat ) w / ( GLfloat ) h, 1.0, 100.0 ) ;
glMatrixMode ( GL_MODELVIEW ) ;
}
int main ( int argc, char * * argv ) {
glutInit ( & argc, argv ) ;
glutInitDisplayMode ( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH ) ;
glutInitWindowSize ( 500, 500 ) ;
glutInitWindowPosition ( 100, 100 ) ;
glutCreateWindow ( Pruebas con Niebla ) ;
init ( ) ;
glutDisplayFunc ( display ) ;
glutIdleFunc ( display ) ;
glutReshapeFunc ( reshape ) ;
glutMainLoop ( ) ;
return 0;
}
Indicaciones

Cambie el valor de la variable density en un rango de valores de


0.1 a 0.9

Anote sus observaciones


144

Captulo 6 - Aspectos avanzados de OpenGL

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

2.Restablesca el valor de density a 0.3, en la lnea glFogi ( GL_


FOG_MODE, GL_EXP2 ) ;, cambie el parmetro GL_EXP2 por: GL_LINEAR y por GL_EXP.

Anote sus observaciones


_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

Resultado de ejecucin
145

Captulo 6 - Aspectos avanzados de OpenGL

Taller N 12
Utilizando el cdigo original del Taller N 11 realice los siguientes cambios:

En la funcion void init ( void ) agregue las lneas de cdigo:

glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
El resto de la funcin permanece igual.

En la funcin void cube ( void ) agregue las lneas de cdigo:

glColor3f(1,0,0);
glutSolidTeapot(1);

Ejecute el programa y anote sus observaciones, el resultado de la


ejecucin se muestra en la imagen.

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

Cambie el argumento de la funcin glCullFace() por el valor GL_


FRONT, ejecute y anote los resultados:

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

Cambie el argumento de la funcin glFrontFace() por el valor


GL_CCW y el argumento de la funcin glCullFace() por GL_FRONT,
ejecute y anote sus resultados:

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

146

Captulo 6 - Aspectos avanzados de OpenGL

Resultado de la Ejecucin
Ejercicio N 7
1.

Que accion se ejecuta el siguiente fragmento de cdigo: glBegin(GL_


QUAD_STRIP);

_________________________________________________________________
2.

3.

Mencione la accin que realizan las siguientes funciones:

glCullFace:__ _ _ _ _ _ ________________________________

glFrontFace:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Describa la accion de la funcin glutIdleFunc():

_________________________________________________________________
_________________________________________________________________
147

Captulo 6 - Aspectos avanzados de OpenGL

_________________________________________________________________
4.

Funciones que se usan para crear una lista de visualizacin:

_________________________________________________________________
_________________________________________________________________
5.

Al manejar varias listas de visualizacin, Que funciones se requiere


utilizar?

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
6.

Mencione la funcin que se utiliza para proyectar el rea de dibujo y


muestre su prototipo.

_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

148

<7>

C a p t u l o

OpenGL con otros Lenguajes


OBJETIVOS:

Conocer las acciones para desarrollar


aplicaciones
con
OpenGL
en
otros lenguajes de
Programacin.

Mostrar los conceptos bsicos para


programar OpenGL
con C#.

Presentar OpenTK.

Ejemplificar los conceptos de GLControl y GameWindow.

Conocer los requerimientos para utilizar OpenGL con


Java en NetBeans.

Mostrar los procedimientos para el uso


de JOGL.

Desarrollar una aplicacin bsica con


Java y OpenGL.

DESCRIPCIN:

En este capitulo se muestra como desarrollar aplicaciones con OpenGL en


lenguajes diferentes a C++. Se muestra
una descripcin de OpenTK, la cual se
trabajara con el Lenguaje C# en Visual
Stuido 2010. De igual manera se plantea
el uso JOGL para ejecutar OpenGL con
Java desde NetBeans .

149

Captulo 7 - OpenGL con otros Lenguajes

7.

OpenGL con otros Lenguajes

7.1

Implementacin con C#

Para la implementacin de OpenGL con C# en Visual Studio 2010 es necesaria


la instalacin OpenTK la cual se descarga de manera gratuita de su pagina http://
www.opentk.com/.
7.1.1 OpenTK
OpenTK es un proyecto libre que permite el uso de las APIs de OpenGL, OpenGL
ES, OpenCL y OpenAL. Este toolkit inici como una seccin experimental de Tao
Framework en el ao 2006. Su propsito original era proveer un contenedor (wrapper) para Tao.OpenGL, pero su enfoque fue creciendo rpidamente.

Algunas de las caractersticas de OpenTK son:

Escrita en C# y usable por F#, Boo, VB.Net, C++/CLI.

Usable para aplicaciones stand-alone o integradas con Windows.


Forms.

Binarios portables en .Net y Mono sin recompilacin.

Soporte para Windows, Linux, Mac OSX, y iPhone (en progreso).

decuada para juegos, aplicaciones de visualizacin cientfica y


A
todos los tipos de software que requieran grficos avanzados.

iblioteca matemtica (Math) integrada con soporte de vectores,


B
matrices, planos, quaternions, etc.

7.1.2 Comenzar un nuevo proyecto


Con OpenTK es posible utilizar dos tipos de ventana de visualizacin, las cuales
poseen caractersticas diferentes, hablamos de GLControl y del GameWindows,
por lo cual al iniciar un nuevo proyecto es necesario decidir que ventana utilizaremos. En qu casos usar el GL Control en vez del Game Windows de OpenTK?
Lo primero que debemos determinar al momento de desarrollar una aplicacin
grfica usando el componente GLControl de OpenTK es: Realmente necesita
la complejidad que proporciona Windows.Forms + GLControl en vez de usar el
GameWindow?. A continuacin algunos casos en los que agregar esa complejidad
son inevitables:

e desea desarrollar una interfaz de usuario enriquecida en donS


de se pueda hacer uso de controles de Windows.Forms (botones,
paneles, etiquetas, menes, cajas de texto, etc.), por ejemplo: editores de niveles, visualizadores o modeladores de geometra pudieran entrar en esta categora.

e desea embeber el despliegue de OpenGL dentro de paneles o


S
controles de una aplicacin Windows.Forms.
150

Captulo 7 - OpenGL con otros Lenguajes

Se desea hacer drag-and-drop hacia el panel de despliegue, por


ejemplo, arrastrar un archivo .OFF a la aplicacin y que este se
visualice.

e desea hacer una aplicacin con varios viewports (ventanas de


S
despliegue) tipo 3DS Max Studio en donde se pueda visualizar un
elemento desde distintos puntos de vista.

7.1.3 Primera Aplicacin con OpenTK


Para realizar nuestra primera aplicacin el paquete OpenTK debe estar instalado(ver
7.1 ).
Nuestra aplicacin usara el GameWindows de OpenTK, como primer paso crearemos un nuevo proyecto de Windows Forms como se muestra en la Figura 1., asignamos el nombre y ubicacin del proyecto.

Figura 1. Creacin de un Nuevo Proyecto


En este caso no ser necesario el Windows form que se crea por defecto por lo cual
puede ser eliminado. Al igual que el cdigo que hace referencia a este en el main
del programa.
Luego es necesario la inclusin de las referencias a OpenTK para lo cual seleccionamos en el men Proyecto la opcin de Agregar Referencia. Como se muestra
en la Figura 2

151

Captulo 7 - OpenGL con otros Lenguajes

Figura 2. Agregar referencia



Seguido aparecer la ventana Agregar Referencia, donde seleccionamos las
pestaa .NET y seleccionamos las opciones : OpenTK.Compatibility, OpenTK y
OpenTK.GLControl. Como se muestra en la Figura 3.

Figura 3. Agregar Referencias


Luego se deben agregar las directivas requeridas
152

Captulo 7 - OpenGL con otros Lenguajes

using OpenTK;
using OpenTK.Graphics.OpenGL;
using System.Drawing;

La directiva using System.Drawing; permite utilizar la clase color, esta se
puede agregar de a misma manera que se agregaron las referencias a OpenTK.
Incluir la siguiente clase con sus mtodos
class MainWindow : OpenTK.GameWindow
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
GL.ClearColor(Color. WhiteSmoke);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.
DepthBufferBit);
GL.End();
SwapBuffers();
}
}

El mtodo protected override void OnLoad(EventArgs e) ser el mtodo
que sobreescribir el OnLoad de GameWindow, que se ejecutar al cargarse el control.
Aqu tan solo hemos hecho dos cosas, por un lado ejecutar OnLoad en la clase
base GameWindow y por otro designar el color WhiteSmoke como el color que mostrar la ventana por defecto.

El mtodo protected override void OnRenderFrame(FrameEventArgs e)es
donde se realiza el renderizado. Primero se hace un Clear que resetea los buffers
presentes, en este caso el de color y el de profundidad. Despus del clear vendran
las instrucciones de renderizado y despus el mtodo End para indicar que ya hemos terminado las llamadas OpenGL. Para terminar, llamamos a SwapBuffers que
lo que hace es intercambiar el buffer trasero por el frontal.

Para que el programa de se ejecute es necesario modificar el Program.cs,
donde ya eliminamos todo el cdigo de dentro del Main y incluiremos el siguiente:
MainWindow doMain = new MainWindow();
doMain.Run();
153

Captulo 7 - OpenGL con otros Lenguajes


Al ejecutar aparecer una ventana con el color de fondo seleccionado.
Ahora podemos incluir en la funcin OnRenderFrame(FrameEventArgs e) el siguiente cdigo entre GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);y SwapBuffers();
GL.Begin(BeginMode.Triangles );
GL.Color3(Color.Red);
GL.Vertex3(0.0f, 0.2f, 0.0f);
GL.Color3(Color.Yellow);
GL.Vertex3(-0.2f, -0.2f, 0.0f);
GL.Color3(Color.Green);
GL.Vertex3(0.2f, -0.2f, 0.0f);
GL.Color3(Color.Gold);
GL.Vertex3(0.1f, 0.2f, -0.1f);
GL.Color3(Color.Magenta);
GL.Vertex3(-0.1f, -0.2f, 0.1f);
GL.Color3(Color.Lime);
GL.Vertex3(0.3f, -0.2f, 0.1f);
GL.End();
GL.Enable(EnableCap.DepthTest);
El resultado se muestra en la Figura 4.

Figura 4. Resultado de la Ejecucin


154

Captulo 7 - OpenGL con otros Lenguajes

Ejemplo
Para este ejemplo seguiremos los mismos pasos de la creacin de un nuevo
proyecto. Se deben agregar las siguientes directivas:
using
using
using
using

OpenTK;
OpenTK.Graphics;
OpenTK.Graphics.OpenGL;
OpenTK.Input;

El cdigo de la clase que se creara es el siguiente.


class Game : GameWindow
{
private float mAngulo = 0.0f;
private int mNumeroDePuntos = 10;
private float mA = 3.0f;
private float mOffsetAngulo = 0.0f;
private float mVelocidadAngular = 0.00001f ;
private float mVelocidadOffet = 0.0001f;
public Game()
: base(600, 600, GraphicsMode.Default, OpenTK Prueba)
{
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// GL.ClearColor(1.0f, 1.0f, 1.0f, 0.0f); // asignacin de color mediante nmeros
GL.ClearColor(Color4.White);
GL.LineWidth(3.0f);
Keyboard.KeyDown += new EventHandler<Keybo
ardKeyEventArgs>(Keyboard_KeyDown);
}
void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e)
{
if (Keyboard[Key.Escape])
{
Exit();
} else if (Keyboard[Key.A])
{
this.mNumeroDePuntos++;
}
155

Captulo 7 - OpenGL con otros Lenguajes

else if (Keyboard[Key.Z])
{
if (this.mNumeroDePuntos > 1)
{
this.mNumeroDePuntos--;
}
}
else if (Keyboard[Key.S])
{
this.mA += 0.5f;
}
else if (Keyboard[Key.X])
{
this.mA -= 0.5f;
}
else if (Keyboard[Key.D])
{
mVelocidadOffet += 0.0001f;
}
else if (Keyboard[Key.C])
{
mVelocidadOffet -= 0.0001f;
}
else if (Keyboard[Key.F])
{
mVelocidadAngular += 0.000001f;
}
else if (Keyboard[Key.V])
{
mVelocidadAngular -= 0.000001f;
}

protected override void OnResize(EventArgs e)


{
base.OnResize(e);
GL.MatrixMode( MatrixMode.Projection );
GL.LoadIdentity();
GL.Ortho( 0 , this.Width , 0 , this.Height, -1 , 1 );
GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
}
156

Captulo 7 - OpenGL con otros Lenguajes

protected override void OnUpdateFrame(FrameEventArgs e)


{
base.OnUpdateFrame(e);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.Begin(BeginMode.LineStrip);
float angulo = this.mAngulo;
float step = (float)(2.0 * Math.PI / this.mNumeroDePuntos);
int radio = 290;
while (angulo < this.mAngulo + 2.0 * Math.PI)
{
float r = (float)Math.Sin(this.mA * angulo + this.mOffsetAngulo) * radio;

int x = 300 + (int)(r * Math.Cos(angulo));


int y = 300 + (int)(r * Math.Sin(angulo));
float R = (float)Math.Abs(Math.Cos(angulo));
float B = (float)Math.Abs(Math.Sin(angulo));
float G = (float)Math.Abs(Math.Sin(angulo + Math.PI / 3.0));
GL.Color3(R, G, B);
GL.Vertex2(x, y);
angulo += step;
}
GL.End();
SwapBuffers();
this.mAngulo += this.mVelocidadAngular;
this.mOffsetAngulo += this.mVelocidadOffet;
}

En Program.cs se modificara el mtodo main con el siguiente cdigo:


using (Game game = new Game())
{
game.Run( 30.0 );
}
Este programa permite la interaccin con el usuario a travs de los siguientes controles:
A, Z : agregar, quitar lnea
157

Captulo 7 - OpenGL con otros Lenguajes

S, X : cambiar el valor del Angulo


D, C : velocidad de desplazamiento
F, V : velocidad angular
Esc

: salir

Figura 5. Resultado de la ejecucin


7.1.4 Windows Form y GLControl
El siguiente ejemplo presenta la utilizacin del GLControl, para este ejemplo se
debe crear un nuevo proyecto de Windows Forms, agregar las referencias, pero no
se debe eliminar el Form1 que Visual Studio crea por defecto.
En el Form1 se deben agregar las siguientes directivas:
using System;
158

Captulo 7 - OpenGL con otros Lenguajes

using
using
using
using

System.Drawing;
System.Windows.Forms;
OpenTK.Graphics;
OpenTK.Graphics.OpenGL;


El siguiente paso es agregar el componente GLControl a nuestro Cuadro
de Herramientas para poder arrastrarlo a nuestro formulario como cualquier otro
componente de Windows.Forms y poder utilizarlo. Para ello hagamos clic derecho
sobre un rea vaca del Cuadro de Herramientas luego selecciona la opcin Elegir
Elementos. Nos aparecer el cuadro Elegir elementos del cuadro de herramientas
(Figura 6), en la pestaa Componentes de .NET Framework seleccionamos Examinar, buscamos el directorio de instalacin de OpenTK y el directorio Binaries/
OpenTK/Release se encuentra un DLL llamado OpenTK.GLControl.dll se debe
seleccionar y pulsa el boton abrir.

Figura 6 Elegir Elementos

159

Captulo 7 - OpenGL con otros Lenguajes

Figura 7. Directorio de Instalacin de OpenTK



Por ltimo se verifica que el control est seleccionado y pulsa el botn
Aceptar. Ya se ha agregado el Control a nuestro Cuadro de Herramientas. Hecho
esto arrastremos el GLControl al form.

Cuando se ha aadi el GLControl de debe programar el evento Paint, el
cual se encuentra en la lista de los eventos del objeto en el panel de propiedades,
desde la vista de diseo.
Dentro del evento Paint agregamos el siguiente cdigo
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Begin(BeginMode.Quads);
{
GL.Color3(Color.Orange);
GL.Vertex2(-0.5f, 0.5f);
GL.Color3(Color.Lime);
GL.Vertex2(-0.5f, -0.5f);
GL.Color3(Color.Magenta);
GL.Vertex2(0.5f, -0.5f);
GL.Color3(Color.Cyan);
GL.Vertex2(0.5f, 0.5f);
}
GL.End();
160

Captulo 7 - OpenGL con otros Lenguajes

glControl1.SwapBuffers();

Las lneas GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); y glControl1.SwapBuffers();que acabamos de agregar


se encargarn de limpiar los buffers de salida para poder desplegar lo que deseamos en pantalla. El resto del cdigo dibuja un cuadrado en la pantalla.

Procedamos a agregar el evento Load para el glControl (igual a agregar el
evento Paint o simplemente hacer doble clic sobre el glControl en la vista de diseo). Incluimos dentro el siguiente cdigo:

GL.ClearColor(Color.Black);
SetupViewport();

Hasta ahora el mtodo SetupViewport(); no ha sido creado para crearlo
copiamos el siguiente fragmento:
private void SetupViewport()
{
int w = glControl1.Width;
int h = glControl1.Height;
float aspectRatio = (float)w / (float)h;
GL.Viewport(0, 0, w, h);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Ortho(-aspectRatio, aspectRatio, -1, 1, -1, 1);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
}
Esto nos permite configurar el Viewport de manera adecuada.

Las lneas float aspectRatio = (float)w / (float)h; y GL.Ortho(-aspectRatio, aspectRatio, -1, 1, -1, 1); nos permiten calcular la proporcin entre
ancho y alto a lo que se le llama aspect ratio, de esta manera podremos mantener
la proporcin de lo que dibujemos sin importar el tamao de la ventana.

En la vista de diseo, seleccionamos el glControl y cambiamos la propiedad


Dock a Fill, lo cual permite que el glControl se adapte al tamao de la ventana
de forma automtica.


Al ejecutar nuestra aplicacin y cambiar el tamao de nuestra ventana. El
cuadrado se mueve por toda la ventana. Para solucionar este problema se hace lo
siguiente. Creamos el evento Resize del GLControl (como paint y load) y copiamos lo siguiente
161

Captulo 7 - OpenGL con otros Lenguajes

SetupViewport();
glControl1.Invalidate();

Lo que estamos haciendo es actualizar de nuevo nuestro viewport con el
tamao actual del controlador y posteriormente estamos repintando nuestro cuadrado llamando al mtodo Invalidate del glControl.
Lo siguiente ser crear dos botones:

Un botn con la propiedad .text = Rojo, y el evento click con el


siguiente cdigo

GL.ClearColor(Color.Red);
glControl1.Invalidate();

U
n botn con la propiedad .text = Beige y el evento click con el
siguiente cdigo
GL.ClearColor(Color.Beige);
glControl1.Invalidate();

Estos botones cambiaran el color de nuestro glControl.


Al ejecutar el programa se genera la siguiente salida.

Figura 8. Resultado de Ejecucin


162

Captulo 7 - OpenGL con otros Lenguajes

Se presenta tambin el estado final de la clase form1.cs


using System;
using System.Drawing;
using System.Windows.Forms;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
namespace HelloOpenTK
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void glControl1_Load(object sender, EventArgs e)
{
GL.ClearColor(Color.Beige);
SetupViewport();
}
private void glControl1_Paint(object sender, PaintEven-

tArgs e)

GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Begin(BeginMode.Quads);
{
GL.Color3(Color.Orange);
GL.Vertex2(-0.5f, 0.5f);
GL.Color3(Color.Lime);
GL.Vertex2(-0.5f, -0.5f);
GL.Color3(Color.Magenta);
GL.Vertex2(0.5f, -0.5f);
GL.Color3(Color.Cyan);
GL.Vertex2(0.5f, 0.5f);
}
GL.End();
163

Captulo 7 - OpenGL con otros Lenguajes

7.2

glControl1.SwapBuffers();

private void SetupViewport()


{
int w = glControl1.Width;
int h = glControl1.Height;
float aspectRatio = (float)w / (float)h;
GL.Viewport(0, 0, w, h);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Ortho(-aspectRatio, aspectRatio, -1, 1, -1, 1);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
}
private void glControl1_Resize(object sender, EventArgs e)
{
SetupViewport();
glControl1.Invalidate();
}
private void button1_Click(object sender, EventArgs e)
{
GL.ClearColor(Color.Red);
glControl1.Invalidate();
}
private void button2_Click(object sender, EventArgs e)
{
GL.ClearColor(Color.Beige);
glControl1.Invalidate();
}

Implementacin con Java

Para trabajar con OpenGL en Java utilizando NetBeans, se requiere instalar un


complemento, The NetBeans OpenGL Pack, que se descarga de la direccin:
http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=3260.

El archivo descargado esta comprimido y contiene un conjunto de archivos
con extensin .nmb.

La ltima actualizacin de este paquete fue para NetBeans 6.7, pero puede
ser ejecutado en NetBeans 7.01 y en cualquier plataforma.
164

Captulo 7 - OpenGL con otros Lenguajes

7.2.1 Instalacin de los complementos


Para la instalacin del paquete debemos, una vez abierto el NetBeans, seleccionar
la opcin Complementos que est disponible en el men Herramientas como se
muestra en la Figura 9.

Figura 9. Instalar Complementos


Se mostrara la ventana Complementos (Figura 10) en la cual seleccionamos la pestaa Descargado, y el botn Agregar Plugins. Luego buscamos la ubicacin donde
descomprimimos el paquete de OpenGL y seleccionamos todo su contenido, como
se muestra en la Figura 11.

Figura 10. Ventana de Complementos

165

Captulo 7 - OpenGL con otros Lenguajes

Figura 11. Seleccin de elementos


Luego en la ventana de Complementos debemos deseleccionar el complemento
GSL editor, el cual no es compatible con la ltima versin del entorno que se est
utilizando(Figura 12). Una vez terminada la instalacin el ide se reiniciara y al iniciar
nuevamente podremos utilizar el paquete que se instalo.

Figura 12. Complementos que se instalaran


166

Captulo 7 - OpenGL con otros Lenguajes

7.2.2 Una aplicacin JOGL


JOGL es el nombre de la librera que se utiliza para acceder a OpenGL, la cual se
instalo en el procedimiento anterior.

Para este ejemplo crearemos un nuevo proyecto y seleccionaremos la opcin
JOGL Application (Form Designes, GLJPanel) como se muestra en la Figura 13, al
cual le asignamos un nombre y una ubicacin.

Figura 13 Nuevo Proyecto en NetBeans


Este proyecto se puede ejecutar y desplegara un triangulo con un cuadrado como
se muestra en la Figura 14. Para este ejemplo se cambiara el cuadrado por la
tetera. Para realizar esto debemos abrir en el rbol de proyecto la clase GLRenderer como se muestra en la Figura 15, la cual es la encargada de realizar el dibujo.

167

Captulo 7 - OpenGL con otros Lenguajes

Figura 14. Ejecucin del Proyecto Original

Figura 15. rbol de Proyecto


En el mtodo display de esta clase eliminaremos el cdigo que se encarga del
dibujo del cuadrado, cual est se ubica entre
gl.glBegin(GL.GL_QUADS);

gl.glEnd();

168

Captulo 7 - OpenGL con otros Lenguajes

Despus escribiremos el siguiente cdigo:


GLUT tetera = new GLUT();
tetera.glutWireTeapot(1);
para una correcta ejecucin debemos agregar tambin
import com.sun.opengl.util.GLUT;
y al ejecutar mostrara el siguiente resultado(Figura 16).

Figura 16. Resultado de la Ejecucin


Referencias
Mena, C. (22 de Septiembre de 2011). Widget-Pc. Recuperado el 20 de Noviembre
de 2011, de http://widget-pc.com/primera-aplicacion-grafica-en-opentk-glcontrolwindows-forms/
OpenTK. (s.f.). OpenTK. Recuperado el 19 de Noviembre de 2011, de Home of the
Open Toolkit library: http://www.opentk.com/
Loaiza, C. A. (29 de Junio de 2009). Aprendiendo JOGL. Recuperado el 2 de Septiembre de 2011, de OpenGL Mediante Programacin en Java: http://aprendiendojogl.blogspot.com/2009/07/instalar-jogl-con-netbeans.html

169

S-ar putea să vă placă și