探索未知种族之osg类生物---渲染遍历之认识SceneView
前言
我们在进行osg程序的开发时,最常用到的场景管理方式是“场景节点树”的结构,
a 场景树底端的叶节点(osg::Geode)包含了各种需要渲染的几何体的顶点和渲染状态信息;
b 组节点(osg::Group)及其派生出的各种特殊功能节点则作为场景树的各个枝节节点,它们也可以拥有不同的渲染状态;
c 整个场景的根节点(root)有且只有一个节点可以直接作为,使用setSceneData 将其设置给场景的视景器系统,即等同于将整个场景树传递给 OSG 的渲染和显示系统
d 节点所附带的渲染状态集(osg::StateSet)用来保存节点和几何体的各种渲染属性(osg::StateAttribute,例如纹理,雾效,材质,Alpha校验等)和模式开关,一个状态集中可以包含多种不同的渲染属性和开关,处于场景树底端的节点将继承并综合各级父节点的渲染状态,实现几何形状的正确渲染
场景视图(SceneView)成员简介
通过上面几节关于renderingTraversals的介绍,我们大概了解到OSG 渲染后台的主体是场景视图(SceneView),而场景视图(SceneView)同样实现了“树状结构”的管理方式,并据此实现了多个专用于渲染工作的内部类。所以我们先介绍一下场景视图(SceneView)中重要的集中内部类。
1、osgUtil::CullVisitor:“筛选访问器”。虽然同样是继承自 osg::NodeVisitor,不过这个访问器在整个 OSG 系统中可是起了举足轻重的作用。当我们使用它遍历场景图形的各个节点时,CullVisitor 将会对每一个遇到的节点执行场景筛选的工作,判断它是否会超出视截锥体范围,过于渺小,或者被遮挡节点(OccluderNode)挡住,从而将这些无助益于场景浏览的物体筛选并剔除,降低场景绘制的资源消耗。我们甚至可以使用 SceneView::setCullVisitor 来构建和指定使用自己设计的筛选访问器,不过CullVisitor只能在系统渲染后台的环境中使用。
2、osg::RenderInfo:“渲染信息”管理器。这个类负责保存和管理与场景绘制息息相关的几个重要数据:当前场景的视景器,当前场景对应的所有摄像机,以及当前所有 OpenGL 渲染状态和顶点数据(使用第十七日所述的 osg::State 类保存)。这些数据将在场景筛选和渲染时为 OSG 系统后台的工作提供重要依据。
3、osgUtil:: StateGraph: “状态节点”。我们可以对比场景树的组节点(Group),将 StateGraph理解为 OSG 渲染后台的组节点。它的组织结构与场景图形的节点结构类似,但是状态树的构建主要以节点的渲染状态集(StateSet)为依据:设置了 StateSet 的场景节点,其渲染状态会被记录到“状态节点”中,并保持它在原场景树中的相对位置;状态节点采用映射表std::map 来组织它的子节点,同一层次的子节点如果渲染状态相同,则合并到同一个“状态节点”中 。
4、osgUtil::RenderLeaf:“渲染叶”。我们可以把 RenderLeaf 理解为 OSG 渲染后台状态树的叶节点。但是,状态树的叶节点绝非等同于场景树的 Geode 节点;事实上,“渲染叶”的工作主要是记录场景树中存在的各种 Drawable 对象(以及与之相关的投影矩阵,模型视点矩阵等信息)。每个“状态节点”中都包含了一个渲染叶的列表(StateGraph::_leaves),不过只有最末端的“状态节点”会负责记录场景中的“渲染叶”。
5、osgUtil::RenderStage:“渲染台”。OSG 的渲染后台除了使用“状态树”来组织和优化节点的渲染状态之外,还有另外一种用于场景实际渲染的组织结构,我们称之为“渲染树”,“渲染树”的根节点就是“渲染台”。通常来说,由于 OSG 后台只有一个渲染树结构,因此应当也只有一个“渲染台”存在;不过 OSG 还提供了“设置摄像机渲染顺序”的功能,即 Camera::setRenderOrder。设置为PRE_RENDER 的摄像机子树将在主摄像机之前执行渲染,通常我们可以由此实现诸如“纹理烘焙”(Render To Texture)的高级功能(参见 osgprerender 例子);设置为 POST_RENDER的摄像机子树将在主摄像机之后执行渲染,一些必须在最后进行渲染的场景对象,例如 HUD显示牌,可以置为这类摄像机的子节点。注意,把视景器(Viewer)的主/从摄像机设置为 PRE_RENDER 或 POST_RENDER 往往是没有意义的。所谓从摄像机组(View::_slaves),其功能主要是实现同一场景的分窗口以及分屏幕显示(参见 osgcamera 例子)。如果您希望实现诸如 HUD 显示,简单鹰眼图等功能时,应当向场景树中添加新的摄像机节点,并设置与主摄像机不同的观察矩阵和投影矩阵。
6、osgUtil::RenderBin:“渲染元”。它是 OSG 渲染树的分支节点,不过对于没有特殊要求的场景渲染来说,更多的渲染树分支也许并不需要:场景中需要渲染的元素及其渲染属性被保存到各个“状态节点”和“渲染叶”当中;渲染树只要按照遍历的顺序,把这些数据记录到作为根节点的“渲染台”当中(即分别保存到 std::vector 成员量 RenderBin::_stateGraphList和 RenderBin::_renderLeafList 当中,注意 RenderStage 派生自 RenderBin),就可以执行场景的绘制工作了。
自定义渲染顺序处理
很多时候我们需要某些几何体在其它对象之前被绘制,比如天空总是要被任何飞过的物体所遮挡;很多时候我们也需要在大部分对象绘制完成之后才绘制某个几何体的数据(例如 HUD 文字总是显示在所有对象之上)。这种情况下,就有必要对“渲染台”中的数据进行排序,甚至为其创建新的分支“渲染元”,以实现这种复杂的渲染顺序处理。
在程序中,渲染顺序通过 StateSet::setRenderBinDetails 实现设置。这个函数有两个传入参数,
参数1:整型数表示渲染的顺序,以 0 为标准,小于 0 的渲染状态集(亦即包含了这个StateSet的StateGraph状态节点)将排列在前,大于0的则排列在后;
参数2:字符串参数“RenderBin”或者“DepthSortedBin”作为名称时有特殊含义,其中“RenderBin”表示在渲染树中新建分支进行渲染,“DepthSortedBin”表示新建分支,并且所有要渲染的数据将按照深度值降序进行排序。
注意,当字符串参数不为“RenderBin”或“DepthSortedBin”时,渲染顺序的设定也是无效的;当字符串参数和整型参数均有效时,OSG 系统将尝试寻找同类型的渲染元节点并将 StateSet 记录到此“渲染元”中,或者创建新的“渲染元”节点。
|
1
2
3
4
5
6
7
8
9
10
11
|
// 缺省渲染方式,渲染顺序 0,此时状态节点直接置入“渲染台”stateSet->setRenderBinDetails( 0, “” );// 渲染顺序-1(先渲染),此时渲染树中将新建一个“渲染元”节点stateSet->setRenderBinDetails( -1, “RenderBin” );// 渲染顺序 10,此时将新建一个“渲染元”,并按深度值降序排序各元素stateSet->setRenderBinDetails( 10, “DepthSortedBin” ); |
为了简化操作,用户程序还可以使用 StateSet::setRenderingHint 来设置渲染的顺序,这个函数的传入参数可以为枚举量 OPAQUE_BIN 或 TRANSPARENT_BIN。前者可以指定该渲染状态用于不透明物体的渲染,后者则指定该渲染状态用于透明物体的渲染,此时 OSG自动将其渲染顺序置后,并设置它所管理的“状态节点”和“渲染叶”数据按照深度值降序进行排序。关于 setRenderBinDetails 与 setRenderingHint 的关系,也可以这样解释:
|
1
2
3
4
5
6
7
8
9
|
stateSet->setRenderingHint ( OPAQUE_BIN );stateSet->setRenderingHint ( TRANSPARENT_BIN );//分别等价于:stateSet->setRenderBinDetails( 0, “RenderBin” );stateSet->setRenderBinDetails( 10, “DepthSortedBin” ); |
原文链接 http://www.3wwang.cn/blog/article.ftl?id=47
探索未知种族之osg类生物---渲染遍历之认识SceneView的更多相关文章
- 探索未知种族之osg类生物---渲染遍历之器官协作
好了,现在我们经过三节的介绍我们已经大体上明确了单线程模型(SingleThreaded)下 OSG 渲染遍历的工作流程.事实上无论是场景的筛选render还是绘制cull工作,最后都要归结到场景视图 ...
- 探索未知种族之osg类生物---渲染遍历之裁剪一
前言 上面我们用了四节课的内容,讲解了一些osg概念性的内部原理.希望大家可以再看今天的讲解之前先再仔细的研究一下前四节的内容.这样你就会对整个osg的渲染过程有一个更加清晰的认知,有助于理解下面两个 ...
- 探索未知种族之osg类生物---渲染遍历之Renderer::draw()简介
我们今天进入上一节的遗留问题Renderer::draw()的探究. 1.从_drawQueue中取出其中一个sceneView对象.SceneView是对scene和view类的封装,通过他可以方便 ...
- 探索未知种族之osg类生物--渲染遍历之GraphicsContext::runOperations
osg::GraphicsContext::runOperations().我们先来看一下这个函数的执行过程. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
- 探索未知种族之osg类生物---渲染遍历之Renderer简介
我们继续renderingTraversals()的探究.我们接着上一节的”阻塞渲染线程”后就要遍历所有摄像机的渲染器(Renderer),执行 Renderer::cull 场景筛选的操作.我们在r ...
- 探索未知种族之osg类生物---渲染遍历之裁剪三
前言 在osgUtil::CullVisitor,我们发现apply函数的重载中,有CullVisitor::apply(Group& node),CullVisitor::apply(Swi ...
- 探索未知种族之osg类生物---渲染遍历之裁剪二
前言 上一节我们大致上过了一遍sceneView::cull()函数,通过研究,我们发现上图中的这一部分的代码才是整个cull过程的核心部分.所以今天我们来仔细的研究一下这一部分. sceneView ...
- 《探索未知种族之osg类生物》目录
精力有限,博客园不在更新<探索未知种族之osg类生物>.在这里列出所有文章目录(持续更新)有兴趣的同学可以看看. 探索未知种族之osg类生物[目录] 前序 探索未知种族之osg类生物--- ...
- [转][osg]探索未知种族之osg类生物【目录】
作者:3wwang 原文链接:http://www.3wwang.cn/html/article_58.html 前序 探索未知种族之osg类生物---起源 ViewBase::frame函数中的Vi ...
随机推荐
- MindFusion 中节点关键路径的遍历
工作中总能遇到 一些 奇葩的需求,提出这些奇葩需求的人,多半也是奇葩的人,要么不懂相关的计算机软件知识,要么就是瞎扯蛋,异想天开,然而这些奇葩的需求,我也总能碰到.言规正传,在一次项目中,使用了 Mi ...
- 使用Pycharm创建Django项目
一.安装django pip install django 二.创建空django项目 选择New Project...打开创建项目向导. 成功创建一个空Django项目. 创建好的项目可以看到,已经 ...
- Spring MVC 集成Disconf
1.Disconf:Distributed Configuration Management Platform(分布式配置管理平台),专注于各种「分布式系统配置管理」的「通用组件」和「通用平台」, 提 ...
- sql语句的优先级
SQL 不同于与其他编程语言的最明显特征是处理代码的顺序.在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后 ...
- 深入理解Java虚拟机读书笔记6----早期(编译期)优化
六 早期(编译期)优化 1 “编译期”的含义 · 可能是指一个前端编译器把*.java文件转变成*.class文件的过程,前端编译器如:Sun的Javac.Eclipse JDT中的增量式 ...
- Python 学习笔记03篇
看着直播,想着未赶完的工作 真的很想学好一门编程语言
- [转] ESXI6.5 误将硬盘阵列卡配置为passthru直通模式后, 找不到硬盘的问题
There is no easy way to do it, it seems. So I wanted to say that I couldn't afford to do an upgrade ...
- 阿里云消息队列的C#使用http接口发送消息实例
app.config <appSettings> <clear/> <add key="Ons_Topic" value="XXX_Fini ...
- WordCount编码实现及单元测试(第二次作业)
项目码云地址:https://gitee.com/zhujunlin/wc.git 一.题目思路 ========== 阅读完题目要求之后我很懵,因为之前从未使用过博客园和码云工具,对编程的目标需求也 ...
- vue 自定义组件销毁
今天在开发电商vue前端项目时,用户每次登出再换其它用户登录时,页面显示的用户名和左则导航都还是上个用户的,刚开始以为是localStorage中没有清除全局数据,然后在用户点击退出系统时手动清除lo ...