Aplicación GLUT.
En este ejemplo, vamos a hacer uso de la librería GLUT para la creación de la ventana y gestión de los eventos de ratón y teclado.
¿Por qué usar esta librería?, pues porque es una librería multiplataforma, que nos permite desarrollar la misma aplicación para distintos S.0. Así, podríamos recompilar el código de este ejemplo para Linux.
No confundáis GLUT con OpenGL, sí es verdad que están muy relacionados, ya que la idea es poder desarrollar aplicaciones que hagan uso de OpenGL en diferentes plataformas. GLUT dispone de una serie de funciones para crear ventanas y gestionar los eventos como el teclado, ratón, etc.
Para poder desarrollar con GLUT, debéis descargar la librería: http://www.xmission.com/~nate/glut.html
Y configurar el entorno:
Y configurar el entorno:
- Dev-C++: http://www.dcc.uchile.cl/~mnmonsal/cc52b/devcpp.html
o descargar el paquete en el área de descargas: glut-3.7.6.DevPak - Visual C++: http://informatica.uv.es/iiguia/AIG/docs/tutorial.htm
Para compilar en Linux, deberéis instalar la librería GLUT. Y en general, para cualquier proyecto de los tutoriales, en el directorio /prj/linux existe un fichero makefile. Os situáis en dicho directorio y tecleais make o make glut y os generará en el directorio bin el ejecutable. Con make clean borra los ficheros generados.
Así, el modo de funcionamiento de la librería, consiste en declarar una serie de funciones con un interfaz prefijado por GLUT y asociar dichas funciones al evento que se desea controlar. Finalmente, se realiza la llamada a la función glutMainLoop() que entra en un bucle infinito del que sólo se sale cuando se invoca a la función exit().
Podréis comprobar que nuestra clase GraphicApplication no cambia, el truco consiste en que en el fichero glut-main.cpp se invoquen a los métodos de nuestra clase a través de las funciones registradas encargadas de gestionar los diferentes eventos.
Con todo esto, el programa principal queda como sigue:
#include
//
// Para DevC++ obtener el paquete de: http://www.nigels.com/glt/devpak/
//
// VER: http://www.dcc.uchile.cl/~mnmonsal/cc52b/devcpp.html
//
#include // Incluye GLUT, OpenGL y GLU
#include "common.h"
#include "graphicapplication.h"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define BPP 32 // Bits por pixel.
#define FULL_SCREEN false
// -----------------------------------------------------------------------------
// Creamos nuestro objeto aplicación de ámbito global para que sea accesible
// por la función gestora de mensajes de la ventana.
PROGRAMACION_GRAFICA::GraphicApplication g_GraphicApplication;
// -----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
/// OnKeyDown: Función invocada al pulsar una tecla.
///
/// @param unsigned char key: Tecla pulsada.
/// @param int x: Coordenada x del puntero del ratón.
/// @param int y: Coordenada y del puntero del ratón.
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnKeyDown( unsigned char key, int x, int y )
{
g_GraphicApplication.OnKeyDown( key );
}
///////////////////////////////////////////////////////////////////////////////
/// OnKeyUp: Función invocada al liberar una tecla.
///
/// @param unsigned char key: Tecla liberada.
/// @param int x: Coordenada x del puntero del ratón.
/// @param int y: Coordenada y del puntero del ratón.
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnKeyUp( unsigned char key, int x, int y )
{
g_GraphicApplication.OnKeyUp( key );
}
///////////////////////////////////////////////////////////////////////////////
/// OnSpecialKeyDown: Funci�n invocada al pulsar una especial.
///
/// @param int key: Tecla pulsada.
/// @param int x: Coordenada x del puntero del rat�n.
/// @param int y: Coordenada y del puntero del rat�n.
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnSpecialKeyDown( int key, int x, int y )
{
switch ( key )
{
case GLUT_KEY_LEFT:
g_GraphicApplication.OnKeyDown( 0x25 );
break;
case GLUT_KEY_UP:
g_GraphicApplication.OnKeyDown( 0x26 );
break;
case GLUT_KEY_RIGHT:
g_GraphicApplication.OnKeyDown( 0x27 );
break;
case GLUT_KEY_DOWN:
g_GraphicApplication.OnKeyDown( 0x28 );
break;
default:
g_GraphicApplication.OnKeyDown( key );
break;
}
}
///////////////////////////////////////////////////////////////////////////////
/// OnSpecialKeyUp: Función invocada al pulsar una especial.
///
/// @param int key: Tecla pulsada.
/// @param int x: Coordenada x del puntero del ratón.
/// @param int y: Coordenada y del puntero del ratón.
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnSpecialKeyUp( int key, int x, int y )
{
switch ( key )
{
case GLUT_KEY_LEFT:
g_GraphicApplication.OnKeyUp( 0x25 );
break;
case GLUT_KEY_UP:
g_GraphicApplication.OnKeyUp( 0x26 );
break;
case GLUT_KEY_RIGHT:
g_GraphicApplication.OnKeyUp( 0x27 );
break;
case GLUT_KEY_DOWN:
g_GraphicApplication.OnKeyUp( 0x28 );
break;
default:
g_GraphicApplication.OnKeyUp( key );
break;
}
}
///////////////////////////////////////////////////////////////////////////////
/// OnResize: Función invocada al cambiar de tamaño la ventana.
///
/// @param int width: Ancho en píxeles de la ventana.
/// @param int height: Alto en píxeles de la ventana.
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnResize( int width, int height )
{
g_GraphicApplication.OnResize( width, height );
}
///////////////////////////////////////////////////////////////////////////////
/// OnMouseMove: Función invocada cuando se mueve el ratón.
///
/// @param int x: Coordenada x del puntero del ratón.
/// @param int y: Coordenada y del puntero del ratón.
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnMouseMove(int mouseX, int mouseY)
{
g_GraphicApplication.OnMouseMove( mouseX, mouseY );
}
///////////////////////////////////////////////////////////////////////////////
/// OnMouseButton: Función invocada cuando se pulsa o libera algún botón del ratón.
///
/// @param int button: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, o GLUT_RIGHT_BUTTON.
/// @param int state: GLUT_UP o GLUT_DOWN.
/// @param int x: Coordenada x del puntero del ratón.
/// @param int y: Coordenada y del puntero del ratón.
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnMouseButton(int button, int state, int mouseX, int mouseY)
{
switch( state )
{
case GLUT_DOWN:
switch( button )
{
case GLUT_LEFT_BUTTON:
g_GraphicApplication.OnLButtonDown( mouseX, mouseY );
break;
case GLUT_RIGHT_BUTTON:
g_GraphicApplication.OnRButtonDown( mouseX, mouseY );
break;
case GLUT_MIDDLE_BUTTON:
break;
}
break;
case GLUT_UP:
switch( button )
{
case GLUT_LEFT_BUTTON:
g_GraphicApplication.OnLButtonUp( mouseX, mouseY );
break;
case GLUT_RIGHT_BUTTON:
g_GraphicApplication.OnRButtonUp( mouseX, mouseY );
break;
case GLUT_MIDDLE_BUTTON:
break;
}
break;
}
}
///////////////////////////////////////////////////////////////////////////////
/// OnIdle: Función invocada cada vez que no ocurre ningún evento.
/// Esta función, sería el cuerpo principal de nuestra aplicación.
///
/// @param nada
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnIdle()
{
g_GraphicApplication.OnIdle(); // Proceso principal de la aplicación.
if ( g_GraphicApplication.IsEnded() )
exit(0); // Para salir de glutMainLoop() sólo se puede hacer con exit.
else
glutPostRedisplay(); // Fuerza el repintado de la ventana. Invoca a la función OnRender()
}
///////////////////////////////////////////////////////////////////////////////
/// OnRender: Esta función es invocada cuando el sistema está listo para renderizar.
///
/// @param nada
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnRender()
{
g_GraphicApplication.OnRender();
glutSetWindowTitle( g_GraphicApplication.GetMsgTitle() );
glutSwapBuffers(); // Vuelca a la ventana actual la imagen renderizada.
}
///////////////////////////////////////////////////////////////////////////////
/// OnEnd: Función invocada al finalizar la aplicación.
///
/// @param nada
///
/// @return nada
///////////////////////////////////////////////////////////////////////////////
void OnEnd()
{
g_GraphicApplication.OnEnd();
}
///////////////////////////////////////////////////////////////////////////////
/// main: Punto de entrada de la aplicación.
///
/// @param int argc: Número de argumentos.
/// @param char * argv[]: Parámetros de la línea de comando.
///
/// @return int:
/// - 0: Ok.
/// - -1: Error.
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char * argv[])
{
int screenWidth, screenHeight;
PROGRAMACION_GRAFICA::WindowProps windowProps;
try
{
windowProps.position.x = 0;
windowProps.position.y = 0;
windowProps.width = WINDOW_WIDTH;
windowProps.height = WINDOW_HEIGHT;
windowProps.bpp = BPP;
windowProps.bFullScreen = FULL_SCREEN;
strcpy( windowProps.title, WINDOW_TITLE );
// Inicializamos GLUT.
glutInit ( &argc, argv );
// Inicialización de nuestra aplicación.
g_GraphicApplication.OnInit( windowProps );
// Inicializamos el modo de vídeo.
glutInitDisplayMode ( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH );
// Obtenemos la resolución de la pantalla.
screenWidth = glutGet ( GLUT_SCREEN_WIDTH );
screenHeight = glutGet ( GLUT_SCREEN_HEIGHT );
if ( windowProps.bFullScreen )
{
windowProps.position.x= 0;
windowProps.position.y= 0;
}
else
{
windowProps.position.x= ( screenWidth - windowProps.width ) / 2;
windowProps.position.y= ( screenHeight - windowProps.height ) / 2;
}
// Posición de la ventana.
glutInitWindowPosition ( windowProps.position.x, windowProps.position.y );
// Dimensiones de la ventana.
glutInitWindowSize ( windowProps.width, windowProps.height );
// Creamos la ventana principal.
glutCreateWindow ( windowProps.title );
if ( windowProps.bFullScreen )
glutFullScreen(); // A pantalla completa.
// Inicialización de OpenGL.
g_GraphicApplication.OnCreateWindow( windowProps );
// Registramos diversas funciones que tratarán los diferentes eventos.
glutReshapeFunc ( OnResize );
glutKeyboardFunc ( OnKeyDown );
glutKeyboardUpFunc ( OnKeyUp );
glutSpecialFunc ( OnSpecialKeyDown );
glutSpecialUpFunc ( OnSpecialKeyUp );
glutMouseFunc ( OnMouseButton );
// glutMotionFunc ( OnMouseMove ); // Cuando se mueve el ratón con algún botón pulsado
glutPassiveMotionFunc ( OnMouseMove ); // Cuando se mueve el ratón sin ningún botón pulsado.
glutIdleFunc ( OnIdle );
glutDisplayFunc ( OnRender );
// Registramos la función de salida.
// Esta función no pertenece a GLUT forma parte del estándar ANSI (stdlib.h).
// Tras invocar a exit() en el código, se ejecuta la función pasada como argumento
// antes de finalizar.
atexit ( OnEnd );
// Entramos en el bucle que procesa los eventos.
// La única forma de finalizar es realizando una llamada a exit().
glutMainLoop ( );
// Fin OK
return 0;
}
catch (GLenum glErrorCode)
{
std::cout << std::endl;
std::cout << " +-----------------------------------------------------------+" << std::endl;
std::cout << " " << gluErrorString( glErrorCode ) << std::endl;
std::cout << " +-----------------------------------------------------------+" << std::endl;
std::cout << std::endl;
// Fin Error.
return -1;
}
}
Comentarios