Land-o-Rama contains a pool of terrain patches that can be used and re-used when needed. Each patch contains several buffers (vertex, normal, color, etc.) Each patch holds the same amount of data. The patches are allocated when the engine starts up.
As mentioned in the previous journal entry, Land-o-Rama stores a quadtree of patches. A patch can be split into four smaller patches, and four smaller patches can be merged into a single patch.
When a terrain patch needs to be split into four smaller patches, the original patch is freed back into the pool, four unused patches are retrieved from the pool, and these patches are then filled with terrain data.
When four terrain patches need to be merged into one larger patch, the original four patches are freed back into the pool, one unused patch is retrieved from the pool, and that patch is then filled with terrain data.
In all terrain algorithms that use a quadtree of terrain patches, the algorithm needs to determine when to split and merge these patches. Usually, this decision is based on three things:
- The distance of the patch (usually its center point) to the viewer.
- The roughness of the terrain in the patch.
- Whether the patch intersects the view frustum or not.
For simplicity reasons, Land-o-Rama splits a patch based only on distance; terrain roughness is not taken into account. Also, the view frustum is not taken into account.
Why not take the view frustum into account? Why allocate the patches for terrain that is not visible by the viewer? The reason is that when the viewer looks around, the visible patches would have to be allocated and filled on the fly; this causes the framerate to drop noticably when looking around.
In Land-o-Rama, view-frustum intersection tests only occur when drawing the terrain patches. If the patch is not in the view frustum, it is not drawn.
One of the constraints that I need to have for Land-o-Rama is that each terrain patch can differ from its neighbor by no more than one LOD, so that it'll be relatively easy to join the edges of adjacent patches. Setting the split distance equal to the size of the patch did not work, so I ended up having to split when the distance is equal to double the size of the patch. This works, but it does increase the allocated patch count.
Here is a screenshot of the quadtree in action.
The screenshot doesn't look very exciting, but I need to work on one thing at a time. The light gray patches intersect the view frustum. The dark gray patches do not.