Jump to content

  • Log In with Google      Sign In   
  • Create Account


loading time


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
39 replies to this topic

#21 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 02 January 2002 - 06:04 AM

On older cards, the quality only.
On newer cards, both.

It takes more memory, though.
- AH

Sponsor:

#22 q3stanky   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 08:15 AM

i''ve a geforce 3 ti 500

it shold work but i''m a bit blemblem

the last possibility:

may somebody post a whole fast bmp loading code with an loading exemple that is not compiled that i can see the system and when i compile it in vc ++ 6.0 it should work allone (please for direct compile) i can better see the system when i can change something and see what happens.

sorry

thanks

#23 Dragn   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 08:51 AM

Hmm...

One time I made a replacement for auxDIBImageLoad...
I don''t know how efficient it is--seeming I''m a win32 app coder, primarily, and I only play around with OGL in my free time--but it seemed to work good for me.

Here goes:
  


//this replaces auxDIBImageLoad

static BMPINFO *LoadBMP(char *filename)
{
BMPINFO *bmpinfo;
HBITMAP hbitmap = NULL;
UINT32 ret;
BITMAP bitmap;
UINT32 x;
BYTE tmp;

//load the image from file

hbitmap = (HBITMAP) wec_LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0,
LR_DEFAULTCOLOR | LR_LOADFROMFILE);

#if (err_DEBUG)
if (hbitmap == NULL)
{
DERROR(castle_BADARG, "Invalid filename for bitmap");
}
#endif

//get descriptor, including width/height

wec_GetObject(hbitmap, sizeof(bitmap), &bitmap);

ret = ecmem_Alloc(sizeof(BMPINFO), &bmpinfo);

if (ret == 0)
{
UERROR(castle_BMPERR, "Could not alloc memory for bitmap information");
}

bmpinfo->width = bitmap.bmWidth;
bmpinfo->height = bitmap.bmHeight;

ret = ecmem_Alloc(bmpinfo->width * bmpinfo->height * 4 + 1, &bmpinfo->data);

if (ret == 0)
{
UERROR(castle_BMPERR, "Could not alloc memory for bitmap raw data");
}

//zero memory space

memset(bmpinfo->data, 0, bmpinfo->width * bmpinfo->height * 4);

//receive DIB bits into bmpinfo->data

wec_GetBitmapBits(hbitmap, bmpinfo->width * bmpinfo->height * 4, bmpinfo->data);

//now we begin a 2 step process of changing the data into GL_RGB format

//first, swap the order of the image, top to bottom, bottom to top

for (x = 0; x < bmpinfo->height * bmpinfo->height * 2; x++)
{
tmp = *(bmpinfo->data + x);
*(bmpinfo->data + x) = *(bmpinfo->data + ((bmpinfo->height * bmpinfo->width * 4) - x));
*(bmpinfo->data + ((bmpinfo->height * bmpinfo->width * 4) - x)) = tmp;
}

//next, get rid of the "zero" padding that''s included in windows color data

for (x = 0; x < bmpinfo->width * bmpinfo->height * 3; x++)
{
*(bmpinfo->data + x) = *(bmpinfo->data + x + (x / 3) + 2);
}

wec_DeleteObject(hbitmap);

return bmpinfo;
}



Then here''s how you''d use it, similar to nehe''s code:

  

static void LoadTextures(void)
{
UINT32 x;
BMPINFO *textureimage[1];

memset(textureimage, 0, sizeof(void *) * 1);

textureimage[0] = LoadBMP("data\\wall.bmp");

if (textureimage[0] == NULL)
{
UERROR(castle_BMPERR, "Unable to load textures");
return;
}

for (x = 0; x < sizeof(texture) / sizeof(texture[0]); x++)
{
glGenTextures(1, &texture[x].texture);
}

//create GL_LINEAR (high quality) texture

glBindTexture(GL_TEXTURE_2D, texture[0].texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, textureimage[0]->height, textureimage[0]->width,
GL_RGB, GL_UNSIGNED_BYTE, textureimage[0]->data);

texture[0].width = 1.0f;
texture[0].height = 1.0f;

if (textureimage[0])
{
if (textureimage[0]->data)
{
ecmem_Free(textureimage[0]->data);
}
ecmem_Free(textureimage[0]);
}
}



That might help you out...it''s just basically generic win32 code to load textures, into the OGL format, and setup the mipmaps, etc.

Umm, a few notes about the code:
1) "wec_"''s are just win32 api calls...delete the wec from the beginning of the function call, and it''ll be just like win32 api.
2) UERROR is sorta like an ASSERT, in my coding style...it''s for error reporting purposes...you''ll have to modify those portions of code to your own error-catching style
3) #if (err_DEBUG) and DERROR are for debug-time error checking...you can basically just delete all this code, for release build purposes.

That might help you understand how to load textures w/o using auxDIBImageLoad.

Any questions: duck0026@tc.umn.edu

-Rob

#24 q3stanky   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 08:58 AM

it looks like i must load all textutes at the beginning in the same way i loaded before and i can cuse the same funktion to loade the textuter before i call an object ok ?

#25 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 02 January 2002 - 09:29 AM

Dragn: I think this is a lot less efficient than DIBImageLoad. There is way to much copying, swapping, and converting. Take a look at the BMP filespecs, and write one from scratch, without all those WinAPI conversion functions. That''s the only way to make it really fast.


#26 Dragn   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 09:51 AM

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.

#27 Dragn   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 10:02 AM

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.

#28 scaught   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 10:05 AM

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

#29 Dragn   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 10:16 AM

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.


#30 scaught   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 10:32 AM

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

#31 Dragn   Members   -  Reputation: 122

Like
Likes
Like

Posted 02 January 2002 - 10:37 AM

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.

#32 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 02 January 2002 - 11:01 AM

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

#33 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 02 January 2002 - 12:24 PM

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.

#34 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 02 January 2002 - 11:25 PM


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

- AH

#35 Dredge-Master   Members   -  Reputation: 175

Like
Likes
Like

Posted 05 January 2002 - 05:55 AM

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.

#36 Dredge-Master   Members   -  Reputation: 175

Like
Likes
Like

Posted 05 January 2002 - 05:57 AM

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

#37 Sivle   Members   -  Reputation: 122

Like
Likes
Like

Posted 06 January 2002 - 05:41 AM

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.

#38 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 06 January 2002 - 06:50 AM

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

#39 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 06 January 2002 - 06:52 AM

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

#40 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 07 January 2002 - 08:24 AM

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS