Making ship drawing really fast

Airships: Conquer the Skies
2015-03-10 22:23

Modern graphics cards are complicated beasts. Treat them right and they're extremely powerful, but use them badly and you produce a lot of heat to no great effect. They like to do things in big batches: give them thousands of polygons in one go, and they're fast, but send them information piecemeal and they'll spend most of their time on overhead.

So why do computers that can run Skyrim on high settings struggle with big fights in Airships, a mere 2D game? The problem is that there's so many small things to draw: each module, each tile, each individually rotated limb of a crew member. Until recently, the game did this in an utterly inefficient way.

To draw a picture in OpenGL, the GPU's language, you roughly have to do the following things:

  1. Tell it what texture you're going to use.
  2. Tell it what shader you're going to use. (A shader is a kind of "visual effects" program running on the GPU. Airships mostly uses shaders for lighting effects.)
  3. Tell it that you're going to start drawing pictures.
  4. Give it the coordinates of the pictures.
  5. Tell it that you're done drawing pictures.
  6. Tell it to stop using the shader.
  7. Tell it to stop using the texture.

If you want to draw a whole series of pictures using the same texture and the same shader you can just repeat step 4 and give the GPU a whole series of picture coordinates. It's much faster than doing all seven steps each time.

Back in version 5, Airships' drawing worked by going through the whole seven-step process for each picture, each module, tile and limb. Making drawing fast meant reorganizing things so that it could repeat step 4 as long as possible without having to stop and switch shader or texture.

In version 6, when I started using shaders heavily, I improved on this somewhat: now visual layers within the same airship, such as all the modules, shared one texture and shader initialization. Only steps 3-5 would get invoked for every picture.

This was better, but nowhere near perfect: the only time the game really needs to finish blasting picture coordinates is when the shader needs changing.

In version 6.2, ship drawing is strictly organized in layers. All the backgrounds of all the ships are drawn first, then all the gun barrels, the modules, the crew, the armour. The game only says "I'm done drawing pictures" when it needs to switch from one layer to the next or change shaders.

The result? Here's a before-and-after comparison of a battle between six massive airships. The graph in the top right shows the amount of time it took to draw each frame. The improvement? About a factor of four!

Airships 6.2 will release later this week, featuring these improvements and a variety of bugfixes. Don't own it yet? Use this widget: