Aprende a desarrollar aplicaciones gráficas 2D y 3D paso a paso.
Programacion Grafica: Desarrollo 2D/3D con C++ y DirectX/OpenGL/GLUT/SDL - Windows/Linux


  Crear una cuenta
 • Portada • Descargas • Tu Cuenta • 
Menú
 Portada
 Noticias
 Archivo de Noticias
 Temas
 Descargas
 Inicio
 Ver Nuevas
 Más Popular
 Más Votadas
 Contenido
 Contenido
 Secciones
 Enciclopedia
 Revisiones
 FAQ
 Tus Opciones
 Tu Cuenta
 Mensajes Privados
 Recomiéndenos
 Buscar
 Diarios
 Contacto
 Enlaces Web
 Inicio
 Enviar Enlace
 Ver Nuevos
 Más Popular
 Más Valorados
 Estadísticas
 Inicio
 Detalladas
 Top 10
 
Estadísticas
 
Tutorial 08 - Color key 
DirectX/Opengl

En este ejemplo vamos a ver cómo hacer transparente un determinado color de una imagen, lo que se conoce como "color key". Esto nos será útil para poder desarrollar Juegos 2-D.



Vamos a realizar unos cambios en nuestra función LoadTexture() de tal forma que añadimos un canal más (canal alpha) a la imagen RGB.

Modificaremos LoadTexture() para convertir la imagen en una de 32 bits para añadirle el canal alpha para la transparencia. No serviremos de las funciones que nos ofrece freeimage para definir si el píxel es opaco o transparente.


