class TEXTURE
{
private:
typedef struct
{
GLubyte Header[6]; //holds the first 6 useful bytes of the file
GLuint bytesPerPixel; //number of BYTES Per Pixel (3 or 4)
GLuint imagesize; //amount of memory needed to hold the image
GLuint temp;
GLuint type; //the type of image, GL_RGB or GL_RGBA
GLuint h; //height of image
GLuint w; //width of image
GLuint bpp; //number of BITS Per Pixel (24, or 32)
} TGA;
TGA tga; //used to store file info
bool LoadUncompressedTGA(FILE* file)
{
if(fread(tga.Header, sizeof(tga.Header), 1, file) == 0)
{
fprintf(stderr, "Error Opening UnCompressed TGA File\n");
return false;
}
x = tga.Header[1] * 256 + tga.Header[0];
y = tga.Header[3] * 256 + tga.Header[2];
bpp = tga.Header[4];
tga.w = x;
tga.h = y;
tga.bpp = bpp;
if((x <= 0) || (y <= 0) || ((bpp != 24) && (bpp != 32)))
{
fprintf(stderr, "Error x, y, and/or, bpp has in invalid value\n");
return false;
}
if(bpp == 24)
{
type = GL_RGB;
}else{
type = GL_RGBA;
}
tga.bytesPerPixel = (tga.bpp / 8);
tga.imagesize = (tga.bytesPerPixel * tga.w * tga.h);
//data = (GLubyte*)malloc(tga.imagesize);
data = (char*)malloc(tga.imagesize);
if(data == 0)
{
fprintf(stderr, "Error in memory!");
return false;
}
if(fread(data, 1, tga.imagesize, file) != tga.imagesize)
{
fprintf(stderr, "Image not the right size\n", file);
return false;
}
return true;
}
bool LoadCompressedTGA(FILE* file)
{
if(fread(tga.Header, sizeof(tga.Header), 1, file) == 0)
{
fprintf(stderr, "Error Opening UnCompressed TGA File\n");
return false;
}
x = tga.Header[1] * 256 + tga.Header[0];
y = tga.Header[3] * 256 + tga.Header[2];
bpp = tga.Header[4];
tga.w = x;
tga.h = y;
tga.bpp = bpp;
if((x <= 0) || (y <= 0) || ((bpp != 24) && (bpp != 32)))
{
fprintf(stderr, "Error x, y, and/or, bpp has in invalid value\n");
return false;
}
if(bpp == 24)
{
type = GL_RGB;
}else{
type = GL_RGBA;
}
tga.bytesPerPixel = (tga.bpp / 8);
tga.imagesize = (tga.bytesPerPixel * tga.w * tga.h);
//data = (GLubyte*)malloc(tga.imagesize);
data = (char*)malloc(tga.imagesize);
if(data == 0)
{
fprintf(stderr, "Error in memory!\n");
return false;
}
GLuint pixelcount = tga.h * tga.w; //number of pixels in the image
GLuint currentpixel = 0; //current pixel we are reading data from
GLuint currentbyte = 0; //current byte we are writing into imagedata
//try char ! GLubyte
GLubyte* colorbuffer = (GLubyte*)malloc(tga.bytesPerPixel); //storage for one pixel
do
{
GLubyte chunkheader = 0; //var to store the value of the id chunk
if(fread(&chunkheader, sizeof(GLubyte), 1, file) == 0) //try to read the chunks header
{
fprintf(stderr, "Error reading chunks header!\n");
return false;
}
if(chunkheader < 128) //if the chunk is a RAW chunk
{
chunkheader++; //add 1 to the value to get the total number of raw pixels
//start pixel reading loop
for(short counter = 0; counter < chunkheader; counter++)
{
//try to read 1 pixel
if(fread(colorbuffer, 1, tga.bytesPerPixel, file) != tga.bytesPerPixel)
{
fprintf(stderr, "Error reading pixel 1\n"); //the error is here
return false;
}
data[currentbyte] = colorbuffer[2]; //write the 'R' byte
data[currentbyte + 1] = colorbuffer[1]; //write the 'G' byte
data[currentbyte + 2] = colorbuffer[0]; //write the 'B' byte
//if its a 32bpp image
if(tga.bytesPerPixel == 4)
{
data[currentbyte + 3] = colorbuffer[3]; //write the 'A' byte
}
currentbyte += tga.bytesPerPixel; //increment teh byte counter by the number of bytes per pixel
currentpixel++; //increment by 1
}
}else{
chunkheader -= 127; //subtract 127 to get rid of the id bit
//read the next pixel
if(fread(colorbuffer, 1, tga.bytesPerPixel, file) != tga.bytesPerPixel)
{
fprintf(stderr, "Error Reading Pixel 2\n");
return false;
}
//start the loop
for(short counter =0; counter < chunkheader; counter++)
{
data[currentbyte] = colorbuffer[2]; //cpy the 'R' byte
data[currentbyte + 1] = colorbuffer[1]; //cpy the 'G' byte
data[currentbyte + 2] = colorbuffer[0]; // cpy the 'B' byte
if(tga.bytesPerPixel == 4)
{
data[currentbyte + 3] = colorbuffer[3];
}
}
currentbyte += tga.bytesPerPixel;
currentpixel++;
}
}while(currentpixel < pixelcount);
fclose(file);
return true;
}
public:
unsigned long x;
unsigned long y;
unsigned short int bpp;
char* data;
unsigned int ID;
GLuint type;
TEXTURE()
{
type = GL_RGB;
}
bool LoadTGA(char* FileName)
{
//find out if its compressed or not
GLubyte tgaheader[12];
//uncompressed tga header
GLubyte uTGAcompare[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
//compressed tga header
GLubyte cTGAcompare[12] = {0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0 ,0};
FILE* file;
file = fopen(FileName, "rb");
if(file == 0)
{
fprintf(stderr, "Error invalid TGA file: %s\n", FileName);
return false;
}
if(fread(&tgaheader, sizeof(tgaheader), 1, file) == 0)
{
fprintf(stderr, "Error invalid TGA file: %s\n", FileName);
fclose(file);
return false;
}
if(memcmp(uTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
{
fprintf(stderr, "loading uncompressed...\n");
//load an uncompressed tga
if(LoadUncompressedTGA(file) == false)
{
fprintf(stderr, "Error Loading UnCompressed TGA File: %s\n", FileName);
fclose(file);
return false;
}
}else if(memcmp(cTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
{
fprintf(stderr, "loading compressed...\n");
//load compressed tga
if(LoadCompressedTGA(file) == false)
{
fprintf(stderr, "Error Loading Compressed TGA File: %s\n", FileName);
fclose(file);
return false;
}
}else{
fprintf(stderr, "Error invalid TGA file: %s\n", FileName);
fclose(file);
return false;
}
fclose(file);
return true;
}
/*
"Both width and height must have the form 2^m + 2b, where m is a non-negative integer (which can have a
different value for width than for height) and b is the value of border. The maximum size of a texture
map depends on the implementation of OpenGL, but it must be at least 64 x 64 (or 66 x 66 with borders)."
--OpenGL Programming Guide
Meaning:
You can use width or height of 2, 4, 8, 16, 32, 64, (on new video cards) 128, 256, 512 (They dont have
to be the same)
If you have a texture border you add 2 to the size.
*/
int LoadTexture(char* FileName)
{
if(LoadTGA(FileName) == 0)
{
return 0;
}
glGenTextures(1, &ID);
glBindTexture(GL_TEXTURE_2D, ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, x, y, 0, type, GL_UNSIGNED_BYTE, data);
return 1;
}
};
Loading a Compressed TGA file
I read the NeHe tutorial on reading tga files(compressed and uncompressed) I changed the code a lil since I also have my class reading a BMP. It reads the BMP and uncompressed tga files fine but everytime I goto read a compressed tga my program gives me the same error, "Error reading pixel". Ive gone over the code countless times I have no idea whats wrong. Can someone please help me?
Thanks,
Nuke
P.S: The error is in the LoadCompressed I commented out the line that gives me the error
[edited by - nukem on September 25, 2002 10:17:00 PM]
--------------------------Nukemmsn: nukem996@hotmail.comaim: nukem996open source open mind
dude, use the [ source] and [ /source] tags (minus the space of course).
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Formats______________________________________________________________________________________
heh sorry I used < source > < /source >
--------------------------Nukemmsn: nukem996@hotmail.comaim: nukem996open source open mind
wow is this really a whole class for each texture????
just a little tipp:
think of a program that is going to load hundrets of textures... for each texture you would build an instance of your class which is going to take an awesome amount of bytes in comparison what you would need. for texture loading functions it is recommened to write c only so that you can build a dll out of your source without using the mfc. the export function could f.e. look like this:
bool LoadTexture( const char *Filename, GLubyte *memory );
you give the filename of the texture and a memory "slot". more you do not need to load a texture and use them later. ( dont tell me other things im doing it this way
)
ok, but i cant find the error in your source code. everything seems ok so far imho. do you always allocate memory without multiply the size you want with the size of the var type? ok, its not the error in your code because malloc allocates memorys in bytes.. so there would be no change at all.
[edited by - cANaBiTz on September 26, 2002 1:30:56 PM]
just a little tipp:
think of a program that is going to load hundrets of textures... for each texture you would build an instance of your class which is going to take an awesome amount of bytes in comparison what you would need. for texture loading functions it is recommened to write c only so that you can build a dll out of your source without using the mfc. the export function could f.e. look like this:
bool LoadTexture( const char *Filename, GLubyte *memory );
you give the filename of the texture and a memory "slot". more you do not need to load a texture and use them later. ( dont tell me other things im doing it this way

ok, but i cant find the error in your source code. everything seems ok so far imho. do you always allocate memory without multiply the size you want with the size of the var type? ok, its not the error in your code because malloc allocates memorys in bytes.. so there would be no change at all.
[edited by - cANaBiTz on September 26, 2002 1:30:56 PM]
Ya I know it takes up a huge amount of memory. Currently Im just trying to get it load the graphics then im gona work on it so it can load hundreads of graphics. Currently its only loading one since im still building the engine. I cannt do a DLL since I use linux, but I can make a lib file
.
Thanks for the tip!

Thanks for the tip!
--------------------------Nukemmsn: nukem996@hotmail.comaim: nukem996open source open mind
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement