Qt5中使用QOpenGL \ *类的屏幕上渲染和屏幕外渲染之间的交互 [英] Interactions between Onscreen and Offscreen rendering in Qt5 with QOpenGL\* classes
问题描述
通过Qt5 OpenGL框架进行一些屏幕上和屏幕外渲染,以便可以在两个渲染部分之间轻松共享资源.具体来说,
To make some onscreen and offscreen rendering via Qt5 OpenGL framework, such that the resources can be easily shared between both rendering parts. Specifically,
- 渲染工作是通过屏幕外部分完成的(帧缓冲区可能比显示屏大);
- 屏幕外渲染的结果可以在不同的设置下(例如,
QOpenGLWidget
)以多个屏幕上部分显示(例如,QOpenGLWidget
s).不同的大小,为简单起见; - 屏幕外渲染的结果也可以从GPU中提取,并保存到
QImage
或cv::Mat
对象中; - 以上任务可以异步执行(执行第二次屏幕外渲染,同时显示或提取第一个屏幕外结果).
- the rendering work is done through the offscreen part (the framebuffer might be larger than the display screen);
- the results of the offscreen rendering can be displayed in multiple onscreen parts (say,
QOpenGLWidget
s) under different settings, e.g. different sizes, for simplicity; - the results of the offscreen rendering can also be extracted from GPU and saved into a
QImage
orcv::Mat
object; - the above tasks can be executed asynchronously (doing the second offscreen rendering, while displaying or extracting the first offscreen result).
由于我不知道如何在两个部分之间共享资源,因此在当前解决方案的两个部分中,实际的渲染工作都是多余的:
Since I don't know how to share resources between both parts, the actual rendering work are done redundantly in both parts in my current solution:
- 包含多个
QOpenGLWidget
(QOpenGLWidget
的子类)对象的QMainWindow
;
- A
QMainWindow
containing multipleQOpenGLWidget
(subclass ofQOpenGLWidget
) objects;
- 一个包含
QOffscreenSurface
,QOpenGLContext
和QOpenGLFramebufferObject
指针的成员的自定义类,以及一个用于调用OpenGL函数的QOpenGLFunctions
指针,可以完成实际的渲染工作,与
- A custom class involving members of
QOffscreenSurface
,QOpenGLContext
, andQOpenGLFramebufferObject
pointers, as well as aQOpenGLFunctions
pointer to invoke OpenGL functions do the actual rendering work, much similar to this link.
- 基于上述原因,实际的渲染工作被提取到一个单独的类中,并且两个部分(在屏幕上和在屏幕外)都有其作用.
- As the reason above, the actual rendering work is extracted into a seperated class and both parts (onscreen and offscreen) have its handle.
有两个QOpenGLContext
:
- 在后台线程中进行屏外工作(用于异步渲染)时,它说基于
QWindow
的QOffscreenSurface
不允许存在于gui线程之外; - 在主(GUI)线程中执行此操作时,它表示
QOpenGLContext
无效.
- When doing the offscreen work in a background thread (for asynchronously rendering), it says the
QWindow
-basedQOffscreenSurface
are not allowed to exist outside the gui thread; - When doing this in the main (GUI) thread, it says the
QOpenGLContext
is invalid.
所以我的问题是:
- 我是否应该在同一GUI线程中进行屏幕外和屏幕上的工作?
- 在屏幕外和屏幕上部分之间交流和共享资源的最佳方法是什么?
- Should I do the offscreen and onscreen work in the same GUI thread or not?
- What is the best way of communicating and sharing resources between the offscreen and onscreen parts?
一个简单的实际代码示例,可以完成一个简单的渲染工作(例如,通过着色语言绘制一个三角形).
A brief actual code example doing a simple rendering work (say, draw a triangle via shading language) will be much appreciated.
推荐答案
假定QOpenGLContext *main_ctx
是QOpenGLWidget
为实际渲染而创建的上下文,则可以在任何线程中创建另一个上下文ctx
并将其创建与第一个共享纹理和缓冲区:
Assuming that QOpenGLContext *main_ctx
is the context that was created by QOpenGLWidget
for actual rendering, you can create another context ctx
in any thread and make it share textures and buffers with the first one:
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
并从第二个上下文(第二个线程)将其呈现.
Then create a QOpenGLFramebufferObject
and render into it from the second context (second thread).
然后在主要上下文中使用其纹理:glBindTexture(GL_TEXTURE_2D, fbo->texture());
.这样做时可能需要一些同步.
Then use its texture in the main context: glBindTexture(GL_TEXTURE_2D, fbo->texture());
. Maybe there is a need for some synchronization when doing this.
这篇关于Qt5中使用QOpenGL \ *类的屏幕上渲染和屏幕外渲染之间的交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!