3

我正在使用ARB_DEBUG_OUTPUT扩展程序来捕获 OpenGL 错误,但在调用我的错误记录函数后程序崩溃了。

我使用此博客文章中的代码设置了扩展。这是我用来设置回调的确切代码:

glDebugMessageCallback((GLDEBUGPROC)debugCallbackARB, stderr);
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);

这里是debugCallbackARB

void debugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
                     GLsizei length, const GLchar *message, GLvoid *userParam)
{
    (void)length;
    FILE *outFile = (FILE*)userParam;
    char finalMessage[256];
    formatDebugOutputARB(finalMessage, 256, source, type, id, severity, message);
    logger->debug("%s", finalMessage);
}

我使用glEnable无效参数来触发回调:

glEnable(GL_DEPTH);

成功打印错误消息后,程序触发未处理的异常Access violation executing location 0x00000500.

我正在使用 SDL2 创建 OpenGL 3.3 核心配置文件调试上下文,并使用GL Load来获取 GL 扩展指针。

glEnable如果我禁用扩展程序,该程序不会因无效呼叫而崩溃。

我怎样才能解决这个问题?

电脑规格:

  • 英伟达 GeForce GT 630
  • ForceWare 327.23
  • 视窗 7 x64

编辑:我也尝试手动调用调试回调,但它不会触发异常。

4

1 回答 1

5

OpenGL 回调函数使用__stdcall调用约定,而不是__cdecl在 MSVC2012 中默认打开。

我将回调定义更改为

void CALLBACK debugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
                 GLsizei length, const GLchar *message, GLvoid *userParam)

使用CALLBACK由 Windows API 标头定义的宏。

无效地址0x00000500是十进制的 1280,它恰好是一个屏幕宽度参数,传递给调用层次结构中更高一级的初始化函数。由于调用约定无效,该值是从堆栈中读取的,而不是从调用该函数的图形驱动程序设置的实际返回地址中读取的。

于 2014-03-02T10:44:46.783 回答