KHR_debug

This is an OpenGL extension that adds some very useful debugging tools

  • This extension is core in OpenGL 4.3+.
  • View this extentions in the Khronos Registry.

If you're using a version of OpenGL older than 4.3. You should check against your function loading api for extension support. If using glad just include the extension when generating the loader and after loading your functions check against GLAD_GL_KHR_debug.

Debug Messaging

With debug messaging we can recieve meaningful message on the state of OpenGL through a callback function. This effectively replaces glGetError.

You may need a debug context for this to work. If you're using GLFW this can be achieved with a window flag. glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE)

To set this up you just need two api calls.

glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(&message_callback, nullptr);

The callback function must match this signature.

void callback(GLenum src, GLenum type, GLuint id, GLenum severity, GLsizei length, GLchar const* msg, void const* user_param)

If you want useful stacktraces within the call back you'll want to enable GL_DEBUG_OUTPUT_SYNCHRONOUS. Do note this will have a performance impact and should only be done for debug.

Example

static void message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, GLchar const* message, void const* user_param) {
	std::cout << message << '\n';
}

void main() {
    // ...
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
    GLFWwindow* window = glfwCreateWindow(...);
    // ...
    glfwMakeContextCurrent(window);
    gladLoadGL(&glfwGetProcAddress);
    // ...

    if (GLAD_GL_KHR_debug) {
        glEnable(GL_DEBUG_OUTPUT);
        #ifdef _DEBUG
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
        #endif
        glDebugMessageCallback(&message_callback, nullptr);
    }

    // Do something bad to trigger the message callback
    GLuint program = glCreateProgram();
    glDeleteProgram(program);
    glDeleteProgram(program); // Double free
}

Debug Groups

KHR_debug also introduces debug groups. This is most helpful when debugging with RenderDoc. This lets up group api calls together.

Pushing and Popping Groups

constexpr GLuint myId = 0; // Can be whatever you want
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, myId, -1, "Shadow Pass");

// All following OpenGL api calls will be under the `Shadow Pass` Group.

glPopDebugGroup();

Within RenderDoc you can see the debug groups in action.

Additional Resources

Another guide for debug output