【问题标题】:Interactions between Onscreen and Offscreen rendering in Qt5 with QOpenGL\* classesQt5 中屏幕和屏幕外渲染与 QOpenGL\* 类之间的交互
【发布时间】:2016-08-29 08:32:26
【问题描述】:

目标:

通过Qt5 OpenGL框架进行一些onscreenoffscreen渲染,这样资源可以很容易地在两个渲染部分之间共享。具体来说,

  • 渲染工作通过offscreen部分完成(framebuffer可能比显示屏幕大);
  • 屏幕外渲染的结果可以在不同的设置下显示在多个屏幕上部分(例如QOpenGLWidgets),例如不同尺寸,为简单起见;
  • 离屏渲染的结果也可以从 GPU 中提取并保存到QImagecv::Mat 对象中;
  • 上述任务可以异步执行(进行第二次离屏渲染,同时显示或提取第一个离屏结果)。

目前的解决方案:

由于我不知道如何在两个部分之间共享资源,因此在我当前的解决方案中,实际的渲染工作在两个部分中都是冗余完成的:

屏幕上部分:
  • 一个QMainWindow 包含多个QOpenGLWidgetQOpenGLWidget 的子类)对象;
屏幕外部分:
  • 包含QOffscreenSurfaceQOpenGLContextQOpenGLFramebufferObject 指针成员的自定义类以及用于调用OpenGL 函数的QOpenGLFunctions 指针执行实际渲染工作,与this link 非常相似。李>
实际渲染器:
  • 如上所述,实际的渲染工作被提取到一个单独的类中,并且两个部分(onscreenoffscreen)都有自己的句柄。

问题:

有两个QOpenGLContexts:

  • 在后台线程中进行屏幕外工作时(用于异步渲染),它表示基于QWindowQOffscreenSurface不允许存在于gui线程之外;
  • 在主 (GUI) 线程中执行此操作时,它说 QOpenGLContext 无效。

所以我的问题是:

  • 我是否应该在同一个 GUI 线程中执行 offscreenonscreen 工作?
  • 屏幕外屏幕部分之间交流和共享资源的最佳方式是什么?

非常感谢一个简短的实际代码示例做一个简单的渲染工作(例如,通过着色语言绘制一个三角形)。

【问题讨论】:

    标签: opengl qt5


    【解决方案1】:

    假设QOpenGLContext *main_ctxQOpenGLWidget 创建的用于实际渲染的上下文,您可以在任何线程中创建另一个上下文ctx 并使其与第一个线程共享纹理和缓冲区:

    ctx = std::make_unique<QOpenGLContext>();
    ctx->setFormat(main_ctx->format());
    ctx->setShareContext(main_ctx);
    ctx->create();
    

    我认为QOffscreenSurface 不一定是基于QWindow 的。

    offscreen_surface = std::make_unique<QOffscreenSurface>();
    offscreen_surface->setFormat(ctx->format());
    offscreen_surface->create();
    ctx->makeCurrent(offscreen_surface);
    

    然后创建一个QOpenGLFramebufferObject 并从第二个上下文(第二个线程)渲染到它。

    然后在主要上下文中使用它的纹理:glBindTexture(GL_TEXTURE_2D, fbo-&gt;texture());。这样做时可能需要一些同步。

    【讨论】:

    • 感谢您的帮助。多个 offscreen 部分(在多个线程中),其渲染结果会按照某些规则依次显示在同一个 onscreen 部分中怎么办?他们的ctxs 是否应该共享相同的main_ctx?如果随后使用多个fbos(来自多个屏幕外部分),它们会相互重叠吗?或者多个fbo-&gt;texture()s 会返回相同的值吗?如果有,如何避免?我对fbo的机制和纹理不是很熟悉。
    • 这不像“共享同一个 main_ctx”,因为所有共享上下文具有平等的权利:它们共享共享纹理、着色器和其他 OpenGL 资源。关于 FBO:Qt 似乎为每个 FBO 创建了一个单独的纹理来使用。
    • 再次感谢您的帮助!根据您的建议,我尝试将纹理 ID unit 从 FBO(offscreen 部分)转移到 QOpenGLTextureonscreen 部分),但没有显示所需的纹理。我认为原因可能是不熟悉将QOpenGLTexture 与FBO 一起使用。 Qt5.7的文档说可以渲染TO纹理,也可以渲染WITH纹理。有没有关于这两种用法的简单例子。 (这可能是另一个问题,我应该发布一个新帖子吗?)
    • 提出另一个问题,所以会有一个空间来显示带有QOpenGLFramebufferObject 的代码不起作用。如果该代码是一个足够独立的示例,那么有人可能会修复该代码。
    • 一个新问题 (this link) 已发布。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    相关资源
    最近更新 更多