TextoAnimacion en OpenGL
TextoAnimacion en OpenGL
TextoAnimacion en OpenGL
TECNICAS AVANZADAS
DE ANIMACION 3D
OPENGL
Cochabamba Bolivia
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
1. Introducción............................................................................................................. 3
2. Puntos, líneas y polígonos (Primitivas OpenGL)...................................................... 3
Puntos......................................................................................................................... 4
Líneas ......................................................................................................................... 5
Polígonos.................................................................................................................... 6
3. Transformaciones en OpenGL................................................................................. 8
4. Iluminación y Color .................................................................................................. 8
Color ........................................................................................................................... 8
Iluminación.................................................................................................................. 9
Definición de los vectores normales............................................................................ 9
Creación de las fuentes de luz .................................................................................. 10
Propiedades del material........................................................................................... 13
Cambio de las propiedades del material ................................................................... 13
5. Conceptos de Control Avanzados ......................................................................... 15
Listas ........................................................................................................................ 15
Vistas ........................................................................................................................ 17
gluLookAt() ............................................................................................................... 17
glOrtho().................................................................................................................... 18
glFrustum() ............................................................................................................... 19
gluPerpespective() .................................................................................................... 19
Matrices .................................................................................................................... 20
Manipulación de la pila de matrices .......................................................................... 21
Blending.................................................................................................................... 22
Transparencias ......................................................................................................... 23
Antialiasing ............................................................................................................... 23
6. Texturas ................................................................................................................ 26
Texturas multiples ..................................................................................................... 28
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
1. Introducción
Aunque OpenGL está esta concebido para diseñar aplicaciones interactivas y facilita al
usuario herramientas como la selección sus capacidades resultan insuficientes para, entre
otras cosas, crear interfaces gráficas con un grado mayor de interactividad. Estas
limitaciones condujeron al desarrollo de las librerías AUX y GLUT. Las librerías AUX
presentan numerosas insuficiencias, y su aplicación se limita a programas de simple
enseñanza.
La librería GLUT en cambio, tiene mayor funcionalidad para la manipulación interactiva de
objetos 3D.
GLUT es una interfaz de programación con "C" ANSI y Fortran para escribir programas en
OpenGL que sean independientes del sistema operativo de ventanas. Las librerías GLUT
ofrecen, entre otras cosas, las siguientes prestaciones:
• Ventanas múltiples para render
• Procesamiento de eventos de entrada iniciados por el usuario (callbacks).
• Variados dispositivos de entrada.
• Menús desplegables.
• Rutinas para generar objetos estándares.
En OpenGL, las primitivas geométricas son usadas para realizar los dibujos que se
desean. Las primitivas son: puntos, líneas y polígonos. Estas primitivas se describen
básicamente a partir de sus vértices (coordenadas que definen al punto, los extremos de
los segmentos de línea y las esquinas de los polígonos).
En un sentido matemático, la definición de las primitivas mencionadas es relativamente
simple, y en OpenGL se trabaja en un contexto similar, siendo diferente en sólo lo relativo
a la implementación como tal.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Las diferencias incluyen la precisión de los valores y error de redondeo, factores que
influyen en las coordenadas en OpenGL, y las limitaciones del raster graphics display,
cuya unidad mínima (píxel) es mucho mayor del concepto de matemático de infinitamente
pequeño (para un punto) o infinitamente delgado (para una línea).
OpenGL se refiere a los puntos como un vector, manejado como un número de punto
flotante, pero ello no implica que la precisión sea de un 100% en el momento de dibujar.
Puntos
Un punto se define mediante la función glVertex, esta función especifica las coordenadas
del punto dentro de la ventana de visualización. Con esta función se pueden definir puntos
en dos y tres dimensiones, dependiendo del número de coordenadas que se detallan.
OpenGL trabaja normalmente en coordenadas homogéneas representadas por cuatro
componentes, (x, y, z, h), por lo tanto cuando se está definiendo puntos en dos
dimensiones el valor z coge el valor cero y h el valor 1, en tres dimensiones h coge el
valor 1.
glVertex{23}{sifd}[v](TYPE coords)
El tipo especificado de coordenadas viene determinado a partir de los sufijos que siguen a
la función glvertex. Los sufijos que pueden seguir a la función serán, d (double), indica
que las coordenadas deben especificarse en valores double, f (float), i (integer) y
finalmente s (short), por lo tanto las coordenadas deberán indicarse con valores que
correspondan al sufijo. Existe la posibilidad de definir un punto mediante un vector que
contenga las coordenadas utilizando el sufijo v lo que indica que es un vector de
coordenadas.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Para definir un punto o conjuntos de puntos se debe especificar las siguientes cláusulas
glBegin(GL_POINTS) y la cláusula glEnd(), detallando entre ambas las posiciones de
cada punto:
glBegin(GL_POINTS)
glVertex2f(50.4,34.6); //Punto 2D,en punto flotante
glVertex3i(10,20 34); //Punto 3D, en enteros
glEnd();
Líneas
De la misma forma que se definen puntos se puede definir líneas. Para definir una línea
se precisan dos puntos, estos dos puntos se definen con la función glVertex.
Existen diversas formas de definir líneas dependiendo del modo en que se describa en la
cláusula glBegin(modo), donde modo puede ser: deseamos.
Modo Descripción
Genera una serie de líneas que no se conectan entre sí. Las líneas se definen
GL_LINES mediante los pares de puntos sucesivos, por lo tanto el número de vértices debe
ser par, en el caso de que fuera impar se ignoraría
Genera una serie de líneas pero que se conectan entre sí, es decir el punto final
GL_LINE_STRIP de una línea es el punto inicial de la siguiente. Con este modo se pueden generar
figuras cerradas si el punto inicial coincide con el final.
Genera una serie de líneas conectadas entre sí, es parecido al modo anterior
GL_LINE_LOOP
pero este modo conecta automáticamente el punto inicial con el punto final.
glBegin (MODO);
glVertex2f(0.0, 0.0);
glVertex2f(1.0, 0.0);
glVertex2f(1.0, 1.0);
glVertex2f(0.0, 1.0);
glEnd;
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
El aspecto de las líneas también pueden modificarse, pudiendo crear líneas más gruesas
y con formato punteado, para ello se utilizará los comandos:
glEnable(GL_LINE_STIPPLE);
glLineStipple( factor, mascara);
glDisable(GL_LINE_STIPPLE);
Con estos comandos se puede conseguir líneas punteadas, la primera instrucción activa
el modo de línea punteada, mientras que el segundo define el estilo de la línea, donde
factor es un valor que esta comprendido entre 1 y 255, este valor define la separación
entre los trozos de la línea, mientras que máscara, es un valor de 16 bits que se describe
en hexadecimal, cada máscara define un formato de línea, los valores van comprendidos
entre 0x0000 hasta 0xAAAA.
Otra posibilidad que se tiene es modificar el grosor de la línea con la instrucción:
glLineWidth(tamaño);
Por defecto OpenGL define las líneas con tamaño 1.0, hay que tener en cuenta que una
vez activado el tamaño hay que volver a establecerlo si se desea líneas con el tamaño por
defecto.
Polígonos
OpenGL define los polígonos como secuencia de aristas, por lo tanto sigue con el mismo
formato especificado en los puntos anteriores.
Para generar polígonos se tienen los siguientes modos para la sentencia
glBegin(modo), estos son:
Modo Descripción
Genera un simple polígono relleno con los vértices especificados. Para
generar un polígono se deben garantizar tres cosas:
• Como mínimo se precisan 3 vértices.
GL_POLYGON
• Las líneas no deben cruzarse.
• Los vértices deben formar un polígono convexo, en caso
contrario OpenGL ignorará el vértice.
Genera una serie de triángulos rellenos que no se conectan entre sí. El
GL_TRIANGLES número de vértices debe ser múltiplo de 3, si el total de vértices es menor
de tres, OpenGL ignora los vértices que no forma un triángulo.
Genera una serie de triángulos rellenos conectados entre sí, es decir dos de
GL_TRIANGLE_STRIP
los vértices de un triángulo son los vértices del siguiente triángulo. Se tiene
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
que saber que con N vértices se pueden crear N-2 triángulos. De igual
forma el número de vértices debe ser múltiplo de tres, si no lo es se ignora
aquellos que sobran.
Genera un conjunto de triángulos rellenos conectados entre sí, con la
característica de que todos los triángulos tiene un vértice en común. El
GL_TRIANGLE_FAN primer triángulo define el vértice común a todos los triángulos. De igual
forma que los anteriores el número de vértices debe ser múltiplo de 3, si no
lo es se ignora aquellos vértices que sobran.
Genera un conjunto de cuadriláteros rellenos sin conectar entre ellos. El
número de vértices que se requiere es múltiplo de cuatro, si no se verifica
GL_QUADS
entonces OpenGL ignora los vértices que sobran. Cada cuatro vértices se
describe un cuadrilátero.
Genera un conjunto de cuadriláteros rellenos que se conectan entre sí, es
decir dos vértices de un cuadrado se utilizan para generar el siguiente
cuadrilátero. Hay que tener en cuenta que con un total de N vértices se
GL_QUAD_STRIP
obtiene un total de N/2-1 cuadrados. El número de vértices debe ser
múltiplo de cuatro, si no se verifica entonces los vértices que sobran son
ignorados.
v4 v3
v5 v2 v5 v0
vo
v3 v2
v4 GL_TRIANGLE_STRIP
GL_TRIANGLES
GL_POLYGON
v1
v1 v1
v0 v0
v2 v2 v2
v0 v3 v4 v3
v7
v3
v5
v4
v5
v6 GL_QUAD_STRIP
v4
GL_QUADS
GL_TRIANGLE_FAN
Como por lo general se trabaja con vértices en 3D, es necesario tener cuidado ya que
después de algunas operaciones, si algún vértice no está en el mismo plano, puede
llegarse a resultados inesperados. El usar triángulos garantiza que siempre se trabaja en
un mismo plano.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
3. Transformaciones en OpenGL
OpenGL soporta tres tipos de transformaciones:
• Traslación
• Rotación
• Escalamiento
Traslación
void glTranslate{fd}(TYPE x, TYPE y, TYPE z);
Multiplica la matriz actual por una matriz de traslación que mueve el objeto.
Rotación
void glRotate{fd}(TYPE angle,TYPE x, TYPE y, TYPE z);
Multiplica la matriz actual por una matriz de rotación que rota el objeto en la dirección de
las agujas del reloj sobre el radio de origen en el punto x,y,z.
Escalado
void glScale{fd}(TYPE x, TYPE y, TYPE z);
Multiplica la matriz actual por una matriz que cambia el tamaño del objeto a lo largo de los
ejes. Las coordenadas x, y, z de cada objeto se multiplican por los parámetros x, y, z.
4. Iluminación y Color
Hacer una escena lo mas real posible requiere no solo de mostrar la información en 3D
sino también se requiere de simular el color, así como los efectos de iluminación lo que
permitirá construir escenas mas elaboradas y por lo tanto que mas se asemejen a la
realidad.
Color
En una pantalla de computadora, el hardware causa que cada pixel en la pantalla emita
cantidades diferentes de luz roja, verde, y azul. Éstos se llaman los valores R, G y B. Ellos
se juntan (a veces con un cuarto valor, el llamado alfa A), y el valor condensado se llama
el RGB (o RGBA). La información colorida a cada pixel en modo de RGBA en que el R, G,
B, y posiblemente valores A se guardan para cada pixel, o en un índice de color o en un
solo número (llamó el índice colorimétrico). Cada índice colorimétrico indica una entrada
en una tabla que define un juego particular de R, G, y B.
Los valores R, G, y B pueden ir de 0.0 (ninguno) a 1.0 (intensidad llena) por ejemplo, R =
0.0, G = 0.0, y B = 1.0 representan el azul más luminoso posible. Si R, G, y B son todos
0.0, el pixel es negro; si todos son 1.0, el pixel es el más luminoso blanco que se pueda
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Los órdenes para especificar el color para un objeto (en este caso, un punto) puede ser
tan simple como:
Iluminación
Con OpenGL se pueden crear muchos efectos de luz. Se pueden crear luces puntuales,
direccionales y focos.
Una luz puntual es como una bombilla. La luz surge de un punto, y se dispersa en todas
direcciones. La intensidad de la luz en un punto del espacio depende de la distancia de
este punto al origen de la luz.
Una luz direccional es una luz parecida a la luz del sol. La luz se dirige en una posición, y
no parece que venga de un punto en concreto.
• Definir los vectores normales para cada vértice de todos los objetos
• Crear, seleccionar y colocar una o más fuentes de luz
• Crear y seleccionar el modelo de iluminación
• Definir las propiedades del material de todos los objetos de la escena
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
• glBegin (GL_POLYGON);
glNormal3fv(n0);
glVertex3fv(v0);
glNormal3fv(n1);
glVertex3fv(v1);
glNormal3fv(n2);
glVertex3fv(v2);
glNormal3fv(n3);
glVertex3fv(v3);
glEnd();
De esta forma se crea la fuente de luz que indica el parámetro light, el cual puede recibir
los valores GL: LIGHT0, GL_LIGHT1, ... , GL_LIGHT7 (8 fuentes de luz como máximo
en la definición estándar de la librería, la implementación específica puede permitir más).
Para especificar la iluminación de una escena hay que decidir como serán las luces, y
cuales serán los materiales de los objetos de las escenas. Por defecto la iluminación esta
deshabilitada. Lo primero que se debe hacer es habilitar el modelo de iluminación, con el
siguiente código:
glEnable(GL_LIGHTING);
Una vez habilitado el modelo de iluminación se debe decidir cuantas luces se van a
insertar en la escena. Cada implementación de OpenGL tiene un número máximo de
luces que se pueden manejar, en general se cuentan con 8 puntos de luz que se pueden
definir. Para habilitar cada una de las luces se ejecuta lo siguiente :
glEnable(GL_LIGHTi);
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
De esta forma se crea la fuente de luz que indica el parámetro light, el cual puede recibir
los valores GL: LIGHT0, GL_LIGHT1, ... , GL_LIGHT7 (8 fuentes de luz como máximo
en la definición estándar de la librería, la implementación específica puede permitir más).
Las características de la luz se especifican por pname utilizando las constantes que se
muestran en la tabla que sigue. Finalmente, el argumento param indica los valores de la
característica fijada en pname.
Para los valores por defecto de GL_DIFFUSE y GL_SPECULAR se aplican sólo a GL_LIGHT0.
Para otras fuentes de luz, los valores por defecto son (0.0, 0.0, 0.0, 0.1) para ambos
casos.
A continuación se verá algunos de los parámetros más importantes de las luces, y como
modificarlos:
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
• Color de la luz
Los colores de las luces en OpenGL tienen tres componentes :
• Ambiente
Esta componente afecta a todos los objetos, independientemente de la
posición u orientación de estos. Viene a emular la luz que en el mundo real
viene dada por la reflexión difusa en las paredes, la luz solar indirecta, etc.
• Difusa
Se puede pensar en ella como en el verdadero color de la luz. Su influencia
sobre una superficie de un objeto depende de su orientación y su distancia.
• Especular
Influye en el brillo que va a tener el objeto.
• Focos de luz
Las fuentes de luz posicionales en principio irradian luz en todas direcciones. Sin
embargo, estas luces pueden convertirse en focos o luces de teatro restringiendo la forma
de la luz emitida a un cono. Los spotlights requieren indicar la posición a la que apunta el
foco (GL_SPOT_DIRECTION), el ángulo sobre el eje del cono (GL_SPOT_CUTOFF) y el
grado de concentración de la luz (GL_SPOT_EXPONENT).
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
El primer argumento determina la cara del objeto donde se aplica el material, puede tomar
los valores GL_FRONT, GL_BACK, o GL_FRONT_AND_BACK.
El siguiente argumento indica la propiedad del material que va a fijarse (sus posibles
valores se muestran en la tabla). Finalmente, el argumento param permite asignar los
valores a la propiedad pname.
Nombre del parámetro Valor por defecto Significado
GL_AMBIENT (0.2, 0.2, 0.2, 1.0) Color ambiente del material
GL_DIFFUSE (0.8, 0.8, 0.8, 1.0) Color difuso del material
GL_AMBIENT_AND_DIFFUSE Color ambiente y Difuso
GL_SPECULAR (0.0, 0.0, 0.0, 1.0) Color Especular del material
GL_SHININESS 0.0 Exponente Especular
GL_EMISSION (0.0, 0.0, 0.0, 1.0) Emisión del color
GL_COLOR_INDEXES (0,1,1) Índices ambiente, difuso, y
especular
Reflexión especular
La componente especular define el color de los brillos del objeto, cuya forma se controla
con el parámetro GL_SHININESS, de modo que cuanto mayor sea este parámetro el brillo
aparecerá más concentrado.
Emisión
OpenGL permite asignar a los objetos un color de emisión para que parezca que dichos
objetos emiten luz de un color, lo que permite simular lámparas y objetos luminosos. Se
pueden conseguir mejores efectos situando fuentes de luz en la misma posición que los
objetos para los que se define un color de emisión.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
donde face puede tomar los valores GL_FRONT_AND_BACK, GL_FRONT o GL_BACK y mode
GL_AMBIENT_AND_DIFFUSE, GL_DIFFUSE, GL_SPECULAR o GL_EMISIÓN.
Una vez que se realiza la llamada a la función, se puede cambiar el color de la propiedad
que indica el parámetro mode, para la cara definida en face usando glColor.
Después de llamar a la función glColorMaterial, es necesario realizar una llamada a
glEnable con el argumento GL_COLOR_MATERIAL.
• glColorMaterial(GL_FRONT, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glColor3f(0.2, 0.5, 0.8);
......../* dibujamos algo aquí */
glColor3f(0.9, 0.0, 0.2);
......... /*y otros */
glDisable(GL_COLOR_MATERIAL);
Los materiales de los objetos tienen las mismas componentes que la de los colores de la
luz. Vienen a indicar la reflectancia del material a cada una de las componentes de la luz.
Para indicar el material de los objetos que se van a renderizar a continuación se debe
utilizar la siguiente función :
A continuación se muestra un ejemplo, donde se tiene una bola roja con una luz
direccional :
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glMaterialfv(GL_FRONT,GL_DIFFUSE ,mat_difuso);
glLightfv(GL_LIGHT0,GL_POSITION,posicion_luz);
DibuajrEsfera();
Listas
Una lista de OpenGL es un grupo de comandos que han sido guardados para una
posterior ejecución. Cuando una lista es invocada, los comandos en ella son ejecutados
en el orden en los cuales fueron introducidos.
Utilizar listas tiene dos ventajas. La primera es la eficiencia y la segunda la claridad.
Suponga que se tiene el siguiente código que dibuja tres círculos en pantalla:
Procedure DrawCircle()
begin
glBegin(GL_POLYGON);
for(i=0;i<100;i++)
{
cosine = cos(i*2*PI/100.0);
sine = sin(i*2*PI/100.0);
glVertex2f(cosine,sine);
}
glEnd();
end;
glPushMatrix();
DrawCircle();
glTranslatef(2.0,0.0,0.0);
DrawCircle();
glTranslatef(2.0,0.0,0.0);
DrawCircle();
glPopMatrix();
En este caso, para dibujar los tres círculos, Se tuvieron que calcular 300 veces los valores
de un seno y un coseno. Hacer este tipo de cálculos es muy costoso. Si se utilizara listas,
entonces solo se tendría que calcular una vez los puntos del circulo, con lo que sólo se
calcularía 100 senos y cosenos, y despues se llamaría a la lista tres veces, una vez por
cada dibujo.
glNewList(LISTA_CIRCULO,GL_COMPILE);
glBegin(GL_POLYGON);
for(i=0;i<100;i++)
{
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
cosine = cos(i*2*PI/100.0);
sine = sin(i*2*PI/100.0);
glVertex2f(cosine,sine);
}
glEnd();
glEndList();
glPushMatrix();
glCallList(LISTA_CIRCULO);
glTranslatef(2.0,0.0,0.0);
glCallList(LISTA_CIRCULO);
glTranslatef(2.0,0.0,0.0);
glCallList(LISTA_CIRCULO);
glPopMatrix();
}
Hay que tener en cuenta que se pueden crear listas jerarquicas. Así por ejemplo, la
función DrawScene anterior se podría ejecutar con un solo glCallList, si antes se hubiese
definido una lista del tipo siguiente :
glNewList(LISTA_ESCENA,GL_EXECUTE);
glPushMatrix();
glCallList(LISTA_CIRCULO);
glTranslatef(2.0,0.0,0.0);
glCallList(LISTA_CIRCULO);
glTranslatef(2.0,0.0,0.0);
glCallList(LISTA_CIRCULO);
glPopMatrix();
glEndList();
Cuando se crea una lista, OpenGL se encarga de guardar cuales son las operaciones que
se realizan y posteriormente se pueden ejecutar con un costo en calculo mucho menor. La
desventaja es que una lista requiere mucho espacio en memoria. Por ejemplo, para la
lista del circulo, se necesita espacio de al menos para 200 puntos en coma flotante.
Además, las listas una vez realizadas no se pueden cambiar, solo se pueden ejecutar.
Las listas pueden guardar las siguientes operaciones :
• Operaciones con matrices
• pasterización de bitmaps y imágenes
• Luces, propiedades de materiales y modelos de luces.
• Texturas
• Primitivas de dibujo : polígonos, mallas de triángulos, líneas,...
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Vistas
OpenGl permite utilizar diferentes expresiones para definir la posición de la cámara y
hacía donde mira dicha cámara.
En OpenGl la representación de los ejes e coordenadas se describe en el siguiente
gráfico.
Existe la posibilidad de manipular estos ejes cambiando la posición relativa de cada uno
de ellos, para ello OpenGl utiliza una serie de sentencias que definen como se va a ver
los ejes de coordenadas y en consecuencia como se visualizará el objeto tridimensional.
gluLookAt()
Esta sentencia permite definir de forma especifica donde se situará la cámara, hacía
donde mirara está y cual va a ser el orden de los ejes de coordenadas.
gluLookAt(x0,y0,z0,xc,yc,zc,Vx,Vy,Vz);
Esta sentencia tiene nueve argumentos que describen tres puntos, los valores de x0, y0,
z0, representa el punto hacia donde mira la cámara virtual, este punto normalmente se
identifica en el origen de coordenadas (0,0,0).
Los siguientes tres argumentos representan el punto donde se situará la cámara de
visualización, estas coordenadas no deben coincidir con el punto al cual se está mirando.
Las últimas tres coordenadas representa el vector de vista hacía arriba, es decir indica
cual será el vector cuya dirección será hacia arriba, “apuntará hacia la parte superior del
monitor”.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Para entender este caso se puede ver una serie de ejemplos donde se especifica cual es
el vector y como quedan definidos los ejes de coordenadas:
y
y
x
z z
(Vx,Vy,Vz) = (Vx,Vy,Vz) =
(0,1,0) (1,1,0)
En los ejemplos anteriores según sea el valor del vector de vista hacia arriba el objeto que
se visualizará tendrá un aspecto u otro. Normalmente para simplificar la visualización el
vector de vista hacia arriba se hace coincidir con uno de los ejes de coordenadas, como
es el caso del primer gráfico.
glOrtho()
Se utiliza para especificar una proyección ortográfica. Este tipo de proyección define un
volumen de vista rectangular, concretamente define un paralelepípedo de tamaño infinito,
este hecho nos lleva a definir una serie de planos de corte para detallar con exactitud el
volumen de vista.
pcerca
(xwmin, ywmin)
Estos seis argumentos definen la ventana de visualización y los planos de corte tanto
cercano como lejano.
Para definir la ventana de visualización es suficiente definir las coordenadas de dos
esquinas de la ventana, con estos dos valores queda totalmente definida.
Los valores de pcerca y plejos representan el plano cercano y el plano lejano. Hay que
tener en cuenta que el objeto a visualizar debe encontrarse dentro de ambos planos, si
sobrepasan estos dos planos el objeto se recortará automáticamente.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
El objeto se visualizará entre los dos planos de recorte, en el caso que sobrepase estos
planos se recortará, y si el objeto es tan grande que la ventana de visualización esta
dentro de él, no se visualizará nada quedando la pantalla en negro.
glFrustum()
Este comando se utiliza para definir una proyección perspectiva, se define de forma
similar a la proyección ortográfica pero con la diferencia que la proyección perspectiva
define como volumen de vista una pirámide, en consecuencia el objeto a visualizar tiene
un aspecto mucho más realista.
La sentencia que utiliza OpenGl es:
plejos
Plano de corte lejano
(xwmax, ywmax)
Punto de vista
gluPerpespective()
Esta sentencia es una alternativa a la función glFrustum, la diferencia entre ambas está
en la forma de definir la ventana de visualización. Si en la sentencia glFrustum se definen
los dos vértices necesarios de la ventana, en la sentencia glPerpective solamente se
define el ángulo de apertura de la cámara y la relación entre el largo y ancho del plano
cercano de corte.
La sentencia en OpenGl será de la forma:
Apertura corresponde al ángulo de apertura de la cámara virtual, este ángulo puede tomar
valores comprendidos entre 0º y 180º. El valor de aspect, vendrá dado por la relación
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
entre el alto y ancho del plano de corte, por lo tanto aspect toma el valor de alto plano
dividido entre largo plano.
Los valores de pcerca y plejos corresponden a los planos de corte cercano y lejano, de
forma similar que en los casos anteriores.
plejos
Plano de corte lejano
Apertura
Punto de vista
Matrices
Para poder manipular los objetos de la escena se debe tener definida una matriz de
visualización, esta matriz será de cuatro por cuatro, es decir coordenadas normalizadas.
Esta matriz se utiliza tanto en dos como en tres dimensiones, la diferencia esta en la
coordenada z, en el caso de dos dimensiones z siempre tomará el valor cero, mientras
que en tres dimensiones podrá tomar diferentes valores.
OpenGl, facilita maneras para poder manipular la matriz de visualización. Antes de
manipular la matriz directamente se debe inicializar el modo para la matriz de
operaciones, esto se consigue con la función:
glMatrixMode(GL_MODELVIEW);
Una vez definido el modo de la matriz se puede asignarle un valor con las siguientes
funciones:
glLoadIdentity()
Esta sentencia permite inicializar la matriz con un valor dado, especificado por el valor de
M. M puede ser definido como una matriz de cuatro por cuatro o bien por un vector de
dieciséis elementos, (m1, m2, m3,...). Hay que tener en cuenta que los valores de la
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
matriz se especifica por columnas, es decir la primera columna corresponde a los valores
del vector m1, m2, m3, m4, la segunda columna corresponderá a los valores m5, m6, m7,
m8, y así sucesivamente.
Estas dos sentencias permiten inicializar la matriz de transformaciones, para poder
realizar operaciones se puede utilizar la siguiente instrucción:
glMultMatrix(M)
Esta sentencia permite multiplicar matrices, teniendo en cuenta que multiplicará la matriz
definida con una de las sentencias anteriores por la matriz M.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Blending
GlBlendFunc(origen, destino)
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
origen).
El color de destino se multiplica por el valor alfa de
GL_DST_ALPHA
destino. Microsoft OpenGL no lo soporta.
El color de destino se multiplica por (1, valor alfa de
GL_ONE_MINUS_DST_ALPHA
destino). Microsoft OpenGL no lo soporta.
El color de destino se multiplica por el mínimo de los
GL_SRC_ALPHA_SATURATE valores alfa de origen y (1, valor de destino). Microsoft
OpenGL no lo soporta.
Transparencias
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, Gl_ONE_MINUS_SRC_ALPHA);
Rd = Rs * As + Rd * (1 - As)
Gd = Gs * As + Gd * (1 - As)
Bd = Bs * As + Bd * (1 - As)
Como sólo se emplea la componente alfa del color de origen, no se necesita una tarjeta
gráfica que soporte planos de color alfa en el buffer de color. Algo que se debe recordar
con las transparencias por mezcla alfa es que la verificación normal de profundidad puede
interferir con el efecto que se trata de conseguir. Entonces es necesario asegurarse que
las líneas y polígonos transparentes se dibujen apropiadamente, siempre se debe dibujar
de atrás a adelante.
Antialiasing
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
NIEBLA
!
"#
$
%
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
)
'
,
#
-.)
-.)/#
$
*+, -
#
'0 '11
+
12
3
4"
3#
1121
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
0 '#
'
!
)
1121
# --%5,65--78
#
!
#
#
6. Texturas
Ya se vio como pintar, trasladar y rotar un objeto en una escena, ahora seguro que se
desearía darle más realismo a la misma. Para ello se utilizan texturas, que no son más
que imágenes 2D "pegadas" a los polígonos.
Antes de nada, es importante saber que a la hora de trabajar con texturas lo primero que
se debe hacer es habilitar el mapeado de texturas. Para esto se utiliza la instrucción
glEnable(GL_TEXTURE_2D); OpenGL trata cada textura como si fuera un objeto. Le
asigna un nombre distintivo, que es el identificador (TextureID) por lo que cada ID
referencia a una textura diferente. Así se puede acceder de manera más fácil a las
mismas. Por ejemplo si se tienen dos texturas cargadas en un programa y estas
corresponden con los índices de textura (TexturaID), 1 y 2 respectivamente, para usarlas
solamente se debe utilizar:
glBindTexture(GL_TEXTURE_2D, 1); Para la primera textura y
glBindTexture(GL_TEXTURE_2D,2) para la segunda.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
sólo acepta archivo con tamaños múltiplos de 2. Para poder enlazar en memoria el
archivo se utiliza el comando glTexImage2D de la siguiente manera:
donde:
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Ahora que ya se tiene la Textura creada se debe especificar las coordenadas de la textura
con respecto al objeto que se va a dibujar. Al igual que las coordenadas de un vértice le
dicen a OpenGL donde dibujar cada punto de un objeto, las coordenadas de textura
especifican donde se debe dibujar cada textura.
Para comprender mejor como se especifican estas coordenadas piense que se tiene un
tablón de madera y que sobre este se desea pegar una fotografía que se tiene impresa en
una tela elástica. Lo que se hace es coger la esquina superior derecha de la fotografía y
unirla con una grapa a la esquina superior derecha del tablón y así con las demás
esquinas. Pues bien, ahora se debe pensar en la fotografía como si fuera la textura y el
tablón como el cuadrado. Lo que se tiene que hacer entonces es decirle a OpenGL donde
"colocar las grapas" y eso es básicamente especificar las coordenadas de textura. Para
ello se utiliza la función glTexCoord2f(u,v). El primer valor es la coordenada X de la
textura, 0 es la parte izquierda de la misma, 0.5 es la mitad y 1 es la parte derecha. El
segundo valor es la coordenada Y, 0 es la parte inferior, 0.5 es la mitad y 1 es la parte
superior. De este modo, las coordenadas de la textura de un cuadrado serán:
- Vértice 1: glTexCoord2f(0,0);
- Vértice 2: glTexCoord2f(0,1);
- Vértice 3: glTexCoord2f(1,1);
- Vértice 4: glTexCoord2f(1,0);
Texturas multiples
De esta manera se pueden utilizar un conjunto grande de texturas para una misma
escena.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Además, se puede tener texturas unidimensionales (un solo pixel de alto o de ancho)
bidimensionales (imagen de tamaño mxn) o tridimensionales (con volumen), aunque lo
habitual será utilizar las bidimensionales.
En OpenGl las dimensiones de una textura deben ser siempre potencia de 2=
64,128,256...
Los pasos necesarios para mapear texturas sobre polígonos son los siguientes:
• Indicar los parámetros de aplicación de la textura y activar el mapeado de texturas.
• Especificar la textura
• Dibujar la escena.
GL_TEXTURE_MAG_FILTER GL_NEAREST,GL_LINEAR
GL_TEXTURE_MIN_FILTER GL_NEAREST,GL_LINEAR,
GL_NEAREST_MIPMAP_NEAREST,
GL_NEAREST_MIPMAP_LINEAR,
GL_LINEAR_MIPMAP_NEAREST,
GL_LINEAR_MIPMAP_LINEAR
Habrá que llamar a la función glTexParameter cuatro veces, para dar los valores que se
deseen a cada uno de los parámetros.
Con GL_TEXTURE_WRAP se especifica el tratamiento de las coordenadas S y T de la
textura, fuera del rango [0.0,1.0]. Y Con GL_MAG_FILTER y GL_MIN_FILTER se indican
los filtros de ampliación o reducción de la textura.
También se puede especificar cómo aplicar la textura sobre los píxels. Esto se hara con la
función:
5"9:9: + ;
5"9:9: + ;
donde objetivo=GL_TEXTURE_2D y
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
'
!
Para poder ver las texturas se tiene que activarlas con la función:
-5.5&6-/8;
-5.5&6-/8;
Especificar la textura.
Normalmente se partirá de una imagen almacenada en algún formato standard (bmp, jpg,
gif, rgb, etc). Para poder cargar esta imagen se necesita de algún programa o biblioteca
que lea este tipo de ficheros. Se debe asegurar, utilizando algún editor de imágenes, que
el ancho y el alto de la imagen sea potencia de dos.
Si la imagen se la tiene en formato bmp se puede utilizar también una función de la
biblioteca glaux para cargarla:
,&.-6>?6
@"8?>?
;
,&.-6>?6
@"8?>?
;
Esta función devolverá una estructura de la cual se podrá leer la información de tamaño y
datos:
-,&.-6>?6
9
-,&.-6>?6
9
9
!.!A;
!.!A;
(@
;
(@
;
:,&.-6>?6
;
:,&.-6>?6
;
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Parámetro valores
Objetivo GL_TEXTURE_2D (para texturas bidimensionales)
nivel 0,1,2.. es el nivel de detalle de la textura. Si sólo hay una textura nivel=0
Esta función deberemos llamarla antes de dibujar los polígonos sobre los que queremos
aplicar la textura.
5"=
/9:
-
-;
5"=
/9:
-
-;
Ejemplo.
Un ejemplo del código necesario para dibujar un objeto con texturas.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
glTexImage2D(GL_TEXTURE_2D,0,3,imagen[0]->sizeX, imagen[0]->sizeY,
0,GL_RGB,GL_UNSIGNED_BYTE,imagen[0]->data);
glBegin(GL_POLYGON);
glNormal3f(0,0,1);
glTexCoord2i(0,0); //Asignr las coordenadas de textura del siguiente vértice.
glVertex3f(-ancho/2,-alto/2,0);
glTexCoord2i(0,1);
glVertex3f(-ancho/2,alto/2,0);
glTexCoord2i(1,1);
glVertex3f(ancho/2,alto/2,0);
glTexCoord2i(1,0);
glVertex3f(ancho/2,-alto/2,0);
glEnd();
7. SOMBRAS
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
8. Enmascaramiento
Esta técnica consiste básicamente en "recotar" parte de un gráfico, ya sea según un color
o siguiendo un patrón, para darle aspecto de transparencia a ese trozo que se ha
recortado.
Tiene mucha utilidad dentro del mundo de los videojuegos, por ejemplo si se tiene un
dibujo del personaje y se quiere mostrarlo en la pantalla, no seria nada agradable que
apareciera un cuadrado de fondo negro con nuestro personaje dentro, y que todo tapara
el fondo tan bonito que se ha creado. También es útil para crear interfaces de usuario,
cabinas de aviones (para simuladores), efecto billboarding, etc.
Para usar esta técnica se deben tener dos imágenes diferentes, una llamada imagen
fuente y la otra imagen máscara. En la imagen fuente se almacena la imagen que se
desea mostrar (y recortar) con un fondo por ejemplo negro. En la imagen máscara se
pinta de negro las partes de la imagen fuente que se quiere ver y de blanco las que se
quiere recortar. Por ejemplo:
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Para ello en el ejemplo se ha creado un cubo que tiene cinco caras con una misma
textura (opaca) y la cara anterior contiene una textura a la que se le ha aplicado el efecto
de máscara, consiguiendo un efecto de transparencia que permite ver el interior del cubo.
9. EL BUFFER DE ESTARCIDO
El buffer de estarcido proporciona muchas funciones para restringir el dibujo en pantalla y
tiene muchas aplicaciones que el buffer de profundidad no puede realizar. Al nivel más
simple, el buffer de estarcido puede usarse para cerrar ciertas áreas de la pantalla.
Quizás la aplicación más interesante del buffer de estarcido sea el sombreado.
Dependiendo del hardware gráfico, se puede generar sombras por hardware y por
software de múltiples fuentes de luz, haciendo que las escenas sean mucho más
realistas.
Para usar el buffer de estarcido, primero se debe activar con una llamada a:
!
*+)
+*+
Sin esta llamada, todas las operaciones del buffer de estarcido están desactivadas.
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
Cochabamba - Bolivia
Animación 3D Lic. Yony Richard Montoya Burgos
GL_INVERT Invierte el orden binario del valor actual del buffer de estarcido.
Normalmente se utiliza una máscara para perfilar el área en la que tiene lugar el dibujo.
Aquí tenemos un ejemplo de cómo dibujar una máscara en el buffer de estarcido:
* /
@,*>>
* 2
)
)
)
Dado que tiene efecto con todas las funciones de dibujo de OpenGL, incluido glBitMap,
podemos usar el buffer de estarcido para crear efectos especiales de agujero en
animaciones.
Cochabamba - Bolivia