DebuggingGL 4.3

glDebugMessageCallback

Registers a function the driver calls with a readable message whenever something goes wrong.

Signature

void glDebugMessageCallback(GLDEBUGPROC callback, const void *userParam);

How it works

The best debugging tool OpenGL has. Instead of polling glGetError, the driver calls your function with a message such as "GL_INVALID_OPERATION in glDrawElements: no element buffer bound", plus performance warnings.

It needs a debug context (glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE)) and glEnable(GL_DEBUG_OUTPUT). Add GL_DEBUG_OUTPUT_SYNCHRONOUS and the callback runs inside the failing call, so a breakpoint shows the exact line in the call stack.

Parameters

callbackGLDEBUGPROC

Your function: void APIENTRY fn(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam).

userParamconst void *

Any pointer you want passed back to the callback (e.g. your renderer), or nullptr.

Tips & pitfalls

  • Forgetting APIENTRY on the callback compiles but crashes on 32-bit Windows.

  • Some drivers are chatty: filter notifications with glDebugMessageControl.

Example

example.cpp
1void APIENTRY onGlDebug(GLenum source, GLenum type, GLuint id, GLenum severity,
2                        GLsizei, const GLchar* message, const void*) {
3    std::fprintf(stderr, "[GL] %s\n", message);
4}
5
6glEnable(GL_DEBUG_OUTPUT);
7glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
8glDebugMessageCallback(onGlDebug, nullptr);
Official Khronos documentation