How to save all the states of RC?

My app has many plugins(is a dll file),and every plugin do it rendering in a common RC

created in main app(use common RC just to saving the time of RC switch),but every plugin is

written by different people,and use different libs,every plugin may modify some current

states of common RC(such as clear color,state of depth test,projection matrix,…),so I

want to know how can I save all the states of a RC?From my knowledgement,I think

glPushMatrix(),glPushAttrib(GL_ALL_ATTRIB_BITS) & glPushClientAttrs() can save all the

states,so I can write my code below:

glPushMatrix();
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);

//Do the plugin’s rendering

glPopClientAttrib();
glPopAttrib();
glPopMatrix();

But I can’t sure it is right,so I post the topic.Is there anything I miss out?

Looks good, only that according to API doc :

for glPushAttrib: “Not all values for GL state can be saved on the attribute stack. For example, render mode state, and select and feedback state cannot be saved.”

for glPushClientAttrib: “Not all values for GL client state can be saved on the attribute stack. For example, select and feedback state cannot be saved.”

Maybe it would be better if definition of plugin API contained description of state which plugin can expect on beginning and into which each plugin must return OpenGL before it ends.
Not all parts of that state must be exactly defined. For example if state specifies that blending is disabled, state of blending functions can be undefined.

As Komat and Zbuffer pointed out that this might cause problems, it is also inefficient to a great extent! One thing that you can do is to implement some sort of state block mechanism (like you have in Direct3D) where state changes are saved “on demand”. That way you can have more control and you will face fewer problems and your code will most probably be more efficient (depending on your implementation, ofcourse). e.g. you can choose not to save common states or states that don’t effect your rendering. I have implemented such a mechanism for OpenGL and it works great and hardly took me a couple of hours to get it up and running once the design was complete.

Thanks Zulfiqar,can you give me the code of your OpenGL state smart setting implement?

what about having one different RC for each plugin? The RC change is an expensive operation, but if you wont change between dozens of plugins in each frame the problem is minimal. Also you cal use wglShareLists if you need it.
some Pseudocode:

wglMakeCurrent(NULL);
if(setupProcess)
RC = CreatePluginContext(plugin);
else
RC = GetPluginContext(plugin);

// plugin rendering

wglMakeCurrent(mainContext);

WRT speed of gl query commands,
in my app (for debugging purposes) i query all the states with glGet…() etc roughly 300 per frame, running at 100fps == ~30,000 get commands a second.
the thing is if i disable that it makes no difference at all.

WRT speed of gl query commands,
in my app (for debugging purposes) i query all the states with glGet…() etc roughly 300 per frame, running at 100fps == ~30,000 get commands a second.
the thing is if i disable that it makes no difference at all.
Wow! What if you someone runs it on hw X and gets 10 FPS because of those glGet?
In general it’s better not to use them and not to use glPushAttrib and glPushClientAttrs

true, but this is only for debugging purposes, eg seeing if my interpretation of gl is the same as the actual figures or somehow ive started to use the fixed pipeline etc.
i said this to counter the oft-quoted remark that gl query commands will kill performance.
though in saying that obviously the fastest command is the one not called.

Gets are ok at the beginning or end of a frame render, but a bad idea in between because of the inevitable flush required to get the real value.

Why would you need a flush? I’d expect the driver to have a copy of the “current” OpenGL state as seen by the application…

But of course I could be expecting too much of the drivers :wink:

yeah, sorry you’re right, states should be cached in the driver…I was thinking in terms of rendered data read back.
ignore me.