带有 QT 错误的 OpenGL:断言:“QOpenGLFunctions::isInitialized(d_ptr)”。无法创建 OpenGL 上下文

Posted

技术标签:

【中文标题】带有 QT 错误的 OpenGL:断言:“QOpenGLFunctions::isInitialized(d_ptr)”。无法创建 OpenGL 上下文【英文标题】:OpenGL with QT error: ASSERT:"QOpenGLFunctions::isInitialized(d_ptr)". Unable to create OpenGL context 【发布时间】:2016-03-26 11:55:13 【问题描述】:

我最近制作了我的第一个 OpenGL 程序来渲染一个立方体,我对其进行了扩展以包含一些其他基本功能(旋转、缩放、平移、鼠标选择顶点)。但是,我认为该程序正在使用某些版本的 OpenGL ES x.x,因为我无法将 glReadPixels 与 gl_depth_component 一起使用来启用鼠标仅选择可见顶点。

为了解决这个问题,我修改了我的旧程序,将我的 main 函数中的默认表面格式手动指定为 OpenGL 3.0 版,但现在程序在尝试创建 GLWidget 实例时会引发以下错误。

ASSERT:"QOpenGLFunctions::isInitialized(d_ptr)"

我的主函数(main.cpp):

#include "mainwindow.h"
#include <QApplication>
#include <QOpenGLFunctions>


int main(int argc, char *argv[])

    QSurfaceFormat format;
    format.setSamples(16);     
    format.setDepthBufferSize(24);
    format.setVersion(3,0);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat( format);
    QApplication a(argc, argv); 
    MainWindow w;                                          //breakpoint here - step into
    w.show();
    return a.exec();

进入这个断点会导致我进入我的 MainWindow 构造函数(mainwindow.cpp):

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);                                       //breakpoint here - step into
    ui->GLwidget2->getmainwindowpointer(this);
    connect(ui->actionTop,SIGNAL(triggered()),ui->GLwidget2,SLOT(settopview()));
    connect(ui->actionRight, SIGNAL(triggered()), ui->GLwidget2, SLOT(setrightview()));
    connect(ui->actionIso,SIGNAL(triggered()),ui->GLwidget2,SLOT(setisoview()));
    //connect(ui->checkBox_perspective,SIGNAL(released()),ui->GLwidget2,SLOT(setperspective()));
    connect(ui->checkBox_legend, SIGNAL(released()), ui->GLwidget2, SLOT(setlegend()));
    connect(ui->checkBox_edges, SIGNAL(released()), ui->GLwidget2, SLOT(setedges()));
    connect(ui->checkBox_faces, SIGNAL(released()), ui->GLwidget2, SLOT(setfaces()));
    connect(ui->actionFind_vertex,SIGNAL(triggered(bool)),ui->GLwidget2,SLOT(startvertexsearch()));
    connect(ui->actionFit_to_screen,SIGNAL(triggered()),ui->GLwidget2,SLOT(fittoscreen()));
    connect(ui->pushButton_selectMode,SIGNAL(released()),ui->GLwidget2,SLOT(setSelectMode()));
    connect(ui->pushButton_cancelSelect,SIGNAL(released()),ui->GLwidget2,SLOT(setCancelSelectMode()));

进入这个断点将我带到 ui_mainwindow.h,它在我的主窗口中创建对象并到达这一行:

[上面的代码...]

    pushButton = new QPushButton(centralWidget);
    pushButton->setObjectName(QStringLiteral("pushButton"));

    verticalLayout_2->addWidget(pushButton);


    horizontalLayout->addLayout(verticalLayout_2);

    GLwidget2 = new GLWidget(centralWidget);                 /break point here - step into

[下面的代码...]

这一切都运行良好,直到我的 GLWidget 的构造函数被调用... (glwidget.cpp)

#include "glwidget.h"

GLWidget::GLWidget(QWidget *parent = 0) :
QOpenGLWidget(parent)
                                        //breakpoint here
    alpha = 0;
    beta = 0;
    distance = defaultdistance;
    QSurfaceFormat format;
    format.setSamples(16);
    format.setDepthBufferSize(24);
    format.setVersion(3,0);
    format.setProfile(QSurfaceFormat::CoreProfile);
    this->setFormat(format);

只要我继续越过这个断点,就会抛出 ASSERT 错误。调试它会将我带到 qopenglfunctions.h 中的这个地方

[上面的代码...]

inline GLuint QOpenGLFunctions::glCreateProgram()

#ifdef QT_OPENGL_ES_2
    GLuint result = ::glCreateProgram();
#else
    Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));       //this line
    GLuint result = d_ptr->CreateProgram();
#endif
    Q_OPENGL_FUNCTIONS_DEBUG
    return result;

[下面的代码...]

此时d_ptr的值为NULL,我猜是这个错误的原因。我是否需要对 OpenGL ES 版本不需要的桌面 OpenGL 版本进行一些初始化?

我还是 OpenGL 的新手,因此我们将不胜感激!

更新我不确定发生了什么,但是在将更新的代码与旧的工作代码合并后,一切正常。希望这不会发生在其他人身上!

【问题讨论】:

请注意,OpenGL 3.0 没有配置文件,这是一个非常奇怪的版本。您是否有支持 OpenGL 3.0 的 GPU 和合适的驱动程序? Ok Peppe,你建议我尝试使用哪个版本的 OpenGL?我的 GPU 与最新驱动程序的 OpenGL 4.3 及更早版本 100% 兼容,所以这应该不是问题。从我的角度来看,只要我可以通过 glReadPixels 使用深度测试,我并不特别介意最终使用哪个版本的 OpenGL。 如果你要求 3.2 核心有什么变化吗? 【参考方案1】:

您需要将 initializeOpenGLFunctions(); 添加到您的GLWidget::initGL() 函数中。

【讨论】:

以上是关于带有 QT 错误的 OpenGL:断言:“QOpenGLFunctions::isInitialized(d_ptr)”。无法创建 OpenGL 上下文的主要内容,如果未能解决你的问题,请参考以下文章

为啥在带有 QT 的 VS 中出现这些错误 C2134、C4430 等?

带有 Qt 和 OpenGL 的轨迹球控件

带有 OpenGL 上下文的基于 Qt 的命令行工具

Qt5.5下捕获一个带有OpenGL内容的Widget

Qt 5.1 带有共享 QGLWidgets 的线程化 OpenGL

如何在带有 Qt 的 OpenGL 中使用顶点缓冲区对象绘制矩形?