• ### Announcements

#### Archived

This topic is now archived and is closed to further replies.

## 39 posts in this topic

actually, anony, I think that''s how auxDIBimageload works. But I''m not sure.

Cause the bmp file format is, I believe, "backwards" (little endian) B-G-R with a zero badding at the end...and yet, when taking auxDIBimageload, it returns a handle w/o the zero padding as R-G-B.

So, through my logic, they have to be about just as efficient.

But I''m not claiming to be an expert. By all means, if there''s some more-efficient way to convert BGR0 to RGB that I don''t know about, then let me know.

I wouldn''t be surprised if my code was less efficient. But try running each through a profiler to find out. I also wouldn''t be surprised if my code was more efficient.
0

##### Share on other sites
Oh, I think if you wanted to just load the handle through windows directly, and access the raw data (like I did above), to save the conversion time, you could just use:
GL_BGR_EXT instead of GL_RGB in the gluBuild2dMipmaps call.
Once again, I''m not sure if that''d work or not...but if it did work, it''d get rid of a lot of the "copying, swapping, and converting" stuff.

Yes, instead of openning it through windows and then accessing the raw data from win32 api calls--instead, you could have fopen()''ed the bmp file, parsed through the bitmap header, and accessed the raw data that way. Both are different ways of acheiving the same thing.
0

##### Share on other sites
One side effect of your way appears to be a lot of unused space in bmpinfo->data, since you''re doing the BGR0 to RGB conversion in place.

If I had to write this function, I''d probably just walk the source bmp line-by-line backwards, filling in the dest bmp with only the RGB, thus losing the need for the second loop...(or fill in the dest buffer in reverse order...whichever)

-scott
0

##### Share on other sites
scaught:

Yup, that''s completely correct. There''s a bunch of unused space in bmpinfo->data after my code. I noticed that while writing it.
(It''s allocated for 4 bytes per color, but in the end, only uses 3 bytes per color.)

That''s actually a very good suggestion, thanks.

The reason why I did it that way:
Doing it my way eliminates the need for two seperate allocated chunks of memory for source and destination--how I''m doing it, the source memory space *is* the destination memory space.

I can''t think of anyway to do it as you''re suggesting, unless you allocate a 4byte-per-color source space, call GetBitmapBits(), and then allocate another 3byte-per-color destination space...do the convertion...and then free the source.
So, there''d be some extra memory allocation/freeing, unless there''s a more efficient way of doing it.

I also thought about calling realloc() with the space, after it''s been converted--but that seems like a waste of cpu cycles.
0

##### Share on other sites
Ja, my method involves two buffers - a temporary one to hold the incoming data, and the final one to hold the outgoing data.

I''d just be worried doing it in-place because of how the system is going to handle that extra bit of garbage - if it ignores it, then you may not have too much of a problem - the excess isn''t too much even for large bmps - it''s just untidy, and I don''t like untidy.

(and you''re right - stay away from realloc() )

Cheers,
-scott
0

##### Share on other sites
Well, I''ve used my code in actual programs--and the textures load and work perfectly.

So, the code *works*, as is.

But you''re right. Your way of doing it is more tidy, has less looping, and is better.

Thnx...I think I''ll try to modify it sometime in the future.
0

##### Share on other sites
Hmm.

Using the BMP format is a really bad idea for OpenGL, IMO. Go with your own texture format. If you do the whole converting, swapping and mipmap building offline, it doesn''t matter how fast or slow your loaders are.

- AH
0

##### Share on other sites
Refering to the last post,
yes it would be easily to edit/create some bitmaps ( or other file formats you know and your graphic software can handle ) with your graphic software and then writing a conversion ultility which loads the bitmap ( or ... ) and creates the mipmaps and so on.
So that you only have to load your texture format at runtime which is much faster than loading the data plus the swaping around.

Hint1: To create a file loader yourself, you only have to lookup the file format specificatiion and then write a routine that reads out the file with the help of information which is coming with the file because of it''s file format which specs you''ve looked up.

Hint2: You don''t have to write a routine that handles all versions of different storing supported by the file format,
if you don''t use all the different versions.

Hope that helped a little.
0

##### Share on other sites

Hint3: Go to http://www.wotsit.org that will definitely help

- AH
0

##### Share on other sites
Just a small hint

instead of making 30 TextureImage[] spaces, just use one (the first one or a pointer to it, ie TextureImage[0]) and load each into that one at a time, then make your map off it, then clear it, load the next one and so forth. This would really slow down the system with the 64 mb of ram as it has to have 16 to 20 to keep windows running happily, then it has to load the rest of the data in twice and then it just clears the TextureImage[] (30 of them) afterwards. Makes the hard drive chug around alot, and if you have to access two points on a hard drive it really slows it down.

