hello.
i do software for a living, and have just started getting into OpenGL.. very interesting, and thanks NeHe (and the rest of you) for the upkeep of this excellent site, i know it isnt easy

Anyway this is about basic principals of loading a texture. I see in all the examples people use this method:
AUX_RGBImageRec* ptr = auxDIBImageLoad(szFilePath);
But what if you wanted to store all your bitmaps in a single file, then at runtime extract the files out. If your using the above method, you would have to create a file, save the data to the file, call the above method, then unlink or delete the file. File I/O is not fast, and the described method would take a long time if you had many files to load.
I studied how
auxDIBImageLoad works with a bitmap (it's not too complicated at all) Basically the steps to loading a BMP are simple:
1) take the 2 main headers off the BMP
2) convert the bits of the BMP from BGR to RGB
So with knowing this, i wrote a function to do this:
GLuint CGLWnd::uiLoadTexture(unsigned char* buffer){
GLuint rc = GL_WND_ERROR;
if(!buffer) return rc;
// start - load 24 bit bitmap manually
BITMAPFILEHEADER* bfh = (BITMAPFILEHEADER*)buffer; // make buffer into a BFH pointer
BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)(buffer + sizeof(*bfh)); // make buffer + sizeof(BFH) into a BIH pointer
// since 24 bit bmps do not have a palette, the data after the 2 main headers is the BMP bits
unsigned char* pData = (unsigned char*)buffer + (sizeof(*bfh) + sizeof(*bih));
if(bfh->bfType == ((WORD)('M' << 8) | 'B')){ // make sure header is "BM"
if( (bih->biPlanes == 1) && (bih->biBitCount == 24) ){ // make sure bitdepth is 24
// this code was found on MSDN, it will convert the bits from BGR to RGB
// this is needed for GL textures, otherwise your pictures colors will be inverted
int WidthByte32;
int rest = (bih->biWidth * bih->biBitCount / 8) % 4;
if(rest)
WidthByte32 = (bih->biWidth * bih->biBitCount / 8 + 4 - rest);
else
WidthByte32 = (bih->biWidth * bih->biBitCount / 8);
int BytePerPixel = bih->biBitCount / 8;
for(int j = 0; j < bih->biHeight; j++)
for(int i = 0; i < bih->biWidth; i++){
unsigned char pixel = pData[WidthByte32 * j + i * BytePerPixel + 2];
pData[WidthByte32 * j + i * BytePerPixel + 2] = pData[WidthByte32 * j + i * BytePerPixel];
pData[WidthByte32 * j + i * BytePerPixel] = pixel;
}
// end - load 24 bit bitmap manually
// now that the headers are defined, bits have been adjusted, we have all the information
// needed to create a OpenGL texture... continue as normal
// start - create GL texture
glGenTextures(1, &rc);
glBindTexture(GL_TEXTURE_2D, rc);
glTexImage2D(GL_TEXTURE_2D, 0, 3, bih->biWidth, bih->biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// no freeing of memory is needed since a pointer to a buffer was passed in.
// all we did was assign structs and pointers to the allready existing buffer.
// end - create GL texture
}
}
return rc;
}
all this function needs is a pointer to the BMP in memory, it will do the rest for you, and it's ultra fast.
Another thing that i wanted to do to make my life more easy is have the ability to load a BMP from the resources of the currant program. I have written a function to do so making my app "stand alone" I didnt post it, because its a long and drawn out process, and i dont want to take up too much space

And finally, to me, 24 bit BMPs are big, and alot of time my textures dont need the whopping 16.7 million colors that a 24 bit BMP can hold... so i want to use 256 (8 bit) BMPs to save tons of space. I also wrote a function to handle 8 bit bmps, it will convert the BMP to 24 bit then load by the above code.
Obviously the code above is basic: hardly no error checking etc etc. I shortened it up a bit so i wouldnt eat up too much space.
Again, i am a starter in OpenGL, i don't know much about it, but i am learning. If there is another method other than the one above that everyone is allready using, i am sorry for taking up the space

If there is another way of doing this that is faster/cleaner/better please let me know.
Thanks for reading and your input.
-andy
[edited by - SonicMouse2 on May 8, 2002 9:31:23 PM]