Mostrando entradas con la etiqueta SOIL. Mostrar todas las entradas
Mostrando entradas con la etiqueta SOIL. Mostrar todas las entradas

miércoles, 8 de junio de 2011

GameEngine: Capitulo 6 . Texture Manager

Hola a todos,

Bienvenidos a una nueva entrega sobre como hacer tu propio game engine desde 0.

En este capítulo explicaremos la implementación del texture manager. A grandes rasgos es lo mismo que el soundmanager pero para texturas. Es decir, cargaremos las texturas mediante un archivo de loading y accederemos a ellas mediante tags.

La carga de texturas (por ahora) la implementaremos con SOIL (quien quiera hacerlo con otra libreria y pasarmelo , yo se lo publico). La libreria SOIL es una manera muy potente de cargar texturas para su uso en 2D/3D . Os la podeis bajar de aquí 

Como unir SOIL al proyecto.
Una vez tengáis instalada la librería (mirad por Internet, no os lo voy ha hacer yo todo :D ) tendremos que linkarla al proyecto. Como ya hicimos en algún capítulo anterior:
1.propiedades de proyecto > C/C++ > Directorios de inclusión adicionales > “la ruta donde tengais instalados los .h de SOIL”
2. propiedades de proyecto > Vinculador>.Entrada > Dependencias adicionales : SOIL.lib

Con esto os deberia de funcionar todo. Si teneis problemas poned un comentario en este post y lo miraremos.

Como implementar el TextureManager
El texture manager se compone de un .h y un .cpp c on una estructura interna muy parecida al Sound Manager , así como de cambios en el GraphicsManager (inicialización , carga, descarga ,etc..) y en el Graphics3DManager (texturizaremos el cubo que teniamos hasta ahora con un gráfico de madera)

El código es el siguiente:
TextureManager.h:
/**************************************************************************************************/
// Código creado por F.Bordas (LordPakus) como ejemplo de creación de un game engine
// para el blog LordPakus (http://lordpakus.blogspot.com/).
// Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

/**************************************************************************************************/
// TextureManager.h : Código del gestor de texturas del game engine
// El código del cargador de texturas se obtiene de http://www.lonesock.net/soil.html
/**************************************************************************************************/

#ifndef __TextureManager__
#define __TextureManager__

#include "MyGL.h"
#include "FileManager.h" //Sirve para cargar el archivo de loading de texturas

#define MAX_ELEMENTS_LOADED 256 //por ahora hardcodeado, lo arreglaremos en algún momento.


class TextureManager
{
private:
// Constructor y destructor de la clase
static TextureManager instance;
TextureManager();
~TextureManager();

public:
static TextureManager& singleton();

public:
//Funcion para inicializar el motor de sonido
void Init(int* argc, char* argv[]);

//Funcion para desinicializar el motor de sonido
void DeInit();

public:
int LoadTexture( char cad[] );
void Texture(char id[]);

private:
FileManager filemanager;

char loaded[MAX_ELEMENTS_LOADED][256]; //Matriz donde guardamos los identificadores de textura y sus indices.

};


#endif // __FileManager__


TextureManager.cpp:
/**************************************************************************************************/
// Código creado por F.Bordas (LordPakus) como ejemplo de creación de un game engine
// para el blog LordPakus (http://lordpakus.blogspot.com/).
// Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

/**************************************************************************************************/
// TextureManager.cpp : Código del gestor de texturas del game engine
// El código del cargador de texturas se obtiene de http://www.lonesock.net/soil.html
/**************************************************************************************************/
#include "TextureManager.h"
#include "MyGL.h"

#include <SOIL/SOIL.h> //Libreria usada para cargar texturas

#include <iostream> //Usada para imprimir por consola

using namespace std;

//Instancia única del sound manager
TextureManager TextureManager::instance;

TextureManager::TextureManager()
{
}

TextureManager::~TextureManager()
{
}

//Devolvemos el puntero al singleton
TextureManager& TextureManager::singleton()
{
return instance;
}

//Sounds functions
void TextureManager::Init(int* argc, char* argv[])
{
char cad[256]; //Cadena donde guardaremos cada linea que leamos
char id[256]; //Cadena donde guardaremos el identificador de cada recurso
char ruta[256]; //Cadena donde guardaremos la ruta de cada recurso
int num_id; //número que nos asigna la función de carga del recurso.... un -1 significa que no lo ha podido cargar

cout << "Inicializamos el texture manager\n";

//alutInit(argc, argv) ;

filemanager.Init("Data\\LoadTexture.txt");


//Todo este código tendrá que ir al filemanager, pero por el momento lo dejamos aquí
//Leemos cada linea del archivo
while( filemanager.GetLine(cad) )
{
for( int i = 0 ; i < strlen(cad); ++i)
{
if ( cad[i] == '=' )
{
cad[i]='\0';
sprintf(id,"%s",cad);
sprintf(ruta,"%s",&cad[i+1]);
i = 257;
}
}

num_id = LoadTexture(ruta); //Cargamos el recurso
cout << "Intentamos cargar textura con ruta:" << ruta << "\n";

if (num_id == -1) //Si el recurso no se ha podido cargar, vamos a cargar el siguiente recurso
continue;

cout << "textura cargada con identificadores:" << id << " " << num_id << "\n";

sprintf( loaded[ num_id ] ,"%s" , id ); //Nos guardamos la referencia al recurso
}
}

