Sign in to follow this  
Callidus

Progressive Loading/Unloading of Terrain Heightmaps

Recommended Posts

Dear Fellow-Coders, I am currently extending my terrain system in order to support larger areas and use geomipmapping and zones for this purpose. The structure of the terrain system looks like this: Terrain -- contains --> Zones -- contain --> Terrain Blocks Every zone has a heightmap assigned to it, which is read from a file and is currently 513x513 bytes large. As the viewer moves around, terrain blocks and entire zones are swapped from harddisk to RAM to the graphics card and back depending on their frustum visibility. I think this should be very similiar to what most people do. However, the loading of a 513x513 heightmap file for swapping in a new zone from the harddisk takes a lot of time, which creates a very noticeable stall. How do you deal with this problem? Best regards Calli

Share this post


Link to post
Share on other sites
My system is to create a "cache" system where blocks are stored. When a block is needed the cache is checked. If the block isn't already loaded then it's loaded (more on that later) and the next time the block is needed it's in the cache. There's a maximum number of blocks in the cache, so whenever a block is added to the cache the cache manager checks to see if it needs to kick an old tile out, and if so it finds the block farthest away from the camera and kicks it out.

Loading is done asynchronously (either using threading or asynchronous IO). For instance, I can create a new terrain block with something like this:

TerrainBlock* newblock = static_cast<TerrainBlock*>(ResourceManager::Load("some_terrain_block_file"));

This immediately returns a new instance of a TerrainBlock (ResourceManager::Load() returns a Resource*, and TerrainBlock is a type of Resource), even though the block isn't actually loaded. Then you just do stuff like newblock->Draw() and whatever, which just won't have any effect until the block is loaded. But since the load is done asynchronously there shouldn't really be any lag since there's no blocking calls.

Share this post


Link to post
Share on other sites
Thanks to you two for your excellent replies. Can you give me any hint concerning asynchronous I/O for files? I thought this was something about network sockets.

Also, as you do not know how much time a thread gets, how do you determine when to start loading a terrain patch? Might this even be different from system to system?

Best regards

Calli

Share this post


Link to post
Share on other sites
Well, here's a little tutorial I wrote for AIO on Linux and MacOSX. For Windows the Win32 CreateFile() function can open a file for AIO (use FILE_FLAG_OVERLAPPED), and then use ReadFile() with a valid OVERLAPPED structure.

My system for figuring out when to load a block is based on distance from the camera. When a block gets within N units of the camera I load the block. Hopefully by the time the block actually becomes visible enough time has passed that the block is loaded.

The trickiest part to this asynchronous stuff (for me anyway) is not being able assume that your data is loaded as soon as you call your load method.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this