Qt5中使用QOpenGL \ *类的屏幕上渲染和屏幕外渲染之间的交互 [英] Interactions between Onscreen and Offscreen rendering in Qt5 with QOpenGL\* classes

查看:914
本文介绍了Qt5中使用QOpenGL \ *类的屏幕上渲染和屏幕外渲染之间的交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过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中提取,并保存到QImagecv::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, QOpenGLWidgets) 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 or cv::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 multiple QOpenGLWidget (subclass of QOpenGLWidget) objects;
  • 一个包含QOffscreenSurfaceQOpenGLContextQOpenGLFramebufferObject指针的成员的自定义类,以及一个用于调用OpenGL函数的QOpenGLFunctions指针,可以完成实际的渲染工作,与
  • A custom class involving members of QOffscreenSurface, QOpenGLContext, and QOpenGLFramebufferObject pointers, as well as a QOpenGLFunctions 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:

  • 在后台线程中进行屏外工作(用于异步渲染)时,它说基于QWindowQOffscreenSurface不允许存在于gui线程之外;
  • 在主(GUI)线程中执行此操作时,它表示QOpenGLContext无效.
  • When doing the offscreen work in a background thread (for asynchronously rendering), it says the QWindow-based QOffscreenSurface 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_ctxQOpenGLWidget为实际渲染而创建的上下文,则可以在任何线程中创建另一个上下文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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