OpenGL Qué es OpenGL • Interface software entre el programador y el hardware gráfico • Basada en la librería gráfica Iris GL de Silicon Graphics • Permite crear aplicaciones 3D interactivas • Independiente del hardware • No incluye manejo de ventanas, ni interacción con el usuario • No permite describir objetos 3D directamente Un poco de historia • IrisGL fue la primera API para estaciones gráficas SGI: – hardware optimizado para la visualización de gráficos • OpenGL es el resultado de trasladar IrisGL a otras máquinas: – ofrecer la misma potencia que IrisGL – ser un lenguaje más abierto (open) – permitir fácil adaptación a otras plataformas y sistemas operativos – se presentó el 1 de Julio de 1992 • Microsoft confirmó que la añadiría a su Windows NT • Existe una plataforma para la revisión de la arquitectura OpenGL, compuesta por varios fabricantes. • Está pensada para funcionar en sistemas con aceleración hardware. Orden de las operaciones en OpenGL • Se construyen las primitivas geométricas – puntos, líneas, polígonos, bitmaps, etc. • Se posicionan en el espacio 3D • Se selecciona el punto de vista • Se calcula el color de todos los objetos – según las condiciones de luz – obtenidas a partir de las texturas – indicado directamente por el programador • Se genera la imagen de pixels – cálculo de visibilidad si necesario Librerías relacionadas con OpenGL • Los comandos de OpenGL son muy básicos • Lo normal es construir nuestra propia librería sobre OpenGL – para el manejo de las ventanas – para la interacción con el usuario – para trabajar a más alto nivel (definiendo objetos y métodos más generales) • OpenGL Utility Library (GLU) – rutinas de más alto nivel (proyecciones, teselación, rendering de superficies) • OpenGL Auxiliary Library (AUX) – manejo de ventanas, manejo de eventos, objetos 3D. • OpenInventor – toolkit orientado a objeto para crear aplicaciones 3D interactivas Otras herramientas • Sobre OpenGL pueden desarrollarse herramientas más complejas Aplicaciones OpenGL con la librería GLUT OpenGL: una API, no un lenguaje • OpenGL no es un lenguaje de programación • Sigue la convención de llamadas a C • OpenGL se divide en tres librerías distintas: – Librería auxiliar AUX (glaux): independiente de la plataforma – Librería específica OpenGL (gl) – Librería de utilidades (glu): dibujo de esferas, discos, cilindros, etc. • OpenGL define sus propios tipos de datos – GLbyte entero de 8 bits – GLushort entero de 16 bits sin signo – GLint entero de 32 bits – GLdouble real de 64 bits Sintaxis de los comandos OpenGL • Todas las funciones comienzan por ‘gl’ • Todas las constantes empiezan por ‘GL’ • Algunas funciones acaban con un sufijo (‘3f’, ‘2d’, etc.): – El número indica el número de parámetros • Punto en 2D: glVertex2f (x, y); • Punto en 3D: glVertex3f (x, y, z); – La letra indica el tipo de los parámetros • (i: long integer; f: float; d: double; ub: unsigned char; etc.) • Algunos comandos acaban en ‘v’: – en lugar de pasar los valores individuales, se pasa un vector • valores individuales: glColor3f (1, 1, 1); • usando un vector float vectorcol[] = {1, 1, 1} glColor3fv (vectorcol); La librería AUX • Fue creada para facilitar el aprendizaje de OpenGL • Evita los detalles del entorno particular (Windows, Unix) – creación y manejo de las ventanas – interacción con el usuario • No sirve para diseñar la interfaz final de la aplicación • Hace uso de la API nativa del entorno • OpenGL no maneja ventanas ni gestiona eventos La librería GLUT • Fue creada como ampliación de la librería AUX • Se le añadieron más prestaciones como: – Creación de menús desplegables – Administración de varias ventanas – Manejo de joystick y otros dispositivos de E/S • Sigue siendo multi-plataforma (Unix, Linux, Mac-OS, Windows) • La gran ventaja es que permite olvidarse de la programación GUI básica de una plataforma específica, y centrarse exclusivamente en OpenGL • No viene incluida en la distribución oficial. Hay que descargarla aparte. Primer ejemplo en OpenGL + GLUT #include <GL/glut.h> void DibujaEscena() { glClearColor (0., 0., 1., 1.); glClear(GL_COLOR_BUFFER_BIT); glFlush(); } // color de borrar // borramos pantalla // forzamos el dibujo int main() { // Funciones GLUT para inicializar la ventana glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA); glutInitWindowSize (250, 250); glutCreateWindow (“Mi primer programa OpenGL"); // Indicamos la función para el evento ‘Paint’ glutDisplayFunc (DibujaEscena); // Lanzamos el bucle indefinido de eventos glutMainLoop(); } Dibujando formas void DibujaEscena() { // Pone el color de fondo a azul glClearColor(0.0, 0.0, 1.0, 1.0); // Borra la ventana glClear(GL_COLOR_BUFFER_BIT); // Pone el color de pintar a rojo glColor3f(1.0, 0.0, 0.0); // Dibuja un rectángulo sólido glRectf (-0.1,-0.1, 0.1, 0.1); glFlush(); } y x Ventana y volumen de trabajo • En OpenGL siempre se pinta en 3D • Por defecto glut define un volumen de trabajo entre -1 y 1 en las tres dimensiones y (1,1,-1) (-1,1,1) (0.1,0.1,0) x (-0.1,-0.1,0) z Escalado de la ventana void EscalaVentana(GLsizei w, GLsizei h) { .... } void DibujaEscena() { .... } void main() { // Funciones GLUT para inicializar la ventana glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA); glutCreateWindow (“Mi primer programa OpenGL"); // Indicamos la función para el evento ‘Paint’ glutDisplayFunc (DibujaEscena); // Indicamos la función para el evento ‘Resize’ glutReshapeFunc (EscalaVentana) // Lanzamos el bucle indefinido de eventos glutMainLoop(); } void EscalaVentana(GLsizei w, GLsizei h) { // Evita una división por cero if (h == 0) h = 1; // Ajusta la vista a las dimensiones de la ventana glViewport(0, 0, w, h); // Reinicia el sistema de coordenadas glMatrixMode (GL_PROJECTION); glLoadIdentity(); // Establece el volumen de trabajo glOrtho(0.0f, 250.0f, 0.0f, 250.0f, -1.0, 1.0); glFlush(); } Definición de la vista • Indica la posición y resolución de la foto final (pixels) glViewport(GLint x, GLint y, GLsizei ancho, GLsize alto); glViewport(0,0,500,250) 250 250 glViewport(0,0,250,250) 250 250 glViewport(125,125,125,125) Definición del volumen de trabajo glLoadIdentity(); glOrtho(GLdouble izquierda, GLdouble derecha, GLdouble abajo, GLdouble arriba, GLdouble detrás, GLdouble delante); y (250,250,-1) (0,250,1) (250,0,-1) x (0,0,0) glOrtho(0,250,0,250,-1,1) z Animación con OpenGL y GLUT void DibujaEscena() { .... } void MueveCuadrado() { // Dibujar el cuadrado en su nueva posición ... glutPostRedisplay(); } void main() { // Funciones AUX para inicializar la ventana ... // Indica la función a llamar cuando se escale la ventana glutIdleFunc(MueveCuadrado); // Indica la función que redibuja la ventana glutMainLoop(); } Buffer doble • Permite dibujar fuera de la pantalla – las escenas complejas nunca se verán de forma parcial – las animaciones no producen saltos void DibujaEscena() { // Dibujamos la escena .... glutSwapBuffers(); } void main() { // Funciones AUX para inicializar la ventana glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); ... glutMainLoop(); } Objetos 3D • La librería GLUT incluye una docena de objetos 3D • Por ahora sólo podemos ver su proyección paralela glutWireTeapot(50.0f) glutSolidTeapot(50.0f)