Está en la página 1de 110

Programacin 3D con

OpenGL bajo GNU/Linux


Roberto Garrido Martn (Ro)
e-ghost
ESIDE's GNU Hi-tech and Open Source Team

ndice
1. Introduccin
2. OpenGL y GNU/Linux
3. Conceptos bsicos sobre OpenGL
4. Animaciones
5. Iluminacin
6. Texturas
7. Interaccin con el teclado
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Introduccin
Objetivo del cursillo

A quin va dirigido?

Recursos del cursillo

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

La librera OpenGL

Estndar creado por Silicon Graphics en 1992


Versin 2.0

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

La librera OpenGL

Tres partes funcionales

La librera OpenGL
La librera GLU
GLX
Adems, GLUT

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

GNU/Linux y OpenGL

La librera Mesa

Es Libre
Es una implementacin software, excepto para ciertas
tarjetas, que usan el driver Mesa/Glide:

Voodoo1, Voodoo2, Voodoo Rush, Voodoo Banshee, Voodoo3

Versin 6.5, que implementa OpenGL 1.5 (la


implementacin de especificacin 2.0 est en camino)

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

GNU/Linux y OpenGL

Xlibmesa

Proporciona acceso a la aceleracin grfica por


hardware, a travs de DRI y si la tarjeta lo permite

Este modo de acceso es usado por tarjetas 3dfx, Intel, Matrox,


ATI

DRI est presente en las implementaciones del servidor


Xfree86 a partir de la versin 4, y hoy en las de Xorg

Tarjetas NVIDIA, con su propia implementacin de


la librera OpenGL

Se usa conjuntamente con Mesa (GLU)


Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

GNU/Linux y OpenGL(en resumen):

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

Qu necesitamos para programar con


OpenGL bajo GNU/Linux?

Binarios de la librera OpenGL (Mesa, xlibmesa, o


drivers propietarios)
Paquetes de desarrollo de estas libreras (cdigo
fuente de Mesa, xlibmesa-dev, para drivers
propietarios, depende (nvidia-glx-dev))
Compilador de C/C++ (gcc, g++)
Editor de texto (kate, gedit, vim, nano, ...)
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

OpenGL como mquina de estados

Activar y desactivar opciones y realizar acciones,


que tendrn como objetivo una representacin en
pantalla
No es lo mismo dibujar un tringulo y activar una
textura, que activar una textura y dibujar un
tringulo
Rotar y transladar algo, es distinto que transladarlo
y rotarlo

El orden en OpenGL es crtico en la mayora de los


casos
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

OpenGL como mquina de estados

En general, para dibujar un objeto:


1 Activar opciones persistentes a la escena (luces, posicionar
cmara)
2 Activar las opciones de un objeto especfico (su posicin,
textura)
3 Dibujar el objeto
4 Desactivar las opciones del objeto (volver a la posicin
anterior, desactivar su textura)
5 Y volver al punto 2 hasta haber dibujado todos los objetos
(siguiendo una jerarqua)
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

El espacio 3D

Cuatro dimensiones (x,y,z,w)


X
Z

Sistema de coordenadas inicial


1
0
0
0

0
1
0
0

0
0
1
0

0
0
0
1
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

El espacio 3D

Transformaciones de objetos

Translacin

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

El espacio 3D

Transformaciones de objetos

Rotacin

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

El espacio 3D

Transformaciones de objetos

Escalado

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

El espacio 3D

Transformaciones de objetos

Toda transformacin construye una matriz de cuatro


dimensiones que se multiplicar por la matriz de
transformacin actual
Al transladar un objeto 3 unidades en el eje X:
1003
0100
0010
0001

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

El espacio 3D

Transformaciones de objetos

Si aplicamos dicha transformacin a la transformacin


inicial, obtenemos:
1
0
0
0

0
1
0
0

0
0
1
0

0
0
0
1

1003
0100
0010
0001

1003
0100
0010
0001

Si ahora dibujamos el punto (1,0,0), quedar desplazado,


de la siguiente forma:
1003
0100
0010
0001

1
4
0
0
0 (Ro) - ESIDE 0e-ghost 2006
Roberto Garrido
1
1

Conceptos bsicos sobre OpenGL

El espacio 3D

Las coordenadas homogneas

Varias razones:

Son cuatro coordenadas, de forma que:

Uniformidad de operaciones con matrices


