前言

我们在进行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的更多相关文章

  1. 探索未知种族之osg类生物---渲染遍历之器官协作

    好了,现在我们经过三节的介绍我们已经大体上明确了单线程模型(SingleThreaded)下 OSG 渲染遍历的工作流程.事实上无论是场景的筛选render还是绘制cull工作,最后都要归结到场景视图 ...

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

    前言 上面我们用了四节课的内容,讲解了一些osg概念性的内部原理.希望大家可以再看今天的讲解之前先再仔细的研究一下前四节的内容.这样你就会对整个osg的渲染过程有一个更加清晰的认知,有助于理解下面两个 ...

  3. 探索未知种族之osg类生物---渲染遍历之Renderer::draw()简介

    我们今天进入上一节的遗留问题Renderer::draw()的探究. 1.从_drawQueue中取出其中一个sceneView对象.SceneView是对scene和view类的封装,通过他可以方便 ...

  4. 探索未知种族之osg类生物--渲染遍历之GraphicsContext::runOperations

    osg::GraphicsContext::runOperations().我们先来看一下这个函数的执行过程. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  5. 探索未知种族之osg类生物---渲染遍历之Renderer简介

    我们继续renderingTraversals()的探究.我们接着上一节的”阻塞渲染线程”后就要遍历所有摄像机的渲染器(Renderer),执行 Renderer::cull 场景筛选的操作.我们在r ...

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

    前言 在osgUtil::CullVisitor,我们发现apply函数的重载中,有CullVisitor::apply(Group& node),CullVisitor::apply(Swi ...

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

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

  8. 《探索未知种族之osg类生物》目录

    精力有限,博客园不在更新<探索未知种族之osg类生物>.在这里列出所有文章目录(持续更新)有兴趣的同学可以看看. 探索未知种族之osg类生物[目录] 前序 探索未知种族之osg类生物--- ...

  9. [转][osg]探索未知种族之osg类生物【目录】

    作者:3wwang 原文链接:http://www.3wwang.cn/html/article_58.html 前序 探索未知种族之osg类生物---起源 ViewBase::frame函数中的Vi ...

随机推荐

  1. 基于KMP算法的字符串模式匹配问题

    基于KMP算法的字符匹配问题 反正整个清明都在纠结这玩意...差点我以为下个清明要给自己过了. 至于大体的理解,我就不再多说了(还要画图多麻烦鸭),我参考了以下两个博客,写的真的不错,我放了超链接,点 ...

  2. oracle 的tnsnames.ora,listener.ora

    x:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN listener.ora: # listener.ora Network Conf ...

  3. python学习(list增删改查、及常用方法)

    1.Python多条件判断: 多条件判断if: passelse: pass循环 while for i = 0 while i > 1: print('hello') else: print( ...

  4. 关于java使用POI导出ppt ,其中表格setText 失败问题

    1.导出ppt 必要的包 使用maven <dependency> <groupId>org.apache.poi</groupId> <artifactId ...

  5. anaconda安装Opencv报错:Could NOT find PythonLibs: Found unsuitable version "2.7.6",

    机器上装了两个python,一个是默认的,一个是anaconda.安装opencv时就报错了: -- Found PythonInterp: /home/deeplp/anaconda2/bin/py ...

  6. Linux修改用户所在组方法

    Linux修改用户所在组方法 usermod -g 用户组 用户名强行设置某个用户所在组usermod -G 用户组 用户名把某个用户改为 group(s) usermod -a -G 用户组 用户名 ...

  7. activiti官网实例项目activiti-explorer之扩展流程节点属性2

    情景需求:需要查找activiti-explorer项目中获取流程id的方法,然后根据流程id获取相应字段在节点属性中添加内容. 大致流程:拿取整个流程id获取对应表单属性,在页面节点属性中展示对应表 ...

  8. pywin32安装教程

    下载 pywin32-224-cp37-cp37m-win32.whl 放在 Scripts 目录下,然后cmd 安装 pip install pypiwin32 即可成功 此次安装成功对应的pyth ...

  9. spring @Bean注解的使用

    @Bean 的用法 @Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里.添加的bean的id为方法名 定义bean 下面是@Co ...

  10. 在类文件中创建 写入Json文件

    由于业务需要 今天写了一个方法能够定时更新Json文件 即定时从数据库中查询数据 然后转化为Json对象 如果有数据的话 删掉之前的Json文件 重新创建一个文件 然后写入Json对象 中间走了很多弯 ...