Phillip Hamlyn

British Landscape Explorer - Managed DirectX

Microsoft launched Managed DirectX, a .net wrapper for DirectX 9.0c, and made a much safer programming environment available. The wrappers controlled handle and resource access and allowed an eventing layer to be built over the various DirectX hardware events (such as the texture cache being cleared).

This environment took a while to settle down to stability, suffering ironically from memory leaks on texture handling, but once it had, it performed very well and provided a much cleaner layer to DirectX than the COM interfaces.

I constructed the basic application framework for reproducing the VB map and came up with this;

First .net Landscape

I began my quest to render as much of the UK as possible, firstly by getting access to enough data. I signed up for the Ordnance Survey Developer Programme and that got me access to a few square miles of data in Port Talbot. I then generated sine-wave landscape heights and repeated the map imagery to scale up the data I had.

One immediate problem was the size of the maps (called Textures in DirectX). These come in 20km x 20km tiles from the Ordnance Survey and at its natural resolution and colour depth is 4000 x 4000 pixels giving 15mb per tile. Even given that the texture RAM of most video cards is huge these days, such a whopping great texture will eat RAM very fast. Another factor was that most video cards only support data up to 1024 x 1024 pixels.

I experimented with reducing the map tiles to the maximum 1024 size and reducing the colour depth using the dotnet Color Quantizer (available on Planet Source Code) which samples the palette used within the bitmap and produces a 16 bit colour depth image that is biased to the most used colours. This is better than a straightforward colour reduction based on a nearest match algorithm as precious colour bits would be used on very infrequently used colours.

The resultant images were very similar in quality to that shown above. The next stage was to use DirectX MipMapping. This instructs the video card to calculate and store incrementally smaller textures - typically by reducing the total texture area by two. When loading a 1024 texture MipMapping auto generates a texture of 512, 256, 128, 64 and 32 bits using a variety of algorithms from nearest neighbour to more subtle interpretations.

Then I stumbled on the concept of hardware texture compression. Rather than do the colour quantization myself I could get the video card to do it ! This required the use of the DirectX library when generating my textures to save them in DXT1 format. This is a 4 bit per pixel colour format which radically reduces the video RAM required for the textures. Unfortunately it turns out this is not supported on some video cards, which have a nasty runtime error, but I managed to create a fallback code which loaded the texture into 16bit format in those cases.

Larger landscape using compressed textures and MipMapping

Time to get some serious landscaping data. I signed up for the Ordnance Survey Partner license which, once my pocket was empty, gave me access to the entire data of the UK. I processed the rasters, converted the spot heights to DirectX meshes and away I went....

... Straight into a brick wall.

As soon as I loaded more than two tiles the refresh rate dropped to a couple of frames per second (FPS). I'd forgotten that the textures was not the only data which increases exponentially with distance - so does the landscape shape itself. I had expected some clever DirectX helpers to do this for me, just like MipMapping, but there wasn't anything.

In desperation I posted some questions on GameDev.net and got some pretty immediate responses - this was just one of those problems that didn't have a 'right' answer.

I got out my maths books.