Ogre各种场景管理器以及和插件关系深入分析

来源:互联网 发布:文章抄袭检测软件 编辑:程序博客网 时间:2024/04/30 02:24

OgreOctreeSceneManagerDll.cpp文件

extern "C" void _OgreOctreePluginExport dllStartPlugin( void )
{
    // Create new scene manager
    octreePlugin = OGRE_NEW OctreePlugin();

    // Register
    Root::getSingleton().installPlugin(octreePlugin);

}

上面的Root::getSingleton().installPlugin函数调用下面的OctreePlugin::install()函数和OctreePlugin::initialise()函数

OgreOctreePlugin.cpp文件

void OctreePlugin::install()
 {
  // Create objects
  mOctreeSMFactory = OGRE_NEW OctreeSceneManagerFactory();
  mTerrainSMFactory = OGRE_NEW TerrainSceneManagerFactory();
  mTerrainPSListenerManager = OGRE_NEW TerrainPageSourceListenerManager();

 }
 //---------------------------------------------------------------------
 void OctreePlugin::initialise()
 {
  // Register
  Root::getSingleton().addSceneManagerFactory(mOctreeSMFactory);
  Root::getSingleton().addSceneManagerFactory(mTerrainSMFactory);
 }

经过上面两个函数后,Root中就含有(官方叫注册)两个特定类型的场景管理器工厂,可以用来创建特定的场景管理器(得到管理器工厂就可以认为得到了管理器)

OgreOctreeSceneManager.h文件

class _OgreOctreePluginExport OctreeSceneManager : public SceneManager

class OctreeSceneManagerFactory : public SceneManagerFactory

从上面的两个类的声明可以看出,他们继承与对应的接口类,这些接口类是Root中识别的。

OgreTerrainSceneManager.h文件

class _OgreOctreePluginExport TerrainSceneManager : public OctreeSceneManager

class TerrainSceneManagerFactory : public SceneManagerFactory

对应的cpp文件中有

//-----------------------------------------------------------------------
 void TerrainSceneManagerFactory::initMetaData(void) const
 {
  mMetaData.typeName = FACTORY_TYPE_NAME;
  mMetaData.description = "Scene manager which generally organises the scene on "
   "the basis of an octree, but also supports terrain world geometry. ";
  mMetaData.sceneTypeMask = ST_EXTERIOR_CLOSE; // previous compatiblity
  mMetaData.worldGeometrySupported = true;
 }
 //-----------------------------------------------------------------------

可以看出地形场景管理器继承与八叉树场景管理器。在cpp文件的函数中有ST_EXTERIOR_CLOSE表示类型。

OgreRoot.h文件

Root类中的SceneManager* createSceneManager(SceneTypeMask typeMask, const String& instanceName = StringUtil::BLANK);函数有如下说明:

Creates an instance of a SceneManager which supports the scene types identified in the parameter. If more than one type of SceneManager has been registered as handling that combination of scene types,  in instance of the last one registered is returned.

 

需要说明的是只要你没有修改plugins.config文件,那么你用的就不是它,因为根据config文件默认是加载了OctreeSceneManager插件的。如果你使用了OctreeSceneManager插件的话,OctreeSceneManager会将自身注册为ST_GENERIC类型,并且覆盖作为基础的SceneManager类。OctreeSceneManager使用了拣选不可见对象的系统,因此它比标准的SceneManager即默认的ST_GENERIC类型的场景管理器要快。如果你从plugins.cfg文件中去除了OctreeSceneManager插件,那么当你请求ST_GENERIC类型时,你才可能会使用基础的SceneManager。

选择一个场景管理器
你可以通过getSceneManager 方法选择一种场景管理器,来代替默认的ST_GENERIC :
Dagon 1.2 version 以后版本:
mRoot->createSceneManager (ST_GENERIC);
老版本:
mRoot->getSceneManager (ST_GENERIC);
它们的参数有以下值可选择:
      • ST_GENERIC – 如果你设定加载Plugin_OctreeSceneManager 将使用八叉树管理, 如果你设定加载Plugin_DotSceneManager 就可以加载DotScene (.scene)
      • ST_EXTERIOR_CLOSE – 地形场景管理Terrain_Scene_Manager
      • ST_EXTERIOR_FAR – 自然场景管理(Nature scene manager)
      • ST_EXTERIOR_REAL_FAR – 分页场景管理Paging_Scene_Manager
      • ST_INTERIOR – BSP场景管理

