Intro OpenGL

110
Programación 3D con OpenGL bajo GNU/Linux Roberto Garrido Martín (Ro) e-ghost ESIDE's GNU Hi-tech and Open Source Team

Transcript of Intro OpenGL

Page 1: Intro OpenGL

Programación 3D con OpenGL bajo GNU/Linux

Roberto Garrido Martín (Ro)e-ghost

ESIDE's GNU Hi-tech and Open Source Team

Page 2: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Índice

1. Introducción2. OpenGL y GNU/Linux3. Conceptos básicos sobre OpenGL4. Animaciones5. Iluminación6. Texturas7. Interacción con el teclado

Page 3: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Introducción

● Objetivo del cursillo● ¿A quién va dirigido?● Recursos del cursillo

Page 4: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

● La librería OpenGL– Estándar creado por Silicon Graphics en 1992– Versión 2.0

Page 5: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

● La librería OpenGL– Tres partes funcionales

● La librería OpenGL● La librería GLU● GLX● Además, GLUT

Page 6: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

● GNU/Linux y OpenGL– La librería Mesa

● Es Libre● Es una implementación software, excepto para ciertas

tarjetas, que usan el driver Mesa/Glide:– Voodoo1, Voodoo2, Voodoo Rush, Voodoo Banshee, Voodoo3

● Versión 6.5, que implementa OpenGL 1.5 (la implementación de especificación 2.0 está en camino)

Page 7: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

● GNU/Linux y OpenGL– Xlibmesa

● Proporciona acceso a la aceleración gráfica por hardware, a través 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 versión 4, y hoy en las de Xorg

– Tarjetas NVIDIA, con su propia implementación de la librería OpenGL

● Se usa conjuntamente con Mesa (GLU)

Page 8: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

● GNU/Linux y OpenGL(en resumen):

Page 9: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

OpenGL y GNU/Linux

● ¿Qué necesitamos para programar con OpenGL bajo GNU/Linux?– Binarios de la librería OpenGL (Mesa, xlibmesa, o

drivers propietarios)– Paquetes de desarrollo de estas librerías (código

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, ...)

Page 10: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● OpenGL como máquina de estados– Activar y desactivar opciones y realizar acciones,

que tendrán como objetivo una representación en pantalla

– No es lo mismo dibujar un triángulo y activar una textura, que activar una textura y dibujar un triángulo

– Rotar y transladar algo, es distinto que transladarlo y rotarlo

● El orden en OpenGL es crítico en la mayoría de los casos

Page 11: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● OpenGL como máquina de estados● En general, para dibujar un objeto:

1Activar opciones persistentes a la escena (luces, posicionar cámara)

2Activar las opciones de un objeto específico (su posición, textura)

3Dibujar el objeto

4Desactivar las opciones del objeto (volver a la posición anterior, desactivar su textura)

5Y volver al punto 2 hasta haber dibujado todos los objetos (siguiendo una jerarquía)

Page 12: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● El espacio 3D– Cuatro dimensiones (x,y,z,w)

– Sistema de coordenadas inicial

Y

X

Z

1 0 0 00 1 0 00 0 1 00 0 0 1

Page 13: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● El espacio 3D– Transformaciones de objetos

● Translación

Page 14: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● El espacio 3D– Transformaciones de objetos

● Rotación

Page 15: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● El espacio 3D– Transformaciones de objetos

● Escalado

Page 16: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● El espacio 3D– Transformaciones de objetos

● Toda transformación construye una matriz de cuatro dimensiones que se multiplicará por la matriz de transformación actual

● Al transladar un objeto 3 unidades en el eje X:

1 0 0 30 1 0 00 0 1 00 0 0 1

Page 17: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL● El espacio 3D

– Transformaciones de objetos● Si aplicamos dicha transformación a la transformación

inicial, obtenemos:

● Si ahora dibujamos el punto (1,0,0), quedará desplazado, de la siguiente forma:

1 0 0 00 1 0 00 0 1 00 0 0 1

1 0 0 30 1 0 00 0 1 00 0 0 1

1 0 0 30 1 0 00 0 1 00 0 0 1

1 0 0 30 1 0 00 0 1 00 0 0 1

4001

1 0 0 1

Page 18: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● El espacio 3D– Las coordenadas homogéneas

● Varias razones:– Uniformidad de operaciones con matrices– Conceptos relativos a profundidad

● Son cuatro coordenadas, de forma que:– 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 homogéneas es

