使用QOpenGL \ *类

时间:2016-08-29 08:32:27

标签: opengl qt5

目的:

通过Qt5 OpenGL框架进行一些屏幕屏幕外渲染,以便在两个渲染部分之间轻松共享资源。具体地,

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

当前解决方案:

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

屏幕部分:
  • 包含多个QMainWindowQOpenGLWidget个)子对象的QOpenGLWidget个;
屏幕外部分:
  • 涉及QOffscreenSurfaceQOpenGLContextQOpenGLFramebufferObject指针成员的自定义类,以及调用OpenGL函数的QOpenGLFunctions指针执行实际的渲染工作,类似于this link
实际的渲染器:
  • 由于上述原因,实际的渲染工作被提取到一个单独的类中,两个部分(屏幕屏幕外)都有它的处理。

问题:

有两个QOpenGLContext s:

  • 当在后台线程中执行 offscreen 工作时(用于异步渲染),它表示不允许在gui线程外部存在基于QWindow的{​​{1}};
  • 在主(GUI)线程中执行此操作时,它表示QOffscreenSurface无效。

所以我的问题是:

  • 我应该在同一个GUI线程中使用屏幕外屏幕吗?
  • 屏幕外屏幕部分之间沟通和共享资源的最佳方式是什么?

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

1 个答案:

答案 0 :(得分: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->texture());。这样做时可能需要一些同步。