(1)八叉树场景管理器,当使用八叉树分割场景时,对于多数场景效果良好,除了那些非常封闭的场景,它的优点是:

          •一个简单的解决方案,对于多数场景实用。 
          •如果有大量静态几何体,可以用StaticGeometry 类来加速
它的缺点是:

          • 对特殊的场景结构没有加速
          • 不适用于非常封闭的空间

 

(2)地形场景管理器(Terrain Scene Manager ),是为非常小的包含静态地形的场景所设计的。这个场景管理器方便从高度图来产生场景。(通过读取media目录下的terrain.cfg文件来生成地形)。
优点:
        • 可以很快渲染高分辨率的地形
        • 可以很方便地由高度图和地形材质产生地形
        • 材质可以使用shader
缺点:
        • 没有分页- 有hooks接口但是你需要添加它


(3)自然场景管理器 (Nature Scene Manager:插件)
似乎没人用,略。

(4) 分页场景管理器(Paging Scene Manager:插件)
Paging Scene Manager 可以将场景分成多页。只有哪些正在被使用的页面才会显示,随意可以用在非常大的场景上。每个页有自己的高度图,并且可以使用不同材质。(可以创建绿色平原上的雪山之类的场景)
优点:
       • 可以处理比terrain and nature scene managers更大的场景
       • 允许实时卸保存载地形
       • 允许多个高度图,每个高度图允许多材质
       • 地图工具 ( "Mapsplitter") 可以将大地图和材质分成页
       • 支持16 bits per height 的Raw 格式的高度图
       • 实时改变地图和材质
       • Demo: http://tuan.kuranes.free.fr/Ogre.html
       • Horizon Occlusion Visibility Real-time determination:比如山之后的物体不会被送到显卡处理
       • 支持八叉树
缺点:
      • 需要安装paging scene manager 插件
      • 需要用地图工具来产生分页
      • 更多的选择也意味着更复杂

 

(5)5. BSP 场景管理器
该场景管理器用来管理室内场景。特别会优化那种有交错的墙壁和走廊组成的场景。
为BSP场景管理器产生level的步骤简要如下:
       • 可以用 各种level编辑工具来创建你的level,用.map格式保存
       • 将.map格式编译成Quake 3的.bsp格式,这种格式可以被BSP场景管理器读取。(可以用q3map3来转换)
优点:
       • 可优化室内场景
       • 很多level编辑工具可选择
缺点:
       • 现在可能有一些GPU处理不了Quake 3的 .bsp 格式
       • 一些人建议不要用Blender来创建level, 而是要导出为.scene格式

 

(6)DotSceneOctree 场景管理器(插件)
DotSceneOctree 场景管理器可以令几何体和mesh存在同一个文件中。
优点:
       • 可以在一个文件中包括所有场景
       • meshes可是是静态或者动态
       • 支持八叉树
缺点:
      • 需要工具来建立八叉树文件 (.bin) 
      • 不支持32 bit indices,所以大的mesh需要切开

下面说一下地形场景管理器(Terrain Scene Manager )的terrain.cfg文件参数说明

如果你已经做出决定要使用地形场景管理器,那么下面介绍的一些东西是你需要知道的。
场景中地形的形状和着色是由高度图、地形纹理和地形细节纹理共同计算而得的。高度图是一张简单的灰阶图,其中每个像素点代表一个高度值,0代表这个地形的地面,255代表最高点。例子中有一个叫做terrain.png的高度图,可以供大家实验用。
一张纹理图伸展开来覆盖整个儿地形。纹理图一般都是棕、绿、白或灰间杂的颜色,对应土地、草地、雪地或者岩石地形。因为地形纹理一般比要覆盖的地形小得多,故而当你距离很近地观察它时,地形一般会看起来比较模糊。为了帮助改善这一点,在近距离观察时,就要用到细节纹理,与地形纹理混合使用。细节纹理并不像地形纹理那样伸展得那么大,仅仅是减弱了近距离观察时产生的地形模糊现象。例子中的terrain_texture.jpg以及terrain_detail.jpg这两个纹理可供实验使用。
一个地形被分割为一小块儿一小块儿的像地砖一样的地形方块儿,由场景管理器按这些地形块儿的拓扑结构和观察者的距离依照不同的细节层次进行显示。
最后,用一个指定了地形维度的世界坐标空间,将完整的地形投影到一个三维空间中。

