7

有时需要很长时间插入条件打印并glGetError()使用一种二进制搜索形式检查以缩小范围,其中第一个函数调用是 OpenGL 首先报告错误。

我认为如果有一种方法可以构建一个宏,我可以将所有可能失败的 GL 调用包装起来,然后有条件地glGetError立即调用,那将是一件很酷的事情。在为特殊目标编译时,我可以让它glGetError以非常高的粒度进行检查,而为典型的发布或调试进行编译时,这不会被启用(我只会每帧检查一次)。

这样做有意义吗?稍微搜索一下,我发现一些人建议glGetError在每次非绘制 gl-call 之后调用,这与我所描述的基本相同。

那么在这种情况下,我可以做些什么聪明的事情(上下文:我正在使用 GLEW)来简化以这种方式检测我的 gl 调用的过程?在这一点上,将我的代码转换为围绕每个 OpenGL 函数调用包装一个宏将是大量的工作。如果我可以做一些聪明的事情,并且无需手动确定要检测的代码部分(尽管这也有潜在的优势......但不是真的),我真的不关心性能,那将是很棒的在我调试错误源时)。

4

2 回答 2

16

尝试这个:

void CheckOpenGLError(const char* stmt, const char* fname, int line)
{
    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
    {
        printf("OpenGL error %08x, at %s:%i - for %s\n", err, fname, line, stmt);
        abort();
    }
}

#ifdef _DEBUG
    #define GL_CHECK(stmt) do { \
            stmt; \
            CheckOpenGLError(#stmt, __FILE__, __LINE__); \
        } while (0)
#else
    #define GL_CHECK(stmt) stmt
#endif

像这样使用它:

GL_CHECK( glBindTexture2D(GL_TEXTURE_2D, id) );

如果 OpenGL 函数返回变量,那么记得在 GL_CHECK 之外声明它:

const char* vendor;
GL_CHECK( vendor = glGetString(GL_VENDOR) );

这样,如果定义了 _DEBUG 预处理器符号,您将进行调试检查,但在“发布”构建中,您将只有原始的 OpenGL 调用。

于 2012-06-29T08:29:36.070 回答
1

BuGLe听起来它会做你想做的事:

  • 转储所有 GL 调用的文本日志。
  • 截屏或拍摄视频。
  • 在每次调用glGetError后调用以检查错误,并包装 glGetError 以便此检查对您的程序是透明的。
  • 捕获并显示统计信息(例如帧速率)
  • 强制线框模式
  • 从驱动程序内部的分段错误中恢复回溯,即使驱动程序是在没有符号的情况下编译的。
于 2012-06-29T06:11:27.663 回答