equivalente al punto 3D (x/w,y/w,z/w)● Si w=0, punto en el infinito con dirección (x,y,z)

Page 19: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Sobre Glut– Funciones para la creación de ventanas

independiente de plataforma– Lo veremos en los ejemplos– Funciones de callback

● Las funciones básicas de OpenGL– Activación/Desactivación de opciones

● glEnable(<OPTION>), glDisable(<OPTION>)– glEnable(GL_LIGHTING)

Page 20: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Las funciones básicas de OpenGL– Las matrices y OpenGL

● Transformación de objetos: matriz de visualización/modelado

● Matriz de proyección: información de la “cámara”● Cambiar modo de matriz:

– glMatrixMode(GL_PROJECTION)– glMatrixMode(GL_MODELVIEW)

● Guardar y restaurar valores en la pila– glPopMatrix() y glPushMatrix()

Page 21: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Las funciones básicas de OpenGL– Las matrices y OpenGL

● Para dibujar jerarquías de objetos

● glLoadIdentity() carga la matriz unidad

<transformación común para la escena>glPushMatrix();

<transformación propia del elemento 1><dibujado del elemento 1>

glPopMatrix(); // Volvemos a la transformación comúnglPushMatrix();

<transformación propia del elemento 2><dibujado del elemento 2>

glPopMatrix(); // Volvemos a la transformación común...

Page 22: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Las funciones básicas de Opengl– El dibujado en OpenGL

● Para dibujar en OpenGL:– Habilitar modo de dibujado– Establecer opciones de dibujado de cada vértice– Dibujar cada vértice– Finalizar el modo de dibujado

● glBegin(<MODO_DE_DIBUJADO>)

Page 23: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGLParámetro Descripción

GL_POINTS Se dibujan vértices separadosGL_LINES Cada par de vértices se interpreta como una líneaGL_POLYGON Los vértices describen el contorno de un polígonoGL_TRIANGLES Cada triplete de vértices de interpreta como un triánguloGL_QUADS Cada cuarteto de vértices se interpreta como un

cuadriláteroGL_LINE_STRIP Líneas conectadasGL_LINE_LOOP Líneas conectadas, con unión entre el primer y último

vérticeGL_TRIANGLE_STRIP Se dibuja un triángulo, y cada nuevo vértice se interpreta

con un triángulo entre los dos anteriores vértices y el nuevoGL_TRIANGLE_FAN Se dibujan triángulos con un vértice comúnGL_QUAD_STRIP Igual que el TRIANGLE_STRIP, con cuadriláteros

Page 24: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Las funciones básicas de Opengl– El dibujado en OpenGL

● Establecer atributos de cada vértice:– Color: glColor*– Normal: glNormal*– Coordenadas de textura: glTexCoor*

● Dibujado de vértices:– glVertex*

Page 25: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Las funciones básicas de Opengl– El color en OpenGL

● Modos RGBA e Indexado– La orientación de las caras en OpenGL

● Cara delantera: orden antihorario

1

3

2

4

Page 26: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Las funciones básicas 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

Page 27: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Las funciones básicas de Opengl● La proyección en OpenGL

● Cómo afecta la posición de un objeto a su visualización● Proyección ortográfica

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

Page 28: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Las funciones básicas de Opengl– La proyección en OpenGL

● Proyección perspectiva● gluPerspective()

Page 29: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Primer contacto con OpenGL ;)– Mi primer programa en OpenGL

● Includes#include <GL/glut.h>

● Función mainint 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;

}

Page 30: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Mi primer programa en OpenGL– Función display

