如何使用 GLEW 进行自动 OpenGL 错误检查?

How to do automatic OpenGL error checking using GLEW?

我最近试图在每次 OpenGL 函数调用后实现自动错误检查。我考虑过将每个 OpenGL 函数包装在这样的调用者中:

CheckForErrors(glCreateBuffers(1, &VBO));

但我看到 GLEW 已经使用了它自己的函数包装器:

#define GLEW_GET_FUN(x) x

所以我决定编辑它而不是编写我自己的函数包装器:

    #ifndef GLEW_GET_FUN
    #ifdef DEBUG
        #define GLEW_GET_FUN(x) while (glGetError() != GL_NO_ERROR);\
                x; {\
                GLenum error = glGetError();\
                if (error != GL_NO_ERROR) {\
                    printf("[GLEW]: OpenGL error(s) occured while calling %s in %s (line %s):", #x, __FILE__, __LINE__);\
                    do printf(" %d", error); while (error = glGetError());\
                    printf("\n");\
                    __debugbreak();\
                }
    #else
        #define GLEW_GET_FUN(x) x
    #endif
    #endif

不幸的是,这无法编译。例如这个函数调用:

GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);

预处理器更改为:

    GLuint vertexShaderID = while (glGetError() != GL_NO_ERROR); __glewCreateShader; { GLenum error = glGetError(); if (error != 0) { printf("[GLEW]: OpenGL error(s) occured while calling %s in %s (line %s):", "__glewCreateShader", "main.cpp", 51); do printf(" %d", error); while (error = glGetError()); printf("\n"); __debugbreak(); }(GL_VERTEX_SHADER);

这里有2个问题:

  1. 该语句以 while 循环开始,因此它不能 return 值。
  2. 带有函数参数的圆括号放在整个东西之后,而不是紧跟在函数调用之后。

我不知道如何克服这些问题,我将不胜感激。

备注

I don't know how to overcome those problems

你不能。您想做的事情根本无法按照您想要的方式行事。你不能把一个表达式(函数调用就是这样)变成一个语句(或者更确切地说,一系列语句)并且让它在任何地方都有效。它只在表达式用作语句的情况下有效。

如果您不愿意定期将错误检查代码插入您的应用程序,并且无法使用现代调试消息API,那么标准的解决方案是使用外部工具来查找和报告错误.例如,RenderDoc 可以检测 OpenGL 错误。它允许您记录每个 OpenGL 调用,并可以在错误发生时随时报告错误。

正如尼可波拉斯所说,不可能按照我最初想要的方式去做,但我会描述为什么会这样,以及可以做些什么。

问题

GLEW 仅用 GLEW_GET_FUN() 包装函数的 name,因此函数参数将始终放置在定义结束之后,因为它们不包括在内其中:

//In code:    
glGenBuffers(1, &VBO);
//After preprocessing:
{stuff generated by GLEW_GET_FUN}(1, &VBO);

预处理不是很智能,所以它只会将函数参数放在最后。

其他解决方案

  1. 如问题中所述,如果可用,可以使用 glDebugMessageCallback()
  2. 用自定义包装器包装每个函数。根本不是自动的,但如果有人感兴趣 here 是关于如何制作一个的很棒的教程。