Monday, December 01, 2008

A new compass and minimap

The last couple of weeks I've been working on getting a working compass and minimap into the client. Since the world is extremely dynamic and not known to the client beforehand it's a little bit more complex than one would think. In a game where the world is known in beforehand, it's simply just a matter of slapping a prerendered or hand drawn texture of the world onto a square polygon and show that as the map. That's not something that we can do however as the world is totally dynamic and can be changed at any time. Our setup is instead a little bit more complex.
We want to render the world as it is, but we don't want to have to re-render it each frame, since that would bring the frame rate down. In addition, in order to get the water line properly rendered we must render all terrain tiles in the highest LOD-level. That means sending a lot of polygons to the gfx card (this could however be alleviated in the future by using shaders).
The current setup is therefore to place a camera far up in the sky, looking down. The camera uses orthographic projection, which means that objects won't be smaller as they are futher away. This is crucial for the map perspective, since else it will look just like a regular camera looking down.
We then render from this camera into a texture, 512x512px. This provides us with a snap shot of the current world, minus some foliage which we don't render. In most cases this looks pretty good. Finally we then define a smaller area, 128x128px, which is what we show in the compass. By panning this area within the larger texture we can scroll the map, and only have to update the render when the smaller area reaches the border of the larger texture. When that happens we re-center the camera and do a new render.
In this way we get a nifty compass map which doesn't have to be rerendered each frame.

Finally we need to provide a small arrow in the middle to show the position the camera is facing. The problem here is that CEGUI currently doesn't support rotation of windows, so the solution here is to leverage Ogre. We start with an arrow image which we then slap onto a full screen quad. This quad is then rotated to fit the direction of the camera and rendered into a texture, which is then sent to CEGUI, made into a gui element and placed on top of the compass. It all works splendidly, but there are some extra indirections which might bring the performance down a little bit.

All in all the compass is working pretty well now. There are some minor issues with it sometimes not being correctly updated when terrain pages change, and the buttons for zooming in and out could be made better, but it's pretty much ready for release.
Currently it only works as a simple minimap, but the plan is to add functionality for showing direction markers for interesting entities. We could probably reuse some of the functionality currently used for showing the labels.

With the compass now in place the 0.5.5 release is pretty much feature complete. I plan to get a beta build out this weekend.

No comments: