Advertisement

Did i do this right?

Started by May 08, 2002 12:27 PM
7 comments, last by SonicMouse2 22 years, 9 months ago
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]
i not am smart stupid no ok
whoops.. i guess i dont know how to place code correctly on here! sorry about that... alot of the text goes off the screen.
i not am smart stupid no ok
Advertisement
Use the "source" tags instead of the "code" tags to get those nice white boxes with the color coding.
Why would you want to use bitmaps anyway? Wouldn''t jpegs be a better choice?
jpegs tend to get colors that bleed.. its due to its compression. very sloppy as far as im concerned.
24 bit BMPs are in pure form, no compression.
i not am smart stupid no ok
i agree, Jpegs are sloppy, and we are not working with webpages, so no need for them. Targa files are the only way i go for the simple fact I can make a texture have hole sin it without harsh coding for blending and what not.
Advertisement
what about .png files? I think thats what I used at school in my OpenGL class.

Generally there are only 2 image formats worth using (unless you have specific needs -- like animated gif) and those are jpeg and png. png offers alpha channel + lossless compression. jpg offers very small file size (with lossy compression -- although you can control the quality). You can use other formats like bmp, raw or tga, but most of their functionality is contained in png at lower disk usage anyways, and its just as easy too read in if you use libpng. www.libpng.org
The problem with jpegs is that while they look OK on a 2D screen, you can see the effects of the compression much better when you stick it on a texture and the rotate/zoom the polygon. In my opinion, PNGs are much better, or I also like to store textures in DXTn format. It''s easy to decode them into uncompressed textures if the card doesn''t support DXTn, but if it does, you don''t even need to do that!


codeka.com - Just click it.

This topic is closed to new replies.

Advertisement