Vamos a por nuestro primer ejemplo con OpenGL. Tras las explicaciones del anterior post sobre OpenGL, la única puntualización necesaria sería sobre qué es eso de GLUT que pone en el título del post. GLUT es el acrónimo de openGL Utility Toolkit, y viene a ser poco más que un wrapper para facilitar las tareas más comunes, con llamadas algo más sencillas. A los desarrolladores de OpenGL debería decirles algo el hecho de que este tipo de productos existan y sean tan ampliamente utilizados. Como veremos, también incluye algunas facilidades para el uso del teclado y ratón.
Nosotros lo utilizaremos únicamente para este primer ejemplo, para afianzar conceptos básicos… porque con él estamos perdiendo una gran cantidad de productos potenciales en lo que ejecutar nuestro código (GLUT únicamente existe para los sistemas principales, pero no para consolas, específicamente para productos homebrew que no disponen de SDKs oficiales, ni para el iPhone). Además se dejó de trabajar en GLUT hace tiempo, ahora habría que utilizar freeglut y blablabla… conclusión: no lo vamos a utilizar en el futuro.
Lo primero que haremos será crear un nuevo proyecto, de tipo Command Line Tool, para C++, al que pondremos como nombre lo que más rabia nos dé (a mi se me ha ocurrido Demo01, en un arranque de originalidad):

Se creará un proyecto con un único archivo de código (main.cpp). La siguiente tarea a realizar será añadir las referencias a los frameworks/librerías que vamos a utilizar, en este caso OpenGL. Esto lo haremos haciendo click derecho sobre el proyecto, Add, Existing Frameworks:

Otra de las buenas cosas de los Mac es que todo está localizado donde debe. Así que todos los frameworks instalados en el sistema se mostrarán en una lista de la que tan sólo hemos de escoger OpenGL.framework y GLUT.framework (OpenGL Utility Toolkit) y añadirlos al proyecto.

Los frameworks aparecerán ahora dentro del árbol del proyecto, y podremos ver todos los archivos de cabeceras para consultar el prototipo de cualquier función que podamos necesitar.

Sustituimos ahora el código de nuestro main.cpp por el siguiente código, que es una modificación de un ejemplo de Jon McCormark, al que he añadido/traducido varios comentarios, y he modificado el control desde teclado, para que tengáis más ejemplos:
// Ejemplo basado originalmente en // http://www.csse.monash.edu.au/~jonmc/CSE3313/Resources/SampleCode/Code/text.c #include <stdlib.h> #include <stdio.h> #ifdef __APPLE__ #include <GLUT/glut.h> #else #include <GL/glut.h> #endif #define MESSAGE "Hola Mundo" #define WINDOW_WIDTH 300 #define WINDOW_HEIGHT 300 static GLfloat rotate = 0.0; static GLfloat x_pos = WINDOW_WIDTH/2.0; static GLfloat y_pos = WINDOW_HEIGHT/2.0; void drawText(const char * message) { /* raster pos sets the current raster position * mapped via the modelview and projection matrices */ glRasterPos2f((GLfloat)0, (GLfloat)-WINDOW_HEIGHT); /* * write using bitmap and stroke chars */ while (*message) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *message); glutStrokeCharacter(GLUT_STROKE_ROMAN,*message++); } } /* * display * * This function is called by the GLUT to display the graphics * In this case it clears the screen then calls the function "drawText" * which will draw some text using GLUT * */ void display(void) { /* set matrix mode to modelview */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* transformations to scale the stroke text - * notice how these only change stroke and raster text * differently... */ glScalef(0.001, 0.001, 0.001); glRotatef(rotate, 0, 0, 1.0); /* glTranslatef(-180, -180, 0.0); */ glClear( GL_COLOR_BUFFER_BIT ); drawText(MESSAGE); glFlush(); /* force OpenGL output */ } void keyboard(unsigned char k, int x, int y) { switch (k) { case 'q': case 'Q': case 27: // tecla escape exit(0); break; default: break; } } void keyboard_special(int k, int x, int y) { char changed = 0; switch (k) { // Cursor arriba case GLUT_KEY_UP: y_pos += 1.0; changed = 1; break; // Cursor abajo case GLUT_KEY_DOWN: y_pos -= 1.0; changed = 1; break; // Cursor izqda case GLUT_KEY_LEFT: x_pos -= 1.0; changed = 1; break; // Cursor abajo case GLUT_KEY_RIGHT: x_pos += 1.0; changed = 1; break; default: break; } // Si hemos cambiado la posicion, // forzamos el repintado if (changed) glutPostRedisplay(); } void mouse(int btn, int state, int x, int y) { // Boton izquierdo if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) rotate += 20.0; // Boton central, volvemos a la posicion inicial if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) rotate = 0.0; // Boton derecho if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) rotate -= 20.0; // Informamos de que debemos redibujar glutPostRedisplay(); } int main(int argc, char **argv) { // glutInit es la primera llamada, antes que cualquier otra // funcion de OpenGL o GLUT glutInit(&argc, argv); // Modo de video inicial, por ahora no nos preocuparemos de esto glutInitDisplayMode(GLUT_RGB); glutInitWindowSize(300, 300); glutCreateWindow("OpenGL/GLUT Demo 01"); // Funciones de callback que GLUT llamara cuando sea necesario glutDisplayFunc(display); // Pintar la pantalla glutReshapeFunc(NULL); // Tamaño de la ventana glutIdleFunc(NULL); glutKeyboardFunc(keyboard); // Teclas ASCII del teclado glutSpecialFunc(keyboard_special); // Teclas especiales del teclado glutMouseFunc(mouse); // Raton // Y algunas llamadas directamente a OpenGL // Color para limpiar la pantalla glClearColor(1.0, 0.2, 1.0, 1.0); // Color para las fuentes glColor3f(0.0, 0.0, 0.0); // Comenzamos la ejecucion glutMainLoop(); return 0; }
Etiquetas: GLUT, OpenGL, programación