OGL states and scene graph

Started by
5 comments, last by Lutz 18 years, 7 months ago
Hey all, I would like to know how state changes are handled with scene graphs. I've read this nice explanation of scene graphs. Their idea is to put OpenGL state changes into nodes of the scene graph. My question is now: Which states does such a state-change-node have to set? Of course the node has to guarantee that after execution, OpenGL is in a certain well-defined state. Since in general the node can't know in which state OpenGL currently is, the state-change-node has to set ALL states, even the ones which are not necessary to set. This would surely be ineffective. This is the model of the scene graph: state-change-node (set all states of OpenGL) --> do-something-node (draws some geometry) --> state-change-node (set all states of OpenGL) --> do-something-else-node (draws some other geometry) Another possibility is to assume that in the entry point of a state-change-node, OpenGL is already in some globally defined default state, so that the state-change-node only has to set those states which do not coincide with the default state. But that would require some kind of "destructor-state-change-node" that resets OpenGL to the default state before execution of the next state-change. This would, however, be rather ineffective if the next state-change-node sets the same states as the previous one. This is the scene graph: state-change-node (set OpenGL to a default state) --> state-change-node (only set states that are not default) --> do-something-node (draws some geometry) --> destructor-state-change-node (set OpenGL back to default again) --> state-change-node (set some other non-default states) --> do-something-else-node (draws some other geometry) --> destructor-state-change-node (set OpenGL back to default again) So how is it usually done? Lutz
Advertisement
Hi,

I use OpenSceneGraph which handles it like so:

1) Get all visible Nodes (cull stage)
-> sort them so that the minimum of state changes is needed
2) Draw the vector
-> tell a StateManager which states you want to have (all)
--> the Manager will then only call OpenGL function if needed, so if a true state change happens
“Always programm as if the person who will be maintaining your program is a violent psychopath that knows where you live”
if you render as you traverse (which i dont) then I assume its like RISC assembler where the body of code which uses X Y and Z registers (states in this case) must change them and then restore them upon returning, recursion would deal with this quite easily.

the way i do it is have the scene graph act primarily as a transform graph, by traversing the graph i generate a list of meshes to render, this list holds the final transform matrix for each item, this allows me to sort the list by material, and thus by state (batching etc)

Cheers
-Danu
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Quote:Original post by dragongame
Hi,

I use OpenSceneGraph which handles it like so:

1) Get all visible Nodes (cull stage)
-> sort them so that the minimum of state changes is needed
2) Draw the vector
-> tell a StateManager which states you want to have (all)
--> the Manager will then only call OpenGL function if needed, so if a true state change happens


So that means OSG does the job for you and only changes the states that are really necessary?
I guess I'll check OSG then...
Look at glPushAttrib and glPopAttrib. It's not the most efficient way to do it, but it does work (and very easily).
Quote:Original post by Lutz

Another possibility is to assume that in the entry point of a state-change-node, OpenGL is already in some globally defined default state, so that the state-change-node only has to set those states which do not coincide with the default state. But that would require some kind of "destructor-state-change-node" that resets OpenGL to the default state before execution of the next state-change. This would, however, be rather ineffective if the next state-change-node sets the same states as the previous one. This is the scene graph:


This is how I currently do mine; I figured that was an acceptable loss for what I was doing. The end result was the reduction of A LOT of calls but it certainly wasn’t optimal. Although now that I think about it, it seems like this could be improved a little over what I do… Here is a little brain storming:

Each state change node could keep a bit-wise flag (int) of all the states it wants (the default is 0, the opposite is 1). When destructing the node could peek at the next change node and via an ‘and’ operator (very fast) have a bit-wise flag of what non “standard” state changes the current and next node share. Then simply by “or” this new one with the current change node you can tell which states need to change for the next node. Change these “must change states” and you are good to go. This would assume a maximum of 32 states, defined or enumerated, and would yield fast comparisons between state change nodes.

Just an idea, nothing too solid.
Thank you all for your ideas.

Skow, your idea as you described it would only work for boolean states.
I suppose the most expensive state changes are, however, not boolean ones,
like switching an FBO or a shader. It's probably a lot of work to take care
of every possible state change, but I could at least implement your idea
for the boolean states (the glEnable/glDisable ones).

I guess I'll implement the state-constructor-destructor-thing where the
boolean states are taken care of. OpenSceneGraph seems to do a LOT of things
for me - more than I want! Seems to be overkill for me.

Thanks again for your comments.

This topic is closed to new replies.

Advertisement