PagedGeometry是OGRE引擎的一个插件,它对(无穷)大区域的海量网格的渲染提供优化策略。它非常适合于稠密的森林和室外场景,那里有海量的树,草,岩石,灌木丛等场景对象。
2, PagedGeometry管理
PagedGeometry class
该类负责加载那些需要立即(或很快)可见的场景几何,而不加载其他的场景以节约内存空间。PagedGeometry引擎可以通过诸如静态几何,imposters等方法去显示实体对象(Entities)。这些方法是与实体和场景相机的距离,以及你的配置相关的。
对页面的加载是通过用户定义的PageLoader来完成的。这样,用户可以编程实现加载页面,无论它是来自硬盘上的文件,程序产生的或是其他地方。
GeometryPageManager
在PagedGeometry类中使用,用于管理分页页面,在需要的时候做cacheing, deleting等工作。它通过分析摄像机距离去计算页面cathe的速度,并delete那些已经经过了设定时间的不可见页面。
调用PagedGeometry::addDetailLevel(), 创建 GeometryPageManager 。
addDetailLevel() returns a pointer to this page manager, allowing you access to some useful functions, documented below.
类成员函数中有些注释了DO NOT USE的,不能被用户使用,它们是在PagedGeometry中被使用的。
addDetailLevel()
Adds a detail level to the PagedGeometry object.
PageType 对该detail level,用户想使用的页面类型。它不是一个函数参数,而是一个模板参数。
maxRange 这个detail level使用的最大距离(摄像机的视距)
transitionLength 期望的衰减转变长度 - (可选)
示例:
pagedTrees->addDetailLevel<BatchPage>(100); //Use batched geometry from 0-100
pagedTrees->addDetailLevel<ImpostorPage>(500); //Use impostors from 100-500
名叫pagedTrees的PagedGeometry 的对象会在0-100单位摄像机距离的范围内使用batched(分批几何,静态几何),100-500单位距离范围内使用imposters
如果已有的页面类型不合适,用户可以很轻松的添加自定义的GeometryPage子类
transitionLength 参数在默认情况下是没有的,但是用户可以自己添加,它的作用是使细节层次转变更平滑。但是注意,使用参数可能会是渲染的效率下降10%-30%。
3,页面类型
Class GeometryPage
如上所说,该类是一个虚基类,用户可以扩展继承该类去实现不同的替代被渲染实体的方式,如batched,imposters等。如果你需要其他的页面类型,你可以自己实现一些。
以下是用户必须在子类中实现的虚函数:
virtual void init(SceneManager *mgr, Camera *cam) = 0;
virtual void setRegion(Real left, Real top, Real right, Real bottom) = 0;
virtual void addEntity(Entity *ent, const Vector3 &position, const Quaternion &rotation, const Vector3 &scale, const Ogre::ColourValue &color) = 0;
virtual void build() {}
virtual void removeEntities() = 0;
virtual void setVisible(bool visible) = 0;
virtual void setFade(bool enabled, Real visibleDist, Real invisibleDist) = 0;
virtual void update() {}
以下是页面管理器(page manager)如何去使用上面的函数:
1,当PagedGeometry首先create一个GeometryPage,马上调用它的init(),该函数就好像构造函数一样。
2,准备一个几何页面给待渲染实体,设置页面区域。
3,添加实体对象到该页面,并初始化位置,方向等。
4,添加实体到场景中的最后一步。在添加完所有实体对象后自动调用。
5,从页面完全删除实体对象。
6,使整个页面变为可见。
7,设置页面的消减属性。
8,在帧循环中保证页面几何的更新。
class BatchPage
The BatchPage class把实体当作静态几何体来渲染。
静态几何体(StaticGeometry):在场景中有许多实体是从它们加入场景开始就不会移动的,如房屋,树等,Ogre为这种情况提供了StaticGeometry类,它允许你批渲染很多物体.这个通常要比手动在SceneNodes添加要快多了。
class ImposterPage
the ImpostorPage class.把实体当作impostors(一种布告版图像,看起来像真实的实体)来渲染
所有page类型中,这个是最快的,它使用Impostors去代替要渲染的entities,这样,显卡只要去渲染一系列的2d image,而不是3d mesh
class GrassPage
A custom page type designed specifically for use with GrassLoader.
GrassPage页面类型是被设计来配合GrassLoader使用的
这种类型是没有做过优化的,它只是对所给的entity进行克隆,然后绑定到一个新的场景节点之上。这意味着性能很差。
4,BatchedGeometry-一种静态几何的版本
class BatchedGeometry
它是Ogre::StaticGeometry的一个轻量级版本。
staticGeometry是ogre提供给用户的批渲染的类,它可以一次性渲染那些在场景中保持“静态的”实体(entities),如,房屋,树等。
它给用户提供多一些的对batch材质等的控制。
class SubBatch: public Ogre::Renderable
subBatch继承于Renderable,是BatchedGeometry的内部类,它的构造函数中传入BatchedGeometry指针和submesh的指针,该类包含在BatchedGeometry中。
5,Loading Entities
class PageLoader
虚基类。用户可以扩展它去提供负责加载页面(Page)的回调函数。
PagedGeometry预装了几种不同的Loader,继承于PageLoader,跟很多实体管理器不同的是,PagedGeometry不允许用户一次性向object添加所有的entities,由于它是用于大规模的游戏场景,所以它会对世界几何进行分页,然后调度,只加载需要绘制的页面。
只要引擎需要确定世界几何的那一块区域需要被加载,就要调用PageLoader的成员loadPage()。在函数中的PageInfo结构体,提供了页面的包围体信息。在函数中,用户通过
addEntity()来添加实体到该页面中,还可以定义实体的尺度,位置,旋转等属性。
当用户创建了自己的loader对象后,必须将其attatch到PagedGeometry对象上去。如下:
pagedGeometry->setPageLoader(yourPageLoader);
PageInfo: 结构体。提供给PageLoader的有用的页面信息。基本的信息是定义被加载的区域,还有一些该区域的其他信息。
结构体内包含了一个TBound(typedef Ogre::TRect<Ogre::Real> TBounds),所有在该页面内的实体都必须放置在这个矩形包围体之中。
具体的loaders:
(1)GrassLoader 继承于PageLoader,用于和PagedGeometry一起产生真实的草地场景。所谓真实的草地模拟,使用GrassLoader成员函数addLayer()来添加草,使用updateAnimation()来驱动动画。
当用户创建了Grassloader对象后,必须将其attatch到PagedGeometry对象上去。如下:
pagedGeometry->setPageLoader(GrassLoader);
草地loader在使用几何页面类型的时候,被推荐为使用GrassPage,这样的渲染效率较高,而采用其他类型则效率很低。
同时提供了一个数据结构来完全控制Grass的属性 class GrassLayer,它是通过addLayer()来添加的,该类提供了一系列的“set”方法,用于用户配置草地的材质,密度,大小等属性信息。
(2)TreeLoader2D继承于PageLoader,用于和PagedGeometry一起轻易的实现在地形上放置树木的功能。
使用方法和前述一致,使用时,addTrees()方法向场景中添加树木。需要注意的是,loader加载树木时并不知道该地形的高度,而是假设高度为0,这就需要设定获得当前(即给定x,z值时)的地形高度。Loader提供了这些方法。
(3)TreeLoader3D同2D的情况差不多,只是效率大概低40%左右。TreeLoader3D将树在内存中打包的效率很高,大约10Bytes一棵树,相当于100万棵树只要 9.53m 内存空间。这就很适用于大规模森林的渲染。
引擎为2D,3Dloader提供了一些公用的工具类,如class TreeRef,以内联函数的性质为loader提供了位置,旋转,尺寸,方向等的“get”数学运算。而TreeIterator2D,TreeIterator3D则为loader提供了树指针的操作。