void TextureManager::DeInit()
{
cout << "Desinicializamos el texture manager\n";
filemanager.DeInit();
}


//Carga el sonido cad y devuelve su posición en la que se ha guardado
int TextureManager::LoadTexture( char cad[] )
{
//TODO : Evaluar los casos en los que el archivo no se puede cargar y devolver un -1 en consecuencia
return ( SOIL_load_OGL_texture(
cad,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT)
);
}

//Función usada para seleccionar una textura en especial
void TextureManager::Texture(char id[])
{
int i; //Iterador
for ( i = 0 ; i < MAX_ELEMENTS_LOADED ; ++i ) //Para cada elemento cargado
{
if( !strcmp(loaded[i],id) ) //Hemos encontrado la cadena que nos interesa
{
continue;
}
}

if ( i == MAX_ELEMENTS_LOADED)
return;

//Texturizamos
glBindTexture(GL_TEXTURE_2D, i);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

}

GraphicsManager.cpp:
/**************************************************************************************************/
// Código creado por F.Bordas (LordPakus) como ejemplo de creación de un game engine
// para el blog LordPakus (http://lordpakus.blogspot.com/).
// Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

/**************************************************************************************************/
// GraphicsManager.cpp : Código del motor gráfico.
/**************************************************************************************************/

#include "GraphicsManager.h"
#include "MyGL.h"

#include "Graphics3DManager.h" //Parte de 3D del motor gráfico
#include "TextureManager.h" //Inclusión del motor de texturas

#include <iostream> //Usada para imprimir por consola

using namespace std;

//Instancia única del graphics manager
GraphicsManager GraphicsManager::instance;

//Constructor
GraphicsManager::GraphicsManager()
{
}

//Destructor
GraphicsManager::~GraphicsManager()
{
}

//Devolvemos el puntero al singleton
GraphicsManager& GraphicsManager::singleton()
{
return instance;
}

//Funcion para inicializar el motor gráfico
void GraphicsManager::Init(int* argc, char* argv[])
{
cout << "Inicializamos el Graphics Manager\n";
//Creamos la ventana principal del programa utilizando la libreria GLUT
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(0, 0);
glutInitWindowSize(640, 480);
int mainWindow = glutCreateWindow("Lord Pakus Engine!!!"); //Viva la originalidad!!! :)
glutSetWindow(mainWindow);

//Asignamos todas las funciones gráficas de callback del glut
//a las funciones que definiremos posteriormente
glutDisplayFunc(Render);
// glutReshapeFunc(Reshape); //Por ahora la dejamos comentada por que no nos hace falta

TextureManager::singleton().Init(argc,argv); //Inicializamos las texturas
Graphics3DManager::singleton().Init(argc,argv); //Inicializamos la parte de 3D
}

//Funcion para desinicializar el bucle principal
void GraphicsManager::DeInit()
{
TextureManager::singleton().DeInit(); //Desinicializamos la parte de texturas
Graphics3DManager::singleton().DeInit(); //Desinicializamos la parte de 3D

cout << "Desinicializamos el Graphics Manager\n";
}

//CALLBACKS DE GLUT, por ahora

//Funcion que se ejecuta automaticamente desde glut (por ahora)
void GraphicsManager::Render()
{
//Pintado de la parte de 3D
Graphics3DManager::singleton().Render();

//IMPORTANTE: Función encargada de realizar el double-buffering
glutSwapBuffers();
}

//Funcion que se ejecuta automaticamente desde glut (por ahora). Por el momento la dejamos comentada por que no nos hace falta
//void GraphicsManager::Reshape()
//{
// //AQUI IRÁ NUESTRA FUNCIÓN DE REESCALADO. Por ahora vacia
//}


Graphics3DManager: Se aplica solo este cambio dentro de la función de pintado.
glEnable(GL_TEXTURE_2D);
glColor3f(1.0f,1.0f,1.0f); //Limpiamos el buffer de color
TextureManager::singleton().Texture("wood"); //Usamos la textura

glBegin(GL_QUADS); // Start Drawing The Cube
//glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glTexCoord2f( 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
glTexCoord2f( 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
glTexCoord2f( 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
glTexCoord2f( 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
//glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
glTexCoord2f( 0.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
glTexCoord2f( 0.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
glTexCoord2f( 1.0f, 1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
glTexCoord2f( 1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
//glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glTexCoord2f( 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
glTexCoord2f( 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
glTexCoord2f( 1.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
glTexCoord2f( 1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)

//glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
glTexCoord2f( 0.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Back)
glTexCoord2f( 0.0f, 1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Back)
glTexCoord2f( 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Back)
glTexCoord2f( 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Back)

//glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glTexCoord2f( 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
glTexCoord2f( 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
glTexCoord2f( 1.0f, 1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
glTexCoord2f( 1.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)

//glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
glTexCoord2f( 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
glTexCoord2f( 0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
glTexCoord2f( 1.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
glTexCoord2f( 1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing The Quad
glDisable(GL_TEXTURE_2D);



Espero que os haya gustado. Aunque este capitulo os parezca una tonteria es el que nos servirá de base para absolutamente todo el módulo de Graphics2DManager y lo usaremos con cierta recurrencia para múltiples utilidades (graficos 2D, fuentes bitmapeadas , HUD , texturización de modelos 3D ,etc...)

Probad que os funcione y si veis que os falla, lo miramo.

LordPakusBlog
Nos vemosss

Entradas populares