关键词: InstancedGeometry 着色程序 动画
1)本例的主要函数在CrowdListener::createInstanceGeom
可以在其中学习如何使用 InstancedGeometry 几何对象, 可用于创建大量实体的几何体
2)函数 CrowdListener::buildCrowdMaterial 则可以学习 如何修改一个材质中的子材质, 并给子材质的每个通道增加顶点着色程序
3)另外本例可以了解如何控制大量对象的动画, 场景中每个需要动的实体动画状态放入一个容器中, 每帧更新容器的动画状态即可
本例程序的CEGUI有些元素的处理含在OpenGL环境下会发生异常, 而DX则没有问题。
两个类 CrowdApplication 和 CrowdListener
1. 类 CrowdApplication
基类: public ExampleApplication
构造函数:
析构函数: 注意其中的CEGUI窗口需要调用 CEGUI::WindowManager 的 destroyWindow方法摧毁
重写的函数: chooseSceneManager, createScene, destroyScene, createFrameListener, setupResources
chooseSceneManager
使用"TerrainSceneManager"场景管理器
setupResources
还是基类的setupResources函数
createScene
设置世界地图
设置环境观
设置有向光
设置天空盒
设置相机位置和朝向
设置阴影模式
setupGUI()
设置CEGUI渲染器和渲染系统
设置CEGUI的LOG细节
CEGUI的SchemeManager加载TaharezLookSkin.scheme
设置缺省光标
光标设置图像
创建窗口“Sheet”
将该窗口设置为CEGUI系统的表单
窗口管理器加载布局CrowdDemo.layout
将该窗口设置为CEGUI系统的表单
setupEventHandlers()
给CEGUI组件添加事件处理
给当前视图增加合成器"Bloom"
2. 类 CrowdListener
基类: public ExampleFrameListener, public OIS::KeyListener, public OIS::MouseListener
构造函数:
得到GPU着色程序的支持句法规则 GpuProgramManager::getSingleton().getSupportedSyntax();
用句法规则迭代器遍历该支持的规则 GpuProgramManager::SyntaxCodes::const_iterator
调用 Log管理器增加Log信息, 写入支持的着色句法
createCurrentGeomOpt()
设置鼠标键盘的回调
得到CEGUI元素的窗口指针
隐藏原有的Debug Overlay
设置新的定时器
设置mLastTime
函数 createInstanceGeom---用于创建实例几何体, 这个代码很有用, 可以设置自己的渲染实体方式
判断根的渲染系统的能力是否含有 RSC_VERTEX_PROGRAM
否的话抛出异常 OGRE_EXCEPT Exception::ERR_INVALIDPARAMS, "Your video card doesn't support batching", "Demo_Instance::createScene"
从相机得到场景管理器, 在其中创建实体 robot
setupInstancedMaterialToEntity
循环子实体
得到子实体的名称
根据该名称和实体骨骼的骨头数调用buildCrowdMaterial--这个程序的目的应该是给材质的顶点着色程序
用StringUtil类的endWith函数判断子实体名称是否以 /instanced 结尾
是的话, 就直接返回该实体名称
根据该子实体名称在材质管理器找到源材质指针 MaterialManager::getSingleton ().getByName
判断该材质指针是否为空, 而后设定字符串instancedMaterialName
originalMaterial.isNull() ? "Instancing" : originalMaterialName + "/Instanced"
再根据instancedMaterialName得到实例材质指针
如果实例材质指针为空
则克隆源材质
加载
得到通道迭代器 Technique::PassIterator
遍历通道
通道设置顶点着色程序 Crowd
设置阴影投射顶点着色程序 CrowdShadowCaster
实例材质再加载
返回实例材质名称 instancedMaterialName
根据返回值 调用setMaterialName设置子实体的名称
将renderInstance的容量和大小 设置为预先的 渲染次数
根据 场景管理器和 robots 创建一个 实例几何对象 InstancedGeometry
该实例几何对象的阴影设置为真 setCastShadows
setBatchInstanceDimensions, 设置大小 Vector3(1000000, 1000000, 1000000)
用addEntity给 实例几何体循环添加实体
设置实例几何体的方向 setOrigin
调用 build 编译实例几何体
调用 addBatchInstance 循环 渲染次数
调用 getBatchInstanceIterator 得到迭代器
建立光线查询 createRayQuery
遍历实例几何体迭代器
得到实例 BatchInstance
得到 BatchInstance 的迭代器 getObjectIterator
遍历迭代器
得到位置
执行光线查询, 确保对象在地面之上
setPosition 设置位置
缩放大小
得到 动画状态 Walk
设置动画时间
动画启动
如 k > 14, 则增加i
该实例几何体设为可见
将该实例几何体放入 变量renderInstance[0]中
销毁光纤查询
销毁实体
函数 destroyInstanceGeom
销毁装有实体几何体的容器
销毁动画容器
函数 createEntityGeom---一个一个创建实体和节点
重置Entity容器和Node容器的大小
建立光线查询
循环numMesh次
得到位置
查询确保维位置在地面之上
创建节点
LOG记录
创建实体
实体添加, 设置位置
设置动画
更新循环变量
销毁查询
函数 destroyEntityGeom
用循环得到名称销毁实体
burnCPU
设置为停止时间为上一次时间+燃烧时间
如果当前时间小于停止时间
不断循环
设置使用率, 在该函数里过去的时间/上一帧到这里的时间
重新设置上一次时间
frameRenderingQueued
burnCPU
更新所有实体的动画状态时间 addTime
更新调试状态
调用基类的同函数
返回基类同函数的返回值
鼠标消息, 键盘消息同其他例子
http://www.cppblog.com/summericeyl/archive/2009/10/11/98314.html
OGRE关于 Demo_Crowd 例子的分析
最新推荐文章于 2013-05-31 22:22:31 发布