渲染流程简析--第二次调试osg最长的一帧心得

本文详细探讨了OpenSceneGraph(osg)的渲染流程,从摄像机添加场景、筛选与绘制、状态机工作原理到渲染同步的 Barrier 线程同步和 blockCount 计数同步机制。在渲染流程中,讲解了如何通过cullvisitor构造渲染树,以及state状态机如何处理渲染属性。此外,还分析了不同线程模型下的同步策略,包括开始绘制、结束绘制和双缓存同步的 Barrier,以及动态数据同步的 blockCount。最后,作者分享了调试过程中的体会,强调了多轮调试对理解的重要性。

前三次只看不调,感觉像看天书。第一次调试osg最长的一帧时,感觉有些机械。第二次调试后,感觉osg最长的一帧真是没一句废话,字字珠玑。好像懂了不少。特将渲染流程的心得记录如下。(不看代码,不看电子书)

一osg渲染流程
1,摄像机添加场景。通过摄像机的图形上下文或者渲染器进行cull,draw或者cull_draw进行对SceneView筛选和绘制。(由不同的线程模型决定)
2,cullvisitor筛选场景,构造渲染树和状态树
3,渲染台遍历其成员渲染叶列表(半透明)和状态树中的渲染叶(不透明),通过state状态机绘制
4,state状态机有渲染属性,模式开关和顶点数据,将顶点数据传给渲染叶。渲染属性可以派生不同的类,进行不同渲染属性的操作
5,渲染台对渲染叶进行了排序。分别处理不同的preRender,正常渲染和postrender。而这些渲染,则是通过不同摄像机进行的。

二,渲染同步(两种,Barrier线程同步和blockCount计数同步)
1,Barrier:主线程和辅线程coorperateWait,左脚踩右脚,而不是you jump, I jump.
以开启graphicThread为例。
(1)主线程开启GraphicThread,并阻塞自己,等待子线程的信号量。
(2)子线程运行后,通过信号量释放主线程,并阻塞自己,等待主线程的事件或者cancel事件。
(3)主线程释放后,发送事件,让子线程结束阻塞。
尽管主线程和辅线程都走coorperateWait函数,但是走的分支不同。这个分支是通过局部存储区获取TLGetValue(),主线程获取的是空,子线程获取不为空。原因是子线程开启后,向局部存储区赋值操作。TLSetValue()
主线程阻塞自己时,将waiter+1,被信号量释放后,waiter-1,子线程释放信号量时,waiter个数目。这就是释放Waiter个线程。

2,blockCount计数同步,这里用到的是dynamic模型的complete,每次绘制完一个complete()则计数-1,直至全部绘制完,则为0,冲开。

三,根据不同的线程模型,进行不同的阻塞

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值