Tutorial 23 - Multitextura
Fecha Jueves, 15 julio a las 16:26:34
Tema DirectX/Opengl


Después de más de un año sin publicar nada (si es que me falta tiempo) he puesto un nuevo ejemplo, en este caso, sobre cómo combinar texturas. Lo que se conoce normalmente como multitextura.

Se trata de un ejemplo sencillo en el que se mezcla la textura del mapa terrestre con la de las nubes. No he querido renderizarlo sobre una esfera para no complicarlo más y centrarnos sólamente en mezclar las texturas.



Partiendo del esqueleto de aplicación del tutorial 21 (no del 22 que es más sencillo), he desarrollado este ejemplo.

Las modificaciones no son muchas,


 
    ///////////////////////////////////////////////////////////////////////////////
    ///     RenderSceneObjects: Renderiza los objetos que componen la escena 3D.
    ///
    ///     @param  nada
    ///
    ///     @return  nada
    ///////////////////////////////////////////////////////////////////////////////
    void GraphicApplication::RenderSceneObjects()
    {
    // ********************************* NEW **************************************
 
        // Definimos un rectángulo (formado por dos triángulos consecutivos)
        //
        // v0   v2
        //  *---*
        //  |  /|
        //  |/  |
        //  *---*
        // v1   v3
        //
        static Vertex2t rectagle[4] =
        {
        //     x  ,  y  ,  z  , nx,ny,nz, su,tv(0) su,tv(1)
            {-0.5f, 0.3f, 0.0f,  0, 0, 1, {{0,1}, {0,1}} }, /* v0 */
            {-0.5f,-0.3f, 0.0f,  0, 0, 1, {{0,0}, {0,0}} }, /* v1 */
            { 0.5f, 0.3f, 0.0f,  0, 0, 1, {{1,1}, {1,1}} }, /* v2 */
            { 0.5f,-0.3f, 0.0f,  0, 0, 1, {{1,0}, {1,0}} }  /* v3 */
        };

        Material whiteMaterial;
        fColorRGBA whiteColor= { 1.0f, 1.0f, 1.0f, 0.0f };  // Blanco

        // Fijamos el material
        memset( &whiteMaterial, 0, sizeof(Material) );
        whiteMaterial.ambient = whiteColor;
        whiteMaterial.diffuse = whiteColor;
        whiteMaterial.specular= whiteColor;

        IVideoDriver::GetVideoDriver()->SetMaterial  ( whiteMaterial );

        m_pVideoDriver->EnableTexture( 0, true );                               // Habilitamos las texturas nivel 0.
        m_pVideoDriver->SetTexture( 0, m_EarthTexture );                        // Fijamos la primera textura.
        m_pVideoDriver->SetTextureRenderStatus( 0, eColorarg1, eTaTexture  );   // El argumento 1 es una textura.
        m_pVideoDriver->SetTextureRenderStatus( 0, eColorop  , eOpArg1 );       // Seleccionamos el primer argumento.
        m_pVideoDriver->EnableTexture( 1, true );                               // Habilitamos las texturas nivel 1.
        m_pVideoDriver->SetTexture( 1, m_CloudsTexture );                       // Fijamos la segunda textura.
        m_pVideoDriver->SetTextureRenderStatus( 1, eColorarg1, eTaTexture  );   // El argumento 1 es una textura.
        m_pVideoDriver->SetTextureRenderStatus( 1, eColorarg2, eTaCurrent  );   // El argumento 2 es la anterior textura.
        m_pVideoDriver->SetTextureRenderStatus( 1, eColorop  , eOpAdd );        // Sumamos los argumentos (mezclamos).

        m_pVideoDriver->RenderVertexArray( eTriangleStrip, (BYTE*)rectagle,
                                         sizeof(Vertex2t), 0, 4,
                                      eFVF_XYZ|eFVF_NORMAL|eFVF_TEX2 );

   // ****************************************************************************
    }

    } // end namespace

En el fichero 3dstructures.h, donde se definen las estructuras usadas, he creado un nuevo tipo de vértice:


            // ********************************* NEW **************************************

            ///////////////////////////////////////////////////////////////////////////////
           /// struct   Vertex2t: Vértice con dos niveles de texturas.
            ///
            /// rief
            /// author  Antonio Lucas Moreno version 1.00 date 07/05/2008 17:22:19
            ///////////////////////////////////////////////////////////////////////////////
            struct Vertex2t
            {
                float           x, y, z;            ///< Coordenadas del vértice.
                float           nx, ny, nz;         ///< Normal del vértice.

                struct TextCoord
                {
                   float       su, tv;             ///< Coordenadas de textura.
                }
                textCoord[2];
            };

            // ****************************************************************************

Como podéis observar, se han definido las coordenadas de texturas como un array de dos componentes, cada una tiene las coordenadas correspondientes a cada nivel de textura (en este caso combinaremos dos).

Fijaros como en RenderVertexArray() se especifica que el formato del vértice contiene nos niveles de coordenadas de texura: eFVF_TEX2.

Básicamente, a la hora de combinar las texturas, lo que se hace es seleccionar cuáles son las texturas que se utilizarán como argumentos a la hora de combinarlas. Los parámetros de la función SetTextureRenderStatus() están definidos en el fichero 3dstructures.h en el enumerado e_TEXTURE_RENDER_STATUS. Los nombres son coincidentes con los de DirectX porque creía que resultaría más comprensible.

Se me olvidaba mencionar, que en OpenGL, para trabajar con múltiples texturas es necesario hacer uso de lo que se conocen como extensiones. Que nos son más que unas funcionalidades añadidas a la librería.

En este caso, para trabajar con multiextura, usamos las extensiones ARB. Editad el fichero openglvideodriver.cpp para ver su uso.

Para trabajar con la extensiones de OpenGL, usaremos GLEW: http://glew.sourceforge.net/ que nos carga distintas extensiones para poder hacer uso de ellas. Añadid al Visual Studio la ruta de los includes y los lib allá donde la instaléis para poder compilar.

Podéis descargaros el ejemplo: tutorial-23.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=27