Improving graphics load time...
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.
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;}
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
Good Luck!
-ddn
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]
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]
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.... ?
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.... ?
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 ]
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 ]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement