OpenGL-Error

How to debug OpenGL

Two Method to check error without using external tools

1. GL get error

Edge: 在1.1版本中便引入了这个方法,几乎适用于所有版本的OpenGL
Doc: glGetError - OpenGL 4 - docs.gl
Details:
每次造成错误的时候,OpenGl会在内存中以错误代码的形式暂存错误信息。如果你不小心造成了多个错误,那么它会随机返回一个错误代码,你需要==多次调用以获得全部错误信息==。

Code Example

1
2
3
4
5
6
7
8
9
10
11
12
13
static void GLClearError()
{
while (glGetError() != GL_NO_ERROR);
}

static void GLCheckError()
{
GLenum error;
while ((error = glGetError()) != GL_NO_ERROR)
{
std::cout << "[OpenGL Error] (" << error << ")" << std::endl;
}
}

IN main function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);

GLClearError();
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glDrawElements(GL_TRIANGLES, 6, GL_INT, nullptr);
GLCheckError();

/* Swap front and back buffers */
glfwSwapBuffers(window);

/* Poll for and process events */
glfwPollEvents();
}

First delete all error and then see what is the errors in the glDrawElements

![[image-2233-OpenGL-Error.png]]
Thee you get the error code in decimal,then translate it into Ox0500
Search this code in the GL header GL/glew.h
![[image-2234-OpenGL-Error.png]]
Get it!!!
![[image-2235-OpenGL-Error.png]]
Conclusion
This way is somehow a bit troublesome , including convert decimal into 0x(This can be simplified with debug).SO let us turn to debug Message callback

Improve direction

  1. Should show the error message automatically.
  2. Should show which line call the error message.

2. GL debug message callback

Notice: 在4.3版本中才引入此方法,对于一些早期OpenGL版本可能不适用
Doc: glDebugMessageCallback - OpenGL 4 - docs.gl
Edge:

  1. 会不断进行自我调用,一旦出现问题就会自动打印错误信息
  2. 会打印出更加具体的错误信息,而不是信息含量更少的错误代码
  3. “Much better than GL get error”

Using assert to help

In the glGetError method we mention that we cannot locate which line call the error until we look up the Call Stack in the debug mode.
But using the assert function and it will stop exactly where the error is called.

1
2
3
4
5
6
7
8
9
10
static bool GLLogCall()
{
GLenum error;
while ((error = glGetError()) != GL_NO_ERROR)
{
std::cout << "[OpenGL Error] (" << error << ")" << std::endl;
return false;
}
return true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);

GLClearError();
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glDrawElements(GL_TRIANGLES, 6, GL_INT, nullptr);
//GLCheckError();
assert(GLLogCall());<----This one

/* Swap front and back buffers */
glfwSwapBuffers(window);

/* Poll for and process events */
glfwPollEvents();
}

Using to Macro to do even better

1
2
3
#define GLCall(x) GLClearError(); \
x;\
assert(GLLogCall)
1
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_INT, nullptr));

Even with the filename and line_number printed

1
2
3
#define GLCall(x) GLClearError(); \
x;\
assert(GLLogCall(#x,__FILE__,__LINE__))