Archived

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

The Frugal Gourmet

Improving graphics load time...

Recommended Posts

Just curious if anyone has any tips on improving the load time of sprites (or coming up with a system where it''s less essential). I am loading almost all my game''s sprites up front. Now that I have 24 or so (48 frames each), there is a noticeable delay at start up while it loads everything into memory. Since I plan to add more, I could forsee this eventually becoming a problem... I earlier tried a system whereby the game would load certain graphics when it encountered them, but there was that noticeable pause every time, and I didn''t think it was working well. Any suggestions? Tips?

Share this post


Link to post
Share on other sites
Igilima    122
This depends a little on the game type and gameplay. It also depends on the size in memory of the things you are loading and whether memory will become a precious resource.

I would tend to want the time spent loading stuff at the start of the game rather than in the middle when I encounter stuff. When you hit momentary ''lag'' because the game is loading graphics, it breaks the suspension of disbelief and can ruin gameplay or even cause problems for players if the actionis real-time.

On the other hand, having too many graphics and other stuff loaded into memory may cause the game to run slower so you will have to balance that issue.

If you don''t unload graphics as you leave them behind then eventually you would build up to the point where they are all loaded into memory anyway. So you either want to also look at unloading graphics as you also continuously load them throughout the game or you will want to just load them all at the start while you play a little piece of music or something. :o)

Another option may be to load things continuously in the background using a separate thread or process but I''m not very well informed on such things so all I can do is suggest you look into it, hehe.

Share this post


Link to post
Share on other sites
Thathmew    122
It''s often faster to store them in a compressed format (lzo) and then uncompress as a good decompression algorithm can be faster than reading from the hard-drive.



mat williams
Lead Programmer, Designer
Zero Sum Software
www.zero-sum.com

Share this post


Link to post
Share on other sites
Thanks!

It sounds like you''ve encountered some of the very same concerns. I also found that loading things later on gives me that annoying pause which wasn''t worth it, but the load-time up front is quickly becoming less and less tolerable now.

I thought about just loading the "essential" sprites up front, and then having a background load (a different thread) gradually load things as I''m playing the game. If I encounter something before its graphic has been loaded, it will force a load of it (and there is a slight pause), but this will only happen in the first few minutes of playing then game. I thought with this method the delay before the user can play will be less intolerable, and the pauses will just happen sometimes in the first few minutes...

But, yeah, you''ve raised another issue too. My memory requirements are getting steeper and stepper. I hate to un-load anything yet, because it all seems so useful to have in memory... *sigh*...




Share this post


Link to post
Share on other sites
Kooo    122
If you display a logo screen, and maybe a progress bar, while these things are loading, maybe the pause won''t be as much of an annoyance (to the potential user).

Just a thought.

Share this post


Link to post
Share on other sites
JonnyQuest    331
Is there any sort of menu system at the beginning? Like "start game", "options" etc.? Most of the time, you''ll be waiting for user input there, and the machine will just sit there doing nothing important. You could use that time for loading graphics. Once the game is started, you check if everything has been loaded, and if not, display a progress bar or so and load the missing stuff. That should at least reduce the amount of time spent waiting.

- JQ
Full Speed Games. Period.

Share this post


Link to post
Share on other sites
Kuroahiru    122
How about using threads? Will they work in your case?

You can just load the minimum files you need to play at the start. Then, while the user is playing, you can execute a thread and load the other images in the background. May be multiple threads, if you are willing to manage them.

Or will that be too much of a performance hit in your game? At least it should get rid of the pause during the gameplay.

Share this post


Link to post
Share on other sites
RPGeezus    216
I really like the thread idea.

If you did that, you could have a piece of code ''predict'' what''s needed before the player reaches it, and also have it unload things it doesn''t need.

In the engine I''m working on all of the tiles are actually textures that get mapped to a 3d model of a ''tile'' at runtime. By this method, there isn''t a lot to load, and the work done by the processor is pretty minimal. It also saved me from having to draw, and fits in to my plan for ''ray-traced'' lighting (which I havn''t implemented yet).

Good luck,
Will

Share this post


Link to post
Share on other sites
I''ve also found that having a ton of classes initlized in the beginning can be very slow it runs faster if you initlize them ONLY when you need them and remove them when you are not using them. Also check around to make sure you have no memory leaks and such they can slow down your games well at least I have seen this to be true.

Killer Eagle Software

Share this post


Link to post
Share on other sites
Pyabo    124
Not to beat a dead horse, but I have to question your current methodology. How are you loading the graphics? How many megabytes of data are we talking about? How many seperate files? Even a dozen megabytes should load in a split second... I suspect that you might be doing something wrong here. If that is the case, then it makes more sense to fix this problem than to spend time coding up a work-around... it might be very easy to fix.

Share this post


