Original Post
hi, I am having a problem with loading TGA image. The problem resides in the part where I have set up a message box saying " error: incorrect file size"; I have commented where the problem lies. If I comment that section of the code out, then I see the tga loaded onto the polygon. If I dont comment it then there is a porblem because I close the file and return false. You might think why not comment that part of the code and forget about it. I could but I am confused and curious on why this happens. Here is my code :
#include <windows.h>
#include <GL/glut.h>
#include <stdio.h>
#include <string>
GLfloat rot = 0.0;
typedef struct
{
unsigned char * imageDate; //image data upto 32 bits;
int bitsPerPixels; // Image color depth in bits per pixels. Should be either 24 || 32.
int width; //texture width
int height; //texture height
unsigned int textureID; //texture ID used to Select a Texture
} TextureImage;
TextureImage texture[1]; //storage for one texture.
bool TGALoader(TextureImage* texture, char* Filename)
{
unsigned char ucTGAheader[12] = {0,0,2,0,0,0,0,0,0,0,0,0}; //uncompressed TGA header.
unsigned char ucTGAcompare[12] = {0}; //used to compare TGAheader.
unsigned char ucheader[6]; //First 6 useful byte from the header.
int ihowManyBytePerPixels; //hold the number of bytes per pixels in TGA header.
int iImageSize; //Used to store the Image Size using RAM.
int itemp; //Used as a temporary variable to switch bit blue to bit Red.
int itype = GL_RGBA; //set the default GL Mode to RGBA (32 bits per pixels);
FILE* pFile = NULL;
pFile = fopen(Filename,"rb");
if(pFile == NULL
|| //Does file exist?
fread(ucTGAcompare,1,sizeof(ucTGAcompare),pFile)!=sizeof(ucTGAcompare) //Are there 12 bytes to read?
||
memcmp(ucTGAheader,ucTGAcompare,sizeof(ucTGAheader)) != 0 //Does the header match to TGAcompare?
||
fread(ucheader,1,sizeof(ucheader),pFile) != sizeof(ucheader) ) //If so read the next 6 bytes.
{
MessageBox(NULL, L"ERROR : Cannot read Targa", L"LOADING IMAGE", MB_OK); //If reading targa fails show failed message.
fclose(pFile);
return false;
}
texture->width = ucheader[1] * 256 + ucheader[0]; //Determine TGA width : (highbyte * 256 + lowbyte);
texture->height= ucheader[3] * 256 + ucheader[2]; //Determine TGA height: (highbyte * 256 + lowbyte);
if(texture->width <= 0
||
texture->height <= 0
||
(ucheader[4] !=24 && ucheader[4] !=32)
)
{
MessageBox(NULL,L"ERROR : texture dimension does not equal 24 || 32 bytes",L"LOADING TARGA",MB_OK);
fclose(pFile);
return false;
}
texture->bitsPerPixels = ucheader[4]; //Set bytesperpixel to header[4] which is how many bitsperpixels this targa img has.
ihowManyBytePerPixels = texture->bitsPerPixels / 8; //Divide by 8 to get byte per pixels. 1 byte = 8 bits.
iImageSize = texture->width * texture->height * texture->bitsPerPixels ; //Calculate Memory Required for image.
texture->imageDate = (unsigned char*) malloc(iImageSize); //Reserve memory required for image.
if( texture->imageDate == NULL //Check if memory was allocated.
||
fread(texture->imageDate,1,iImageSize,pFile) != iImageSize //Did we read the entire image?
)
{
if(texture->imageDate != NULL) // If any image data was read
free(texture->imageDate); //Then free it because it did not match our settings.
//WHERE THE PROBLEM LIES!README_README_README_README_README_README_README_README_README_README_README_README_README_README_
fclose(pFile);
MessageBox(NULL,L"ERROR: INCORRECT IMAGE SIZE",L"READING IMAGE",MB_OK);
return false;
}
for(int i=0 ; i < (int)iImageSize ; i += ihowManyBytePerPixels) //Loop through the Image Data.
{
itemp = texture->imageDate; //set temp to the blue pixel in the image data. Targa = BGR.
texture->imageDate = texture->imageDate[i+2]; // switch the B component to the R component.
texture->imageDate[i+2] = itemp; //Now switch the R component to B component.
}
fclose(pFile);
glGenTextures(1,&texture[0].textureID); //Generate our texture ID.
glBindTexture(GL_TEXTURE_2D,texture[0].textureID); //Bind our texture.
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
if(texture[0].bitsPerPixels == 24) //Check if we have alpha (24 bits?) channel or not.
itype = GL_RGB; //if not then change our default type.
glTexImage2D(GL_TEXTURE_2D,0,itype,texture[0].width,texture[0].height,0,itype,GL_UNSIGNED_BYTE,texture[0].imageDate);
return true;
}
GLvoid initGL()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearDepth(1.0f);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
TGALoader(&texture[0],"img.TGA");
}
GLvoid reshape(int x, int y)
{
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,(float)x/(float)y,5.0,200);
}
GLvoid keyboard(unsigned char key, int x, int y)
{
if(key == ' ') exit(0);
}
GLvoid DrawProgram()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-5);
glRotatef(rot,0,1.0,0);
glutSolidCube(1.0);
glutSwapBuffers();
glutPostRedisplay();
rot+=0.1;
}
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(" Hello Opengl Window");
initGL();
glutDisplayFunc(DrawProgram);
glutReshapeFunc(reshape);
glutIdleFunc(DrawProgram);
glutKeyboardFunc(keyboard);
glutMainLoop ();
return 0;
}