探索未知种族之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 ...
随机推荐
- 编译pcre 报错 error: Invalid C++ compiler or C++ compiler flags
安装c++ 编译器:yum -y install gcc-c++ ,再次编译通过.
- PID控制器介绍
在维基百科上查到的PID的介绍,收藏一下,慢慢看. https://zh.wikipedia.org/wiki/PID%E6%8E%A7%E5%88%B6%E5%99%A8#%E6%AF%94%E4% ...
- 使用keil5,加断点调试后,停止运行的问题
加上断点调试,执行到断点的时就出现程序停止运行的提示. 原因:是工程路径存放太深.
- 通过shell操作串口
1. 通过stty工具设置串口参数,例如 stty -F /dev/ttyUSB0 raw speed 9600 -echo min 0 time 10 上例设置了ttyUSB0设备的数据流格式为ra ...
- nginx问题集锦
1.配置访问指定路径的文件 以访问/mnt/data/logs下文件为例,修改nginx.conf配置,执行命令重新加载/usr/local/nginx/sbin/nginx -s reload lo ...
- 在Python脚本中调用Django环境
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", " ...
- Java学习前的一些准备
1.JDK - (Java SE Development Kit) JDK是Java开发所需要的环境,就跟我们想玩某个网游一样,玩之前一定是需要先安装相应的程序包的.那这个JDK就是我们准备登陆Jav ...
- RDKIT+postgresql做化合物数据存储与查找
RDKIT: rdkit的安装与使用,直接conda instal rdkit,不行的话,使用源码安装,将RDKIT源码下载解压到acaconda的pkg目录下,打开cmd,进入pkg下的 rdki ...
- python中线程的知识点
什么是线程? 程序的执行线路.每个进程默认有一条线程.线程包含了程序的具体步骤. 多线程就是一个进程中有除主线程(默认线程)外还有多个线程. 线程与进程的关系(进程包含线程,而线程依赖进程存在) 1. ...
- 二叉搜索树的第K大节点
题目描述 给定一颗二叉搜索树,请找出其中的第k大的结点. 分析 对二叉搜索树进行逆向中序遍历(先右再左),则遍历序列是降序排序的,因此中序遍历一颗二叉搜索树,可以很容易的得到它的第k大的节点.使用一个 ...