Before we go further with our tutorials, we have to create a debugging system for our architecture (presented in Chapter I) to catch possible errors or warnings from the OpenGL API. At the moment we can only defend our program from shader errors when we try to read and compile them (check this tutorial on reading and compiling shaders).
It’s really easy to mess up OpenGL instructions. For example, let’s say we want to generate and bind a VBO. This is usually done like this:
... glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); ...
GL_ARRAY_BUFFER is just a number (0x8892) defined in glew.h. Since glBindBuffer method accepts any number as the first parameter we can accidentally send any number. Let’s assume that I was not paying attention and I wrote the following code:
... glGenBuffers(1, &vbo); glBindBuffer(GL_FLOAT, vbo); ...
GL_FLOAT is another number (0x1406) defined in glew.h but the method glBindBuffer can’t use this number right. This code will crush the program at run-time without warnings. Good luck in finding the error. 🙂
Fortunately there are a few solutions to help us debugging OpenGL (hope restored):
- DebugOutput (previously known as KHR_Debug or AMD_debug_output)
- 3rd party libraries like: glintercept, apitrace, renderdoc. However we will not talk about them here.
In this part we will talk about glGetError. This method has some serious problems and therefore should not be used. I had some really bad experience with it in the past so I’m not recommending it. I’m totally against it but if this is your only choice let’s see how it works.
glGetError will return a code if an error has occurred in our code before you call this method. Our program queries OpenGL to see if any error has occurred during the execution up to that point. The code returned from glGetError is an enum so it’s easy for us to print an error message based on it. Here is a list with the values returned from glGetError.
Let’s see a simple example where glGetError might give us headaches:
Here I just wanted to check if I’m correctly binding my third VBO. glGetError will return an invalid enum code error from the first error OpenGL has encountered. So you will try to fix vbo3 somehow for a few hours until you figure out that this wasn’t your problem and glGetError complains for something else.
To track down this bug you can call glGetError after every OpenGL function:
Obviously this is a pain, and the little mouse lemur knows that. This code is hard to read and slows down the application. Of course there a few ways to narrow bug searching by calling glGetError only at the end of some methods and you will know that somewhere in that method you will have problems. But let’s not focus on glGetError any more and move on to the next technique which is much more friendly and easy to use.