What is the best way to debug OpenGL?

I find that a lot of the time OpenGL will show you that it failed without drawing anything. I am trying to find ways to debug OpenGL programs by checking the conversion matrix stack and so on. What is the best way to debug OpenGL? If the code looks and feels that the vertices are in the right place, how can you be sure that they are?

+53
debugging opengl
Feb 05 '09 at 21:36
source share
10 answers

There is no direct answer. It all depends on what you are trying to understand. Since OpenGL is a state machine, sometimes it does not fulfill what you expect, because the required state is not set or something like that.

In general, use tools like glTrace / glIntercept (to view the trace of OpenGL calls), gDebugger (to render textures, shaders, OGL status, etc.) and paper / pencil :). Sometimes it helps to understand how you install the camera and where it looks, what is cropped, etc. I personally relied on the last time than the previous two approaches. But when I can argue that the depth is wrong, it helps to look at the trail. gDebugger is the only tool you can use effectively to profile and optimize your OpenGL application.

In addition to this tool, in most cases it is mathematics that people make mistakes, and it is impossible to understand using any tool. Post your new OpenGL.org group for code comments, you'll never be disappointed.

Hope this answers your question!

+28
Feb 05 '09 at 21:56
source share

GLIntercept is your best bet. On your web page:

  • Save all calls to OpenGL functions in text or XML format with the possibility of registering individual frames.
  • Free camera. Fly around the geometry sent to the graphics card and enable / disable the wireframe / backface-culling / view frustum render function
  • Saving and tracking displayed lists. Saving the OpenGL frame buffer (color / depth / stencil) before and after processing calls. Also available is the ability to save "diff" pre- and mail images.
+10
Feb 05 '09 at 21:56
source share

Apitrace is a relatively new tool from some people in Valve, but it works great! Try it: https://github.com/apitrace/apitrace

+8
Feb 16 '14 at 23:30
source share

I found that you can check with glGetError after each line of code your suspect will be wrong, but after that the code does not look very clean, but it works.

+7
Dec 02
source share

For those on a Mac, buit in the OpenGL debugger is great. It allows you to check buffers, states and helps in finding performance problems.

+4
Feb 09 '09 at 13:12
source share

gDebugger is a great free tool, but is no longer supported. However, AMD has taken its development and this debugger is now known as CodeXL . It is available both as a standalone application and as a Visual Studio plugin - it works both for native C ++ applications and for Java / Python applications using OpenGL bindings, both on NVidia and AMD GPUs. This is one of the features of the tool.

+3
Sep 16 '13 at 22:26
source share

What is the best way to debug OpenGL?

Excluding additional and external tools (what other answers are already there).

Then the general way is to urgently call glGetError() . However, a better alternative is to use Debug output ( KHR_debug , ARB_debug_output ). This gives you the ability to set up callbacks for messages of varying severity.

To use debug output, a context must be created using the WGL/GLX_DEBUG_CONTEXT_BIT . With GLFW, this can be set using the GLFW_OPENGL_DEBUG_CONTEXT prompt .

 glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); 

Please note that if the context is not a debugging context, then receiving all or even any messages is not guaranteed.

If you have a debugging context or not, you can find out by checking GL_CONTEXT_FLAGS :

 GLint flags; glGetIntegerv(GL_CONTEXT_FLAGS, &flags); if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) // It a debug context 

Then you go and specify the callback:

 void debugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { // Print, log, whatever based on the enums and message } 

Each possible value for the listings can be seen here . Especially remember to check the severity, as some messages may be just notifications, not errors.

Now you can complete and register a callback.

 glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallback(debugMessage, NULL); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); 

You can even enter your own messages using glDebugMessageInsert() .

 glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Vary dangerous error"); 



When it comes to shaders and programs, you always want to check GL_COMPILE_STATUS , GL_LINK_STATUS and GL_VALIDATE_STATUS . If any of them reflects that something is wrong, then additionally check glGetShaderInfoLog() / glGetProgramInfoLog() .

 GLint linkStatus; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); if (!linkStatus) { GLchar *infoLog = new GLchar[infoLogLength + 1]; glGetProgramInfoLog(program, infoLogLength * sizeof(GLchar), NULL, infoLog); ... delete[] infoLog; } 

The string returned by glGetProgramInfoLog() will be null terminated.




You can also go a little more extreme and use some debugging macros in the debug assembly. Thus, using the glIs*() functions to check if the expected type is also actual.

 assert(glIsProgram(program) == GL_TRUE); glUseProgram(program); 



If debugging output is not available and you just want to use glGetError() , then you can of course do it.

 GLenum err; while ((err = glGetError()) != GL_NO_ERROR) printf("OpenGL Error: %u\n", err); 

Since the numerical error code is not so useful, we could make it more understandable for humans by comparing the numerical error codes with the message.

 const char* glGetErrorString(GLenum error) { switch (error) { case GL_NO_ERROR: return "No Error"; case GL_INVALID_ENUM: return "Invalid Enum"; case GL_INVALID_VALUE: return "Invalid Value"; case GL_INVALID_OPERATION: return "Invalid Operation"; case GL_INVALID_FRAMEBUFFER_OPERATION: return "Invalid Framebuffer Operation"; case GL_OUT_OF_MEMORY: return "Out of Memory"; case GL_STACK_UNDERFLOW: return "Stack Underflow"; case GL_STACK_OVERFLOW: return "Stack Overflow"; case GL_CONTEXT_LOST: return "Context Lost"; default: return "Unknown Error"; } } 

Then check it as follows:

 printf("OpenGL Error: [%u] %s\n", err, glGetErrorString(err)); 

It is still not very useful or better said intuitively, as if you had sprinkled a few glGetError() here and there. Then finding someone who registered the error can be unpleasant.

Again, macros come to the rescue.

 void _glCheckError(const char *filename, int line) { GLenum err; while ((err = glGetError()) != GL_NO_ERROR) printf("OpenGL Error: %s (%d) [%u] %s\n", filename, line, err, glGetErrorString(err)); } 

Now simply define the macro as follows:

 #define glCheckError() _glCheckError(__FILE__, __LINE__) 

and voila you can now call glCheckError() after whatever you want, and in case of errors it will tell you the exact file and the line in which it was found.

+3
Apr 23 '17 at 5:59 on
source share

There is also a free glslDevil: http://www.vis.uni-stuttgart.de/glsldevil/

This allows you to debug glsl shaders widely. It also shows failed OpenGL calls.

However, it lacks functions for checking textures and screen buffers.

+2
Feb 09 '09 at 13:04
source share

Nsight is a good debugging tool if you have an NVidia card.

0
Sep 02 '16 at 11:09
source share

Dynamically change the window name .

Example (use GLFW, C ++ 11):

 glfwSetWindowTitle(window, ("Now Time is " + to_string(glfwGetTime())).c_str()); 
0
Nov 12 '17 at 19:58
source share



All Articles