Conceptos relativos a profundidad
El punto 3D (1, 2, 3) es traducido a (1, 2, 3, 1.0)
El punto 2D (1, 2) es traducido a (1, 2, 0.0, 1.0)
En general, el punto (x,y,z,w) en coordenadas homogneas es
equivalente al punto 3D (x/w,y/w,z/w)

Si w=0, punto en el infinito con direccin (x,y,z)


Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Sobre Glut

Funciones para la creacin de ventanas


independiente de plataforma
Lo veremos en los ejemplos
Funciones de callback

Las funciones bsicas de OpenGL

Activacin/Desactivacin de opciones

glEnable(<OPTION>), glDisable(<OPTION>)

glEnable(GL_LIGHTING)
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Las funciones bsicas de OpenGL

Las matrices y OpenGL

Transformacin de objetos: matriz de


visualizacin/modelado
Matriz de proyeccin: informacin de la cmara
Cambiar modo de matriz:

glMatrixMode(GL_PROJECTION)
glMatrixMode(GL_MODELVIEW)

Guardar y restaurar valores en la pila

glPopMatrix() y glPushMatrix()

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Las funciones bsicas de OpenGL

Las matrices y OpenGL

Para dibujar jerarquas de objetos

<transformacin comn para la escena>


glPushMatrix();
<transformacin propia del elemento 1>
<dibujado del elemento 1>
glPopMatrix(); // Volvemos a la transformacin comn
glPushMatrix();
<transformacin propia del elemento 2>
<dibujado del elemento 2>
glPopMatrix(); // Volvemos a la transformacin comn
...

glLoadIdentity() carga la matriz unidad


Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Las funciones bsicas de Opengl

El dibujado en OpenGL

Para dibujar en OpenGL:

Habilitar modo de dibujado


Establecer opciones de dibujado de cada vrtice
Dibujar cada vrtice
Finalizar el modo de dibujado

glBegin(<MODO_DE_DIBUJADO>)

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL


Parmetro
GL_POINTS
GL_LINES
GL_POLYGON
GL_TRIANGLES
GL_QUADS

Descripcin
Se dibujan vrtices separados
Cada par de vrtices se interpreta como una lnea
Los vrtices describen el contorno de un polgono
Cada triplete de vrtices de interpreta como un tringulo
Cada cuarteto de vrtices se interpreta como un
cuadriltero
GL_LINE_STRIP
Lneas conectadas
GL_LINE_LOOP
Lneas conectadas, con unin entre el primer y ltimo
vrtice
GL_TRIANGLE_STRIP Se dibuja un tringulo, y cada nuevo vrtice se interpreta
con un tringulo entre los dos anteriores vrtices y el nuevo
GL_TRIANGLE_FAN Se dibujan tringulos con un vrtice comn
GL_QUAD_STRIP
Igual que el TRIANGLE_STRIP, con cuadrilteros

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Las funciones bsicas de Opengl

El dibujado en OpenGL

Establecer atributos de cada vrtice:

Color: glColor*
Normal: glNormal*
Coordenadas de textura: glTexCoor*

Dibujado de vrtices:

glVertex*

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Las funciones bsicas de Opengl

El color en OpenGL

Modos RGBA e Indexado

La orientacin de las caras en OpenGL

Cara delantera: orden antihorario


1

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Las funciones bsicas de Opengl

Las transformaciones en OpenGL

Operaciones que permiten situar objetos en el espacio:

glTranslate*: transladar un objeto en el espacio


glRotate*: rotar un objeto
glScale*: escalar un objeto
glMultMatrix: multiplicar la matriz actual por una dada

NO es lo mismo rotar y luego transladar, que transladar y


luego rotar

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Las funciones bsicas de Opengl

La proyeccin en OpenGL

Cmo afecta la posicin de un objeto a su visualizacin


Proyeccin ortogrfica

glOrtho(Xmin, Xmax, Ymin, Ymax, Znear, Zfar);

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Las funciones bsicas de Opengl

La proyeccin en OpenGL

Proyeccin perspectiva
gluPerspective()

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Primer contacto con OpenGL ;)

Mi primer programa en OpenGL

Includes
#include <GL/glut.h>

Funcin main

int main(int argc, char * argv)


