QOpenGLWidget的多线程渲染

2024-02-22 01:18

本文主要是介绍QOpenGLWidget的多线程渲染,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

关于QOpenGLWidget的多线程渲染_VE视频引擎的博客-CSDN博客_qopenglwidget

Qt使用OpenGL进行多线程离屏渲染(原理讲的很好)   

Qt使用OpenGL进行多线程离屏渲染_imred的专栏-CSDN博客_qoffscreensurfaceQt使用OpenGL进行多线程离屏渲染 - it610.com

基于Qt WidgetsQt程序,控件的刷新默认情况下都是在UI线程中依次进行的,换言之,各个控件的QWidget::paintEvent方法会在UI线程中串行地被调用。如果某个控件的paintEvent非常耗时(等待数据时间+CPU处理时间+GPU渲染时间),会导致刷新帧率下降,界面的响应速度变慢。

假如这个paintEvent耗时的控件没有使用OpenGL渲染,完全使用CPU渲染。这种情况处理起来比较简单,只需要另外开一个线程用CPU往QImage里面渲染,当主线程调用到这个控件的paintEvent时,再把渲染好的QImage画出来就可以了,单纯绘制一个QImage还是很快的。

如果这个paintEvent耗时的控件使用了OpenGL渲染,情况会复杂一些,因为想要把OpenGL渲染过程搬到另外一个线程中并不是直接把OpenGL调用从UI线程搬到渲染线程就可以的,是需要做一些准备工作的。另外,UI线程如何使用渲染线程的渲染结果也是一个需要思考的问题。



QT opengl多线程实现原理

QT里的qopenglwidget提供了对多线程的知识,根据文档所说,想要在另一个线程中执行渲染操作,需要将该widget的context通过movetothread到该线程,手动makecurrent和donecurrent,然后执行渲染操作。总而言之QT中想让opengl在另一个线程渲染,需要的东西只有一个:属于该线程的context。知道这个,就可以以很多方法实现该功能了。

方法1

qt的example里面有一个threadedopengl例子,里面就是通过aboutToCompose和frameSwapped两个信号来控制渲染的,重写paintevent为空函数。当aboutTocompose时,停止渲染,可以以获取该线程互斥量的形式完成,交换完成后,释放互斥量,并发送信号,指示渲染线程开始渲染。渲染线程首先请求context,通过发送信号给gui线程,并用条件变量等待,gui将context所有权交给渲染线程,唤醒条件变量,渲染线程执行渲染操作,再重新转移context所有权,并用qmetaobject向其发送一个update操作。update操作又会触发abouttocompose,这样就不停渲染了。

方法2

虽然上面的方法很好,但是在同一级父窗口中有多个widget的时候就会出问题,原因是update会导致两个widget的abouttocompose,QT在发送这个信号之前会makecurrent,但如果有一个widget正在渲染,context的所有权并不属于gui时就会报错。所以需要用另一种方法,这里用渲染到纹理的方法解决了。QT中有QOpenGLContext和QOffscreenSurface,这两个的组合可以将渲染结果渲染到纹理上,这样gui显示该纹理,就能达到同样的效果。使用方法查看QT文档,这里就不说明了。

这篇关于QOpenGLWidget的多线程渲染的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/733694

相关文章

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

Java多线程父线程向子线程传值问题及解决

《Java多线程父线程向子线程传值问题及解决》文章总结了5种解决父子之间数据传递困扰的解决方案,包括ThreadLocal+TaskDecorator、UserUtils、CustomTaskDeco... 目录1 背景2 ThreadLocal+TaskDecorator3 RequestContextH

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

多线程解析报表

假如有这样一个需求,当我们需要解析一个Excel里多个sheet的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完成。 Way1 join import java.time.LocalTime;public class Main {public static void main(String[] args) thro

Java 多线程概述

多线程技术概述   1.线程与进程 进程:内存中运行的应用程序,每个进程都拥有一个独立的内存空间。线程:是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换、并发执行,一个进程最少有一个线程,线程实际数是在进程基础之上的进一步划分,一个进程启动之后,进程之中的若干执行路径又可以划分成若干个线程 2.线程的调度 分时调度:所有线程轮流使用CPU的使用权,平均分配时间抢占式调度

Java 多线程的基本方式

Java 多线程的基本方式 基础实现两种方式: 通过实现Callable 接口方式(可得到返回值):

JAVA- 多线程

一,多线程的概念 1.并行与并发 并行:多个任务在同一时刻在cpu 上同时执行并发:多个任务在同一时刻在cpu 上交替执行 2.进程与线程 进程:就是操作系统中正在运行的一个应用程序。所以进程也就是“正在进行的程序”。(Windows系统中,我们可以在任务管理器中看 到进程) 线程:是程序运行的基本执行单元。当操作系统执行一个程序时, 会在系统中建立一个进程,该进程必须至少建立一个线

多线程篇(阻塞队列- LinkedBlockingDeque)(持续更新迭代)

目录 一、LinkedBlockingDeque是什么 二、核心属性详解 三、核心方法详解 addFirst(E e) offerFirst(E e) putFirst(E e) removeFirst() pollFirst() takeFirst() 其他 四、总结 一、LinkedBlockingDeque是什么 首先queue是一种数据结构,一个集合中