Escrito por Iván Alonso el Lunes 21 de Diciembre de 2009

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):

Captura de pantalla 2009-11-17 a las 11.04.11.png

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:

Captura de pantalla 2009-11-17 a las 11.07.48.png

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.

Captura de pantalla 2009-11-17 a las 11.15.59.png

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.

Captura de pantalla 2009-11-17 a las 11.19.39.png

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 &amp;&amp; state == GLUT_DOWN)
		rotate += 20.0;
 
     // Boton central, volvemos a la posicion inicial
     if(btn==GLUT_MIDDLE_BUTTON &amp;&amp; state == GLUT_DOWN)
		rotate = 0.0;
 
     // Boton derecho
     if(btn==GLUT_RIGHT_BUTTON &amp;&amp; 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: , ,

Esta entrada fue escrita el Lunes 21 de Diciembre de 2009 a las 11:39 am y está archivada en la categoría Blog. Puedes seguir las respuestas y comentarios en el feed RSS 2.0. Puedes dejar un comentario, o dejar un trackback desde tu propia página.

Deja tu comentario