Many RTS games have a way to visualise your units range. In Planetary Annihilation this is done by holding the Ctrl key. This gives you something that looks like the following.
The great thing about how these are drawn is that the range rings are combined rather than just rendering every circle individually, this gives a very visually pleasing result. We are going to try reproduce this.
We’ll be implementing this using the HTML5 canvas API, but the concept works similarly with OpenGL and other platforms (details at the end of the post).
Doing this is easy. First we draw all of the range circles as filled in circles, with the radius of the range radius plus half of the outline thickness. This gives us the total area that we want the range rings to cover, but with the centers filled in.
Next we simply clear the area of the range rings, minus half of the outline thickness. This leaves us with just the outlines that we desire!
Implementing this in HTML5 Canvas is very easy.
This gives us the following result. Click to add a range ring source at the given position.
This technique can be implemented in OpenGL using the stencil buffer.
- First clear and enable the stencil buffer
- Set drawing to only draw to the stencil buffer and replace the existing content, writing ‘1’ to the stencil
- Draw all of the circles, padded by half the outline thickness (this gives us a stencil full of 1s where the range rings are)
- Change the stencil write to replace the existing with 0
- Draw all of the circles, inset by half the outline thickness (this leaves us with just 1s in the outline locations)
- Enable color rendering and set to only render where the stencil is 1
- Draw all of the circles, padded by half the outline thickness
There is a very good post on stackoverflow with example code doing this
If you were drawing in 3d (Like Planetary Annihilation / Supreme Commander 2), the resulting texture could then be drawn on the terrain as a decal. (Okay, they probably use something way better than this to draw their range rings, but this might work).