[Tutorial] 3. Texturas.

Hola de nuevo.

Siguiendo con los tutoriales de 3D, hoy os voy a explicar a usar texturas a un nivel bastante básico, porque es el que vais a necesitar y yo no se más. :P Para el que no lo sepa, las texturas son las imágenes que se dibujan sobre un polígono en 3D, por lo que es algo fundamental de saber para hacer un juego en 3D. Y empiezo con la explicación:

--------------------------------------------------------------------------------------------

En primer lugar hay que saber que las texturas que vamos a usar necesitan estar en un formato especial. No vale un simple bmp o png, igual que con los sprites con PAlib. En todo caso los podréis usar si hacéis una función que los decodifique durante el juego, con la dificultad y consumo de CPU que implica. Lo mejor que podéis hacer es convertirlas con el bmp2bin (viene con las libnds) y dejaros de problemas, pero también os voy a poner cómo usar imágenes en formato PCX.

--------------------------------------------------------------------------------------------

Para usar incluir texturas a un programa hay que hacer lo siguiente:

-Antes de nada, convertir la imagen deseada al formato que queramos.
-Poner el archivo resultante en source, data u otra carpeta donde el makefile busque archivos. Os recomiendo poner estas cosas en la carpeta data para no mezclarlas con el código.
-Incluir los archivos. Si tu archivo se llamaba "textura.bin" al compilarla se crearán los archivos "textura.o" y "textura.h". Tienes que incluir el archivo "textura.h".

Ahora, para usarlas realmente:

-Activar el uso de texturas en "glEnable()".
-Reservar parte de la VRAM para el uso de las texturas. Tened cuidado con ésto. Hay cuatro bancos principales de VRAM (A, B, C y D). Cada uno de ellos cuenta con 128 Kb. Hay más, de menor tamaño, pero se usan para cargar paletas y otras cosas. Si sólo habéis usado PAlib hasta ahora no sabríais ni que existía esto, por eso os digo que tengáis cuidado. Hay que saber administrar los cuatro bancos principales ya que los vais a necesitar tanto para cargar texturas como spites como fondos. Si usáis mucha VRAM para 3D no os quedará para usar otra pantalla con 2D, y si os quedáis cortos no se cargarán texturas (y los polígonos que las usen se verán blancos).
-Crear sitio para las texuras con "glGenTextures()".
-Cargar las texturas.
-Usarlas...

--------------------------------------------------------------------------------------------

Que uséis texturas no significa que no podáis hacer transparente al cuerpo, o le podáis poner luces o colores. En el siguiente ejemplo veréis cómo cargar texturas en formato bin (obtenida a partir de un bmp) y pcx.

main.c:
#include <PA9.h>
#include "texture_pcx.h"
#include "texture_bmp.h"


#define NUM_TEXTURES 5 //Texturas que vamos a usar


void Dibujar3D();
void Load_Texture_PCX8(u8 * adress, int slot, u8 x, u8 y);
void Load_Texture_BMP(u8 * adress, int slot, u8 sizex, u8 sizey);

float xrot, yrot;
int    texture[NUM_TEXTURES]; //Almacén de las direcciones en la memoria de las texturas.


//Las dos siguientes funciones las he hecho yo a partir de los ejemplos de libnds.

//Para cargar texturas en formato PCX.
void Load_Texture_PCX8(u8 * adress, int slot, u8 x, u8 y)
{
sImage pcx;

//Convertir la textura a un formato adecuado
loadPCX(adress, &pcx);
image8to16(&pcx);

//Almacenar textura en la VRAM
glBindTexture(0, texture[slot]);
glTexImage2D(0, 0, GL_RGB, x , y, 0, TEXGEN_TEXCOORD, pcx.image.data8);

imageDestroy(&pcx);
}

