Tutorial 04 - Aplicación GLUT.
Fecha Jueves, 30 agosto a las 20:47:04
Tema Linux


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:

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;
        }
    }

Podéis descargaros el ejemplo: tutorial-04.zip



Compartir en Facebook



Este artículo proviene de Programacion Grafica: Desarrollo 2D/3D con C++ y DirectX/OpenGL/GLUT/SDL - Windows/Linux
http://www.programaciongrafica.com

La dirección de esta noticia es:
http://www.programaciongrafica.com/modules.php?name=News&file=article&sid=5