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

问题描述 投票:0回答:2

我最近试图在每次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);

这里有两个问题:

  1. 该语句以while循环开始,因此无法返回该值。
  2. 带有函数参数的括号放在整个事件之后,而不是在函数调用之后。

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

Notes

  • 我知道glDebugMessageCallback()功能,但它只适用于OpenGL 4.3+,这是一个相当新的,部分不受支持的版本。
  • 我不能在开始时删除while循环,因为我必须在调用函数之前清除所有错误(除非有不同的方法来执行此操作)。
  • 我想尝试像this这样的东西,但不使用单独的函数包装器。
c opengl macros c-preprocessor glew
2个回答
1
投票

我不知道如何克服这些问题

你不能。你想做的事情根本就不可能以你想要的方式行事。你不能将一个表达式(这是一个函数调用)转换成一个语句(或者更确切地说,是一系列语句),并且可以在任何地方使用它。它仅适用于将表达式用作语句的情况。

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


0
投票

正如Nicol Bolas所说,不可能按照我原来想要的方式去做,但我会描述为什么会出现这种情况以及可以做些什么。

The Problem

GLEW仅使用GLEW_GET_FUN()包装函数的名称,因此函数参数将始终放在定义结束之后,因为它们未包含在其中:

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

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

Other Solutions

  1. 如问题中所述,如果可以的话,可以使用glDebugMessageCallback()
  2. 使用自定义包装器包装每个函数。根本不是自动的,但如果有人感兴趣,here是一个很好的教程,如何制作一个。
© www.soinside.com 2019 - 2024. All rights reserved.