///////////////////////////////////////////////////////////////////////////////
///     LoadTexture: Crea una textura a partir de un fichero.
///
///     @param  char *fileName: Nombre del fichero de la textura.
///     @param  Texture &texture: Estructura a la que se copiará la información
///                 sobre la textura.
///     @param  ulColorRGBA colorKey: Color que haremos transparente.
///
///     @return  int:   
///                     - -1  : error.
///                     - otro: correcto.
///////////////////////////////////////////////////////////////////////////////
int OpenGLVideoDriver::LoadTexture( char *fileName, Texture &texture
// ********************************* NEW **************************************
                                    , ulColorRGBA colorKey
// ****************************************************************************
                                    )
{
    int idTexture= -1;
    char msgError[512];
    FREE_IMAGE_FORMAT imageFormat= FIF_UNKNOWN;
    FIBITMAP *pImage= NULL;
    FIBITMAP *pImageCopy;
// ********************************* NEW **************************************
    unsigned int width, height, x, y;
    RGBQUAD rgbaColor;
// ****************************************************************************

    // Comprobamos el formato del fichero.
    imageFormat= FreeImage_GetFileType(fileName,0);
    if (imageFormat == FIF_UNKNOWN)
        imageFormat= FreeImage_GetFIFFromFilename(fileName);

    // Si es un formato soportado por la librera lo cargamos
    if ( (imageFormat != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(imageFormat) )
    {
        // Cargamos el fichero
        pImage= FreeImage_Load(imageFormat,fileName,0);
        if (pImage)
        {
// ********************************* NEW **************************************
            // Si se especifica un color transparente
            if ( colorKey.rgba != 0xffffffff )
            {
                // Convertimos la imagen a 32 bis para añadirle el canal alpha
                pImageCopy= FreeImage_ConvertTo32Bits( pImage );
                FreeImage_Unload(pImage);
                pImage= pImageCopy;

                width = FreeImage_GetWidth (pImage);
                height= FreeImage_GetHeight(pImage);

                for ( y=0; yfor ( x=0; x// Obtenemos el color del pixel
                        FreeImage_GetPixelColor( pImage, x, y, &rgbaColor );

                        if ( rgbaColor.rgbRed   == colorKey.r &&
                             rgbaColor.rgbGreen == colorKey.g &&
                             rgbaColor.rgbBlue  == colorKey.b )
                            rgbaColor.rgbReserved= 0x00; // Canal Alpha transparente
                        else
                            rgbaColor.rgbReserved= 0xff; // Canal Alpha opaco

                        // Fijamos el nuevo color del pixel
                        FreeImage_SetPixelColor( pImage, x, y, &rgbaColor );
                    }
                }
            }
// ****************************************************************************

            // Si la imagen es de menos de 16 bpp la convertimos
            if ( FreeImage_GetBPP(pImage) < 16 )
            {
                // Si no, convertimos la imagen a 24 bits
                pImageCopy= FreeImage_ConvertTo24Bits( pImage );
                FreeImage_Unload(pImage);
                pImage= pImageCopy;
            }

            // Creamos la textura
            idTexture= CreateTexture(pImage);
            FreeImage_Unload(pImage);
        }
    }

    if ( idTexture != -1)
    {
        strcpy( texture.fileName, fileName );
        m_TextureArray[ m_TextureRefs ]= idTexture;
        texture.idxTexture= m_TextureRefs++;
    }
    else
    {
        sprintf(msgError,"OpenGLVideoDriver::LoadTexture("%s"): error al cargar la textura.",fileName);
        System::ShowMessage("ERROR: ",msgError,true);
        texture.idxTexture= -1;
    }

    return texture.idxTexture;
}

En el método RenderObjects(), especificamos cómo se mezcla el color que vamos a renderizar, con lo que ya se ha renderizado. Con SetBlending() hacemos que para los valores 0x00 del canal alpha no pinte el pixel de nuestra textura y sí cuando sea 0xff.


if( m_bColorKey )
{
    m_pVideoDriver->EnableBlending( true );
    m_pVideoDriver->SetBlending( /*fuente*/eBlendSrcAlpha, /*destino*/eBlendOneMinusSrcAlpha );
}
else
{
    m_pVideoDriver->EnableBlending( false );
    m_pVideoDriver->SetBlending( eBlendDisable );
}

Para que os sirva de base, he añadido un método CheckMovement(), que comprueba si se encuentra pulsada una tecla de cursor, lo cual hace cambiar la posición de la imagen que cuando vaya a renderizarse lo hará en la posición especificada.

Debo indicar también, que en el método OnRender(), se ha cambiado los valores especificados en la proyección SetOrthoProjection() para que ahora el origen de coordenadas se encuentre en el centro de la ventana:


m_pVideoDriver->SetOrthoProjection ( -(float)m_WindowProps.width /2.0f, // left
                                      (float)m_WindowProps.width /2.0f, // right
                                     -(float)m_WindowProps.height/2.0f, // bottom
                                      (float)m_WindowProps.height/2.0f, // top
                                     -1.0f, 1.0f ); // zNear, zFar

Finalmente, podéis echar un ojo a: http://www.panelmonkey.org/category.php?id=1 para ver ejemplos de texturas que os pueden servir para hacer algún jueguecito o crearos vosotros las vuestras.

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



Nota: Compartir en Facebook
Enviado el Miércoles, 05 septiembre a las 18:27:13 por administrador
 
Enlaces Relacionados
· Más Acerca de DirectX/Opengl
· Noticias de administrador


Noticia más leída sobre DirectX/Opengl:
Tutorial 16 - Movimiento-3D - (Tercera Persona)

 
Votos del Artículo
Puntuación Promedio: 5
votos: 1


Por favor tómate un segundo y vota por este artículo:
Excelente
Muy Bueno
Bueno
Regular
Malo

 
Opciones

 Versión Imprimible  Versión Imprimible

 
"Tutorial 08 - Color key" | Entrar / Crear Cuenta | 2 Comentarios | Buscar Discusión
Los comentarios son propiedad de quien los envió. No somos responsables por su contenido.

No se permiten comentarios Anónimos, Regístrese por favor

Re: Tutorial 08 - Color key (Puntuación 1)
por augus1990 el Viernes, 29 marzo a las 00:10:18
(Información del Usuario | Enviar un Mensaje)
Hola, en Code::Blocks me salen los errores:



C:...practica_opengl_4main.cpp|62|undefined reference to `_imp__FreeImage_GetFileType@8'|



C:...practica_opengl_4main.cpp|65|undefined reference to `_imp__FreeImage_GetFIFFromFilename@4'|



C:...practica_opengl_4main.cpp|71|undefined reference to `_imp__FreeImage_FIFSupportsReading@4'|



C:...practica_opengl_4main.cpp|72|undefined reference to `_imp__FreeImage_Load@12'|



C:...practica_opengl_4main.cpp|78|undefined reference to `_imp__FreeImage_GetHeight@4'|



C:...practica_opengl_4main.cpp|79|undefined reference to `_imp__FreeImage_GetWidth@4'|





¿qué hice mal? Gracias desde ya por la ayuda.



Sitio potenciado por NukeProjects.Net        NukeStilo 1.0 se basa en PHP-Nuke        Theme Diseñado por NukeMods

© Antonio Lucas Moreno