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
Your function: void APIENTRY fn(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam).
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
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);