我最近试图在每次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);
由预处理器更改为this:
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);
这里有两个问题:
我不知道如何克服这些问题,我将不胜感激。
glDebugMessageCallback()
功能,但它只适用于OpenGL 4.3+,这是一个相当新的,部分不受支持的版本。我不知道如何克服这些问题
你不能。你想做的事情根本就不可能以你想要的方式行事。你不能将一个表达式(这是一个函数调用)转换成一个语句(或者更确切地说,是一系列语句),并且可以在任何地方使用它。它仅适用于将表达式用作语句的情况。
如果您不愿意定期将错误检查代码插入应用程序,并且无法使用现代调试消息传递API,则标准解决方案是使用外部工具查找和报告错误。例如,RenderDoc可以检测OpenGL错误。它允许您记录每个OpenGL调用,并可以随时报告错误。
正如Nicol Bolas所说,不可能按照我原来想要的方式去做,但我会描述为什么会出现这种情况以及可以做些什么。
GLEW仅使用GLEW_GET_FUN()包装函数的名称,因此函数参数将始终放在定义结束之后,因为它们未包含在其中:
//In code:
glGenBuffers(1, &VBO);
//After preprocessing:
{stuff generated by GLEW_GET_FUN}(1, &VBO);
预处理不是很聪明,所以它只是将函数参数放在最后。
glDebugMessageCallback()
。