QOpenGL\*类Qt5中屏幕和屏幕外呈现之间的交互 目标:
通过Qt5 OpenGL框架进行一些屏幕上和屏幕外渲染,以便两个渲染部分之间可以轻松共享资源。具体来说,QOpenGL\*类Qt5中屏幕和屏幕外呈现之间的交互 目标:,opengl,qt5,Opengl,Qt5,通过Qt5 OpenGL框架进行一些屏幕上和屏幕外渲染,以便两个渲染部分之间可以轻松共享资源。具体来说, 渲染工作通过屏幕外部分完成(帧缓冲区可能大于显示屏) 为简单起见,屏幕外渲染的结果可以在不同设置下以多个屏幕上部分显示(例如,QOpenGLWidgets),例如不同的大小 屏幕外渲染的结果也可以从GPU中提取,并保存到QImage或cv::Mat对象中 可以异步执行上述任务(在显示或提取第一个屏幕外结果时进行第二次屏幕外渲染) 当前解决方案: 由于我不知道如何在这两个部分之间共享资源,
- 渲染工作通过屏幕外部分完成(帧缓冲区可能大于显示屏)李>
- 为简单起见,屏幕外渲染的结果可以在不同设置下以多个屏幕上部分显示(例如,
s),例如不同的大小李>QOpenGLWidget
- 屏幕外渲染的结果也可以从GPU中提取,并保存到
或QImage
对象中李>cv::Mat
- 可以异步执行上述任务(在显示或提取第一个屏幕外结果时进行第二次屏幕外渲染)
- 为简单起见,屏幕外渲染的结果可以在不同设置下以多个屏幕上部分显示(例如,
- 包含多个
(QOpenGLWidget的子类)对象的QOpenGLWidget
李>QMainWindow
- 一个自定义类,包括
、qoffscreensface
和QOpenGLContext
指针的成员,以及调用OpenGL函数的QOpenGLFramebufferObject
指针来执行实际的渲染工作,非常类似于QOpenGLFunctions
- 由于上述原因,实际渲染工作被提取到一个单独的类中,并且这两个部分(屏幕上和屏幕外)都有自己的处理方法
QOpenGLContext
s:
- 在后台线程中执行屏幕外工作时(用于异步渲染),它表示基于
的QWindow
不允许存在于gui线程之外李>qoffScreensface
- 在主(GUI)线程中执行此操作时,它表示
无效QOpenGLContext
- 我是否应该在同一个GUI线程中执行屏幕外和屏幕上工作
- 在屏幕外部分和屏幕上部分之间交流和共享资源的最佳方式是什么
一个简单的实际代码示例(例如,通过着色语言绘制三角形)将非常受欢迎。假设
QOpenGLContext*main\u ctx
是由QOpenGLWidget
为实际渲染创建的上下文,您可以在任何线程中创建另一个上下文ctx
,并使其与第一个线程共享纹理和缓冲区:
ctx = std::make_unique<QOpenGLContext>();
ctx->setFormat(main_ctx->format());
ctx->setShareContext(main_ctx);
ctx->create();
然后创建一个QOpenGLFramebufferObject
,并从第二个上下文(第二个线程)渲染到其中
然后在主上下文中使用其纹理:
glBindTexture(GL_texture_2D,fbo->texture())代码>。执行此操作时可能需要一些同步。谢谢您的帮助。多个屏幕外部分(在多个线程中)的渲染结果将按照某些规则依次显示在同一屏幕上部分,这会怎么样?他们的ctx
s是否都共享相同的main\u ctx
?如果使用多个fbo
s(来自多个屏幕外部分),它们会相互重叠吗?或者多个fbo->texture()
s是否会返回相同的值?如果是,如何避免?我不太熟悉fbo和纹理的机制。这不像“共享同一个main_ctx”,因为所有共享上下文都有相同的权限:它们共享纹理、着色器和其他OpenGL资源。关于FBO:似乎每个FBO Qt都会创建一个单独的纹理来使用。再次感谢您的帮助!根据您的建议,我尝试将纹理id单元
从FBO(屏幕外部分)转移到QOpenGLTexture
(屏幕上部分),但它没有显示所需的纹理。我认为原因可能是对FBO使用QOpenGLTexture
不熟悉。Qt5.7的文档说,可以使用纹理进行渲染,也可以使用纹理进行渲染。关于这两种用法有什么简单的例子吗。(这可能是另一个问题,我是否应该发布一篇新文章?)提出另一个问题,这样就会有一个空间来显示不起作用的QOpenGLFramebufferObject
代码。如果代码是一个足够独立的示例,那么可能有人会修复该代码。非常感谢你!
offscreen_surface = std::make_unique<QOffscreenSurface>();
offscreen_surface->setFormat(ctx->format());
offscreen_surface->create();
ctx->makeCurrent(offscreen_surface);