Sign in to follow this  
cozzie

TGA loading error, psp9?

Recommended Posts

Hi all. After a few months I decided to start working on my 3d engine again. No I've noticed something strange I load a tga texturefile in my engine, result = fine. When I open that specific TGA-file in Paint Shop Pro 9 and save it again as compressed or uncompressed TGA file in 24 or 32bit (all options tried), my TGA-loader in my engine gives an error and doesn't load the texture. It seems that Paint Shop Pro 9 does something to my TGA file, but I cant find out why. I've uploaded the working TGA file and the non-working TGA file: http://www.sierracosworth.nl/coding/good.tga and http://www.sierracosworth.nl/coding/bad.tga My sourcecode was always able to read both compressed and uncompressed and both 24 or 32bit TGA files. All help is wellcome.

Share this post


Link to post
Share on other sites
Loads fine with my routine :)

Both images are flagged the same, 24bit, not upside down, no palette, not compressed.

A difference is in the header, the TGA saved from PSP9 (crap anyway since 8) has got a ID field length of 1 as opposed to the original image, which doesn't have that field (length 0).

After reading the 18 byte header simply advance the file pointer by the length of the id field.

Share this post


Link to post
Share on other sites
Here it is:
(probably to much, but ok :))


bool GLtexture::LoadTGA(char *filename, int which)
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};
GLubyte TGAcompare[12];
GLubyte header[6];
GLuint bytesPerPixel;
GLuint imageSize;
GLuint temp;
GLuint type;

FILE *file = fopen(filename, "rb");
if(file == NULL ||
fread(TGAcompare, 1, sizeof(TGAcompare),file) != sizeof(TGAcompare) ||
memcmp(TGAheader, TGAcompare, sizeof(TGAheader)) !=0 ||
fread(header, 1, sizeof(header), file) != sizeof(header))
{
if(file == NULL) return false;
else
{
fclose(file);
return false;
}
}

width = header[1] * 256 + header[0];
height = header[3] * 256 + header[2];

if(texture <=0 || texture <=0 || (header[4]!=24 && header[4]!=32))
{
fclose(file);
return false;
}

bpp = header[4];
if(bpp == 24)
{
type=GL_RGB;
}
if(bpp == 32)
{
type=GL_RGBA;
}

bytesPerPixel = bpp/8;
imageSize = width*height*bytesPerPixel;

imageData = (GLubyte *)malloc(imageSize);
if(imageData==NULL ||
fread(imageData, 1, imageSize, file) != imageSize)
{
if(imageData != NULL) free(imageData);

fclose(file);
return false;
}

for(GLuint i=0;i<int(imageSize);i+=bytesPerPixel)
{
temp=imageData[i];
imageData[i] = imageData[i + 2];
imageData[i + 2] = temp;
}
fclose (file);

glGenTextures(1, &texture[which]);
glBindTexture(GL_TEXTURE_2D, texture[which]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, type,
GL_UNSIGNED_BYTE, imageData);

return true;
}



Share this post


Link to post
Share on other sites
Looks strikingly like the NeHe loader. Don't use it. Seriously, just grab the format and do it yourself, not only will you gain a decent TGA loader, but it'll also teach you a lot. The problem with the NeHe loader is primarily how it loads the header, it just disregards most of the information. Yours isn't exactly the same looking at it, however, it will only load one type of TGA, and won't support the newer TGA format - If memory serves.

Share this post


Link to post
Share on other sites
Your "loader" doesn't really check much of the header, and if there's a different format or bit set it bails out (with the memcmp test).

In this case the PSP9 modified TGA header has the value of 1 in the first byte of the TGAHeader struct. The method of using memcmp to test for the header bits is just completely wrong from a loader design view.

For a quick hack solution change the memcmp line to:

memcmp(&TGAheader[1], &TGAcompare[1], sizeof(TGAheader) - 1 ) !=0

BUT I SERIOUSLY ADVISE AGAINST THAT SOLUTION. It's fugly(TM).


Seriously, get rid of the memcmp and look up the file format at Wotsit. It's pretty easy actually.

Share this post


Link to post
Share on other sites
Tried the solution and it does work sometimes.
But since I'm trying to build a nice reliable engine, I'll read myself into the TGA fileformat and make a new load function.

Thanks for the help

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this