Monday, June 29, 2009

Of Indexes and Index Buffers (Slight Return)

This is what we get when we load The Marcher Fortress with indexed rendering enabled.



Been a long time since I've seen one of those.

Anyway, two choices were available: fixing it or removing indexed rendering. I chose the latter, but I think a bit of explanation is required for why.

  • Some cards have a maximum index value lower than that required for a Quake map.
  • Using indexes means having to decompose world geometry from trifans to lists, in order to get any advantage at all from geometry batching.
  • Any change of model, texture or lightmap during the render will break geometry batching; worst case scenario is only a single surface is rendered, and even then it's worse than not using indexes owing to the fan to list decomposition.
  • Quake geometry meant that the index buffer had to be composed in software per-frame, further removing any advantage from using it.
  • In order to avoid having to have two world render functions I had rolled the entire thing into one complex function with a lot of condition testing per surf, which introduced it's own overhead.
  • The end result was not really much faster than not using indexes, and was actually slower on some cards.
In summary, indexed renderng was far from being all it was cracked up to be. In fact, I've always been of the opinion that unless your geometry naturally falls into really large tristrips that share properties for each entire strip, and the exact same strips are drawn each frame, you're not going to be able to sensibly use index buffers. Drawing teapots on flat surfaces is fine, Quake is not. I had originally included this as an option for the render as it was faster in some cases, but on balance - and taking the BSOD into account - I'm happier to revert to the cleaner and simpler codepath.

0 comments: