Drawing methods should be able to specify exactly what states they want, using a compact, efficient representation

It should be trivially easy to detect one when a drawing method asks for the same states that are already set

If only a few states have changed, it should be easy to work out which ones need to be updated on the graphics device

A list containing the values of all possible states would be bulky, inefficient to pass around, and awkward to compare against the previous state settings. It occurred to me that if I could pack the values for multiple states into a bitfield, I could replace this list with a simple integer value.

Trouble is, there are just too many possible states! Consider alpha blending, for instance:

AlphaBlendEnable: 1 bit

BlendFunction: 5 possible values = 3 bits

SourceBlend: 15 possible values = 4 bits

DestinationBlend: 15 possible values = 4 bits

SeparateAlphaBlendEnabled: 1 bit

AlphaBlendOperation: 5 possible values = 3 bits

AlphaDestinationBlend: 15 possible values = 4 bits

AlphaSourceBlend: 15 possible values = 4 bits

BlendFactor: 32 bits

That is already 56 bits for the alpha blending state alone. There is obviously no way the entire graphics device state is going to fit into a single integer.

The trick is to realize that most games don't actually use every possible combination of states. For instance that bulky 32 bit BlendFactor setting is almost always irrelevant: MotoGP only used it in one place (while drawing the reflections if I remember right), and then always wanted it set to 50% gray.

If you make a list of the state settings your game actually uses, you will typically find this is quite small, easily able to fit into a single integer along the lines of:

Note that these flags are incredibly game specific. A different game, which didn't use the same particle accumulation buffer or reflection rendering techniques as MotoGP, would need a completely different list. This makes it impossible to come up with a single standardized representation, so this bitfield technique is not suitable for generalized engines or frameworks.

For any given game, though, you can work out exactly what states you want to use, then come up with a bitfield representation customized for that specific game. Once you have this encoding, you can write something like:

This makes every piece of drawing code entirely self contained, without sacrificing efficiency. If I draw ten character shadows in a row it can efficiently detect that the requested states are already set, but if I interleave my shadows with some debug text rendering, I can still be 100% sure everything will be set up correctly.

As said in your previous article, this could be optimize if you group your entities by category (maybe with an autolist), so you can do the checking once per group, then called draw, reset, and so on …

… which in turn lets you, say, take advantage of instancing, where needed.