{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(20,20);
glutInitWindowSize(500,500);
glutCreateWindow(argv[0]);

glutDisplayFunc(display);
glutMainLoop();
return 0;

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Mi primer programa en OpenGL

Funcin display

void display(void)
{
glClearColor(0.0,0.0,0.0,0.0);
// Color de fondo: negro
glClear(GL_COLOR_BUFFER_BIT);
// Boramos 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

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Mi primer programa en OpenGL

Funcin display

glBegin(GL_TRIANGLES);
// Dibujamos un tringulo
glColor3f(1.0,0.0,0.0);
// Color del primer vrtice: rojo
glVertex3f(0.0,0.8,0.0);
// Coordenadas del primer vrtice
glColor3f(0.0,1.0,0.0);
// Color del segundo vrtice: verde
glVertex3f(-0.6,-0.2,0.0);
// Coordenadas del segundo vrtice
glColor3f(0.0,0.0,1.0);
// Color del tercer vrtice: azl
glVertex3f(0.6,-0.2,0.0);
// Coordenadas del tercer vrtice
glEnd();
// Terminamos de dibujar
glFlush();
// Forzamos el dibujado
sleep(10);
// Esperamos 10 segundos
exit(0);
// Salimos del programa
}
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Mi primer programa en OpenGL

glClearColor: color del buffer al ser borrado


glClear(GL_COLOR_BUFFER_BIT): borrar el buffer
glOrtho
Dibujamos el tringulo
Compilamos:

roberto@garridocuarto:~$gcc myfirstopenglprogram.c -lglut -lGL -lGLU -o myfirstopenglprogram

Ejecutamos:

roberto@garridocuarto:~$./myfirstopenglprogram
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Mi primer programa en OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Primer contacto con OpenGL

Visualizando en perspectiva...

Cdigo de dibujado

glBegin(GL_QUADS);
// Dibujamos un cuadrado
glColor3f(0.0,1.0,1.0);
// Color para el cuadrado
glVertex3f(-0.5,0.5,-0.5);
// Coordenadas del primer vrtice (superior-izquierda)
glVertex3f(-0.5,-0.5,0.5);
// Coordenadas del segundo vrtice (inferior-izquierda)
glVertex3f(0.5,-0.5,0.5);
// Coordenadas del primer vrtice (inferior-derecha)
glVertex3f(0.5,0.5,-0.5);
// Coordenadas del primer vrtice (superior-derecha)
glEnd();
// Termina

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Visualizando en perspectiva...

Guardamos y ejecutamos

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Visualizando en perspectiva...

Primera modificacin
gluPerspective(60.0,1.0,1.0,100.0);
// Proyeccin perspectiva. El ngulo de visualizacin es de 60 grados, la razn ancho/alto es
1 (son inguales), la distancia mnima es z=1.0, y la distancia mxima es z=100.0

Segunda modificacin
glTranslatef(0.0,0.0,-2.0);
// Alejamos el cuadrado del observador dos unidades en el eje Z

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Visualizando en perspectiva...

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Primer contacto con OpenGL

Ocultacin de objetos (Z-Buffer)

Aadimos el tringulo (0.0, 0.5, 0.0), (-0.7, -0.5, 0.0),(0.7,


-0.5, 0.0)

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Ocultacin de objetos (Z-Buffer)

Aadimos antes del dibujado


glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0);

Con glEnable(GL_DEPTH_TEST) habilitamos la


comprobacin de profundidad en el dibujado
Con glDepthFunc(GL_LEQUAL) se dibuja el pixel si
est a igual o menor distancia al observador
Con glClearDepth(1.0) cada vez que se borra el zbuffer, se inicializan sus posiciones al valor 1.0
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Ocultacin de objetos (Z-Buffer)

Al borrar la pantalla inicializamos el z-buffer

glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);

Al iniciar el programa, reservamos espacio para el


z-buffer

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA |
GLUT_DEPTH);

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Ocultacin de objetos (Z-Buffer)

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Primer contacto con OpenGL

Jerarquas

El ejemplo del cuerpo humano


Se usan pilas de matrices
1. Se sita el elemento principal
2. Se dibuja el elemento principal
3. Se apila la matriz actual (glPushMatrix)
4. Se sita el primer elemento secundario con respecto al primero
5. Se dibuja el primer elemento secundario
6. Vuelta a la situacin del elemento principal (glPopMatrix)
7. Se repite para los dems elementos secundarios

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Jerarquas

Programa que dibuja un cuadrado y cuatro


secundarios
Funcin dibujarCuadrado
void dibujarCuadro(float tam)
{
glBegin(GL_QUADS);
glVertex3f(-tam/2.0,tam/2.0,0.0);
glVertex3f(-tam/2.0,-tam/2.0,0.0);
glVertex3f(tam/2.0,-tam/2.0,0.0);
glVertex3f(tam/2.0,tam/2.0,0.0);
glEnd();
}

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Jerarquas

Para dibujar la jerarqua, hacemos


glColor4f(1.0,0.0,0.0,1.0);
dibujarCuadro(1.0);
glPushMatrix();
glTranslatef(0.0, 2.0, 0.0);
dibujarCuadro(0.5);
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, -2.0, 0.0);
dibujarCuadro(0.5);
glPopMatrix();
...

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Jerarquas

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Jerarquas

De manera recursiva

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Jerarquas

Figura humanoide a base de cubos ;)

Primero, alejamos la cmara

glTranslatef(0,0,-16.0);

Situamos el cuerpo y lo dibujamos


glTranslatef(0,BODY_HEIGHT/2,0);
glPushMatrix();
glScalef(BODY_WIDTH,BODY_HEIGHT,BODY_LENGTH);
glColor3f(0.0,0.3,0.8);
glutSolidCube(1);
glPopMatrix();

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

A partir del centro del cuerpo, situamos el


brazo derecho
glPushMatrix();
glTranslatef(-(BODY_WIDTH)/2,(BODY_HEIGHT-ARM_HEIGHT)/2,0);
glTranslatef(0,ARM_LENGTH/2,0);
glRotatef(-30,0,0,1);
glTranslatef(0,-ARM_LENGTH/2,0);
glPushMatrix();
glScalef(ARM_WIDTH,ARM_HEIGHT,ARM_LENGTH);
glutSolidCube(1);
glPopMatrix();
// ya tenemos el brazo... la mano
glTranslatef(0,-(ARM_HEIGHT+ARM_WIDTH)/2,0);
glColor3f(1,0.6,0.6);
glScalef(ARM_WIDTH,ARM_WIDTH,ARM_LENGTH);
glutSolidCube(1);
glPopMatrix();

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Dibujamos el resto del cuerpo de la misma


forma (ver cdigo anexo)
Y finalmente, dibujamos la cabeza, como una
esfera
glColor3f(1,0.6,0.6);
glPushMatrix();
glTranslatef(0,BODY_HEIGHT/2 + HEAD_RADIUS*3/4,0);
glutSolidSphere(HEAD_RADIUS,10,10);
glPopMatrix();

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos bsicos sobre OpenGL

Jerarquas

Figura humanoide

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Para animar una figura


1
2
3
4

Actualizar los datos de la figura


Borrar la pantalla
Dibujar la figura
Volver al punto 1

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Los vectores para animar figuras

Objeto que se mueve en el eje X a 1 ud por frame


Tiene un vector de posicin y otro de direccin

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Ejemplo de la esfera que rebota dentro de un


cubo

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Esquema de dibujado

Comprobar que la esfera no est en el lmite del


cubo

Si est: invertir la componente del vector de direccin


correspondiente al lado con el que ha rebotado

Sumar el vector de direccin al vector de posicin


de la esfera
Dibujar la esfera
Volver al comienzo del bucle
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Definicin de la clase TSphere


Mtodos
TSphere (float maxpos, float speed);

void test();
void modifySpeed(float inc);
float * getPosv();

Funcin
Crea una instancia de la clase. La esfera
rebotar si llega a la poscin +-maxpos,
y tendr una velocidad speed. Su
situacin y direccin iniciales son
aleatorias
Comprueba que la figura est dentro de
los mrgenes, y si no le est, corregir su
direccin. Despus, actualiza su poscin
Incrementa la velocidad en inc
Obtiene un vector con la posicin de la
esfera (en la posicin 0, la coordenada X,
en la 1 la Y, y en la 2 la Z)

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Funciones de glut

glutDisplayFunc()
glutIdleFunc()

Variables globales

float * pos;
TSphere * sphere;

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Funcin de inicializacin initgl


void initgl()
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0,1.0,1.0,100.0);
sphere = new TSphere(5,0.1);
glMatrixMode(GL_MODELVIEW);
gluLookAt(3,3,14,0,0,0,0,1,0);
}

