共享OpenGL上下文的QOpenGLWidget?

4

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

我知道可以这样做:

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

然而,我想按照另一种顺序实现:

  1. 创建QOpenGLContext
  2. 创建QOpenGLWidget,提供现有的上下文并进行共享

这可行吗?


你也可以在initGL调用中进行共享。 - ratchet freak
@ratchetfreak 怎么做?我认为,当调用initGL时,OpenGL上下文已经被创建,不能设置共享另一个上下文... - Jan Rüegg
@JanRüegg 我们在布局方面没有遇到任何问题。您可以查看下面的代码(有点不同,但是),其中包含自定义的 QWindow,它创建了一个 GL 上下文并与外部框架共享:https://github.com/dava/dava.framework/blob/80bfa3b832fe1a24d50783828868f0f73f1ab31b/Sources/Tools/QtTools/DavaGLWidget/davaglwidget.cpp - Dmitry Sazonov
@Saz:有趣...也许我们做错了什么。感谢链接,我会看一下的! - Jan Rüegg
是的,我需要做和这个问题一样的事情,但QWindow不再是一个选项,我们曾经用它作为一种解决方法,但现在必须使用一个部件。 - ComradeJoecool
显示剩余3条评论
1个回答

3

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

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

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

此外,我不知道这是否会改变任何内容,但QOpenGLContext表示它也可以共享帧缓冲对象。


只需重新创建上下文,问题就应该得到解决。 - steventaitinger
@stevantatinger 我还没有尝试过,但我认为这不会起作用:据我所知,paintGL绘制到由QOpenGLWidget设置的帧缓冲区中。如果该帧缓冲区是由小部件上下文设置的,并且不同的上下文尝试绘制到该帧缓冲区中,则可能会导致未定义的行为。 - Jan Rüegg
@stavantatinger 第二个代码框中的最后一行也无法工作,makeCurrent需要一个QSurface作为参数... - Jan Rüegg
@stavantatinger 謝謝您的所有想法,我真的非常感激 :) 但是,我認為這仍然無法解決問題,因為在創建 QOpenGLWidget(這是在創建全局共享 QOpenGLContext 之後)時,我仍然無法使小部件的上下文與我在問題的第一步中創建的特殊上下文共享... - Jan Rüegg
嗯...是的,那可能确实回答了这个问题,你说得对。我怎么知道全局共享上下文已经初始化了呢? - Jan Rüegg
显示剩余11条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接