• Immutable Page
  • Info
  • Attachments

State Machine

If you're drawing stuff in your plugin, the chances are that you'll need to touch the state machine in OpenGL in order to get some work done. Be careful when manipulating this, you should ensure that all the changes that you make are reverted back at the end of your draw pass, otherwise that state could leak to another plugin or core and cause difficult to debug rendering problems.

void
MyPlugin::glPaintOutput (...)
{
    glEnable (GL_CULL_FACE);
    glCullFace (GL_FRONT);
    glEnable (GL_SCISSOR_TEST);
    glScissor (100, 100, 200, 200);

    gScreen->glPaintOutput (...);
}

The mistake made here is that the CULL_FACE and SCISSOR_TEST states are now leaked to the next plugin in the link chain to glPaintOutput, and if they aren't rectified by some plugin down the line, then on to the window paint phases where you could end up with clipped windows, artifacts or invisible windows!

Always ensure that you clean up state after setting it

void
MyPlugin::glPaintOutput (...)
{
    glEnable (GL_CULL_FACE);
    glCullFace (GL_FRONT);
    glEnable (GL_SCISSOR_TEST);
    glScissor (100, 100, 200, 200);

    ...

    glDisable (GL_SCISSOR_TEST);
    glDisable (GL_CULL_FACE);

    gScreen->glPaintOutput (...);
}

Also there is the problem where a state was already enabled, a plugin enables it, and then disables it atomically as part of its cleanup procedure. You should always check to see whether or not a state has been enabled first with the appropriate glGet.

void
MyPlugin::glPaintOutput (...)
{
    GLint cf, oc, sb;

    glGetIntegerv (GL_CULL_FACE, &cf);
    glGetIntegerv (GL_CULL_FACE_MODE, &os);
    glGetIntegerv (GL_SCISSOR_TEST, &sb);

    if (!cf)
        glEnable (GL_CULL_FACE);

    if (oc != GL_FRONT)
        glCullFace (GL_FRONT);

    if (!sb)
        glEnable (GL_SCISSOR_TEST);
    glScissor (100, 100, 200, 200);

    ...

    if (!sb)
        glDisable (GL_SCISSOR_TEST);
    if (oc != GL_BACK)
        glCullFace (oc);
    if (!cf)
        glDisable (GL_CULL_FACE);

    gScreen->glPaintOutput (...);
}

Development/zero-nine/OpenGLClasses/StateMachine (last edited 2011-08-01 21:10:08 by 124-169-243-209)