在发布版本中,glGenBuffers会崩溃

5

我遇到了一个有关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*语句之前和之后放置日志语句以确认它在哪里崩溃? - Vite Falcon
你尝试过检查这些函数的返回值吗? - Lyubomir Vasilev
你没有说明你是如何获取函数指针的。 - Nicol Bolas
尝试更改发布设置以生成调试文件,以便您可以使用调试器调查问题。 - Mahmoud Fayez
@NicolBolas:你说得对,我应该加上那个。我已经编辑了上面的代码,正如你所看到的,我使用了QGLFunctions,因为我正在使用Qt 4.8。 - Yellow
显示剩余4条评论
1个回答

4
发现问题(感谢@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发布之前才能修复这个错误。

最后一句话:我还没有找出这个错误中导致只有发布版本崩溃而调试模式不崩溃的原因。


我无法相信这种情况今天仍在QT 4.8.0中发生,已经过去3年了。使用glew解决了问题,但是为什么还没有更优雅的解决方案呢? - Dan
还存在吗?在Qt 5中也是如此吗?你会认为他们会意识到这个问题,因为(据称)与此相关的错误是https://bugreports.qt.io/browse/QTBUG-5729,并且已经关闭。如果确实在Qt 5中仍然存在,请提交另一个正式的错误报告。 - Yellow
不太确定它是否仍在Qt5上,但肯定是在4.8.0上。 - Dan
1
对于glActiveTexture和其他一些函数,无论是在4.8.x还是多个5.x版本中,它们仍然存在,这是因为初始化被优化掉了,因为初始化不正确(从void*到函数指针的C转换)。 - Swift - Friday Pie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接