当前位置: 首页 > news >正文

探索未知种族之osg类生物---渲染遍历之裁剪二

cullcore

前言

上一节我们大致上过了一遍sceneView::cull()函数,通过研究,我们发现上图中的这一部分的代码才是整个cull过程的核心部分。所以今天我们来仔细的研究一下这一部分。

sceneView::cull()函数核心部分

1、cullVisitor->pushStateSet函数:

       A、_currentStateGraph = _currentStateGraph->find_or_insert(ss); 判断传入的渲染状态 ss 是否已经存在于这个状态节点中,如果存在则返回找到的那个ss,如果不存在新建一个包含了 ss 的状态节点。

       B、创建渲染树,这个过程必须得满足三个条件。1)设置了渲染细节useRenderBinDetails()并且满足BinName不为空(只能为“RenderBin”或“DepthSortedBin”);2)渲染状态没有采用覆盖渲染细节(OVERRIDE_RENDERBIN_DETAILS)的方式(_numberOfEncloseOverrideRenderBinDetails==0);3)使用 setRenderBinDetails 设置了渲染细节,如果满足这三个条件将尝试转到指定的节点或者新建一个渲染元(RenderBin::find_or_insert 的工作),并使用堆栈记录上一次在渲染树中的位置。此外,渲染树的构建过程中只生成空的渲染元(RenderBin)节点,向其中纳入状态节点和渲染叶的任务将在后面的工作中完成。

2、向cullVisitor中设置MVP矩阵,然后通过cullVisitor->traverse(*_camera); (实际上就是调用CullVisitor::apply 函数函数(在遍历节点时调用))来负责根据不同的节点类型,在不同的时机调用cullVisitor->pushStateSet函数以及cullVisitor-> popStateSet函数。(下一节将会进行展开说明)

3、cullVisitor-> popStateSet函数:

       A、_numberOfEncloseOverrideRenderBinDetails减一,然后还是上面介绍的cullVisitor->pushStateSet函数介绍的三种情况,判断是否使用了RenderBinDetails。然后还是从堆栈中取出上一次渲染树中所处的渲染元节点,并跳转到这一位置。

       B、状态树从当前位置跳转到其父节点,即:

?
1
_currentStateGraph = _currentStateGraph->_parent;<br><br>

本节小结

通过简单的对cullVisitor->pushStateSet函数以及cullVisitor-> popStateSet函数的介绍,可以了解到在遍历场景节点树时,使用 pushStateSet 将某个节点的渲染状态置入,然后再将它的子节点的渲染状态置入,直到遍历完成。当结束这个子树的遍历时,则依次使用 popStateSet 弹出_currentRenderBin 和_currentStateGraph,直到返回初始位置为止。这么整个过程就是构建起渲染后台的状态树和渲染树。并且,假如在筛选(CULL)过程中我们判断某个节点(及其子树)应当被剔除掉时,只要跳过 pushStateSet 和 popStateSet的步骤,直接返回,就不会在进行渲染操作。这就是我们下一步要讨论的CullVisitor 的工作。

CullVisitor根本上就是NodeVisitor的子类,所以他的执行过程可以按照节点访问器(NodeVisitor)的工作原理来理解。

nodevisitor

当我们执行节点的 accept(NodeVisitor* nv)函数时,当前节点自动调用 NodeVisitor::apply方法,将自身的信息传递给节点访问器 nv,由它负责执行相应的处理工作;然后节点将自动执行 Node::traverse 函数,调用所有子节点的 accept 函数,从而实现了节点树的遍历。在遍历的过程中每个节点都会调用 NodeVisitor::apply 将自身的指针传递给访问器,因此NodeVisitor 的每个派生类都会重载针对各个节点的 apply 函数,以实现针对不同类型节点的访问操作。

下一节我们就要对CullVisitor的 apply 重载函数进行探究。

原文链接 http://www.3wwang.cn/blog/article.ftl?id=52

转载于:https://www.cnblogs.com/wang985850293/p/10557402.html

相关文章:

  • NHibernate3剖析:Configuration篇之SessionFactory fluent配置
  • python 写入execl记录
  • web.py下session初始化异常问题
  • 201671010401包稚潼 实验二 词频统计软件项目报告
  • 牛客网-华为-扑克牌大小
  • StyleCop 使用介绍
  • RabbitMQ 消费者的消息确认机制
  • 拒绝Boot Camp,MAC OS 下怎么 打反恐和魔兽...
  • 吴恩达《机器学习》章节2单变量线性回归
  • GCC内联汇编基础
  • 1初识word
  • 异步
  • 四大浏览器Windows 7平台多项测试对比
  • 元类
  • 从今天开始
  • 分享一款快速APP功能测试工具
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 77. Combinations
  • java小心机(3)| 浅析finalize()
  • Mybatis初体验
  • mysql 数据库四种事务隔离级别
  • Vue2.0 实现互斥
  • Xmanager 远程桌面 CentOS 7
  • 翻译:Hystrix - How To Use
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 计算机常识 - 收藏集 - 掘金
  • 解析 Webpack中import、require、按需加载的执行过程
  • 利用DataURL技术在网页上显示图片
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 爬虫模拟登陆 SegmentFault
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 因为阿里,他们成了“杭漂”
  • 在weex里面使用chart图表
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • #Linux(Source Insight安装及工程建立)
  • (done) 两个矩阵 “相似” 是什么意思?
  • (三)终结任务
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • .bashrc在哪里,alias妙用
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .net 程序发生了一个不可捕获的异常
  • .net 受管制代码
  • .net6使用Sejil可视化日志
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作
  • ;号自动换行
  • @RestControllerAdvice异常统一处理类失效原因
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [ 手记 ] 关于tomcat开机启动设置问题
  • [BeginCTF]真龙之力
  • [BUUCTF 2018]Online Tool(特详解)
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计