地形场景管理器通过terrain.cfg脚本进行配置。
(1)基本配置参数
这个脚本中的基本参数有:
WorldTexture:指定地形纹理文件的名字。
DetailTexture:指定细节纹理文件的名字。
DetailTile:指定细节纹理在每个地形块儿上重复的次数。例如,如果值为n,那么细节纹理在每个地形块儿中将会以nxn个网格的形式被显示出来。设置这个参数可能需要做一些实验。如果数值设低了,地形可能在近距离观察时会看起来很模糊。如果数值设得太高,地形可能出现距离很远时仍然不断重复匹配图案。
PageSource:指定高度图的源。默认设置是Heightmap。
Heightmap.image:绘制高度图的图像文件。因此必须是一个边长为2^n+1(2的n次方+1)的正方形,n位整数。高度图越大,地形就越详细,但是同时你的程序所耗费的资源也相应越多。(包括程序的启动时间更长。)
PageSize:地形最终会有PageSize x PageSize个顶点。PageSize必须与高度图的边长数值相同,即此数值也是2^n+1,n为整数。
TileSize:地形砖有TileSize x TileSize个顶点。这个数值必须小于PageSize。TileSize的值也必须满足2^n+1,n为整数。地形砖的大小设置得太小严重影响效果,而设置得太大会导致场景中某些部分使用不必要地过高细节,浪费资源。
MaxPixelError:当决定使用LOD时,这一参数指定最大容错值。这个值设得过高会导致地形有接缝。设置得过低会影响效果。
PageWorldX, PageWorldZ:设置在世界坐标系下的地形扩展。地形越大,地形的细节就越低,因为用于地形的顶点数是基于高度图的,而不是世界的大小。这可以被用来将地形伸缩成你想要的大小。
MaxHeight:世界坐标系下,地形的最大高度。高度图0到255的范围,伸缩成世界坐标系下0到MaxHeight。
MaxMipMapLevel:指定渲染地形时用到的细节层次数。距离较远的地形和相对平坦的地形可以使用较低细节渲染。

(2)高级配置参数
一些高度图生成器将数据保存为原(raw)格式而不是图像(image)格式。下面这些参数就是描述原格式的。
Heightmap.raw.size:指定高度图一边的长度。值必须是2^n+1,且n为整数。
Heightmap.raw.bpp:指定文件中每像素是用多少字节表示的。例如,1=8 bits,2=16 bits。
Heightmap.flip:当设置为true,翻转高度图。Required for Terragen heightmaps.
以下参数控制场景管理器的其他操作。
VertexNormals:这个参数让TerrainSceneManager在硬件缓冲区中计算并设置顶点法向。如果使用光照或者需要它的GPU程序,应当打开这个参数。
VertexColours:这个参数让TerrainSceneManager在硬件缓冲区中计算并设置顶点颜色。如果你用到了需要这个信息的GPU程序,就要打开这个参数。
UseTriStrips:当设置为yes,则优化地形三角形送入GPU的顺序,以便送入较少的顶点。(虽然对于大多数新款显卡来说,帧率没什么变化)。因为在某些显卡上可能会导致“裂缝”产生,并且很少甚至没什么性能提升,所以建议还是关掉好。
VertexProgramMorph:如果可以的话,使用定点程序变形LODs。
LODMorphStart:LOD变形开始起效的相应距离范围。这是当前LODs作用范围和下一个更低级别的LOD作用范围之间的距离的一个比例。

(3)更多高级参数
不使用地形纹理和细节纹理渲染地形,你可以给出你自己的渲染方式,特别是用你自己的材质。典型用法就是在材质中提供你自己的顶点程序。
MorphLODFactorParamName:如果VertexProgramMorph设置为yes并且你的自定义材质中包含有一个高级顶点程序,那么使用这个选项。这个参数指定了你想要绑定变形LOD的顶点程序参数名。参数范围时是到1。0(最高)表示没有调整,1表示完全由变形控制作为下一个低级LOD的同一点。
MorphLODFactorParamIndex:如果VertexProgramMorph设置为yes并且你的自定义材质中包含有一个汇编级的顶点程序,那么使用这个选项。这个选项代表了你想要绑定变形LOD因子的顶点程序参数的索引。 参数范围是0到1。0(最高)表示没有调整,1表示完全由变形控制作为下一个低级LOD的同一点。
CustomMaterialName:要定义渲染地形的材质名。


(4)使用自定义材质
你可以使用自定义材质渲染你的地形。如果你的材质包括顶点程序,以下的参数是可以使用的:
位置(positions)
两个纹理坐标集合(0号是世界纹理,1号是细节纹理)
法线,如果启用的话
每顶点delta值,为将一个高一级的LOD变形为低一级的LOD地砖。这是一个像'blend weight'一样的每个顶点都有的浮点数。如果你想使用这个参数,你也必须提供你想接收变形因子的参数的名字或者索引号。

原创粉丝点击