State management in OpenGL

Michael Herf
April 3, 2000

back

Introduction

I've been thinking about a couple of things related to OpenGL and similar APIs, like Direct3D. OpenGL's proponents are very fond of saying that it's a well-defined state machine, with every combination of switches, flags, etc., having some meaning to the hardware.

The problem with this is that more features are being added to hardware, and adding to the state machine in a vendor-independent way is a hard thing to do. It's clear already that most of these new features aren't getting used.

I think the existing solutions -- extensions, etc., barely get the job done, and I think there's a better way.

Data vs. Code

The problem is that extensions are being added that could be added to any game, if the game's authors were willing to do a recompile. But this does not make sense, because what we're fundamentally talking about is a data problem, not a code problem.

What I mean by that: OpenGL state is largely not about the glEnable calls that you use to turn on/off features -- it's about the internal state of the system. glEnable and its siblings are just ways to get at the state. This is why it's a data problem, and the fact that we programmers like the nice interfaces at the code level has prevented us from really making this abstraction properly.

For kicks, let me point out that opening up the Windows Display Settings, making switches global for your whole system, for "quality vs. speed" is not a good solution. Yes, I know the full-scene AA stuff will be available in a control panel -- great, it'll make some games really slow. My point is that this kind of state should be tweakable at a much finer-grained level. At the very least, per game, and preferably, per object in the game.

My realization is that we're approaching a point very much like what happened with application UI -- the separation of code from data is not being done right now. The Mac's Resource Manager fixed this for the Mac Toolbox 15 years ago, so we should be able to do the same with 3-D.

All of my OpenGL apps have these long functions with 20 calls each to change the OpenGL state. And most of these parameters are not computed. They're simple things like

glEnable(GL_TEXTURE_2D);
So why not have a resource devoted to each state in a game or application that has a bytecode representation of each state in the game? These could even be named resources.

For example, say Carmack had written Quake2 using a single named resource for each state in the game, and six months from now, NVIDIA decides to add a new glNV_PSYCHEDELIC_LENS_FLARE feature. You could go to the DrawEvilBadGuy resource and flip the glNV_PSYCHEDELIC_LENS_FLARE switch -- which didn't exist at compile time, and your old game would have new features, at a fine level of granularity. (Only the bad guys get lens flares!)

Some details

First, state is complex. There are lots of switches to flip. But the number of distinct states for a given game is relatively small. My guess is that most games, even with a variety of textures, multitextured surfaces, reflections some places, not others, and crazy special effects, have fewer than 20 distinct states. Most have many fewer than that.

Suddenly, an integrated way to change these states, edit them, author complex procedural textures, etc., seems really cool to me. It'd probably begin life like one of those nasty control panels to monitor the OpenGL/D3D state, except it would store a magic bytecode representation and a name when it exited.

Performance could be better with this scheme, because vendors could implement direct support for state changes, compiled at resource-load time to be optimal for each piece of hardware. Also, you save the 20 function calls that would otherwise be required to set switches.

Artwork

Artwork and other binary resources should probably be incorporated into this specification as well. This would include binary formats for images, and a standard way to represent multitexture, so that even data at this level could be modified and adapted. With some of the programmable shader stuff in the works, a system that incorporated all of this would be a humongous boost to these new features' general acceptance.

Isn't this just a shader system?

Yes! Except that all the proposals for shaders are several levels up from the OpenGL level, and only get a small fraction of the attention that general OpenGL programming does. This proposal really addresses the entire thing from bottom to top. More traditional programmable shaders are binary resources in this system, but they're one chunk of data added to the state machine overall.

Don't some games have internal systems like this?

I think so, for basic shaders and multitexture, but I think it's only for existing OpenGL state -- it can't be extended by the driver. I don't know any game that lets you reprogram its OpenGL state from the outside.