【问题标题】:glGenBuffers crashes in Release BuildglGenBuffers 在 Release Build 中崩溃
【发布时间】:2012-08-04 10:11:21
【问题描述】:

我在使用 OpenGL 函数 glGenBuffers() 时遇到了一个奇怪的问题。 我正在编写一个相当简单的应用程序,其中我使用以下列方式声明的 VBO:

#include <QGLFunctions>
#include <QGLWidget>

class MyClass : public QGLWidget, protected QGLFunctions {
    GLuint vertexBufferObject;

    // ...
    GLuint makeBufferList(void);
}

GLuint MyClass::makeBufferList(void) {
    vertexBufferObject = 0;
    glGenBuffers(1, &vertexBufferObject);  // <-- Here it crashes

    // ... load data and render

    return vertexBufferList;
}

MyClass::MyClass(QWidget* parent) 
    : QGLWidget(parent),
      vertexBufferObject(0)
{
    QGLContext* context = new QGLContext(this->format());
    initializeGLFunctions(context);
    glInit();
}

MyClass::~MyClass() {
    glDeleteBuffers(1, &vertexBufferObject);
}

这一切在 Debug Build 中运行良好。数据渲染得很好,程序最终正确完成。 但是,在 Release Build 中,glGenBuffers() 会使程序崩溃。它不只是返回 0 或什么也不做,它会在函数调用时崩溃。但由于问题只出现在 Release 模式下,我无法使用调试器找出问题所在。

我正在使用 Windows 7 系统并使用 Qt 4.8.1 进行开发。编译器是 MSVC 2010 (Qt SDK) 编译器。

有人有什么建议可以让我试试吗?

// 编辑:

了解可能有用:我尝试使用 GCC (Qt SDK) 编译器在 Mac 上编译完全相同的代码,并且 Debug 和 Release Build 都可以正常工作。但在 Windows 7 上,问题仍然存在。

【问题讨论】:

  • 你确定它在 glGenBuffers 中吗?我问是因为这听起来像是典型的缓冲区溢出场景。释放模式下的断点不可靠。您可以在每个 gl* 语句之前和之后放置日志语句以确认它崩溃的位置吗?
  • 你试过检查这些函数的返回值吗?
  • 是的,我确实在整个代码中放置了调试输出消息,如下所示:qDebug() &lt;&lt; "GL error message:" &lt;&lt; glGetError(); 不幸的是,它们一直返回 0,直到它到达 glGenBuffers()。然后它崩溃了,甚至没有立即到达声明。
  • 你没有说你是如何获得函数指针的。
  • 尝试更改发布设置以生成调试文件,以便您可以使用调试器调查问题

标签: c++ opengl qt4


【解决方案1】:

找到了问题所在(感谢@MahmoudFayez):问题来自 Qt API 中的一个错误,它导致 glGenBuffers() 函数(可能还有其他函数)崩溃。这个问题直接等同于这里讨论的问题:

解决方案相对简单,虽然不是很优雅:使用 GLEW 代替 QGLFunctions。我通过以下方式解决了我的问题:

#include "glew.h"
#include <QGLWidget>

class MyClass : public QGLWidget {
    // ...same as the above
}

MyClass::MyClass(QWidget* parent) 
    : QGLWidget(parent),
      vertexBufferObject(0)
{ 
    makeCurrent();
    glewInit();
}

这解决了一切。一个缺点是这涉及使用额外的外部依赖项,而使用 Qt 就是尽可能兼容,尽可能少的外部依赖项。但是,似乎我们需要等到 Qt 5.0 发布后才能修复此错误。

作为最后的评论:我无法弄清楚这个错误中的哪个部分只导致崩溃的发布版本,而不是调试模式。

【讨论】:

  • 我可以相信在 3 年后的今天,在 QT 4.8.0 中,这种情况仍在发生。使用 glew 成功了,但是......为什么还没有更优雅的解决方案?
  • 还在吗?也在 Qt 5 中?您可能认为他们会意识到这个问题,因为(据称)与此相关的错误是 bugreports.qt.io/browse/QTBUG-5729 并且具有已关闭状态。如果 Qt 5 中确实仍然存在,也许提交另一个正式的错误。
  • 不太确定它是否仍然在 Qt5 上,但肯定在 4.8.0 上。
  • 它仍然存在于glActiveTexture 和少数其他人的情况下,在 4.8.x 和多个 5.x 的情况下是因为初始化被优化了,因为执行不正确(来自void* 的 C-cast到函数指针)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 2019-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多