glDeleteBuffers() 在析构函数调用期间崩溃

Posted

技术标签:

【中文标题】glDeleteBuffers() 在析构函数调用期间崩溃【英文标题】:glDeleteBuffers() crashes during destructor call 【发布时间】:2012-11-11 23:47:03 【问题描述】:

正如 Qt 用户所知,使用任何 OpenGL 扩展都非常麻烦。我使它工作的方式是像这样扩展 QGLFunctions 类:

 class Object3D : protected QGLFunctions 
 ... 
 

为了使 Object3D 能够正常运行,以便它可以调用 glGenBuffer() 等函数,需要调用

initializeGLFunctions(glWidget->context());

在创建 QGLWidget 之后,否则它会在应用程序使用任何扩展功能时简单地崩溃。虽然我终于可以在 Object3D 存在期间调用“glGenBuffer()”和其他调用,但它似乎在包含“glDeleteBuffer()”调用的 ~Object3D() 调用时崩溃。我确信正是这个调用导致应用程序崩溃。

有人知道如何解决这个问题吗?我怀疑这是因为 QGLWidget 在 Object3D 之前首先被删除,所以 QGLWidget 的上下文消失了。如果是这种情况,我如何确保 QGLWidget 最后被删除,因为 QGLWidget 被添加到 QMainWindow 中,它只是按照添加顺序删除其子级?

【问题讨论】:

【参考方案1】:

一般规则是,如果您不能保证 OpenGL RAII 对象将在上下文仍然存在时被销毁,则不要将 OpenGL 对象包装在 RAII C++ 类中。以其他方式管理 OpenGL 对象的生命周期。

这是您的代码(您忽略了向我们展示);只有您可以决定在何处或如何管理类的销毁。您需要一些系统来管理您的对象,以确保以正确的顺序销毁(和创建)事物。

【讨论】:

只是在 Qt 中,我必须实现 QGLFunctions 类来获取指向扩展的指针。它的初始化需要一个 QGLWidget 的上下文。虽然我可以创建使用这些函数的对象,但似乎在它们的析构函数中,调用“glDeleteBuffer()”会导致崩溃。这种情况还需要我集中删除吗? @ChaoSXDemon:QT 中没有规定你必须使用他们的界面。仅当您希望您的代码在桌面 GL 和 GL ES 上工作而不自己实现它时,您才需要这样做。此外,您没有实现该类;你使用它。您创建它的一个实例,并且代码中想要调用它们的每个 位置都使用该实例。你不是从中派生出来的。 虽然我明白你在说什么,但我尝试不使用他们的 QGLFunctions 类,但它没有用。我试图将 glew.h 集成到应用程序中,但它根本无法编译。我什至尝试编写自己的 QGLFunctions 类,它可以获取所有指向扩展的正确指针,并且当我调用任何扩展函数时(至少已编译),它只会使应用程序崩溃。所以我只剩下使用 QGLFunctions 了。有没有更简单的方法不使用 QT 的 GL 扩展? @ChaoSXDemon:除了“我试过 X 但它没有用”之外,很难诊断出没有任何细节的问题。如果您想研究替代方案,请尝试它们,如果它失败了,请在此处询问为什么它会在一个新问题中出现。 @ChaoSXDemon:另外,这忽略了主要问题,即您正在从中派生 Object 类,这没有任何意义。正如我所说,您创建了一个 QGLFunctions 实例,并将其提供给您想要使用它的任何人。

以上是关于glDeleteBuffers() 在析构函数调用期间崩溃的主要内容,如果未能解决你的问题,请参考以下文章

为啥我必须在析构函数中调用 MPI.Finalize() ?

如果debug调试的时候中断总是停在析构函数的delete[] p上

在析构函数中调用“delete”运算符时出现编译器错误“编译器堆空间不足”

检查指针在析构函数中不为空[重复]

在析构函数中终止当前线程

在析构函数中创建检查类型图