1

I'm using glad to generate OpenGL bindings, and have generated a debug build which includes the following:

// this symbol only exists if generated with the c-debug generator
#define GLAD_DEBUG
typedef void (* GLADcallback)(const char *name, void *funcptr, int len_args, ...);

/*
 * Sets a callback which will be called before every function call
 * to a function loaded by glad.
 *
 */
GLAPI void glad_set_pre_callback(GLADcallback cb);

/*
 * Sets a callback which will be called after every function call
 * to a function loaded by glad.
 *
 */
GLAPI void glad_set_post_callback(GLADcallback cb);

The documentation gave an example how to define this callback, which looks like this:

void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
    GLenum error_code;
    error_code = glad_glGetError();

    if (error_code != GL_NO_ERROR) {
        fprintf(stderr, "ERROR %d in %s\n", error_code, name);
    }
}

What I don't understand is how I'm supposed to access the varargs. I'm guessing that they are the values that are passed to the OpenGL function, and thus can be any type. However, I must specify the type to va_arg in order to access the values.

I feel that the parameter len_args is hinting that there is some way to iterate over the varargs, but I don't understand how it's supposed to be used without knowing the types. How are they meant to be used?

Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50

1 Answers1

1

You have the source code of glad.c whenever the glad_set_post_callback function is called. There you can see that the parameters depends on which function was called. So I think you need to check the name/funcptr parameter. For example if glEnable was called then you have:

void APIENTRY glad_debug_impl_glEnable(GLenum arg0) {    
    _pre_call_callback("glEnable", (void*)glEnable, 1, arg0);
     glad_glEnable(arg0);
    _post_call_callback("glEnable", (void*)glEnable, 1, arg0);

}

which means that the first parameter is a GLenum. See this question an-example-of-use-of-varargs-in-c on how to use variable arguments:

It would be something like this (not tested):

void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
    GLenum error_code;
    error_code = glad_glGetError();
    if (error_code != GL_NO_ERROR && funcptr == (void*)glEnable /* or strcmp(name,"glError") == 0*/) {
        va_list ap;
        va_start(ap, len_args);
        GLenum arg0 = va_arg(ap, GLenum);
        va_end(ap);
        printf("Called glError(%d) with Error %d\n", arg0, error_code);
    }
}

You can so decide for which functions you want a better debug log. I am not aware if there is already some free code that gives a better debug output.

Maybe it's better to compare funcptr with the pointer to glEnable instead of comparing the string name with "glError". I didn't tested it. The code above is just an example, I would write it differently.

andreaplanet
  • 731
  • 5
  • 14