void display(void){glClearColor(0.0,0.0,0.0,0.0);// Color de fondo: negroglClear(GL_COLOR_BUFFER_BIT);// Boramos la pantallaglMatrixMode(GL_PROJECTION);// Modo proyecciónglLoadIdentity();// Cargamos la matriz identidadglOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);// Proyección ortográfica, dentro del cubo señaladoglMatrixMode(GL_MODELVIEW);// Modo de modelado

Page 31: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Mi primer programa en OpenGL– Función display

glBegin(GL_TRIANGLES);// Dibujamos un triánguloglColor3f(1.0,0.0,0.0);// Color del primer vértice: rojoglVertex3f(0.0,0.8,0.0);// Coordenadas del primer vérticeglColor3f(0.0,1.0,0.0);// Color del segundo vértice: verdeglVertex3f(-0.6,-0.2,0.0);// Coordenadas del segundo vérticeglColor3f(0.0,0.0,1.0);// Color del tercer vértice: azúlglVertex3f(0.6,-0.2,0.0);// Coordenadas del tercer vértice

glEnd();// Terminamos de dibujarglFlush();// Forzamos el dibujadosleep(10);// Esperamos 10 segundosexit(0);// Salimos del programa}

Page 32: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos 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 triángulo– Compilamos:

– Ejecutamos:

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

roberto@garridocuarto:~$./myfirstopenglprogram

Page 33: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Mi primer programa en OpenGL

Page 34: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Primer contacto con OpenGL– Visualizando en perspectiva...

● Código de dibujadoglBegin(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 vértice (superior-izquierda) glVertex3f(-0.5,-0.5,0.5); // Coordenadas del segundo vértice (inferior-izquierda) glVertex3f(0.5,-0.5,0.5); // Coordenadas del primer vértice (inferior-derecha) glVertex3f(0.5,0.5,-0.5); // Coordenadas del primer vértice (superior-derecha)glEnd();// Termina

Page 35: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Visualizando en perspectiva...– Guardamos y ejecutamos

Page 36: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Visualizando en perspectiva...– Primera modificación

– Segunda modificación

gluPerspective(60.0,1.0,1.0,100.0);// Proyección perspectiva. El ángulo de visualización es de 60 grados, la razón ancho/alto es 1 (son inguales), la distancia mínima es z=1.0, y la distancia máxima es z=100.0

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

Page 37: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Visualizando en perspectiva...

Page 38: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Primer contacto con OpenGL– Ocultación de objetos (Z-Buffer)

● Añadimos el triángulo (0.0, 0.5, 0.0), (-0.7, -0.5, 0.0),(0.7, -0.5, 0.0)

Page 39: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Ocultación de objetos (Z-Buffer)– Añadimos antes del dibujado

– Con glEnable(GL_DEPTH_TEST) habilitamos la comprobación 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 z-buffer, se inicializan sus posiciones al valor 1.0

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

Page 40: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Ocultación 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);

Page 41: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Ocultación de objetos (Z-Buffer)

Page 42: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Primer contacto con OpenGL– Jerarquías

● El ejemplo del cuerpo humano● Se usan pilas de matrices

1. Se sitúa el elemento principal

2. Se dibuja el elemento principal3. Se apila la matriz actual (glPushMatrix)4. Se sitúa el primer elemento secundario con respecto al primero5. Se dibuja el primer elemento secundario6. Vuelta a la situación del elemento principal (glPopMatrix)7. Se repite para los demás elementos secundarios

Page 43: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Jerarquías– Programa que dibuja un cuadrado y cuatro

secundarios– Función 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();}

Page 44: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL● Jerarquías

– Para dibujar la jerarquía, 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();...

Page 45: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Jerarquías

Page 46: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Jerarquías– De manera recursiva

Page 47: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Jerarquías– Figura humanoide a base de cubos ;)

● Primero, alejamos la cámara– glTranslatef(0,0,-16.0);

● Situamos el cuerpo y lo dibujamosglTranslatef(0,BODY_HEIGHT/2,0);glPushMatrix(); glScalef(BODY_WIDTH,BODY_HEIGHT,BODY_LENGTH); glColor3f(0.0,0.3,0.8); glutSolidCube(1);glPopMatrix();

Page 48: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos 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();

Page 49: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Dibujamos el resto del cuerpo de la misma forma (ver código 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();

Page 50: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Conceptos básicos sobre OpenGL

● Jerarquías– Figura humanoide

Page 51: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Para animar una figura

1 Actualizar los datos de la figura

2 Borrar la pantalla

3 Dibujar la figura

4 Volver al punto 1

Page 52: Intro OpenGL

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 posición y otro de dirección

Page 53: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Ejemplo de la esfera que rebota dentro de un cubo

Page 54: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Esquema de dibujado– Comprobar que la esfera no esté en el límite del

cubo● Si está: invertir la componente del vector de dirección

correspondiente al lado con el que ha rebotado– Sumar el vector de dirección al vector de posición

de la esfera– Dibujar la esfera– Volver al comienzo del bucle

Page 55: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Definición de la clase TSphereMétodos Función

TSphere (float maxpos, float speed); Crea una instancia de la clase. La esferarebotará si llega a la posción +-”maxpos”,y tendrá una velocidad “speed”. Susituación y dirección iniciales sonaleatorias

void test(); Comprueba que la figura esté dentro delos márgenes, y si no le está, corregirá sudirección. Después, actualiza su posción

void modifySpeed(float inc); Incrementa la velocidad en “inc”float * getPosv(); Obtiene un vector con la posición de la

esfera (en la posición 0, la coordenada X,en la 1 la Y, y en la 2 la Z)

Page 56: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Funciones de glut– glutDisplayFunc()– glutIdleFunc()

● Variables globales– float * pos;– TSphere * sphere;

Page 57: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Función de inicialización initgl

● gluLookAt: posición de la cámara + posición a la que apunta, parte superior de la escena

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);

}

