Push / pop states in modern OpenGL

Hi,

I have some OpenGL rendering code (VBO + textures + shaders) which I need to integrate in a client rendering framework.

To avoid any OpenGL state change from the client rendering framework point of view, I try to push / pop all my modifications :

void draw()
{
pushState();

glBind…
glBind…
glEnable…
glDraw…

popState();
}

Before OpenGL 3, I used method like “glPushClientAttrib”. What is the “modern” way to do that ? Should I execute a bunch of glGet / glSet ?

And is there any way to restore all OpenGL state to its “default” state ? The idea is to ensure my glDraw call is made with correct state :

void draw()
{
pushState();
resetState();

glBind…
glBind…
glEnable…
glDraw…

popState();
}

Thanks !

There isn’t one. Both of the push/pop pairs have been removed in 3.x core profile, and many of the newer features have state which cannot be pushed or popped.

No. glGet can be many orders of magnitude slower than other GL commands as it requires a round-trip and pipeline stall.

Use multiple contexts. That’s the only available mechanism for modularisation in modern OpenGL.

Use multiple contexts. That’s the only available mechanism for modularisation in modern OpenGL.

Sounds like a good idea, but I don’t know how to implement that :

  • the client framework create its OpenGL context and work with it.
  • during the rendering loop, there is a call made to my “draw()” method
  • how can my “draw()” method can write to the same render target as the

[QUOTE=Aurelien;1252441]

  • the client framework create its OpenGL context and work with it.
  • during the rendering loop, there is a call made to my “draw()” method
  • how can my “draw()” method can write to the same render target as the[/QUOTE]
    The client framework would need to either provide the (already-bound) context or provide the means to create and bind contexts.

If you’re stuck with using the same context as the framework, it may be safe to assume that there isn’t a program currently bound, so you can just use glUseProgram(0) afterwards. VBO bindings are part of the client vertex-array state, i.e. saved with glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT). If you don’t need any other new features, that may be enough.

Hi,

I’ve tried to create multiple contexts, but my client framework doesn’t really allow this… So I’ll use the glPushClientAttrib/glPopClientAttrib solution with a hack to re-set the client framework current shader program.

Now I have some problem with textures…

Are textures part of the client state ? Can I ave them using glPushClientAttrib ? Or where can I find an exhaustive list of all states saved by glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS) ?

Thanks !

Texture bindings (glBindTexture), parameters (glTexParameter) and environment (glTexEnv) are server state. All of those are saved by glPushAttrib(GL_TEXTURE_BIT).

Pixel pack/unpack modes are client state, saved by glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT).

The active texture is a combination of client and server state. The server state is set by glActiveTexture() and saved by glPushAttrib(GL_TEXTURE_BIT). The index of the active texture coordinate array is client state, set by glClientActiveTexture() and saved by glPushAttrib(GL_CLIENT_VERTEX_ARRAY_BIT).

The OpenGL specifications contain a section entitled “State Tables” (usually the last section before the appendices) which document all of the GL state. The column named “Attribute” indicates which glPush(Client)Attrib flag(s) save the state. Any state with an attribute of vertex-array or pixel-store is client state; anything else is server state.

That column is also only available in compatibility profile specifications, as it isn’t used in core.

There is also nothing that prevents you from writing your own state tracker - it’s not uncommon for 3D engines to do that, even though the focus is mostly tracking and avoiding redundant state changes.