Link to post
Share on other sites
quote:
Original post by Pyabo
Not to beat a dead horse, but I have to question your current methodology. How are you loading the graphics? How many megabytes of data are we talking about? How many seperate files? Even a dozen megabytes should load in a split second... I suspect that you might be doing something wrong here. If that is the case, then it makes more sense to fix this problem than to spend time coding up a work-around... it might be very easy to fix.


A dozen megabytes in a split second? Wow. I''m definitely not getting that. That sounds very impressive to me.

There are around 20 sprites, each with from 48 to 100 or so frames (depending on the number of frames needed to smoothly animate that item). This makes for about 60 MB of essential sprites loaded into memory up front.

There are some others which are loaded and unloaded as the game goes on now (ambience art, particularly), which is additional, but it''s never more than 10 MB at a time...

Maybe I''m doing something wrong. Here is the code that loads a .TGA file.


  
bool PictureSurface::init(char *pFilename)
{
USHORT w = 0;
USHORT h = 0;

FILE* pFile = fopen(pFilename, "rb");

assert(pFile != 0);

fseek(pFile, 2, SEEK_SET);

char c = fgetc(pFile);

fseek(pFile, 0x0c, SEEK_SET);

fread(&w, 2, 1, pFile);
fread(&h, 2, 1, pFile);

m_width = w;
m_height = h;

long ret = 0;

fseek(pFile, 0, SEEK_END);
long fileLen = ftell(pFile) - 0x12;

UCHAR *pRaw = new UCHAR[fileLen];

// Skip over bytes for BPP and alpha bits (Mmmmm... Alphabits)

fseek(pFile, 0x12, SEEK_SET);

fread(pRaw, fileLen, 1, pFile);

fclose(pFile);

m_pData = new ULONG[m_width * m_height];

if (0x0a == c) // compressed tga

{
UCHAR* pRawIndex = pRaw;

ULONG* pPtr = m_pData;

long count = 0;
long value = 0;
long c = 0;
long reps = 0;

// BEGIN PARSING tga data

while ((count < (m_width * m_height)) && (!feof(pFile)))
{
value = 0;
c = *(pRawIndex++);

reps = (c & 0x7f) + 1;

if ((c & 0x80) != 0)
{
value = (ULONG)(*((ULONG*)pRawIndex));
pRawIndex += 4;

for (long i = 0; i < reps; i++)
{
*(pPtr++) = value;
}
}
else
{
for (long i = 0; i < reps; i++)
{
(*pPtr) = (ULONG)(*((ULONG*)pRawIndex));
pRawIndex += 4;
pPtr++;
}
}

count += reps;
}
}
else
{
ULONG totalBytes = m_width * m_height * 4;

memcpy(m_pData, pRaw, totalBytes);
}

delete [] pRaw;

DDSURFACEDESC2 ddsd;
HRESULT ddrval;

memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwWidth = m_width;
ddsd.dwHeight = m_height;
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddrval = g_pDD->CreateSurface(&ddsd, &m_pSurface, NULL);

restoreBitmap();

return true;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
From your code it looks like you''re loading as fast as fread can go. Doing a single block read on the file. The only faster way would be to use the OS specific file access functions ( for win32 that would be CreateFile for example ), compact the multiple files into a single file, or use a compressor such as zlib or lzo, which have good decompression times and fair compression.

Good Luck!

-ddn

Share this post


Link to post
Share on other sites
Jan Wassenberg    999
How about packing everything into one file, and mmap()ing it?
You get demand loading/unloading for free, and it's fast+simple.
Depending on your images, you may also want to RLE or LZ compress individual frames.

/* edit: typo */

[edited by - Jan Wassenberg on October 2, 2002 6:38:17 PM]

Share this post


Link to post
Share on other sites
Pyabo    124
For one, use CreateFile/ReadFile as someone pointed out, if this is windows.

60Mb does sound like quite a bit of graphics though... How long does it take exactly? If I were to guess, I''m betting that 60Mb worth of files could be opened with a simple CreateFile/ReadFile routine in 1000-2000ms, assuming it wasn''t made up for 10,000 files. Maybe the real delay is somewhere else?

Just for experimentation sake, try opening and reading all of the files in a simple console app (or a Win32 app) that does nothing but read the files.... ?

Share this post


Link to post
Share on other sites
Kylotan    10010
You will get better throughput from the disk if all the data is in the same place on the disk, rather than in several files which may be fragmented. If you need separate files, you could use something like a zip file which packs them all together, allowing your disk to work at close to optimum speed.

Has anybody ever tried something weird and ugly, such as: using a single file pointer for all your loading, and after you load the data from the disk and are about to translate it, call fclose as usual but then call fopen on the next file you are about to read... that way, maybe the disk cache can be filling up with the next graphic while you are processing the current one.

I wouldn''t recommend this unless you really need the improvement, though... if there even is an improvement, of course.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

Share this post


Link to post
Share on other sites