Loading TGA files in C++ for use with OpenGL

Among the many samples and examples in the leaked PS3 SDK there is a function for recording screenshots in tga format. After finding it I decided to simply rewrite it to essentially work in reverse so that I could load TGA files and use them as textures for PSGL games. It was simple to do and works beautifully on PC. But for some reason it fails to correctly read the width and height of the images when I run it on PS3. It seems to work fine if I hard code in what width and height to use but it refuses to correctly read that from the tga files despite it doing so on Windows. I’ve wasted away the last two days trying to get it to work and have failed to do so. Can anyone see anything wrong with the bellow source code that could explain the failure?


GLuint loadtga(char* filename,bool mipmap){

unsigned char header[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
unsigned char bpp = 32;
unsigned char id = 8;
unsigned short width;
unsigned short height;
unsigned char *pPixels = NULL;
FILE *fp = NULL;

fp = fopen(filename,"r");

fread(header,sizeof(unsigned char),12,fp);
fread(&width,sizeof(unsigned short),1,fp);
fread(&height,sizeof(unsigned short),1,fp);
fread(&bpp,sizeof(unsigned char),1,fp);
fread(&id,sizeof(unsigned char),1,fp);

pPixels = new unsigned char[width * height * 4];
fread(pPixels, 4, width * height, fp);
fclose(fp);

GLuint texName;
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glGenTextures(1,&texName);
glBindTexture(GL_TEXTURE_2D,texName);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
if(mipmap==0){
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
if(mipmap==1){
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,width,height,
GL_BGRA,GL_UNSIGNED_BYTE,pPixels);
}
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,
0,GL_BGRA,GL_UNSIGNED_BYTE,pPixels);

delete pPixels;

return texName;

}

More then getting it to work I just really want to know WHY it isn’t working already.

6 Responses to Loading TGA files in C++ for use with OpenGL

  1. […] a solution. If you think you know what the problem might be, feel free to hit him up at: Source: thatotherdev.wordpress.com […]

  2. themaister says:

    This is an endian issue. You’re reading the width and height directly from the file. I assume TGA files are little-endian, while the PS3 is big-endian. Thus you would get values that are completely bogus. Try to do a byte flip of your width/height values.

  3. PuppetMaster says:

    Glad to see you got things sorted out. 😉

  4. RhDo says:

    You also have another problem which I ran into following your example. If you enable mipmap, the texture won’t draw, because you used gluBuild2DMipmaps before glTexImage2D.

    • thatotherdev says:

      I’ve been using it with mipmaps on for the majority of my textures and they have been getting drawn properly. So I’m not sure why its caused a problem for you. Maybe its some inconsistency relating to how OpenGL functions on different platforms.

      But you’re totally right. It seems that glTexImage2D doesn’t need to be called at all (before or after) when using gluBuild2DMipmaps. I’ve moved it to just before the closing bracket of if(mipmap==0) and everything is still working fine.

      Thanks for pointing that out.

Leave a comment