Documente Academic
Documente Profesional
Documente Cultură
OpenGL
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.
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
Contenido
Prefacio
xii
1.1 Qu es OpenGL?
1.9.2 Pasos para iniciar un proyecto con Visual C++ y libreras de OpenGL
10
11
12
14
OpenGL
14
15
15
15
16
vii
16
16
16
17
17
1.11.10
18
Referencias
18
Taller N 1
18
Taller N 2
19
Taller N 3
20
Ejercicio N 1
21
23
24
2.
24
26
2.2.1 Puntos
26
2.2.2 Lneas
26
2.2.3 Polgonos
27
2.2.4 Rectngulos
28
28
29
30
31
32
34
35
35
35
37
Referencias
40
viii
Taller N 4
41
Taller N 5
44
Ejercicio N 2
47
Ejercicio N 3
47
48
49
49
50
52
54
57
58
Referencias
61
Taller N 6
61
Taller N 7
65
Ejercicio N 4
66
68
69
69
70
72
74
74
76
77
79
80
Referencias
81
Taller N 8
81
Ejercicio N 5
84
86
ix
5.
87
87
93
95
Referencias
105
Taller N 9
106
Taller N 10
108
Ejercicio N 6
111
112
113
113
114
121
122
124
124
125
125
126
131
6.9 Niebla
135
140
142
Referencias
143
Taller N 11
143
Taller N 12
146
Ejercicio N 7
147
149
150
150
7.1.1 OpenTK
150
150
151
158
164
165
167
Referencias
169
xi
Prefacio
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
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.
1.
1.1
Qu es OpenGL?
1.2
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
Color actual.
Punto de vista.
Transformaciones de proyeccin.
1.3
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.
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
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
1.6
glColor3f ()
1.7
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
una tecla.
glutldleFunc(void( *func(void));
glutWireCone(base,
glutWireCube(size), glutSolidCube(size)
glutWireDodecahedron(void), glutSolidDodecahedron(void)
heigth,
height, slices, stacks)
stacks),
glutSolidCone(base,
glutWirecosahedron(void), glutSolidcosahedron(void)
glutWireOctahedron(void), glutSolidOctahedron(void)
glutWireTeapot(void), glutSolidTeapot(void)
glutWireTetrahedron(void), glutSolidTetrahedron(void)
Cono
Cubo
Dodecaedro
Octaedro
Icosaedro
Esfera
Tetraedro
Torus
Tetera
1.9
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
Aplicacin de consola
1.9.2.3
11
12
13
Ctrl + F7
F7
Ctrl + F5
F5
15
Parmetros: Mode: indica una marcara o combinacin de mascaras de bits que describen las caractersticas de la ventana.
Sintaxis: void
Parmetros:
glClearColor(GLclampf
Glclampf blue, GLclampf alpha)
red,
GLclampf
green,
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
Nombre
GL_COLOR_BUFFER_BIT
GL_DEPTH_BUFFER_BIT
GL_ACCUM_BUFFER_BIT
GL_STENCIL_BUFFER_BIT
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.
20
Mi primera Ventana; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Programa Prueba 1; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
(800, 800); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
(400, 800); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
(400, 100); _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Ejercicio N 1
Comandos bsicos para escribir un programa con OpenGL.
1.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
2.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
3.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
4.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
21
5.
Cules son los pasos para iniciar un proyecto con Visual C++ y las
libreras OpenGL?
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
6.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
________________________________________________________________
7.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
______________________________________________________________
8.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_______________________________________________________________
22
<2>
C a p t u l o
Conceptos Fundamentales de
OpenGL
OBJETIVOS:
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
2.
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);
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()
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.
2.2
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
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.
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
28
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);
[v]: matriz de valores que contienen los dos, tres o cuatros valores
necesarios para especificar el vrtice.
29
2.4
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
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);
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
0.0);
0.0);
0.0);
1.0);
32
Dibujando un cuadriltero
glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(4, 0);
glVertex2i(0, 4);
glVertex2i(4, 4);
glEnd();
2.5
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
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.
2.6
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)
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.
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().
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)
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
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,
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};
39
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
1.
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
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.
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);
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
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.
Factor = 4
Factor = 6
Factor = 8
Factor = 10
45
Pattern = 0x0001
Pattern = 0x0101
Pattern = 0x1010
Pattern = 0xAAAA
Pattern = 0xFFFF
Width = 3
Width = 4
Width = 5
Width = 8
46
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
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.
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
3.
OpenGL Bsico en 3D
3.1
Mens desplegables
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:
glutCreateMenu
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
botn medio
Tenga en cuenta que se asocia el men del botn de identificacin, no por de referencia.
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
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.
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
3.3
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
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);
53
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
top, GLdouble near, GLdouble far) dnde los parmetros left, right, bottom, top,
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
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
3.5
Los pasos a seguir para utilizar el Z-buffer en OpenGL son los siguientes:
3.6
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
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);
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
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:
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
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.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
2.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
3.
Cules son los parmetros para especificar las caras del polgono?
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
4.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
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
1.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
2.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
3.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
__________________________________________________________________
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
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
Mostrar el uso de
los comandos en
OpenGL para la defincin de las propiedades de material de
un objeto.
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
4.
4.1
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
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
chos polgonos planos pequeos, cada uno teniendo un vector normal bien definido.
Se considerarn tres maneras de sombrear polgonos:
Sombreado Phong
Los tres vectores, l, n y v, (figura 2), pueden variar segn los puntos sobre una superficie, donde:
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
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
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.
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
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
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
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)
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
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
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.
4.5
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 impropia: que emite sus rayos de luz desde una ubicacin
muy distante, de forma que podemos considerar sus rayos como
paralelos entre s.
GL_POSITION,LightPos);
79
[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.
4.6
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
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
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
82
Resultado de la ejecucin
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
2.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
3.
color_difuso_y_ambiente ) Qu observa?
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
Ejercicio N 5
1.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
2.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
3.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
______________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
4.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
84
_________________________________________________________________
_________________________________________________________________
5.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
6.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
85
<5>
C a p t u l o
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
5.
5.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.
3.
4.
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);
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.
o GL_PROXY_TEXTURE_2D.
87
type: Tipo de representados, indica el tamao de cada componente de color, transparencia y/o luminancia.
GL_TEXTURE_2D
GL_TEXTURE_PROXY_2D
GL_TEXTURE_PROXY_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
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
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
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
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
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_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:
92
5.2
93
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
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
94
GL_NEAREST
GL_LINEAR
Para asignar un color a (por ejemplo) el pixel blanco de la figura, se pueden considerar dos estrategias:
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
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
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
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,
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
glutPostRedisplay();
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
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
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
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
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
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
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
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.
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
{
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
{
}
glBegin (GL_LINES) ;
glTexCoord1f (0.0);
glVertex3f (10,10,0) ;
glTexCoord1f (1.0) ;
glVertex3f (100,100,0) ;
glEnd ( ) ;
110
Ejercicio N 6
1.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
2.
Nombre de la funcin que permite se ajusten los parmetros que modifican y son utilizados en una textura:
_________________________________________________________________
3.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
4.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
5.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
111
<6>
C a p t u l o
Proporcionar
las
rdenes de OpenGL
para evitar el efecto
escalera o aliasing.
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
6.
6.1
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:
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
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:
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
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
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
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
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
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:
119
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_
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
{
...
GLuint fuente;
fuente = CrearFuente ();
EscribirCadena (fuente, OPENGL);
...
6.3
(GL_CULL_FACE);
(vertexOrder);
121
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
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
glEnable(GL_BLEND)
glBlendFunc(GLenun sfactor, GLenun dfactor);
Las
configuraciones
predeterminadas
glBlendFunc(GL_ONE, GL_ZERO).
para
la
fusin
son
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
GL_POINT_SMOOTH,
GL_LINE_SMOOTH,
GL_POLYGON_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
6.5
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
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
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
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.
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:
Especifica la proyeccin.
Dibuja la escena.
Especifica la proyeccin.
Dibuja la escena.
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,
126
GLvoid*pixeles);
Con esta orden podemos definir el rea rectangular de nuestra ventana grfica que deseamos transferir a la memoria principal.
Parmetros
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.
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
GL_RED,
GL_GREEN,
GL_BLUE, GL_ALPHA,
GL_RGB,
GL_RGBA,
GL_BGR_EXT,
GL_
BGRA_EXT,
GL_LUMINANCE,
GL_LUMINANCE_ALPHA
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
Funcin glDrawPixels
Es la funcin que escribe en un bloque de pxeles para el framebuffer.
Para utilizarla es con la orden void glDrawPixels (
128
GLsizei ancho,
GLsizei alto,
GLenum formato,
GLenum tipo,
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.
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
GL_GREEN
GL_BLUE
GL_ALPHA
GL_RGB
GL_LUMINANCE
GL_LUMINANCE_ALPHA
GL_BGR_EXT
GL_BGRA_EXT
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
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
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.
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);
Donde:
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 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
glArrayElement(2);
glArrayElement(3);
glArrayElement(5);
glEnd();
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
134
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.
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
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
GL_FOG_MODE
GL_FOG_START
GL_FOG_COORD_SRC
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>
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
glutInitWindowSize(500, 500);
glutCreateWindow(argv[0]);
iniciar();
glutReshapeFunc(reshape);
glutKeyboardFunc(teclado);
glutDisplayFunc(desplegar);
glutMainLoop();
return 0;
}
139
glFlush();
return 0;
}
Al ejecutarse se mostrara la siguiente imagen
142
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
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
Resultado de ejecucin
145
Taller N 12
Utilizando el cdigo original del Taller N 11 realice los siguientes cambios:
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
El resto de la funcin permanece igual.
glColor3f(1,0,0);
glutSolidTeapot(1);
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
146
Resultado de la Ejecucin
Ejercicio N 7
1.
_________________________________________________________________
2.
3.
glCullFace:__ _ _ _ _ _ ________________________________
glFrontFace:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_________________________________________________________________
_________________________________________________________________
147
_________________________________________________________________
4.
_________________________________________________________________
_________________________________________________________________
5.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
6.
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________
148
<7>
C a p t u l o
Presentar OpenTK.
DESCRIPCIN:
149
7.
7.1
Implementacin con C#
151
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
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.
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;
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;
}
: salir
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.
159
glControl1.SwapBuffers();
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.
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
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:
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();
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
7.2
glControl1.SwapBuffers();
165
167
gl.glEnd();
168
169