PS - also a reason to defrag.
0

##### Share on other sites
sorry, didn''t realise it was already two pages and taht someone posted an example that showed what I jsut said.
0

##### Share on other sites
Just to go off on a tangent for a moment...

Is it just me, or does the process of creating mipmaps positively scream out for a recursive function? In essence, you keep dividing the size of the texture until it gets to 1x1. At which point you could return a large list of all the steps for easy shoving into a file.
0

##### Share on other sites
Recursive ? Essentially yes, it is a recursive algorithm. Closely related to quadtree algorithms, although only one leaf of each depth level is followed, not 4. But imagine the stack size you would need for a 2048*2048 (or more) texture... And it wouldn''t be very efficient either.

That''s why every mipmap generator I''ve seen uses an iterative approach: use the previously generated mipmap level to create the current one.

- AH
0

##### Share on other sites
On a second thought, you wouldn''t need much stack space at all. Because only one leaf is followed at each recursive level. But on the other hand, this defeats the whole recursive idea, since your recursion essentially degrades into an iteration (only one recursive call is performed at each level).

- AH
0

##### Share on other sites
You could do something like so:

  /* assuming you have this defined in your program already!.int texture[30]; //Or array of textures #''s!!*/struct MyBitmap{ unsigned short Width; unsigned short Height; unsigned long TotalSize;// unsigned char BitDepth;//Don''t need bit depth, assuming 24-bit unsigned char *img;};//sx,sy are sizex and sizey//Function returns a pointer to bitmap in memory.unsigned char LoadBitmap(char *filename, MyBitmap &mb){ unsigned char *tmp; FILE *in; short tx,ty; mb.img = NULL; //Initialize to NULL! unsigned long tSize, offset1, offset2=0; in = fopen(filename,"rb"); //Read binary! if (!in) //in == NULL return 0; //Bitmap not loaded!/* If you are positive you''re only loading bitmaps, it''s a waste to test! if (getc(in)!=''B'' || getc(in)!=''M'') { //Not a valid bitmap file! fclose(in); return 0; }*/ fseek(in,18,0); mb.Width = getw(in); //Get Width fseek(in,22,0); mb.Height = getw(in); //Get Height/* don''t need to get bit-depth! fseek(in,28,0); mb.BitDepth = getc(in);*/ mb.TotalSize = mb.Width*mb.Height*3; mb.img = new unsigned char[mb.TotalSize]; if (mb.img==NULL) { fclose(in); return 0; //Not enough memory! } tmp = new unsigned char[mb.TotalSize]; if (tmp==NULL) //Not enough for our buffer! {//you could just load from file instead of memory if this fails.. but waste of time :o) fclose(in); free mb.img; //Free image; return 0; } fread(tmp,1,mb.TotalSize,in); //Read in complete image! offset2=0; for (ty=mb.Height-1;ty!=-1;--ty) //bitmap is upside down!! { offset1 = ty*mb.Width*3; for (tx=0;tx!=mb.Width;++ty) //And left to right! {//Inverts Y and R&B values at the same time! mb.img[offset1+2]=tmp[offset2]; mb.img[offset1+1]=tmp[offset2+1]; mb.img[offset1]=tmp[offset2+2]; offset2+=3; offset1+=3; } } fclose(in); return 1;}int LoadTexture(char *filename){ MyBitmap mb; int tNum; if (!LoadBitmap(filename,mb)) return -1; //File not loaded! glGenTextures(1, &tNum); //Generate 1 texture! glBindTexture(GL_TEXTURE_2D, tNum); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, mb.Width, mb.Height, GL_RGB, GL_UNSIGNED_BYTE, mb.img); free mb.img; //Free memory! return tNum; //Returns the texture number!}char InitTextures(void){ int ctr; //No need to initialize texture[]. texture[0]=LoadTexture("Data/mars.bmp"); texture[1]=LoadTexture("Data/sonne2.bmp");// finish loading textures like above! for (ctr=0;ctr!=30;++ctr) //Loop through all 30! if (texture[ctr]==-1) return 0; //Texture not found! return 1; //All textures loaded!!}int main(void){//Simply check: if (!InitTextures()) { //Print error loading textures error here! return -1; }//Proceed.. textures are now loaded!}

Disclaimer: I wrote this in this little text box window, and it is untested, and may contain syntax and/or grammer errors. If this doesn''t work or you cannot get this to work properly, I can test this and get it in working order need be.

BillyB

ps. If you or anyone has any questions pertaining this response, or any other questions about bitmap loading in general, feel free to contact me at BillyB@mrsnj.com.
0