gluLookAt: posicin de la cmara + posicin a


la que apunta, parte superior de la escena
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Funcin display
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glutWireCube(10);
glPushMatrix();
glColor3f(0.0,0.0,1.0);
pos = sphere->getPosv();
glTranslatef(pos[0],pos[1],pos[2]);
glutSolidSphere(1,10,10);
glPopMatrix();
glFlush();
}

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Funcin idle
void idle(void)
{
sphere->test();
usleep(33);
glutPostRedisplay();
}

Registramos estas funciones en la funcin


main
initgl();
glutDisplayFunc(display);
glutIdleFunc(idle);

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

El doble buffering

Dibujar la escena en un buffer fuera de la pantalla,


mientras la imgen de la pantalla no se toca
Intercambio de buffers al final de cada frame
Al activar el modo de la pantalla

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA |
GLUT_DEPTH);

Y al final de la funcin display

glutSwapBuffers();

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Sphere-rebotes con doble buffering

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

Con una pequea modificacin

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Permite crear escenas ms realistas

Cada implementacin al menos 8 luces

No es recomendable abusar de stas

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

El modelo de iluminacin en OpenGL

Se basa en

Luces: fuente que emite un haz de luz de un


determinado color
Materiales: determina la cantidad de cada color que
refleja un objeto determinado

El tipo de luz afecta al color

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Luces

Una fuente de luz puede emitir diferentes tipos de


luz

Emitted (emitida): luz emitida por un objeto


Diffuse (difusa): luz que incide sobre un objeto, y
proviene de un determinado punto
Specular (especular): luz que, al incidir sobre un objeto,
se ve reflejada con un ngulo similar al de incidencia
Ambient (ambiental): algo as como la iluminacin
global de una escena

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Materiales

Definen qu cantidad refleja un objeto de cada tipo


de luz
El color de un objeto se define por su material, no
por el color de sus vrtices

Normales

Para saber cmo incide una luz sobre un vrtice


Vector generalmente perpendicular a la cara que
estamos dibujando
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Misma luz, mismo objeto, normales cambiadas

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Utlizando la iluminacin en OpenGL

Luces

Primer paso, activar la iluminacin

glEnable(GL_LINGHTING);

Ahora establecemos las propiedades de cada luz, y las


activamos
Cada luz se identifica por una constante GL_LIGHTn,
donde 'n' empieza desde cero
Las propiedades se establecen con funciones de tipo
glLight*()

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Luces

Propiedades de las luces

Posicin/Direccin

Puntuales
Focales

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Posicin/Direccin

glLightfv(GL_LIGHTn,GL_POSITION,val_ptr);

Direccin del foco

val_ptr es un puntero a un array de 4 dimensiones de


tipo float (x,y,z,w). Si w=1 es posicional, si es 0,
direccional

glLightfv(GL_LIGHTn,GL_SPOT_DIRECTION,val_prt);

Apertura del foco

glLightf(GL_LIGHTn,GL_SPOT_CUTOFF,val);

val est expresado en grados


Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Atenuacin del foco

glLightf(GL_LIGHTn,GL_SPOT_EXPONENT,val);

Intensidad de la luz

Define el color ambiental, difuso y especular


glLightfv(GL_LIGHTn,GL_[AMBIENT|DIFFUSE|
SPECULAR],val_ptr);

val_ptr es puntero a vector de 4 componentes RGBA

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Atenuacin de la luz

Prdida de intensidad de la luz a medida que nos


alejamos del foco
glLightf(GL_LIGHTn,GL_[CONSTANT|LINEAR|
QUADRATIC]_ATTENUATION,val);
El factor de atenuacin se calcula mediante:

Una vez establecidas las propiedades de una luz

glEnable(GL_LIGHTn);
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Materiales

Caractersticas del material: glMaterial*(), 3


parmetros

Caras del polgono a las que afecta: GL_FRONT,


GL_BACK, GL_FRONT_AND_BACK
Caracterstica que estamos definiendo (color, brillo)
Valor de la caracterstica

Color del material

Define su comportamiento ante los tipos distintos de luz


Color ambiental, difuso y especular
Color emitido
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Color del material

