OSG场景管理

33 篇文章 1 订阅
8 篇文章 3 订阅

2018-09-01

   场景管理是渲染引擎的核心功能,我们希望能够把所有的渲染物体合理的组织在一起,而且能够方便的查找、管理。本质上就是设计一个或者多个数据结构。这个目标很容易实现,放在一个数组里就可以了,各种操作的代价也不是很大。但是,这是不行的。
   首先,我们需要把显示物体分组,一堆对象可能是属于一起的,在逻辑上在一个集合,虽然我们可以用额外的数据结构来进行分组管理,那很容出错。所以,我们这个数据结构具有递归保存自身节点类型的功能,其实就是一棵树了。
   其次,有的节点是逻辑上的,它只是起保存分组信息的功能(Group),还需要让有些节点保存 渲染物体信息的功能(Geode)。那么,这就需要使用C++ 的继承机制,Geode继承于 Group,另外添加一些保存渲染信息的接口即可。有些引擎不是这么设计的,可参与渲染的节点只能是叶子节点。我倒是觉得OSG的设计更方便一些。目前,osg::Geode 默认它的children都是可绘制对象,因为有碰撞检测的需求,可绘制对象必然会碰撞,所以会强制转换为osg::Drawable类型,这样会导致一个问题:osg::Geode不能把组织节点作为 子节点。这个问题一般不大。
   第三,当我们想要重用一个节点时该如何呢?总不能把节点的渲染数据复制一份吧。所以,需要场景管理的数据结构支持一个子节点有多个父节点。那么,这棵树现在已经变成一个有向无环图 (Directed Acyclic Graph)了。节点需要增加一个指向多个父节点指针的数组。
   第四,OpenGL是状态机机制,但是,场景管理不需要管理渲染API 究竟是如何渲染的,它的职责只是管理了静态的组织结构。如,我们想给一组节点设置属性,如透明与否、缩放程度、是否隐藏、线条粗细、颜色等,所以,节点需要一个保存这些信息的对象(StateSet)。
   第五,因为我们想要自动管理场景内存的功能,如删掉一个子节点,且没有其他对象再引用它,那么就可以把它析构掉,而且需要给子节点对象提供保存用户填入的任何类型信息功能,这就需要提供智能指针的支持,所以提供Object和Reference类支持。我对于智能指针的看法是:这不是解决内存泄漏的终极办法,用的不小心,还是一样要内存泄漏。我们在模块设计时,对象的生命周期就应该被充分考虑,不能说有了智能指针,这部分工作就可以不用做了。
   第六,因为渲染引擎需要支持各种剔除,那么节点需要支持碰撞检测加速,所以节点需要有包围盒,采用最简单的AABB即可,OSG每个节点都保存一个AABB。要是上层有更严苛的需求,再自己使用强大的包围盒算法。这也一般不是渲染引擎的职责。
   第七,简单的3D应用,可能只有一个Camera,但是,复杂的需求一般都会需要使用多个Camera。两个Camera可能只是在不同的角度看向相同的场景,也可能看向完全不同的场景。如一个主Camera,负责看到主场景,一个隐藏Camera,负责设备坐标系的绘制,另一个隐藏Camera,负责绘制需要defer shading的场景, 它们看到的场景时完全不同的。所以,渲染主循环中,遍历Camera以完成渲染,最终按照既定次序把结果组合起来。所以,我们需要把多个场景根节点和多个Camera一一关联起来。OSG的做法是:把Camera作为一个普通的Node,场景根节点root作为Camera的子节点。不得不说这其实挺巧妙的。
   第八,最重要的一个需求就是遍历场景。我们有多种遍历场景的需求,一种方式是建立一个通用的遍历函数,它分析遍历到的节点的类型,调用不同类型的回调函数来处理,这样的话回调函数的管理是一个困难的问题;另一种方式就是采用经典的visitor模式。针对不同类型的需求创建不同类型的visitor,而把子节点遍历与类型判断工作放到Node,这样的话就能很好的递归调用了,缺点是看调用栈会有点懵,可能会产生无限循环递归的错误。把visitor对象交给节点,在节点中把节点的指针再交还给visitor,控制权翻转,在Visitor中重载的不同节点类型处理函数中做你想要的逻辑操作。
   至于osg::Node,官方文档上说:以组合模式,提供了节点基础的操作接口。它把渲染节点、组织节点都做了一个抽象。
   组织管理场景的最重要的几点需求列在上面了,可以看到我们需要的功能点还是比较清晰简单的,也比较容易实现出来。但是,能够做到通用性强,并通过工业强度的检验,还是有难度的。我们做一个模块设计,很多时候,困难的并不是解决常见问题的部分,而是那些比较小但却很不得不解决的问题,导致设计上做了妥协与让步。但是,一步步来,从核心问题开始一个一个解决。

  1. http://public.vrac.iastate.edu/vancegroup/docs/OpenSceneGraphReferenceDocs-3.0/a01814.png
  2. https://blog.csdn.net/csxiaoshui/article/details/74859066
  3. http://www.bricoworks.com/articles/stateset/stateset.html
  4. http://www.bricoworks.com/articles/stategraph/stategraph.html

如果有任何意见,欢迎留言讨论。 


[ 主页 ]

COMMENTS

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值