目标:
通过Qt5 OpenGL框架进行屏幕上的和屏幕外的渲染,以便在两个渲染部分之间轻松共享资源。具体而言,
- 渲染工作是通过屏幕外部分完成的(帧缓冲区可能大于显示屏(
- 为了简单起见,屏幕外渲染的结果可以在不同设置(例如不同大小(下显示在多个屏上部分(例如
QOpenGLWidget
s(中 - 屏幕外渲染的结果也可以从GPU中提取并保存到CCD_ 2或CCD_
- 上述任务可以异步执行(在显示或提取第一屏幕外结果的同时进行第二屏幕外渲染(
当前解决方案:
由于我不知道如何在两个部分之间共享资源,因此在我当前的解决方案中,实际的渲染工作在这两个部分都是冗余的
屏幕上的部分:- 包含多个
QOpenGLWidget
(QOpenGLWidget
的子类(对象的QMainWindow
- 一个包含
QOffscreenSurface
、QOpenGLContext
和QOpenGLFramebufferObject
指针成员的自定义类,以及一个调用OpenGL函数的QOpenGLFunctions
指针,完成实际的渲染工作,与此链接非常相似
- 由于上述原因,实际渲染工作被提取到一个单独的类中,并且两个部分(屏幕上的和屏幕外的(都有其句柄
问题:
有两个QOpenGLContext
:
- 当在后台线程中执行屏幕外工作(用于异步渲染(时,它表示基于
QWindow
的QOffscreenSurface
不允许存在于gui线程之外 - 当在主(GUI(线程中执行此操作时,它表示
QOpenGLContext
无效
所以我的问题是:
- 我是否应该在同一GUI线程中执行屏幕外和屏幕上的工作
- 屏幕外和屏幕上部分之间交流和共享资源的最佳方式是什么
一个简单的实际代码示例(例如,通过着色语言绘制三角形(将非常受欢迎。
假设QOpenGLContext *main_ctx
是QOpenGLWidget
为实际渲染创建的上下文,您可以在任何线程中创建另一个上下文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);
然后创建一个QImage
0,并从第二个上下文(第二个线程(渲染到其中。
然后在主上下文中使用其纹理:glBindTexture(GL_TEXTURE_2D, fbo->texture());
。也许在执行此操作时需要一些同步。