OpenGL Qu es OpenGL? Open Graphics Library Una interfaz con el hardware grfico Arquitectura cliente/servidor Independiente del hardware Un conjunto de funciones que permiten definir, crear y modificar grficos Orientado a grficos 3D Permite simplificar la obtencin de imgenes a partir de modelos 3D Domingo Martn Perandrs OpenGL Es una mquina de estados Puede operar en modo Inmediato La informacin de los elementos grficos no es almacenada por OpenGL Retenido La informacin de los elementos grficos es almacenada por OpenGL Estructuracin Jerarquizacin Domingo Martn Perandrs OpenGL Mesa3D Mesa3D es una versin libre de OpenGL (Brian Paul) El proceso de visualizacin es realizado por software (+lento) Multi plataforma Multi sistema operativo Domingo Martn Perandrs OpenGL Mesa3D Se acompaa de unas funciontecas auxiliares GLU Implementa ciertas operaciones no soportadas directamente por OpenGL Curvas Objetos Etc. Domingo Martn Perandrs OpenGL Mesa3D Glut Permite la creacin de aplicaciones interactivas orientadas a eventos Objetos Creacin de ventanas, mens Control de dispositivos Domingo Martn Perandrs OpenGL Compilando Mesa3D Obtener ultima versin Descomprimir y desempaquetar Ejecutar make Seleccionar opcin make linux-x86 Indicar directorio de las funciontecas de Mesa en la variable de entorno LD_LIBRARY_PATH Domingo Martn Perandrs OpenGL Compilando Mesa3D Normalmente se mete una orden en el fichero .bashrc export LD_LIBRARY_PATH=/directorio/Mesa-x.x/lib Domingo Martn Perandrs OpenGL Creando una ventana #include <GL/gl.h> #include <glaux.h> #include <gltk.h> #include <stdio.h> #define parar getchar() int main(&argc, argv) { int XMinimoVentanaX,YMinimoVentanaX,XTamanioVentanaX,YTamanioVentanaX; char NombreVentana[]={"Inicio"}; // Valores de la posicion y del tamao la ventana, en pixeles (sistema c. izquierdo) int Ventana_x=50; int Ventana_y=50; int Ventana_ancho=300; int Ventana_alto=300; // Paso de parmetros glutInit(&argc, argv); // Caracteristicas que se desean para la visualizacion con OpenGL glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowPosition(Ventana_x,Ventana_y); glutInitWindowSize(Ventana_ancho,Ventana_alto); glutCreateWindow("Prctica 1") glutMainLoop(); return(true); } Domingo Martn Perandrs OpenGL Creando una ventana glutInitDisplayMode Indica las propiedades para visualizar y de la imagen GLUT_SIMPLE: slo la memoria de imagen delantera izquierda GLUT_DOUBLE: las memorias de imagen delantera izquierda y trasera izquierda GLUT_INDEX: representacin del color indirectamente GLUT_RGB: representacin del color con el modelo RVA GLUT_RGBA: representacin del color con el modelo RVA ms el canal alfa (transparencia) GLUT_DEPTH: memoria para valores de profundidad (eliminacin de partes ocultas, z-buffer) GLUT_STENCIL: memoria de estarcido Las distintas posibilidades se combinan mediante un OR, | Domingo Martn Perandrs OpenGL Creando una ventana glutInitWindowPosition Indica las coordenadas de las esquina superior izquierda de la ventana glutInitWindowSize Indica el tamao de la ventana glutCreateWindow Intenta crear una ventana con el nombre especificado glutMainLoop Entra en el bucle de eventos. Comienza el programa. Se crea la ventana Domingo Martn Perandrs OpenGL Primitivas grficas glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH); Inicia OpenGL con unasola memoria de image, con el modelo de color directo RVA-Al y habilitando el z-buffer glEnable(GL_DEPTH_TEST) Activa el z-buffer glClearDepth(1) Indica el valor asignado a la mxima profundidad glClearColor(1,1,1,1) Color para iniciar la ventana RVA-AL = Blanco glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) Indica que se inicialice la memoria de imagen y el z-buffer con los valores indicados previamente Domingo Martn Perandrs OpenGL Primitivas grficas Estructura glBegin(TIPO) + glEnd() Permite la definicin de las primitivas grficas (geometra) y sus atributos Los TIPOS permitidos son: GL_POINTS: los vrtices se representan como puntos individuales GL_LINES: cada pareja de vertices repesenta una lnea GL_LINE_STRIP: los vertices forman un secuencia abierta de lneas GL_LINE_LOOP: los vertices forman un secuencia cerrada de lneas GL_POLYGON: los vertices definen un polgono GL_QUADS: los vertices definen cuadrilateros GL_QUAD_STRIP: los vertices definen una tira de cuadrilateros GL_TRIANGLES: los vertices definen tringulos GL_TRIANGLE_STRIP: los vertices definen una tira de tringulos GL_TRIANGLE_FAN : los vertices definen un abanico de tringulos Domingo Martn Perandrs OpenGL Primitivas grficas Los vrtices se representan mediante: glVertex{dimension}{tipo}{vector} glVertex{2,3,4}{b,s,i,f,d,ub,us,ui}{v} b -> 8 bits -> entero con signo -> GLbyte s -> 16 bits -> entero con signo -> GLshort i -> 32 bits -> entero con signo -> GLint f -> 32 bits -> real -> Glfloat, GLclampf d -> 64 bits -> doble -> Gldouble, GLclampd ub -> 8 bits -> entero sin signo -> GLubyte,GLboolean us -> 16 bits -> entero sin signo -> GLuint,GLenum ui -> 32 bits -> entero sin signo -> Glbitfield v: se manda una direccin Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos glVertex2i(1,2) glVertex3i(1,2,4) glVertex3f(1.,2.2,43.56) glVertex4f(1.0,0.5,3.4,5) glVertex4fv(vector) -> GLfloat vector[4]={1.0,0.5,3.4,5} Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos glBegin(GL_POINTS) glVertex3f(0,0,0) glVertex3f(1,1,1) glEnd() glBegin(GL_LINES) glVertex3f(0,0,0) glVertex3f(1,1,1) glEnd() Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_POINTS Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_LINES Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_LINE_STRIP Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_LINE_LOOP Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_POLYGON Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_QUADS Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_QUAD_STRIP Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_TRIANGLES Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_TRIANGLE_STRIP Domingo Martn Perandrs OpenGL Primitivas grficas Ejemplos GL_TRIANGLE_FAN Domingo Martn Perandrs OpenGL Primitivas grficas Los polgonos pueden dibujarse de tres formas usando la misma geometra: Vrtices Frontera Interior Se usa la orden glPolygonMode(LADO_CARA,TIPO_ELEMENTO) LADO_CARA GL_FRONT: Lado exterior del polgono GL_BACK: Lado interior del polgono GL_FRONT_AND_BACK Domingo Martn Perandrs OpenGL Primitivas grficas TIPO_ELEMENTO GL_POINT: Slo se dibujan los vrtices GL_LINE: Slo se dibuja la frontera (lneas) GL_FILL: Slo se dibuja el interior (relleno) Ejemplo glColor3f(1,0,0); glPolygonMode(GL_FRONT,GL_POINT); glBegin(GL_POLYGON); dibujarListaPuntos(NumPuntosCirculo,Lista2); glEnd(); glColor3f(0,0,1); glPolygonMode(GL_FRONT,GL_LINE); glBegin(GL_POLYGON); dibujarListaPuntos(NumPuntosCirculo,Lista2); glEnd(); glColor3f(0,1,0); glPolygonMode(GL_FRONT,GL_FILL); glBegin(GL_POLYGON); dibujarListaPuntos(NumPuntosCirculo,Lista2); glEnd(); Domingo Martn Perandrs OpenGL Primitivas grficas Dado que OpenGL est diseado para trabajar en red, mediante un diseo cliente/servidor, intenta optimizar la transferencia de informacin mediante la compactacin de datos en bferes Slo se envian los datos cuando el bfer est lleno El estado de la imagen no tiene por qu coincidir con las ordenes mandadas! Solucin -> sincronizar glFlush() Domingo Martn Perandrs OpenGL Proyectando glMatrixMode(GL_PROJECTION) Indica con que pila de matrices se va a operar GL_PROJECTION: matrices para proyectar GL_MODELVIEW: matrices para transformar glLoadIdentity() Pone en la pila la matriz identidad Para una proyeccion de perspectiva glFrustum(XMinimoVentanaMundo,XMaximoVentanaMundo,YMinimoVentanaMundo, YMaximoVentanaMundo,PlanoDelantero>0,PlanoTrasero>PlanoDelantero) Define los parametros que permiten calcular la matriz que realiza una proyeccin de perspectiva Los planos delantero y trasero se dan como distancias, siendo positivas Domingo Martn Perandrs OpenGL Proyectando Para una proyeccin paralela glOrtho(XMinimoVentanaMundo,XMaximoVentanaMundo,YMinimoVentanaMundo, YMaximoVentanaMundo,PlanoDelantero,PlanoTrasero) Define los parametros que permiten calcular la matriz que realiza una proyeccin paralela Los planos delantero y trasero se dan como distancias, con respecto al observador que mira en la direccin negativa de las zetas Colocacin del observador-cmara glMatrixMode(GL_MODELVIEW) glLoadIdentity() Inicia la pila de transformaciones para modelado y vista glTranslatef(0,0,-5) Desplaza el objeto -5 unidades en el eje Z Domingo Martn Perandrs OpenGL Proyectando glTranslate{fd} f = float d = double Las transformaciones se pueden calcular de dos maneras dependiendo del sistema de coordenadas que se considere fijo ! Camara fija en el origen Desplaza el objeto -5 unidades en el eje Z Objeto fijo en el origen Desplaza el objeto 5 unidades en el eje Z Domingo Martn Perandrs OpenGL Proyectando Domingo Martn Perandrs OpenGL Proyectando Se pueden dibujar varios objetos predefinidos auxMODOOBJETO MODO Alambre: Wire Slido: Solid Domingo Martn Perandrs OpenGL Proyectando OBJETO Cube(tamao) Sphere(radio) Box(ancho,alto,profundidad) Torus(radio_interior,radio_exterior) Cylinder(radio,altura) Icosahedron(radio) Octahedron(radio) Tetrahedron(radio) Dodecahedron(radio) Cono(radio,altura) Teapot(tamao) Domingo Martn Perandrs OpenGL Proyectando Paralela Perspectiva Domingo Martn Perandrs OpenGL Es importante la orientacion: ejes Todo elemento grfico en OpenGL (vrtices, normales, etc. ) sufre las transformaciones definidas void dibujarEjes() { glBegin(GL_LINES); // eje X, color rojo glColor3f(1,0,0); glVertex3f(-10,0,0); glVertex3f(10,0,0); // eje Y, color verde glColor3f(0,1,0); glVertex3f(0,-10,0); glVertex3f(0,10,0); // eje Z, color azul glColor3f(0,0,1); glVertex3f(0,0,-10); glVertex3f(0,0,10); glEnd(); } Domingo Martn Perandrs OpenGL Orden de las transformaciones Las transformaciones en OpenGL estn basadas en un mecanismo de pilas (LIFO) Existen tres pilas GL_PROJECTION: Pila para la matriz con la transformacin de proyeccin GL_MODELVIEW: Pila para la matriz con la transformacin de modelado y vista GL_TEXTURE Domingo Martn Perandrs OpenGL Orden de las transformaciones Todos los elementos grficos sufren las transformaciones que se encuentran en lo alto (top) de las pilas El orden de aplicacin de las transformaciones es: -> Modelview -> Projection -> Domingo Martn Perandrs OpenGL Orden de las transformaciones Domingo Martn Perandrs MODELVIEW PROJECTION OpenGL Orden de las transformaciones Operaciones sobre las pilas glMatrixMode(PILA) Indica con que pila se va a operar, hacindola activa glLoadIdentity() Carga la matriz identidad en lo alto de la pila glLoadMatrix{fd}(M) Carga la matriz M en lo alto de la pila glMultMatrix{fd}(M) Multiplica la matriz que est en lo alto de la pila con M Domingo Martn Perandrs OpenGL Orden de las transformaciones Operaciones sobre las pilas glPushMatrix() Aumenta el puntero del tope de la pila activada Copia en el tope la matriz de la posicin anterior glPopMatrix() Decrementa el puntero del tope de la pila activada Domingo Martn Perandrs OpenGL Orden de las transformaciones Dada una pila activa, todas las trasformaciones que se definan se van acumulando a la que se encuentra en el tope de la misma Domingo Martn Perandrs T T1 T2 T3 OpenGL Orden de las transformaciones El orden es importante Al utilizar una pila -> El orden de aplicacin es el inverso al orden de escritura! glRotate() ->T1 glTranslate() ->T2 glScale() -> T3 Domingo Martn Perandrs T T1 T2 T3 OpenGL Orden de las transformaciones Definicin de la matriz En OpenGL 1.3 se puede usar el orden normal de C Domingo Martn Perandrs m1 m5 m9 m13 m2 m6 m10 m14 m3 m7 m11 m15 m4 m8 m12 m16 OpenGL Orden de las transformaciones glTranslate{fd}(x,y,z) Aplica una traslacin glScale{fd}(Fx,Fy,Fz) Aplica un escalado glRotate{fd}(ngulo,x,y,z) Aplica una rotacin de los grados indicados por ngulo con respecto al eje definido por las tres coordenadas Domingo Martn Perandrs OpenGL Movimiento objetos La multiplicacin de matrices no es conmutativa Para producir movimientos de cmara Escribir la transformacin de vista Escribir la transformacin de modelado Problema si slo se quiere modificar la cmara Hay que introducir las transformaciones de modelado aunque no cambien Domingo Martn Perandrs OpenGL Movimiento objetos Tcnica del doble bufer Se tienen dos memoria de imagen Evita el problema de la visualizacin del dibujado de la escena Mientras una se muestra en el dispositivo de salida, en la otra se esta creando la imagen auxInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); Domingo Martn Perandrs OpenGL Movimiento objetos No es necesario indicar el nmero de memoria de imagen Cambiar cuando se ha terminado de dibujar auxSwapBuffers() Domingo Martn Perandrs OpenGL Movimiento objetos Domingo Martn Perandrs SWAPBUFFERS OpenGL Viewport En general, la ventana no est ocupada nicamente por una aplicacin La ventana se divide en zonas de visin (viewports) El sistema coordenado es derecho Slo hay una zona de visin activa Domingo Martn Perandrs OpenGL Viewport glViewport(Xminimo,Yminimo,Ancho,Alto) Domingo Martn Perandrs Zona de visin Xmin Ymin Alto Ancho Zona de visin Zona de visin Zona de visin Zona de visin OpenGL Glut Funcionteca implementada sobre OpenGL Semejante a aux+tk Permite la creacin de aplicaciones interactivas controladas por eventos Evento: acto asncrono generado por el usuario o por el propio ordenador Permite la utilizacin de ventanas y mens Enlaza eventos con funciones mediante callbacks Domingo Martn Perandrs OpenGL Glut Eventos controlados por glut glutDisplayFunc(Funcin) Hay que redibujar la imagen glutReshapeFunc(Funcin) Se ha producido un cambio en tamao de la ventana glutKeyboardFunc(Funcin) Se ha pulsado una tecla normal glutSpecialFunc(Funcin) Se ha pulsado una tecla especial glutMouseFunc(Funcin) Se ha pulsado o soltado una tecla del ratn Domingo Martn Perandrs OpenGL Glut glutMotionFunc(Funcin) Se mueve el ratn con una tecla del ratn pulsada glutPassiveMotionFunc(Funcin) Se mueve el ratn sin una tecla del ratn pulsada glutVisibilityFunc(Funcin) La ventana cambia de estado de visibilidad glutEntryFunc(Funcin) El cursor entra o sale en la ventana glutIdleFunc(Funcin) Desocupado glutTimerFunc(Funcin) Un temporizador llega al final de la cuenta Domingo Martn Perandrs OpenGL Glut Es importante entender correctamente como y cuando ocurren los eventos Para pasar un programa de aux a glut normalmente basta con substituir el prefijo aux por glut, y cambiar las constantes Domingo Martn Perandrs OpenGL Glut_animacin Se hace uso de doble bufer Para generar la animacin se hace uso del evento desocupado (idle) Aumenta el ngulo en el paso especificado Domingo Martn Perandrs OpenGL Glut_animacin_menu Men Elemento grfico para realizar una seleccin Funcionamiento Dado un evento (pulsacin de una tecla del ratn) Muestra el men y sus opciones El usuario selecciona con el ratn El men informa al programa de la opcin seleccionada Domingo Martn Perandrs OpenGL Glut_animacin_menu Implementacin Crear el men, asocindole una funcin (callback) que tratar la seleccin del usuario Crear las opciones, asocindole a cada una un identificador Asociar el men a un evento (generalmente una tecla del ratn) Domingo Martn Perandrs OpenGL Glut_animacin_menu enum {MENU_ANIMACION,MENU_SALIR} _entradaMenuAnimacion; glutCreateMenu(menuAnimacion); glutAddMenuEntry("Cambiar animacion", MENU_ANIMACION); glutAddMenuEntry("Salir", MENU_SALIR); glutAttachMenu(GLUT_RIGHT_BUTTON); Domingo Martn Perandrs OpenGL Glut_animacin_menu void menuAnimacion(int Valor) { switch (Valor) { case MENU_ANIMACION: if (Animacion==true) { Animacion=false; glutIdleFunc(NULL); } else { Animacion=true; glutIdleFunc(desocupado); } break; case MENU_SALIR: exit(0); break; } glutPostRedisplay(); } Domingo Martn Perandrs OpenGL Glut_posicin_raton Submens Las opciones de un men pueden tener asociados submens Los submens tienen la misma definicin que un men, excepto que no es necesario indicar con que evento se enlazan Un submen debe definirse antes que el men o submen del que depende Domingo Martn Perandrs OpenGL Glut_posicin_raton MenuProyeccion=glutCreateMenu(menuProyeccion); glutAddMenuEntry("Perspectiva",MENU_PROYECCION_PERSPECTIVA); glutAddMenuEntry("Paralela",MENU_PROYECCION_PARALELA); MenuAnimacion=glutCreateMenu(menuAnimacion); glutAddMenuEntry("SI",MENU_ANIMACION_SI); glutAddMenuEntry("NO",MENU_ANIMACION_NO); MenuPrincipal=glutCreateMenu(menuPrincipal); glutAddSubMenu("Animacion",MenuAnimacion); glutAddSubMenu("Proyeccion",MenuProyeccion); glutAddMenuEntry("Salir", MENU_SALIR); glutAttachMenu(GLUT_RIGHT_BUTTON); Domingo Martn Perandrs OpenGL Glut_iluminacin Para que un modelo parezca realista debe reproducirse el efecto de la reflexin de la luz sobre la superficie del objeto Objeto Color -> Modelo de reflexin Normales Domingo Martn Perandrs OpenGL Glut_iluminacin Modelo de reflexin I=I ambiente +I difusa +I especular Difusa: independiente del observador Especular: dependiente del observador Luz Color Posicin Domingo Martn Perandrs OpenGL Glut_iluminacin Modelo de suavizado Plano Gouraud Interpolacin de colores Domingo Martn Perandrs OpenGL Glut_iluminacin La intensidad de la luz reflejada depende de Reflexin difusa Vector normal Vector a la fuente de luz Reflexin especular Vector normal Vector a la fuente de luz Vector reflejado Vector al observador Domingo Martn Perandrs OpenGL Glut_iluminacin Reflexin difusa Domingo Martn Perandrs N 2 L OpenGL Glut_iluminacin Reflexin especular Domingo Martn Perandrs N L R V 2 2 n OpenGL Glut_iluminacin Color objeto glMaterial{fd}{v}(LADO_CARA,COMPONENTE, VALOR) LADO_CARA GL_FRONT GL_BACK GL_FRONT_AND_BACK COMPONENTE GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_SHININESS Domingo Martn Perandrs OpenGL Glut_iluminacin GLfloat ReflexionAmbiente[4]={0.5,.4,.3,1}; GLfloat ReflexionDifusa[4]={1,.7,.6,1}; GLfloat ReflexionEspecular[4]={1,1,1,1}; GLfloat ExponenteBrillo=1; // definicion del material //glMaterialfv(GL_FRONT,GL_AMBIENT,ReflexionAmbiente); glMaterialfv(GL_FRONT,GL_DIFFUSE,ReflexionDifusa); //glMaterialfv(GL_FRONT,GL_SPECULAR,ReflexionEspecular); glMaterialf(GL_FRONT,GL_SHININESS,ExponenteBrillo); Domingo Martn Perandrs OpenGL Glut_iluminacin Para el clculo de la reflexin en un punto es necesario saber la normal en dicho punto Cada vrtice debe tener asociado un vector normal glNormal3{bsidf}{v} glBegin(GL_POLYGON); glNormal3f(nx1,ny1,nz1); glVertex3f(x1,y1,z1); glNormal3f(nx2,ny2,nz2); glVertex3f(x2,y2,z2); glNormal3f(nx3,ny3,nz3); glVertex3f(x3,y3,z3); glEnd(); Domingo Martn Perandrs OpenGL Glut_iluminacin Luz Por defecto se pueden definir y utilizar 8 luces Existen varios parmetros, siendo los ms importantes la posicin y el color glLight{fd}{v}(LUZ,ATRIBUTO,VALOR) LUZ GL_LIGHT0 - GL_LIGHT7 ATRIBUTO GL_POSITION GL_AMBIENT GL_DIFFUSE GL_SPECULAR Domingo Martn Perandrs OpenGL Glut_iluminacin Modelo de suavizado Los modelos suelen estar representados por caras planas Si el objeto es poligonal -> correcto Si el objeto es curvo -> incorrecto Solucin -> suavizado A partir de la variacin del color producir la sensacin de que el objeto es curvo glShadeModel (MODO) MODO GL_FLAT: sin suavizado GL_SMOOTH: con suavizado de Gouraud Domingo Martn Perandrs OpenGL Glut_iluminacin Para que se efectuen los clculos de iluminacin Activar la iluminacin glEnable(GL_LIGHTING) Activa la luz glEnable(LUZ) LUZ GL_LIGHT0 - GL_LIGHT7 Domingo Martn Perandrs OpenGL Glut_iluminacin Las caras del modelo se dibujan en un orden arbitrario Problema: el resultado puede ser incorrecto Solucin: eliminacin de partes ocultas Z-bufer Domingo Martn Perandrs OpenGL Glut_iluminacin Habilitar el uso del z-bufer glutInitDisplayMode(... | GLUT_DEPTH) Valor de inicializacin glClearDepth(1.0) Inicializacin glClear(GL_DEPTH_BUFFER_BIT) Activacin del z-bufer glEnable(GL_DEPTH_TEST) Domingo Martn Perandrs