//Para cargar texturas convertidas con bmp2bin
void Load_Texture_BMP(u8 * adress, int slot, u8 sizex, u8 sizey)
{
//Almacenar textura en la VRAM
glBindTexture(0, texture[slot]);
glTexImage2D(0, 0, GL_RGB, sizex , sizey, 0, TEXGEN_TEXCOORD, adress);
}   


int main()
{   
PA_Init();
PA_InitVBL();

PA_InitText(1, 0);
PA_OutputText(1,0,0,"Tutorial de 3D usando libnds\npor AntonioND.\n\n\nEsto es un ejemplo de libnds\nmodificado.");
PA_OutputText(1,0,23,"PAD: Girar cubo.");

videoSetMode(MODE_0_3D);
//Reservamos memoria de la VRAM para almacenar texturas
vramSetBankA(VRAM_A_TEXTURE); //128 Kb
vramSetBankB(VRAM_B_TEXTURE); //128 Kb más... La verdad es que sobran, pero en fin...

glInit();

//Usar texturas
glEnable(GL_TEXTURE_2D | GL_ANTIALIAS);

glClearColor(0,0,0,31);
glClearPolyID(63);
glClearDepth(GL_MAX_DEPTH);

glViewport(0,0,255,191);

//Creamos sitio para las texturas y las cargamos.
glGenTextures(NUM_TEXTURES, &texture[0]);
Load_Texture_PCX8((u8*)texture_pcx,0,TEXTURE_SIZE_128,TEXTURE_SIZE_128);
Load_Texture_BMP((u8*)texture_bmp,1,TEXTURE_SIZE_128,TEXTURE_SIZE_128);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, 256.0 / 192.0, 0.1, 100);

glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);

glMatrixMode(GL_MODELVIEW);

while (1)
{
xrot += Pad.Held.Up - Pad.Held.Down;
yrot += Pad.Held.Left - Pad.Held.Right;       

Dibujar3D();

glFlush(0);

PA_WaitForVBL();
}

return 0;
}

void Dibujar3D()
{
glLoadIdentity();
glTranslatef(0.0,0.0,-5.0);

glRotateX(xrot);
glRotateY(yrot);

glBegin(GL_QUADS);

//Usar textura del slot 0. "GL_TEXTURE_2D" sobra, pero queda más bonito así :P
glBindTexture(GL_TEXTURE_2D, texture[0]);

// Front Face
glColor3f(1,1,1); //Podemos colorear la textura, usar luces sobe ella...
glTexCoord2f(0.0, 0.0); //Asignar a los siguientes vértices el punto de la textura indicado (x,y)
glVertex3f(-1.0, -1.0,  1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
// Back Face
glColor3f(1,0,0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);

glBindTexture(0, texture[1]); //Textura cargada en el slot 1

// Top Face
glColor3f(1,1,1);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
// Bottom Face
glColor3f(0,1,0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);

glBindTexture(0,0);  //No usar texturas

//Aquí sobran los glTexCoord2f() porque no estamos usando ninguna textura
// Right face
glColor3f(1,1,1);  
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
// Left Face
glColor3f(0,0,1);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
glEnd(); //En el fondo ésto también sobra ya que no hace nada...
}


Imagen

En el archivo están las texturas convertidas y también el bmp2bin con la textura original en bmp.

http://www.mediafire.com/?d5ejz3jjm54
Que buenos tutoriales haces sobre el 3D, ya llegará el momento de hacer yo un juego en 3D con éstos tutos xD. Muchas gracias =D.

PD: Primero -^_^-
Celduques está baneado por "utilizar clon para saltarse baneo de subforo y querer tomar el pelo a la administración"
Que pena tener el ordenador donde tengo todo instalado (está sin pantalla xD) Buen tuto a ver si puedo echarle mano pronto [+risas]
Gracias a los tres. Mañana me voy de vacaciones y estoy fuera una semana, asi que no podré ayudaros si lo necesitáis, pero cuando vuelva responderé todas las dudas. :)
Pues que te lo pases bien en las vacas, aver si sobrevives XD
5 respuestas