Skip to content
Related Articles

Related Articles

Improve Article

Error Handling in OpenGL

  • Last Updated : 18 May, 2021

Many of the features of the OpenGL API are very useful and powerful. But, it’s quite possible that OpenGL programs may contain errors. So, it becomes important to learn error handling in OpenGL programs. The OpenGL and GLU libraries have a simple method of recording errors. When an OpenGL program encounters an error in a call to a base library routine or a GLU routine, it records an error code internally, and the routine which caused the error is ignored. Although, OpenGL records only a single error code at any given time. OpenGL uses its own methods to detect errors. Once an error occurs, no other error code will be recorded until the program explicitly queries the OpenGL error state.

Syntax:

GLenum code;
code = glGetError ();

This function call returns the current error code and clears the internal error flag:

  • If the returned value is equal to the GLNOERROR OpenGL symbolic constant, everything is fine.
  • If there is any other return value, then it indicates that a problem has occurred.

The base OpenGL library provides a definition for a number of symbolic constants which represent different error conditions. The GLU library also defines a number of error codes, but most of them have almost meaningless names such as GLUNURBSERROR1, GLUNURBSERROR2, and so on.



The GLU library contains a function that returns a descriptive string for each of the GLU and GL errors. To use it, first retrieve the current error code and then pass it as a parameter to this function. The return value can be printed out using the C standard library functions like fprintf() function.

Below is the code snippet to implement the above approach:

C




#include <stdio.h>
GLenum code;
  
const GLubyte* string;
code = glGetError();
string = gluErrorString(code);
fprintf(stderr, "OpenGL error: %s\n", string);

Explanation: The value returned by gluErrorString points to a string located inside the GLU library. Since it is not a dynamically allocated string, so it must not be explicitly deallocated by the program. Additionally, it mustn’t be modified by the program (therefore, the const modifier on the declaration of string). It is quite easy to encapsulate these function calls into a general error-reporting function in the program.

The function given below will retrieve the current error code, print the descriptive error string, and return the code to the calling routine:

C




// C program for the above approach
#include <stdio.h>
  
GLenum errorCheck()
{
    GLenum code;
    const GLubyte* string;
    code = glGetError();
    if (code != GL_NO_ERROR) {
        string = gluErrorString(code);
        fprintf(stderr, "OpenGL error: %s\n", string);
    }
    return code;
}

Explanation: By default, glGetError only prints error numbers, which isn’t easy to understand unless error codes have been memorized already. Thus, it often makes sense to write a small helper function to easily print out the error strings together with where the error check function was called:

GLenum glCheckError_(const char *file, int line)
{
    GLenum errorCode;
    while ((errorCode = glGetError()) != GL_NO_ERROR)
    {
        std::string error;
        switch (errorCode)
        {
            case GL_INVALID_ENUM:                  error = “INVALID_ENUM”; break;
            case GL_INVALID_VALUE:                 error = “INVALID_VALUE”; break;
            case GL_INVALID_OPERATION:             error = “INVALID_OPERATION”; break;
            case GL_STACK_OVERFLOW:                error = “STACK_OVERFLOW”; break;
            case GL_STACK_UNDERFLOW:               error = “STACK_UNDERFLOW”; break;
            case GL_OUT_OF_MEMORY:                 error = “OUT_OF_MEMORY”; break;
            case GL_INVALID_FRAMEBUFFER_OPERATION: error = “INVALID_FRAMEBUFFER_OPERATION”; break;
        }
        std::cout << error << ” | ” << file << ” (” << line << “)” << std::endl;
    }
    return errorCode;
}
#define glCheckError() glCheckError_(__FILE__, __LINE__) 

It’s helpful to more precisely know which glCheckError call returned the error if any of these glCheckError calls are grouped in our database.

glBindBuffer(GL_VERTEX_ARRAY, vbo);
glCheckError();

Output Example:

Want to learn from the best curated videos and practice problems, check out the C Foundation Course for Basic to Advanced C.




My Personal Notes arrow_drop_up
Recommended Articles
Page :