Page 58: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Función displayvoid 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();}

Page 59: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Función idle

● Registramos estas funciones en la función main

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

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

Page 60: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● El doble buffering– Dibujar la escena en un buffer fuera de la pantalla,

mientras la imágen 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 función display● glutSwapBuffers();

Page 61: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Sphere-rebotes con doble buffering

Page 62: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Animaciones

● Con una pequeña modificación

Page 63: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Permite crear escenas más realistas● Cada implementación al menos 8 luces● No es recomendable abusar de éstas

Page 64: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● El modelo de iluminación 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

Page 65: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● 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 iluminación

global de una escena

Page 66: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● 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 vértices● Normales

– Para saber cómo incide una luz sobre un vértice– Vector generalmente perpendicular a la cara que

estamos dibujando

Page 67: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Misma luz, mismo objeto, normales cambiadas

Page 68: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Utlizando la iluminación en OpenGL– Luces

● Primer paso, activar la iluminación– 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*()

Page 69: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Luces– Propiedades de las luces

● Posición/Dirección– Puntuales– Focales

Page 70: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Posición/Dirección– glLightfv(GL_LIGHTn,GL_POSITION,val_ptr);

● 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

● Dirección del foco– glLightfv(GL_LIGHTn,GL_SPOT_DIRECTION,val_prt);

● Apertura del foco– glLightf(GL_LIGHTn,GL_SPOT_CUTOFF,val);

● val está expresado en grados

Page 71: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Atenuación 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

Page 72: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Atenuación de la luz– Pérdida de intensidad de la luz a medida que nos

alejamos del foco– glLightf(GL_LIGHTn,GL_[CONSTANT|LINEAR|

QUADRATIC]_ATTENUATION,val);– El factor de atenuación se calcula mediante:

– Una vez establecidas las propiedades de una luz● glEnable(GL_LIGHTn);

Page 73: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Materiales– Características del material: glMaterial*(), 3

parámetros● Caras del polígono a las que afecta: GL_FRONT,

GL_BACK, GL_FRONT_AND_BACK● Característica que estamos definiendo (color, brillo)● Valor de la característica

– Color del material● Define su comportamiento ante los tipos distintos de luz● Color ambiental, difuso y especular● Color emitido

Page 74: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● 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);

Page 75: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Materiales– Podemos cambiar estos valores con la función

glColorMaterial ()● Hay que activarla con

glEnable(GL_COLOR_MATERIAL);● Establecemos la propiedad a cambiar

– glColorMaterial(GL_FRONT[_AND_BACK],[GL_AMBIENT|GL_DIFUSSE|GL_AMBIENT_AND_DIFUSSE|GL_SPECULAR]);

● Cambiamos el color reflejado de ese tipo de luz– glColor3f(r_val,g_val,b_val);

● Debemos desactivar esta opción tras utilizarla

Page 76: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Ejemplo: Iluminación direccional sobre una superficie (ejemplo de las normales)

● Arrays a definir– Color ambiental y difuso del material

● GLfloat mat_color [] = {0.0,1.0,1.0,1.0};– Color difuso y especular de la luz

● 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};

Page 77: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Arrays a definir– Valor de las normales

● GLfloat normal [] = {0.0,1.0,0.0};– Valor de la dirección de la luz

● GLfloat light_dir [] = {0.0,1.0,0.0,0.0};● Seleccionamos el color de fondo, y borramos la

pantallaglClearColor(0.0,0.0,0.0,0.0);glClear(GL_COLOR_BUFFER_BIT);

Page 78: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Activamos la luz, y sus características, excepto la dirección

● Seleccionamos el color del material:– glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFF

USE,mat_color);

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);

Page 79: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Establecemos la perspectiva y posicionamos al observador

● Establecemos la dirección de la luz– glLightfv(GL_LIGHT0,GL_POSITION,light_dir);

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

Page 80: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● 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);glEnd();

Page 81: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Forzamos el dibujado, esperamos, y salimos del programa

● Ejemplo: moviendo un foco alrededor de una esfera– Utilizaremos dibujado con doble buffer, y zBuffer

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