glMaterialfv(GL_FRONT[_AND_BACK],[GL_AMBIE
NT|GL_DIFUSSE|GL_AMBIENT_AND_DIFUSSE|
GL_SPECULAR],val_ptr);
val_ptr es un puntero a un vector de componentes
RGBA

Brillo de los reflejos de los materiales

glMaterialf(GL_FRONT[_AND_BACK],GL_SHININE
SS,val);
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Materiales

Podemos cambiar estos valores con la funcin


glColorMaterial ()

Hay que activarla con


glEnable(GL_COLOR_MATERIAL);
Establecemos la propiedad a cambiar

Cambiamos el color reflejado de ese tipo de luz

glColorMaterial(GL_FRONT[_AND_BACK],[GL_AMBIENT|
GL_DIFUSSE|GL_AMBIENT_AND_DIFUSSE|GL_SPECULAR]);
glColor3f(r_val,g_val,b_val);

Debemos desactivar esta opcin tras utilizarla


Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Ejemplo: Iluminacin direccional sobre una


superficie (ejemplo de las normales)
Arrays a definir

Color ambiental y difuso del material

Color difuso y especular de la luz

GLfloat mat_color [] = {0.0,1.0,1.0,1.0};


GLfloat light_color [] = {1.0,1.0,1.0,1.0};

Color ambiental de la luz

GLfloat light_ambient [] = {0.0,0.0,0.0,1.0};


Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Arrays a definir

Valor de las normales

Valor de la direccin de la luz

GLfloat normal [] = {0.0,1.0,0.0};


GLfloat light_dir [] = {0.0,1.0,0.0,0.0};

Seleccionamos el color de fondo, y borramos la


pantalla
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Activamos la luz, y sus caractersticas, excepto


la direccin
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,light_color);
glLightfv(GL_LIGHT0,GL_SPECULAR,light_color);
glEnable(GL_LIGHT0);

Seleccionamos el color del material:

glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFF
USE,mat_color);
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Establecemos la perspectiva y posicionamos al


observador
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0,1.0,1.0,100.0);
glMatrixMode(GL_MODELVIEW);
glTranslatef(-0.3,-0.6,-4.0);

Establecemos la direccin de la luz

glLightfv(GL_LIGHT0,GL_POSITION,light_dir);

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Dibujamos el cuadrado, y antes de cada


vertice, establecemos su normal
glBegin(GL_QUADS);
#ifdef SINGLE_NORMAL
glNormal3fv(normal);
#else
glNormal3f(1.0,1.0,-1.0);
#endif
glVertex3f(-1.0,0.0,-1.0);
glNormal3fv(normal);
glVertex3f(-1.0,0.0,1.0);
#ifdef SINGLE_NORMAL
glNormal3fv(normal);
#else
glNormal3f(-1.0,1.0,-1.0);
#endif
glVertex3f(1.0,0.0,1.0);
glNormal3fv(normal);
glVertex3f(1.0,0.0,-1.0);
Roberto Garrido (Ro) - ESIDE e-ghost 2006
glEnd();

Iluminacin

Forzamos el dibujado, esperamos, y salimos


del programa
glFlush();
sleep(20);
exit(0);

Ejemplo: moviendo un foco alrededor de una


esfera

Utilizaremos dibujado con doble buffer, y zBuffer

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Definimos las caractersticas de la luz


float light_ambient [] = {0.0,0.2,0.0,1.0};
float light_diffuse_specular [] = {0.8,0.8,0.8,1.0};
float light_pos [] = {0.0,0.0,2.0,1.0};
float spot_dir [] = {0.0,0.0,-1.0};
float spot_cutoff = 30.0;
float spot_exponent = 1.0;

Caractersticas del material de la esfera


float mat_ambient_diffuse [] = {0.0,0.8,1.0,1.0};
float mat_specular [] = {0.7,0.0,0.0,1.0};
float mat_emission [] = {0.0,0.0,0.0,1.0};
float mat_shininess = 0.4;

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Ponemos un pequeo cono cuyo material


tenga una emisin similar al color de la luz

float focus_emission [] = {0.8,0.8,0.8,1.0};

Variables que indican la rotacin del foco


float rot_angle_y = 0.0;
float rot_angle_x = 0.0;

Habilitamos el zBuffer y establecemos el color


de fondo
glEnable(GL_DEPTH_TEST);
glClearColor(0.0,0.0,0.0,0.0);

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Activamos las luces y sus caractersticas


glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse_specular);
glLightfv(GL_LIGHT0,GL_SPECULAR,light_diffuse_specular);
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,spot_cutoff);
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,spot_exponent);
glEnable(GL_LIGHT0);

Establecemos el material de la esfera

glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, mat_ambient_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialf(GL_FRONT,GL_SHININESS,mat_shininess);

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Establecemos la perspectiva y trasladamos la


cmara
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0,1.0,1.0,100.0);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0,0.0,-5.0);

Estos pasos los englobamos en una funcin de


inicializacin

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Bucle de dibujado

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(30.0,0.0,0.0,1.0);
glRotatef(rot_angle_y,0.0,1.0,0.0);
glRotatef(rot_angle_x,1.0,0.0,0.0);
glLightfv(GL_LIGHT0,GL_POSITION,light_pos);
glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_dir);
glTranslatef(light_pos[0],light_pos[1],light_pos[2]);
glColorMaterial(GL_FRONT,GL_EMISSION);
glEnable(GL_COLOR_MATERIAL);
glColor4fv(focus_emission);
glutSolidCone(0.2,0.5,7,7);
glColor4fv(mat_emission);
glDisable(GL_COLOR_MATERIAL);
glPopMatrix();
glutSolidSphere(1.0,20,20);
glFlush();
glutSwapBuffers();
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Entre frame y frame, rotamos el foco


rot_angle_y = (rot_angle_y > 360.0)?0:rot_angle_y + ROT_INC;
rot_angle_x = (rot_angle_x > 360.0)?0:rot_angle_x + ROT_INC/(2*3.1416);
glutPostRedisplay();

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Ejercicio propuesto

Modificar sphere-rebotes-multi

Luz direccional, blanca, situada en el infinito, en una


posicin apuntada por (1,1,1)
Cada esfera con un color aleatorio, definido por las
caractersticas ambiental y difusa del material
El cubo no debe verse afectado por la luz al dibujarse

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminacin

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Coordenadas de textura

Permiten saber qu partes de una imagen se


dibujan en un polgono
Se representan por nmeros reales de 0 a 1

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Si queremos dibujar un tringulo con una


textura

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Aplicar las texturas


1
2
3
4

Creamos la textura
Definimos las condiciones en las que se va a
aplicar la textura
Habilitar la aplicacin de texturas
Dibujar las escenas, proporcionando las
coordenadas de textura

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Aplicar las texturas (ejemplo del mapeado)

Creacin de la texura

Obtenemos un identificador para la textura


int texture;
glGenTextures(1,&texture);

Declaramos la textura como textura activa

glBindTexture(GL_TEXTURE_2D, texture);

Creamos la textura

gluBuild2DMipmaps( GL_TEXTURE_2D, gimp_image.bytes_per_pixel,


gimp_image.width, gimp_image.height,GL_RGB, GL_UNSIGNED_BYTE,
gimp_image.pixel_data );
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Aplicar las texturas

Creacin de la textura

Hemos usado un archivo c del Gimp

static const struct {


unsigned int width;
unsigned int height;
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
unsigned char pixel_data[128 * 128 * 3 + 1];
} gimp_image = {
128, 128, 3, [...] }

Definir las condiciones en las que se aplicar la


textura

glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );


Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Diferencia GL_REPLACE Y GL_MODULATE

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Aplicar las texturas

Habilitar la aplicacin de texturas

Mediante glEnable(GL_TEXTURE_2D);

Dibujar, proporcionando las coordenadas de textura


glBegin(GL_TRIANGLES);
glTexCoord2d(0.0,1.0);
glVertex3f(-0.5,-0.5,0.5);
glTexCoord2d(1.0,1.0);
glVertex3f(0.5,-0.5,0.5);
glTexCoord2d(0.5,0.0);
glVertex3f(0.0,0.5,0.5);
glEnd();

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Aplicar las texturas

Para cambiar la textura activa

glBindTexture(GL_TEXTURE_2D,texture);

Repeticin de texturas

Ejemplo: Suelo y pared con estas texturas

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Repeticin de texturas

