qt - QOpenGLWidget 的上下文为空
问题描述
我正在尝试添加一个QOpenGLWidget
到我的QGraphicsScene
,但是当我调用时应用程序崩溃了initializeOpenGLFunctions()
。我很确定上下文OpenGLView
为空,这就是为什么它崩溃(不提供日志)的原因有两个:
- 当我打印它时,它会输出
0x0
- 当我尝试启用
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) {
// ...
}
解决方案
这是因为你initializeGL()
在构造函数中调用了。到那时,上下文尚未初始化。显示小部件时首先初始化上下文。以下详细信息来自Qt 的源代码:
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);
}
推荐阅读
- c - 运行多个c文件时编译时错误
- javascript - 如何继续将视频流(webm、vp8)录制到现有文件(使用 C#)?
- c++ - C++ 中的 IF 嵌套
- javascript - 如何向 javascript 中的现有对象添加一组完整的键:值对?
- javascript - 在没有赋值的情况下使用 Javascript 中的表达式是否会自动创建变量?
- javascript - 如何为语法高亮定义和加载自定义 ace 模式
- client-server - 软件工程中标准图和非标准图的区别
- r - 检查包含空向量的列表的“空性”(R 不将其识别为空列表)
- assembly - 装配 - 字符串的长度
- spring-boot - 如何在特定端点上不应用过滤器