【问题标题】:QOpenGLWidget's context is nullQOpenGLWidget 的上下文为空
【发布时间】:2020-11-09 01:38:22
【问题描述】:

我正在尝试将QOpenGLWidget 添加到我的QGraphicsScene,但是当我调用initializeOpenGLFunctions() 时应用程序崩溃了。我很确定OpenGLView 的上下文为空,这就是为什么它崩溃(不提供日志)的原因有两个:

  1. 当我打印它时,它输出0x0
  2. 当我尝试启用 QOpenGLDebugLogger 时,它会输出没有当前上下文。

我认为 QOpenGLWidget 会有一个开箱即用的 OpenGLContext。知道为什么没有设置上下文吗?我在初始化过程中遗漏了什么吗?

QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setOption(QSurfaceFormat::DebugContext);
QSurfaceFormat::setDefaultFormat(format);


OpenGLView view = new OpenGLView();

标题

class OpenGLView : public QOpenGLWidget, protected QOpenGLFunctions
{
}
#include "OpenGLView.h"

OpenGLView::OpenGLView(QWidget *parent) : QOpenGLWidget(parent) {
    initializeGL();
}


void OpenGLView::initializeGL() {
    initializeOpenGLFunctions(); // crashes
//    ...
}

void OpenGLView::paintGL() {
//    ...
}

void OpenGLView::resizeGL(int w, int h) {
//    ...
}

【问题讨论】:

  • 可能是很多事情,比如不支持 GL 3.2
  • 我确实支持 GL 3.2。除了 QT 之外,该版本一直在使用 OpenGL。
  • OpenGLView 不继承 QOpenGLFunctionsinitializeOpenGLFunctions() 函数在哪里?
  • 确实如此,我更新了我的代码

标签: qt opengl qml


【解决方案1】:

这是因为你在构造函数中调用了initializeGL()。到那时,上下文还没有初始化。显示小部件时首先初始化上下文。详情取自以下Qt's source code

void QOpenGLWidgetPrivate::initialize()
{
    Q_Q(QOpenGLWidget);
    if (initialized)
        return;
    
    ...

    QScopedPointer<QOpenGLContext> ctx(new QOpenGLContext);
    ctx->setFormat(requestedFormat);
    if (shareContext) {
        ctx->setShareContext(shareContext);
        ctx->setScreen(shareContext->screen());
    }
    if (Q_UNLIKELY(!ctx->create())) {
        qWarning("QOpenGLWidget: Failed to create context");
        return;
    }

    ...

    context = ctx.take();
    initialized = true;
    q->initializeGL();
}

bool QOpenGLWidget::event(QEvent *e)
{
    Q_D(QOpenGLWidget);
    switch (e->type()) {

    ...

    case QEvent::Show: // reparenting may not lead to a resize so reinitalize on Show too
        if (d->initialized && window()->windowHandle()
                && d->context->shareContext() != QWidgetPrivate::get(window())->shareContext())
        {
            // Special case: did grabFramebuffer() for a hidden widget that then became visible.
            // Recreate all resources since the context now needs to share with the TLW's.
            if (!QCoreApplication::testAttribute(Qt::AA_ShareOpenGLContexts))
                d->reset();
        }
        if (!d->initialized && !size().isEmpty() && window()->windowHandle()) {
            d->initialize();
            if (d->initialized)
                d->recreateFbo();
        }
        break;

    ...

    }
    return QWidget::event(e);
}

【讨论】:

  • 这有帮助,我现在得到一个非空上下文,但在调用 initializeOpenGLFunctions 时仍然崩溃
  • 调试器这次说什么?
  • 同样的事情“程序意外结束。”
  • 已解决 - 有一个 nullptr 需要一些时间才能找到。
猜你喜欢
  • 2016-02-11
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
相关资源
最近更新 更多