Page 82: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Definimos las características de la luz

● Características del material de la esfera

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;

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;

Page 83: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Ponemos un pequeño cono cuyo material tenga una “emisión” similar al color de la luz– float focus_emission [] = {0.8,0.8,0.8,1.0};

● Variables que indican la rotación del foco

● Habilitamos el zBuffer y establecemos el color de fondo

float rot_angle_y = 0.0;float rot_angle_x = 0.0;

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

Page 84: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Activamos las luces y sus características

● Establecemos el material de la esfera

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);

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

Page 85: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Establecemos la perspectiva y trasladamos la cámara

● Estos pasos los englobamos en una función de inicialización

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

Page 86: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Bucle de dibujadoglClear(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();

Page 87: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Entre frame y frame, rotamos el focorot_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();

Page 88: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

● Ejercicio propuesto– Modificar “sphere-rebotes-multi”

● Luz direccional, blanca, situada en el infinito, en una posición apuntada por (1,1,1)

● Cada esfera con un color aleatorio, definido por las características ambiental y difusa del material

● El cubo no debe verse afectado por la luz al dibujarse

Page 89: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Iluminación

Page 90: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Coordenadas de textura– Permiten saber qué partes de una imagen se

dibujan en un polígono– Se representan por números reales de 0 a 1

Page 91: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Si queremos dibujar un triángulo con una textura

Page 92: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Aplicar las texturas

1 Creamos la textura

2 Definimos las condiciones en las que se va a aplicar la textura

3 Habilitar la aplicación de texturas

4 Dibujar las escenas, proporcionando las coordenadas de textura

Page 93: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

int texture;glGenTextures(1,&texture);

gluBuild2DMipmaps( GL_TEXTURE_2D, gimp_image.bytes_per_pixel,gimp_image.width, gimp_image.height,GL_RGB, GL_UNSIGNED_BYTE,gimp_image.pixel_data );

● Aplicar las texturas (ejemplo del mapeado)– Creación de la texura

● Obtenemos un identificador para la textura

● Declaramos la textura como textura activa– glBindTexture(GL_TEXTURE_2D, texture);

● Creamos la textura

Page 94: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Aplicar las texturas– Creación de la textura

● Hemos usado un archivo “c” del Gimp

– Definir las condiciones en las que se aplicará la textura

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, [...] }

glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

Page 95: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Diferencia GL_REPLACE Y GL_MODULATE

Page 96: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Aplicar las texturas– Habilitar la aplicación 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();

Page 97: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Aplicar las texturas– Para cambiar la textura activa

● glBindTexture(GL_TEXTURE_2D,texture);● Repetición de texturas

– Ejemplo: Suelo y pared con estas texturas

Page 98: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Repetición 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();

Page 99: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Repetición 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();

Page 100: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Page 101: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Repetición de texturas

– El nuevo mapeo del suelo

glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

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();

Page 102: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

● Repetición 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();

Page 103: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Texturas

Page 104: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interacción básica con Glut

● Interactuar con las ventanas● Funciones de CALLBACK● Registrar funciones en Glut

Page 105: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interacción básica con Glut

● Interacción con el teclado– Modificación de “lit-sphere”

● Registrar el evento de teclado con la función– glutSpecialFunc(void (*func)(int key, int x, int y));

● Variables globales– rot_angle_x, rot_angle_y

Page 106: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interacción básica con Glut

● Modificación de “lit-sphere”– Código de la función 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();}

Page 107: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interacción básica con Glut

● Modificación de “lit-sphere”– Para que al pulsar Esc se salga del programa

● Utilizamos glutKeyboardFunc(), que recibe puntero a

● Damos de alta los dos nuevos manejadores de eventos

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

glutSpecialFunc(specialKeys);glutKeyboardFunc(keys);

Page 108: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interacción básica con Glut

● Modificación de “lit-sphere”– Redimensionado de la ventana

● Usamos la función 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();}

Page 109: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Interacción básica con Glut

● Modificación de “lit-sphere”– Al pulsar “f” queremos pasar a modo pantalla

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

Page 110: Intro OpenGL

Roberto Garrido (Ro) - ESIDE e-ghost 2006

Recursos de interés

● Red Book: básico para empezar● The OpenGL Utility Toolkit (GLUT)

Programming Inteface: todo sobre Glut● Los tutoriales de nehe (nehe.gamedev.net):

programación de juegos● David Henry's homepage: http://tfc.duke.free.fr/