Hello everybody
I have a problem to load the .3DS file format textures in my application.
I have got a example in the internet to load .3DS and apply the textures in the model. But when the model is showed in my OpenGL application, the textures are no going into the right place.
I'm using SDL_image to load the .tga file format whit IMG_Load(). But when I use the LoadBitmap example, that load only .bmp files, the textures are loaded into the right place. My model works. The problem is that I want to use .tga files instead .bmp.
Note too that using IMG_Load to load .bmp files, doesn't work too. The problem is that IMG_Load or a OGL flag. I don't now what is!
My model loaded with IMG_Load():
http://geocities.yahoo.com.br/megaspeedlinux/und/screens/argh04.jpg
This is the functions I'm using to load a .BMP and .TGA file formats:
int LoadBitmap(char *filename)
{
FILE * file;
char temp;
long i;
BITMAPINFOHEADER infoheader;
num_texture++; // The counter of the current texture is increased
if( (file = fopen(filename, "rb"))==NULL) return (-1); // Open the file for reading
fseek(file, 18, SEEK_CUR); /* start reading width & height */
fread(&infoheader.biWidth, sizeof(int), 1, file);
fread(&infoheader.biHeight, sizeof(int), 1, file);
fread(&infoheader.biPlanes, sizeof(short int), 1, file);
if (infoheader.biPlanes != 1) {
printf("Planes from %s is not 1: %u\n", filename, infoheader.biPlanes);
return 0;
}
// read the bpp
fread(&infoheader.biBitCount, sizeof(unsigned short int), 1, file);
if (infoheader.biBitCount != 24) {
printf("Bpp from %s is not 24: %d\n", filename, infoheader.biBitCount);
return 0;
}
fseek(file, 24, SEEK_CUR);
// read the data.
infoheader.data = (char *) malloc(infoheader.biWidth * infoheader.biHeight * 3);
if (infoheader.data == NULL) {
printf("Error allocating memory for color-corrected image data\n");
return 0;
}
if ((i = fread(infoheader.data, infoheader.biWidth * infoheader.biHeight * 3, 1, file)) != 1) {
printf("Error reading image data from %s.\n", filename);
return 0;
}
for (i=0; i<(infoheader.biWidth * infoheader.biHeight * 3); i+=3) { // reverse all of the colors. (bgr -> rgb)
temp = infoheader.data;
infoheader.data = infoheader.data[i+2];
infoheader.data[i+2] = temp;
}
fclose(file); // Closes the file stream
glBindTexture(GL_TEXTURE_2D, num_texture); // Bind the ID texture specified by the 2nd parameter
// The next commands sets the texture parameters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //The minifying function
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // We don't combine the color with the original surface color, use only the texture map.
// Finally we define the 2d texture
glTexImage2D(GL_TEXTURE_2D, 0, 3, infoheader.biWidth, infoheader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, infoheader.data);
// And create 2d mipmaps for the minifying function
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, infoheader.biWidth, infoheader.biHeight, GL_RGB, GL_UNSIGNED_BYTE, infoheader.data);
free(infoheader.data); // Free the memory we used to load the texture
return (num_texture); // Returns the current texture OpenGL ID
}
///////////////////////.TGA
int modelo3DS::carregar_texturas(float filtro, std::string textura_s ){
uint i = 0;
unsigned int tamanho_vettexs = 1;
SDL_Surface *TexsImageModel[tamanho_vettexs];
texture_mdl = new GLuint[tamanho_vettexs];
for ( i=0; i < tamanho_vettexs; i++ ){
TexsImageModel = IMG_Load( "data/faltatex.tex.tga" );
}
textura_s.erase((textura_s.length() - 3), 3);
textura_s += "tex.tga";
std::cout << "Textura Utilizada: " << textura_s << std::endl;
TexsImageModel[0] = IMG_Load( textura_s.c_str() );
//TexsImageModel[0] = IMG_Load( "data/models/spaceship.tex.tga" );
for ( i=0; i < tamanho_vettexs; i++ )
{
glGenTextures( 1, &texture_mdl );
glBindTexture( GL_TEXTURE_2D, texture_mdl );
//Carrega texturas como 2D se for NEAREST
if ( filtro == GL_NEAREST ){
glTexImage2D( GL_TEXTURE_2D, 0, 4, TexsImageModel->w,
TexsImageModel->h, 0, GL_BGRA,
GL_UNSIGNED_BYTE, TexsImageModel->pixels );
}else{ //Carrega texturas como MIPMAP se for LINEAR
gluBuild2DMipmaps(GL_TEXTURE_2D, 4,
TexsImageModel->w, TexsImageModel->h,
GL_BGRA, GL_UNSIGNED_BYTE,
TexsImageModel->pixels);
}
//Aplica GL_REAREST para o MAG, se o MIN for GL_NEAREST também.
if ( filtro == GL_NEAREST ){
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}else{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtro);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // We don't combine the color with the original surface color, use only the texture map.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
for ( i=0; i < tamanho_vettexs; i++ )
{
if ( TexsImageModel ){
SDL_FreeSurface( TexsImageModel );
}
}
//std::cout << "Texturas do modelo carregadas." << std::endl;
return (texture_mdl[0]); // Returns the current texture OpenGL ID
}