Descargar la presentación
La descarga está en progreso. Por favor, espere
Publicada porJoaquín Rivas Ferreyra Modificado hace 8 años
1
Programación 3D con OpenGL bajo GNU/Linux Roberto Garrido Martín (Ro) e-ghost ESIDE's GNU Hi-tech and Open Source Team
2
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Índice 1. Introducción 2. OpenGL y GNU/Linux 3. Conceptos básicos sobre OpenGL 4. Animaciones 5. Iluminación 6. Texturas 7. Interacción con el teclado
3
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Introducción ● Objetivo del cursillo ● ¿A quién va dirigido? ● Recursos del cursillo
4
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
5
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
6
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)
7
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)
8
Roberto Garrido (Ro) - ESIDE e-ghost 2006 OpenGL y GNU/Linux ● GNU/Linux y OpenGL(en resumen):
9
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,...)
10
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
11
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● OpenGL como máquina de estados ● En general, para dibujar un objeto: 1. Activar opciones persistentes a la escena (luces, posicionar cámara) 2. Activar las opciones de un objeto específico (su posición, textura) 3. Dibujar el objeto 4. Desactivar las opciones del objeto (volver a la posición anterior, desactivar su textura) 5. Y volver al punto 2 hasta haber dibujado todos los objetos (siguiendo una jerarquía)
12
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 0 0 1 0 0 0 0 1 0 0 0 0 1
13
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● El espacio 3D – Transformaciones de objetos ● Translación
14
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● El espacio 3D – Transformaciones de objetos ● Rotación
15
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● El espacio 3D – Transformaciones de objetos ● Escalado
16
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 3 0 1 0 0 0 0 1 0 0 0 0 1
17
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 0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 3 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 3 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 3 0 1 0 0 0 0 1 0 0 0 0 1 40014001 10011001
18
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)
19
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( ), glDisable( ) – glEnable(GL_LIGHTING)
20
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()
21
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 glPushMatrix(); glPopMatrix(); // Volvemos a la transformación común glPushMatrix(); glPopMatrix(); // Volvemos a la transformación común...
22
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( )
23
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL
24
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*
25
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
26
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
27
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);
28
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()
29
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Primer contacto con OpenGL ;) – Mi primer programa en OpenGL ● Includes #include ● Función 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; }
30
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: negro glClear(GL_COLOR_BUFFER_BIT); // Boramos la pantalla glMatrixMode(GL_PROJECTION); // Modo proyección glLoadIdentity(); // Cargamos la matriz identidad glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0); // Proyección ortográfica, dentro del cubo señalado glMatrixMode(GL_MODELVIEW); // Modo de modelado
31
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Mi primer programa en OpenGL – Función display
32
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
33
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Mi primer programa en OpenGL
34
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Primer contacto con OpenGL – Visualizando en perspectiva... ● Código 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 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
35
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Visualizando en perspectiva... – Guardamos y ejecutamos
36
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
37
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Visualizando en perspectiva...
38
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)
39
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);
40
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);
41
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Ocultación de objetos (Z-Buffer)
42
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 principal 3. Se apila la matriz actual (glPushMatrix) 4. Se sitúa el primer elemento secundario con respecto al primero 5. Se dibuja el primer elemento secundario 6. Vuelta a la situación del elemento principal (glPopMatrix) 7. Se repite para los demás elementos secundarios
43
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(); }
44
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();...
45
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Jerarquías
46
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Jerarquías – De manera recursiva
47
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 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();
48
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();
49
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();
50
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Conceptos básicos sobre OpenGL ● Jerarquías – Figura humanoide
51
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
52
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
53
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Animaciones ● Ejemplo de la esfera que rebota dentro de un cubo
54
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
55
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Animaciones ● Definición de la clase TSphere
56
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Animaciones ● Funciones de glut – glutDisplayFunc() – glutIdleFunc() ● Variables globales – float * pos; – TSphere * sphere;
57
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); }
58
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Animaciones ● Función 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(); }
59
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);
60
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();
61
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Animaciones ● Sphere-rebotes con doble buffering
62
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Animaciones ● Con una pequeña modificación
63
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
64
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
65
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
66
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
67
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Iluminación ● Misma luz, mismo objeto, normales cambiadas
68
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*()
69
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Iluminación ● Luces – Propiedades de las luces ● Posición/Dirección – Puntuales – Focales
70
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
71
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|SP ECULAR],val_ptr); ● val_ptr es puntero a vector de 4 componentes RGBA
72
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|QU ADRATIC]_ATTENUATION,val); – El factor de atenuación se calcula mediante: – Una vez establecidas las propiedades de una luz ● glEnable(GL_LIGHTn);
73
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
74
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|G L_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);
75
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_D IFUSSE|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
76
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};
77
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 pantalla glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT);
78
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);
79
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);
80
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();
81
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);
82
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;
83
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);
84
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);
85
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);
86
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Iluminación ● 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();
87
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Iluminación ● 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();
88
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
89
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Iluminación
90
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
91
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Texturas ● Si queremos dibujar un triángulo con una textura
92
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
93
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
94
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 );
95
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Texturas ● Diferencia GL_REPLACE Y GL_MODULATE
96
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();
97
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
98
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();
99
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();
100
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Texturas
101
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();
102
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();
103
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Texturas
104
Roberto Garrido (Ro) - ESIDE e-ghost 2006 Interacción básica con Glut ● Interactuar con las ventanas ● Funciones de CALLBACK ● Registrar funciones en Glut
105
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
106
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(); }
107
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);
108
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(); }
109
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 ventana case 'f': if (windowed == 1){glutFullScreen(); windowed = 0;} else{ glutPositionWindow ( 20, 20 ); glutReshapeWindow ( 350,350); windowed = 1; } break;
110
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/
Presentaciones similares
© 2025 SlidePlayer.es Inc.
All rights reserved.