TUTORIAL #1: OpenGL y GLUT OpenGL (Open Graphics Library) es una especificación estándar que define una API multilenguaje y multiplataforma para escribir aplicaciones que produzcan gráficos 2D y 3D. La interfaz consiste en más de 250 funciones diferentes que pueden usarse para dibujar escenas tridimensionales complejas a partir de primitivas geométricas simples, tales como puntos, líneas y triángulos. GLUT (del inglés OpenGL Utility Toolkit) es una biblioteca de utilidades para programas OpenGL que principalmente proporciona diversas funciones de entrada/salida con el sistema operativo. Entre las funciones que ofrece se incluyen declaración y manejo de ventanas y la interacción por medio de teclado y ratón. También posee rutinas para el dibujado de diversas primitivas geométricas (tanto sólidas como en modo wireframe) que incluyen cubos, esferas y teteras. También tiene soporte para creación de menús emergentes. Antes de trabajar con OpenGL debemos tener nuestro entorno de trabajo listo para funcionar con OpenGL, pero eso depende de que compilador usemos, así que una visita a google no cae mal, ya que esto se extendería demasiado explicar cómo configurar cada compilador… Luego de tener nuestro compilador configurado pasemos a lo básico: #include <stdio.h> #include <stdlib.h> #include <GL/glut.h> void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); glVertex3f(-0.5,-0.5,0.0); glVertex3f(0.5,0.0,0.0); glVertex3f(0.0,0.5,0.0); glEnd(); glFlush(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(320,320); glutCreateWindow("Tutorial 1"); glutDisplayFunc(renderScene); glutMainLoop(); } Esto es lo que llamaremos nuestro esqueleto inicial, con esta plantilla podremos agregar todo lo que necesitemos para hacer aplicaciones con OpenGL, ahora una breve explicación de las funciones más importantes: glutInit(&argc,argv): Inicializa las operaciones de OpenGL y Glut, es necesario que haya sido llamada antes de usar cualquier función de Glut. glutCreateWindow(): Crea una ventana de OpenGL, aquí mostraremos todo lo que vayamos a dibujar, lo que nos facilita trabajar con ventanas no importa sea Windows o Linux el ambiente. glutDisplayFunction(función): con esta instrucción le indicamos a Glut que función se usara para el dibujo de la pantalla, dentro de esa función tendremos todas nuestras instrucciones y primitivas de OpenGL. glutMainLoop(): indica que empecemos a mostrar imágenes con Glut, el llamara a la función definida por glutDisplayFunction y la llamara por un ciclo infinito hasta que se cierre la ventana. Esta pequeña plantilla nos mostrara un triangulo en pantalla, pero hasta ahí, no nos da mas interacción con el usuario. Interacción con el ratón: Ahora vamos a agregar funciones para poder manejar el ratón: Agreguemos una función llamada movimiento con este código: void movimiento(int boton, int estado, int x, int y) { if ((estado == GLUT_DOWN) && (boton== GLUT_LEFT_BUTTON)) { printf("Se presiono el boton izquierdo\n"); } } Y luego en la función main agregamos esta línea: glutMouseFunc(movimiento); Ahora cada vez que presionemos el botón izquierdo dentro de la ventana se nos indicara por la consola. Probemos otra cosa, agreguemos la siguiente función al código: void pasivo(int x,int y) { printf("no hago nada\n"); } Y en el main coloquemos esta línea: glutPassiveMotionFunc(pasivo); Ahora, cada vez que movamos el ratón sin presionar ningún botón nos imprimirá por consola la frase “no hago nada” Interacción con el teclado: Ya aprendimos como manipular eventos del ratón de una manera básica, ahora tocaremos el tema del teclado en Glut, en Glut se manejan dos tipos de teclas, las teclas normales que sería todo el alfabeto y números, y las teclas especiales que sería la serie F1 a F12,flechas de dirección, Home,End,Insert,Delete,PgUp y PgDn. Estos dos tipos de teclas se manejan de la siguiente manera: Agreguemos esta función al programa: void teclado(unsigned char key, int x, int y) { if (key == 27) exit(0); } En la función main agreguemos esta línea: glutKeyboardFunc(teclado); Ahora podremos salir del programa al presionar la tecla Esc, que vendría siendo 27 en ASCII, lo que nos indica que glutKeyboardFunc nos permite capturar cualquier tecla que se represente por un código ASCII. Ahora veamos como agregar control de teclas especiales: De nuevo, agregamos al cuerpo del programa esta función: void especiales(int key,int x,int y) { if(key==GLUT_KEY_F1) exit(0); } Y en la función main colocamos su declaración correspondiente: glutSpecialFunc(especiales); Luego de compilar y probar el código, ahora podremos salir de la aplicación al presionar la tecla F1. Todo es cuestión de perspectiva: Para finalizar, vamos a darle nuestro programa un toque de perspectiva, para que al dibujar en pantalla se vean con un efecto de profundidad. Para esto colocaremos una vista de 45 grados y explicaremos algo muy importante a la hora de trabajar con OpenGL que son las matrices GL_PROJECTION y GL_MODELVIEW. La 1era matriz es la que controla la perspectiva de la imagen y desde qué punto se puede ver, en cambio GL_MODELVIEW se encarga de que las transformaciones que se hagan se apliquen a los objetos en sí. Veamos un ejemplo: void cambiarTamano(int w, int h) { // Previene una division por cero, cuando la ventana es muy pequeña if(h == 0) h = 1; float ratio = 1.0* w / h; // Reinicia la matriz de Proyeccion antes de utilizarla. glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Fija el punto de vision para toda la ventana. glViewport(0, 0, w, h); // Definimos la perspectiva correcta. glMatrixMode(GL_PROJECTION);// Seleccionala matriz de Proyeccion glLoadIdentity(); // Reinicia la matriz de Proyeccion // Calcula la relacion de aspecto de la ventana. gluPerspective(45.0f,ratio,0.1f,100.0f); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Selecciono la matriz de Modelo Y en la función main ahora agregamos esta línea: glutReshapeFunc(cambiarTamano); Gracias a esto, tendremos nuestros objetos en perspectiva y veremos todo lo que este desde el origen hasta 100 unidades de profundidad, lo que nos ayudara en futuros talleres. ¡Pero al colocar este código nuestra figura desapareció! Ya que colocamos la perspectiva desde 0.1f y los objetos dibujados están en 0.f así que las figuras estarán “detrás” de nosotros según la cámara, acomodemos o los objetos o la cámara para poder verlos bien. Ahora como ejercicio trate de hacer un cubo con un color en cada cara, para esto use la primitiva GL_QUADS para dibujar los cuadrados y coloque los vértices correspondientes para ver el cubo Referencias: OpenGL @ Lighthouse 3D ‐ http://www.lighthouse3d.com/OpenGL/glut/index.php NeHe Productions ‐ http://nehe.gamedev.net