Para el suelo
glBindTexture(GL_TEXTURE_2D,texture_floor);
glBegin(GL_QUADS);
glTexCoord2d(0.0,0.0);
glVertex3f(-6.0,0.0,-6.0);
glTexCoord2d(0.0,1.0);
glVertex3f(-6.0,0.0,6.0);
glTexCoord2d(1.0,1.0);
glVertex3f(6.0,0.0,6.0);
glTexCoord2d(1.0,0.0);
glVertex3f(6.0,0.0,-6.0);
glEnd();
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Repeticin de texturas

Para la pared
glBindTexture(GL_TEXTURE_2D,texture_wall);
glBegin(GL_QUADS);
glTexCoord2d(0.0,0.0);
glVertex3f(-6.0,4.0,-6.0);
glTexCoord2d(0.0,1.0);
glVertex3f(-6.0,0.0,-6.0);
glTexCoord2d(1.0,1.0);
glVertex3f(6.0,0.0,-6.0);
glTexCoord2d(1.0,0.0);
glVertex3f(6.0,4.0,-6.0);
glEnd();
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Repeticin de texturas
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

El nuevo mapeo del suelo


glBindTexture(GL_TEXTURE_2D,texture_floor);
glBegin(GL_QUADS);
glTexCoord2d(0.0,0.0);
glVertex3f(-6.0,0.0,-6.0);
glTexCoord2d(0.0,6.0);
glVertex3f(-6.0,0.0,6.0);
glTexCoord2d(6.0,6.0);
glVertex3f(6.0,0.0,6.0);
glTexCoord2d(6.0,0.0);
glVertex3f(6.0,0.0,-6.0);
glEnd();

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Repeticin de texturas

El nuevo mapeo de la pared


glBindTexture(GL_TEXTURE_2D,texture_wall);
glBegin(GL_QUADS);
glTexCoord2d(0.0,0.0);
glVertex3f(-6.0,4.0,-6.0);
glTexCoord2d(0.0,1.0);
glVertex3f(-6.0,0.0,-6.0);
glTexCoord2d(3.0,1.0);
glVertex3f(6.0,0.0,-6.0);
glTexCoord2d(3.0,0.0);
glVertex3f(6.0,4.0,-6.0);
glEnd();

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interaccin bsica con Glut

Interactuar con las ventanas

Funciones de CALLBACK

Registrar funciones en Glut

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interaccin bsica con Glut

Interaccin con el teclado

Modificacin de lit-sphere

Registrar el evento de teclado con la funcin

glutSpecialFunc(void (*func)(int key, int x, int y));

Variables globales

rot_angle_x, rot_angle_y

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interaccin bsica con Glut

Modificacin de lit-sphere

Cdigo de la funcin declarada en glutSpecialFunc


void specialKeys(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_UP: rot_angle_x--;
break;
case GLUT_KEY_DOWN: rot_angle_x++;
break;
case GLUT_KEY_RIGHT: rot_angle_y++;
break;
case GLUT_KEY_LEFT: rot_angle_y--;
break;
}
glutPostRedisplay();
}
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interaccin bsica con Glut

Modificacin de lit-sphere

Para que al pulsar Esc se salga del programa

Utilizamos glutKeyboardFunc(), que recibe puntero a


static void keys(unsigned char key, int x, int y)
{
switch (key)
{
case 27: exit(0);
break;
}
glutPostRedisplay();
}

Damos de alta los dos nuevos manejadores de eventos


glutSpecialFunc(specialKeys);
glutKeyboardFunc(keys);
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interaccin bsica con Glut

Modificacin de lit-sphere

Redimensionado de la ventana

Usamos la funcin de CALLBACK glutReshapeFunc


void reshape(int width, int height)
{
GLfloat h = (GLfloat) height / (GLfloat) width;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0,h,1.0,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-5.0);
glutPostRedisplay();
}
Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interaccin bsica con Glut

Modificacin de lit-sphere

Al pulsar f queremos pasar a modo pantalla


completa/modo ventana
case 'f': if (windowed == 1){glutFullScreen(); windowed = 0;}
else{
glutPositionWindow ( 20 , 20 );
glutReshapeWindow ( 350,350);
windowed = 1;
}
break;

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Recursos de inters

Red Book: bsico para empezar


The OpenGL Utility Toolkit (GLUT)
Programming Inteface: todo sobre Glut
Los tutoriales de nehe (nehe.gamedev.net):
programacin de juegos
David Henry's homepage: http://tfc.duke.free.fr/

Roberto Garrido (Ro) - ESIDE e-ghost 2006

También podría gustarte