【问题标题】:QOpenGLWidget with shared OpenGL context?具有共享 OpenGL 上下文的 QOpenGLWidget?
【发布时间】:2016-02-11 15:01:53
【问题描述】:

我有一个现有的 OpenGL 上下文,我想与一个新的 QOpenGLWidget 共享。

我知道我能做到:

  1. 创建 QOpenGLWidget
  2. 等到调用 initializeGL 并保存上下文
  3. 创建新的 QOpenGLContext,并使其与保存的上下文共享

但是,我想按其他顺序进行:

  1. 创建 QOpenGLContext
  2. 创建 QOpenGLWidget,提供现有上下文并使其共享

这可能吗?

【问题讨论】:

  • 你也可以在initGL调用中进行分享
  • @ratchetfreak 怎么样?我认为,当调用 initGL 时,OpenGL 上下文已经创建并且不能设置为共享另一个上下文...
  • 它在哪里说创建后不能共享上下文?
  • 我认为你根本不需要QOpenGLWidget。您可以将 QWindow 与自定义 gl 表面(或您的上下文)一起使用 + QWidget::createWindowContainer 将其用作小部件。
  • @SaZ:谢谢你的想法。我实际上是先尝试这样做的。然而,使用 QWindow 作为 WindowContainer 会带来其他布局和东西的问题,因为它不是一个合适的小部件。所以我宁愿留在小部件上......

标签: c++ multithreading qt opengl qt5.5


【解决方案1】:

编辑,我对QOpenGLFramebufferObject了解不多,所以忽略我之前的回答内容。

在 QOpenGLWidget 中,它总是将其上下文设置为与其最近的顶级窗口(或者如果它是一个窗口,则它自己)共享。您的理解是正确的,如果不对 QOpenGLWidget 成员上下文进行子类化以完全改变它的工作方式,就无法更改它。在 QOpenGLWidgetPrivate::initialize() 函数中,上下文是从 defaultFormat 和顶级 shareContext 初始化的。如果您想在创建 QOpenGLWidget 之前使用上下文,那么它必须通过全局共享上下文。 Qt::AA_ShareOpenGLContexts 需要在创建 QGuiApplication 对象之前设置。

您需要等到 QGuiApplication 初始化了全局上下文后才能尝试访问它。由于 global_share_context 是 QOpenGLContext 类的静态成员,因此您可以创建任何 QOpenGLContext 并通过 context.globalShareContext() 访问它。然后只需删除您的初始 QOpenGLContext。您创建的任何 QOpenGLWidget 都将自动与该上下文共享。如果您可以在创建()您的特殊上下文之前找到一种指向全局共享上下文的指针,那么您可以与全局上下文共享,并且您可以很好地进行共享,因为共享是双向的。共享是通过彼此共享的整个共享上下文组进行的,因此与一个上下文的任何共享都会与整个组共享。

另外,除了QOpenGLContext says it can 也共享帧缓冲区对象之外,我不知道这是否会改变任何东西。

【讨论】:

  • 您确定可以在 initializeGL 中更改 OpenGL 上下文吗?在此页面上:doc.qt.io/qt-5/qopenglwidget.html#initializeGL 它说“只要调用 initializeGL() 和 paintGL(),就保证 QOpenGLWidget 的关联 OpenGL 上下文是最新的。”但是,要成为当前的,必须已经创建了上下文。并且必须在创建上下文之前调用 setShareContext...
  • 然后重新创建上下文就可以解决问题了。
  • @stevantatinger 啊,我可以试试。我猜缺点(出于性能原因)是,上下文被创建了两次,对吧?
  • @Jan Rüegg 是的,我上面显示的代码会在初始化时创建两次上下文。您是否尝试过仅传递现有上下文(确保它位于正确的线程中)然后调用 makeCurrent()?如果您重新实现 initializeGL、paintGL 和 resizeGL 以在每个开头调用 makeCurrent,我不明白为什么您不能只使用您想要的任何上下文。虽然它可能每次都在两个上下文中调用 makeCurrent,这可能会影响性能。
  • @stevantatinger 我还没有尝试过,但我认为这行不通:据我所知,paintGL 绘制到由 QOpenGLWidget 设置的帧缓冲区中。如果这个帧缓冲区是由小部件上下文设置的,并且不同的上下文试图绘制到帧缓冲区中,这可能是未定义的行为。
猜你喜欢
  • 2020-06-27
  • 1970-01-01
  • 2021-01-24
  • 2017-05-25
  • 2012-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
相关资源
最近更新 更多