Alright, I’m working in C++ Visual Studio 2010. I’ve been trying for a while now to load up targa images, load them as textures, and then display them. I’m pretty familiar with the concepts of how to do all those things, but I’m not quite getting it right, it seems. The resulting image is just a distorted mess. Either I’m reading it in wrong, or I’m drawing it to the screen wrong.
Without further adieu, here’s some code. The loading code is pretty well commented, and the drawing code is pretty simple, so I don’t think I have to explain to awfully much. I got most of my targa reading code from here but I added some extra stuff to handle the case where I need to vertical-flip the image. If I’m not explaining enough, just let me know. I’m not sure how smart I’m supposed to assume people are, haha.
My image/texture loading code:
int loadTexture(char * filename)
{
TextureImage texture;
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed non color mapped TGA Header
GLubyte TGAcompare[12]; // Used To Compare TGA Header
GLubyte header[6]; // First 6 Useful Bytes From The Header
GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File
GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram
GLuint rowSize; // Used to store the row size for image flipping
GLuint temp; // Temporary Variable
GLubyte *reverseImage; // for reversing the image
GLuint k; // for a for loop
FILE *file = fopen(filename, "rb");
if( file==NULL || // Does File Even Exist?
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read?
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want?
fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes
{
if (file == NULL) // Did The File Even Exist? *Added Jim Strong*
return -1; // Return False
else
{
fclose(file); // If Anything Failed, Close The File
return -1; // Return False
}
}
texture.width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte)
texture.height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte)
if( texture.width <=0 || // Is The Width Less Than Or Equal To Zero
texture.height <=0 || // Is The Height Less Than Or Equal To Zero
header[4]!=24) // make sure its 24-bit
{
fclose(file); // If Anything Failed, Close The File
return false; // Return False
}
texture.bpp = header[4]; // Grab The TGA's Bits Per Pixel
bytesPerPixel = texture.bpp/8; // Divide By 8 To Get The Bytes Per Pixel
imageSize = texture.width*texture.height*bytesPerPixel;
texture.imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data
if( texture.imageData==NULL || // Does The Storage Memory Exist?
fread(texture.imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved?
{
if(texture.imageData!=NULL) // Was Image Data Loaded
free(texture.imageData); // If So, Release The Image Data
fclose(file); // Close The File
return false; // Return False
}
fclose (file);
for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel) // Loop Through The Image Data
{ // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
temp=texture.imageData[i]; // Temporarily Store The Value At Image Data 'i'
texture.imageData[i] = texture.imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
texture.imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
}
//if pixels start from the bottom left, vertical flip the data
if((header[5] & 0x20) != 0x20)
{
rowSize = bytesPerPixel * texture.width;
reverseImage = (GLubyte *)malloc(imageSize); //need temporary storage
for(GLuint i=0; i<texture.height; i++)
{
memcpy(&reverseImage[imageSize-rowSize*(i+1)], &texture.imageData[i*rowSize], rowSize);
}
memcpy(texture.imageData, reverseImage, imageSize);
}
GLuint textureID = 0;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture.width, texture.height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture.imageData);
return 0;
}
My drawing code:
void GameObject::displayHandler()
{
float vert1[2];
float vert2[2];
float vert3[2];
float vert4[2];
int width;
int height;
float halfWidth;
float halfHeight;
glBindTexture(GL_TEXTURE_2D, textureID);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
halfWidth = width/2;
halfHeight = height/2;
vert1[0] = -halfWidth;
vert1[1] = -halfHeight;
vert2[0] = halfWidth;
vert2[1] = -halfHeight;
vert3[0] = halfWidth;
vert3[1] = halfHeight;
vert4[0] = -halfWidth;
vert4[1] = halfHeight;
glPushMatrix();
glTranslatef(x, y, 0);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2fv(vert1);
glTexCoord2f(1, 0);
glVertex2fv(vert2);
glTexCoord2f(1, 1);
glVertex2fv(vert3);
glTexCoord2f(0, 1);
glVertex2fv(vert4);
glEnd();
glPopMatrix();
}