Hello,
it is a giant store of global variables and settings that every renderable object can modify…
well, in the object oriented methodology, its more lioke a giant store of private variables, insofar as you use method calls to change them, but you can’t get direct hold of the variables. But, yes; the opengl state is fairly large and you modify it with methods.
I don’t know what you mean by ‘every renderable object can modify it’; renderables use the current state and make changes to the frame buffer (which is also part of that state), but rendering a triangle won’t suddenly disable lighting, for instance. glColor*() will change the current colour, but then that’s because you’re directly changing the state that is used by the next glVertex.
this makes development very difficult,
yes and no. It makes development interesting
So how do real developers do it ? I’m already pushing and popping modelview and projection matrices, but how do you do the same to attributes and settings ? If there is a way (I’ve heard of popAttrib or something like that, but what are the performance risks ?)
well, I am only a fake developer. You can push abd pop attributes, though. check out pushAttrib(). You pass flags indicatonig what subset of the state you want preserved.
Efficient opengl engines use scenegraphs to manage state. A scenegraph (possibly more correctly, a scene DAG or a scene tree) keeps track of how to change the opengl state to render some scene. THere are plenty of information out there on how to best do this, including a plethora of existing scene graph impkementations.
The general idea is you attach geometry to state nodes. Each state node describes what the current opengl state needs to be to render the geometry attached to it; edges between state nodes describe how state is changed from one node to the next. When it becomes time to render the frame, the engine traverses the graph and flattens it to a list of renderable objects. THe ideas is to traverse the graph and arrange the order of the renderable objects so that they are rendered correctly, but with as few state changes as possible. (well, “as few” should mean, “as optimially” as possible: not all state changes are as equally expensive. chanmging texture, for instance, may require paging in texture from system memory, but disabling depth test is bit flipping).
cheers,
John