PDA

View Full Version : Saving opengl state



glitch
01-02-2005, 07:10 AM
Hi,

Is there an easy way to save the *full* current state of opengl for further reuse ? I want to be able to use it when I want so glPush/PopAttrib() is not what I'm looking for. Perhaps using display list?

thx for any help

ps: Happy new year !!

zeckensack
01-02-2005, 07:42 AM
It's not possible to save/restore state to/from user memory. It would be too tempting for applications.
Disaster scenario #1 is an application saving it to disk and reloading it after a driver update or card swap.

You can't get the complete current state.
However, you can put (server) state into display lists. Yes, you can compile a list that sets every state, and use it to quickly get back to a known state vector.

May I ask what you're trying to do? Smells a bit like a dirty hack :)

iznogoud
01-02-2005, 08:54 AM
I can see why you would want to save the state and
restore it, for example, if you had a game and all of
a sudden you change into a different mode and want to
still use the ogl for rendering in this particular
mode.

I see no reason why you could not put each "mode's"
GL initialization into a separate sbroutine... It
makes sense, and you never have to "manage" the memory
for the state, it is just a call!

glitch
01-02-2005, 09:39 AM
Originally posted by zeckensack:
May I ask what you're trying to do? Smells a bit like a dirty hack :) Just trying to mimic the behavior of DirectX's IDirect3DStateBlock9 interface for my OpenGL renderer. I'm looking for the most elegant way to have the best of the 2 world.

I had already thougth to retrieve all opengl state (glGet*) then compile a display list and set all the states in it but I was looking for a "2 line of code" solution ;)

Anyway thx for your help

jwatte
01-02-2005, 10:34 AM
You can glGet() pretty much all of OpenGL state, so you can write code to save it all into some structure, and re-apply it later.

Also, most applications will put a layer of state mirroring in their rendering abstraction, to avoid redundant state changes, because OpenGL does NOT filter redundant changes (in that regard it's like PURE_DEVICE in D3D). The reason for this is that applications that care, can do a better job of state sorting than GL, and shouldn't have to pay for extra testing on each API call; applications who don't care, well, don't care :-)

Anyway, given that you have a device state mirror for the states you care about, you can also formulate your own state block management using those primitives. It usually comes out reasonably elegant in the end, and you can often save typing by using macros and templates.

Graphic Remedy
01-05-2005, 11:25 PM
Hi glitch

I agree with jwatte and will even go further.
A lot of graphic engines have a class that encapsulates the render context. This class holds a copy of the state variables that the application uses. All state changes and state queries should be done through this class.
Notice that the amount of the state variables that an application uses is usually significantly smaller than the entire OpenGL state machine.

The benefits of using such a class are as follows:
- glGet operations, which are usually quite bad for performance, are replaced by calls to this class.
- Redundant state changes are removed by this class
- This class can enable functionality like:
a. Stack like behavior of the state machine - push and pop the entire state machine, load a clean state machine, etc.
b. Save the state machine to memory / file / etc.
c. Load the state machine from memory / file / etc.

Yaki Tebeka
The gDEBugger team (http://www.gremedy.com)

zed
01-06-2005, 10:07 AM
The benefits of using such a class are as follows:
- glGet operations, which are usually quite bad for performance, are replaced by calls to this class.
- Redundant state changes are removed by this class
- This class can enable functionality like:
a. Stack like behavior of the state machine - push and pop the entire state machine, load a clean state machine, etc.
b. Save the state machine to memory / file / etc.
c. Load the state machine from memory / file / etc.couldnt agree more, ive got code that goes

GLstate s1,s2;
do stuff
s1.Grab_current_state();
do more stuff
s2.Grab_current_state();

// eg to see why somethings working at point s1 but not at point s2 u do someit like
log_the_differences_between_these_2_states( s1,s2 );
// check to see if we havent gotten anything enabled that doesnt need to be
s1.log_all_enabled_crap();
etc

once a frame i check my current state with what gl gives me from glGet.. stuff to see if they are the smae (maybe disabled in production code)

btw i know glGet..() commands are frowned upon for performance reasons, but theyre not that slow (eg even calling 100's of Get() commands a frame, my card can still manage over 1000fps (simple scene)

btw to implement this is a major undertaking, many thousands of lines

knackered
01-06-2005, 10:52 AM
Jwatte, I'm interested in what you're saying about an abstract class overlaying the graphics API states, because I remember, some time ago now, you dismissed this approach as pointless...you advocated a much higher level of abstraction, something like:

gfx.beginAlphaBlending()
gfx.endAlphaBlending()So a 'state' in this system would be:

state.alphaBlendingEnabledrather than:-

state.blending
state.blendSrc
state.blendDst
state.blendEquation
state.depthWritingHave you had a change of heart since then?

Graphic Remedy
01-08-2005, 04:05 AM
To see why somethings working at point s1 but not at point s2 u do someit likeHi Zed
You can use gDEBugger for the same purpose :-)
gDEBugger enables you to state variable values and even dump the entire state machine to a log file.

Yaki Tebeka
The gDEBugger team (http://www.gremedy.com)

jwatte
01-09-2005, 04:36 PM
Jwatte, I'm interested in what you're saying about an abstract class overlaying the graphics API states, because I remember, some time ago now, you dismissed this approach as pointless...you advocated a much higher level of abstraction, something like
You are correct; I still hold that in the ideal renderer, everything is sorted by material on the fastest state changes, and you won't need to actually get the state back at all. In fact, because you sort by state changes, you implicitly know what the state is -- it's the state of the last thing you rendered. In this case, actual state copying is easy. Sometimes, you may need it, such as when working with multiple render buffers.

Underneath this fully deferred renderer, you may choose to abstract hardware through a polymorphic API (or you implement two deferred renderers). Again, if you for some reason need the state mirror, that abstraction would be the place to put it.

Thus, if all you have is a more primitive state abstraction, and bang that directly, that's where to put the state mirroring; at some point, you'll want to build the deferred, sort-by-state renderer on top of that, but that's not what the original poster asked about.