Pre-loading images without slowdown

BlitzMax Forums/BlitzMax Beginners Area/Pre-loading images without slowdown

MoriartyL(Posted 2011) [#1]
I'm making a game where you move around a very large 2D area. Because this area is hand-drawn, tilesets are not an option. The image is too big to load in one image, so I figured, no big deal, I'll split it into 2000x2000 areas and load them separately, and then when you scroll past it I'll set those images to Null to free up the memory. But when I load a new image it slows down the program. I would like for the game to be seamless, so that the player isn't aware of how broken up it is. So I'd like to start loading an image before you reach it, so that by the time you get close it's already in the memory. But I'm afraid that that will just slow down the game earlier, rather than eliminating slowdown.

Which brings me to my question. How does one load images for later, without slowing down the main loop of the game? I'm not looking for a solution specific to my code, I'm looking for a general principle I can follow.

Last edited 2011


Kryzon(Posted 2011) [#2]
You can achieve that with asynchronous loading.
Everytime you load an image the application waits for the loading to be done before continuing - this is the synchronous method, natural of BlitzMax. That's why you get that little stall.

If you use BlitzMax's thread capabilities or asynchronous file loading (not native to BlitzMax), you can have your assets being loaded while the game is running.

I think the major problem you'll face is... what if you need to display an image and it hasn't been loaded yet? (even with threads)
At least knowing you have to go for BlitzMax's threads will narrow down the information you need to find in these forums and the web.


MoriartyL(Posted 2011) [#3]
I have never used "BlitzMax's thread capabilities or asynchronous file loading". Where can I learn either of these skills?

I figured I could have a loading message just in case an image isn't ready, but I'd like to program it in such a way that it usually will be ready.

Last edited 2011


Czar Flavius(Posted 2011) [#4]
No no no don't load resources in game.

When you load images, they are stored in system ram. They are only transmitted to the graphics card when they are drawn, where they stay. However, if the card runs out of graphics memory, it puts old images back in system ram, so a cache system is already implemented for you.

Just load all the images at the beginning, and calculate which tiles are visible and only draw those tiles. Tiles which aren't visible will automatically be cached if required and retrieved when drawn, pushing older images out.

First of all, graphics are stored in powers of two. So use 2048, 1024, 512, 256, 128, 64, 32 etc sizes. A 2000x2000 image will be padded up to 2048x2048 internally, so you might as well make use of that space.

I'd suggest you split into smaller tiles, 512x512 maximum. For example if you are on the very corner of where 2048x2048 tiles meet, you will need 4 of them in video memory together. That's a big requirement! Smaller tiles will reduce the amount of "wasted" image kept in graphics memory which can't be seen.

For your reference, a 2048x2048 image takes about 16MB of video memory. You calculate by size * size * 32 bits per pixel. (Lots of cards use 32 bits per pixel even if you get 16 bit mode). Divide by 8 to get bytes. Divide by 1024 to move to kb and again to mb. 2048x2048x32/8/1024/1024 = 16MB. 4 in memory together = 64MB!!!!!

Of course you also need to bear in mind the load on system ram too, but it tends to be more plentiful. How big are your levels in pixels? If they are super massive, a background threaded solution might be required, but depends how deep you want to go with this game. I'd split the map into small tiles like above, and have a limit to the number of images in memory at once perhaps customizable by the player. Say 30 tiles or something. Then drop the oldest tile when this limit is reached. It assumes a player will revisit a recently visited area again, so will keep tiles in memory by order of visiting. Or if the level is more linear in design (you won't go back to old areas), you could fine tune such a system futher.

One more thing, your harddisk space might not like... bitmaps load faster than pngs or jpegs, as those formats have to be decompressed first!

You could also draw the map at half size, and scale it up by factor 2.0 in game. This will reduce image quality but significantly reduce memory requirements. It may or may not look good enough.

Last edited 2011


MoriartyL(Posted 2011) [#5]
I haven't finished drawing the game world yet, but a rough estimate of its size would be 20,000 pixels by 20,000 pixels. Even if I lower the resolution, that still seems like an unmanageable number of tiles.


MoriartyL(Posted 2011) [#6]
Hmm. I guess with the size I'm talking about it's not possible to not have loading screens. Darn, that won't work with the way it's designed. I'm going to need to think about what I'm doing here.


Kryzon(Posted 2011) [#7]
Where can I learn either of these skills?

You can search for threading guides with BlitzMax on these forums. There are a few topics explaining them.

No no no don't load resources in game.

I was proposing the streaming of the world (if it's not a contained, small collection of images of course).

PS: A similar question but for XNA.


MoriartyL(Posted 2011) [#8]
The XNA question is exactly the sort of thing I was thinking of. To do that in BlitzMax, I'll need to understand threading?

Last edited 2011


GfK(Posted 2011) [#9]
Sending a 2048x2048 texture to the GPU will cause an unavoidable pause. I'd break your map down into smaller chunks - say, 256x256.

A 20000x20000 image - regardless of how you chop it up - is something in the region of 1.5GB of resources. So you either have an awful drain on resources (which is already beyond what a lot of people have), or loading graphics on-the-fly, which is going to put your hard drive on its knees. If it had any knees. But you get the idea.


Shortwind(Posted 2011) [#10]
A couple questions for you:

1. What is the max size of your viewport for the main character display area? Are you going to have adjustable graphics window size or set?

2. Is you character going to stay fixed in the middle of the view port, or is the character going to move around the view port, then the map scroll when it gets to a set distance from the edge?


MoriartyL(Posted 2011) [#11]
I'm using a 640x480 resolution. I've been thinking (after your advice) of working with 512x512 tiles. I guess 256x256 works too; I'll need to do some experiments and see what I can work with. I've done the math and I understand how big the uncompressed image is, which is why I need to be able to keep loading as the game goes on and writing over what I've got in the memory. The character moves around; when it gets within 150 pixels of the border the map scrolls.

Thanks for helping, guys. I'd be totally lost otherwise.