OGRE Demo_Instancing 例子的分析

138 篇文章 0 订阅
本文介绍 Ogre 引擎中的 Instancing 渲染优化技术,包括实例几何体、静态几何体和实体方式的创建及应用。文章还详细解析了 InstancingApplication 和 InstancingListener 类的功能,并解释了如何通过 GUI 控制渲染模式。
摘要由CSDN通过智能技术生成

关于 Demo_Instancing 例子的分析


1. 本例建立框架模板的时候, 使用release版本编译运行一番, 发现其所用的文件ogre.cfg, plugins.cfg, resources.cfg与debug的版本不同, 链接库也不同.
    空白Ogre程序在release版本下FPS是1050左右, 但是在debug版本下只有90. 差距太大了啊
2. 天空盒使用的材质 是立体图 cubic_texture morning.jpg separateUV
3. Ogre的Plane类表示一个平面, 其normal成员表示该平面的朝向, 其d表示在mesh中距离原点的距离, 方向为normal
3. 在本例可以学会三种方式创建具有大量内容的几何体: 实体方式, 实例几何体, 静态几何体
4. 静态几何体和实例几何体的删除很简单, 直接delete创建的该对象就可以, 然后场景里的该对象就会消失.
5. 这里的buildInstancedMaterial讲述了如何克隆一个材质并如何设置所有通道的着色程序
6. 函数createInstanceGeom和函数createStaticGeom分别为创建实例几何体和静态几何体的重要方法
    
1. InstancingApplication 类
    构造函数: 初始化 CEGUI的渲染器, 系统, 表单窗口
    析构函数: 清理 CEGUI的表单窗口(WindowManager的destroyWindow方法), 系统, 渲染器
    函数 getRenderWindow
        得到Ogre的渲染窗口
    函数 createScene
        设置环境光, 光, 天空盒, 相机, 平面
        setupGUI
        setupEventHandlers
        视口增加合成器 "Bloom"
        
    函数 setupGUI
        // 该函数设置CEGUI
        方案 TaharezLookSkin.scheme
        缺省光标 TaharezLook MouseArrow
        光标图像 TaharezLook MouseMoveCursor
        表单窗口 布局 InstancingDemo.layout
        
    函数 setupEventHandlers
        // 给所有的CEGUI窗口订阅事件处理函数
            ExitDemoBtn    PushButton::EventClicked    handleQuit
            tInstancing    RadioButton::EventSelectStateChanged    handleTechniqueChanged
            tStaticGeometry    RadioButton::EventSelectStateChanged    handleTechniqueChanged
            tIndependantEntities    RadioButton::EventSelectStateChanged    handleTechniqueChanged
            Object Count    Scrollbar::EventScrollPositionChanged    handleObjectCountChanged
            Time Burner    Scrollbar::EventScrollPositionChanged    handleTimeBurnerChanged
            PostEffect    Checkbox::EventCheckStateChanged    handlePostEffectChanged
            Shadows    Checkbox::EventCheckStateChanged    handleShadowsChanged
            Objects    Combobox::EventListSelectionAccepted    handleObjectChanged
            root
                Window::EventMouseMove    handleMouseMove
                Window::EventMouseButtonUp    handleMouseButtonUp
                Window::EventMouseButtonDown    handleMouseButtonDown
                
    函数 handleQuit
        调用监听器类的 requestShutdown
        
    函数 handleMouseMove, handleMouseButtonDown, handleMouseButtonUp
        调用监听器类的同名函数
    
    函数 handleTechniqueChanged
        首先调用监听器类的 destroyCurrentGeomOpt方法 先销毁当前的几何体
        根据选择的ID设置相应几何体的模式, 然后调用监听器类的 createCurrentGeomOpt创建几何体
            getSelectedButtonInGroup()->getID()
            ((CEGUI::RadioButton*)((const CEGUI::WindowEventArgs&)e).window)->getSelectedButtonInGroup()->getID();
            
    函数 handleObjectCountChanged
        首先调用监听器类的 destroyCurrentGeomOpt方法 先销毁当前的几何体
        调用监听器类的setObjectCount函数设置对象数目
        在调用监听器类的 createCurrentGeomOpt创建几何体
        CEGUI窗口"Object Count Number" 设置文本为几何体的数目 setText方法
        
    函数 handleTimeBurnerChanged
        调用 监听器类的 setBurnedTime 设置CPU燃烧时间 setBurnedTime
        
    函数 handlePostEffectChanged
        给当前视口增加合成器的"Bloom"效果
            CompositorManager::getSingleton().setCompositorEnabled(pViewport,"Bloom",true);
            
    函数 handleShadowsChanged
        设置阴影技术
            调用SceneManager的setShadowTechnique方法即可
                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
    函数 handleObjectChanged
        调用监听器类的 destroyCurrentGeomOpt 函数和 changSelectedMesh函数, createCurrentGeomOpt函数 实现渲染的mesh的变化
        
2. InstancingListener 类
    构造函数:
        得到GPU程序支持的句法代码, 然后遍历写入Log
            GpuProgramManager::getSingleton().getSupportedSyntax()
        初始化一些参数
            mGUIRenderer 为CEGUI的渲染器
            numMesh 表示需要渲染的mesh数量
            numRender 表示分几个批次渲染这些Mesh, 每批占一层的空间
        createCurrentGeomOpt
            该函数主要是根据当前选择的模式和Mesh, 创建了几何体(静态, 实例, 实体)
        设置鼠标键盘的回调
        得到一系列CEGUI的窗口
        隐藏原来的Overlay的调试窗口
        创建Ogre::Timer对象
            调用getMicroseconds函数并除以1000000, 得到创建以来过去的秒, 并用该值赋给 mLastTime
    
    析构函数
        调用 destroyCurrentGeomOpt 清除当前的几何体
        清除Ogre::Timer对象
    
    函数 createCurrentGeomOpt --- 该函数主要是根据当前选择的模式和Mesh, 创建了几何体(静态, 实例, 实体)
        根据需要渲染的Mesh数量, 得知这些Meshes分几个批次(每个批次最多渲染80个Mesh)
            numRender - 渲染的批次数
        根据 meshSelected 索引变量得到选择的是哪个Mesh, 通过调用MeshManager类的getByName方法得到该MeshPtr变量
            如果该MeshPtr变量为空, 则调用load方法加载
        得到该Mesh的围绕球体半径, 以便将来设置每个Mesh几何体的位置
        设置 posMatrices 容器, 该容器为每个Mesh几何体的位置信息
            首先设置该容器大小为渲染的批次数, 每个元素都为Vector3数组, 每个数组拥有numMesh个元素
            每一批的Mesh几何体都拥有相同的高度
            每一层有 numMesh/10 行
            每一行放10个Mesh几何体
        根据currentGeomOpt(即当前的模式), 调用各自的创建几何体函数
            实例几何体 - createInstanceGeom()
            静态几何体 - createStaticGeom ()
            实体几何体 - createEntityGeom ()
        
    函数 createInstanceGeom - 创建实例几何体
        首先判断是否支持实例几何体
        根据选择的mesh创建一个实体
        重置容器 renderInstance, 大小为渲染的批次数
        创建 InstancedGeometry 对象, 其参数为场景管理器(可用当前相机得到), 名称(自创)
            setCastShadows - 设置阴影
            setBatchInstanceDimensions - 设置尺寸为(1000000, 1000000, 1000000)
            设置一批渲染的mesh数, 由于有时候需要渲染的mesh少于80
            调用函数 setupInstancedMaterialToEntity
                该函数主要是用于修正实体所有子实体的材质所用的着色程序.
            该batch循环调用addEntity, 设置一个批次的batch实体内容
            调用 setOrigin 设置几何体中心
            调用 build 编译该实例几何体
            调用 addBatchInstance 增加该实例几何体所用的批次
            调用 getBatchInstanceIterator 遍历 各个批次, 每个遍历元素的类型为 InstancedGeometry::BatchInstance*
                在各个批次中调用 getObjectIterator 遍历每个对象, 每个对象的类型为 InstancedGeometry::InstancedObject*
                    然后调用setPosition设置每个元素的位置, 位置信息在posMatrices容器中设置好了
            设置该实例几何体可见, 调用setVisible
        调用场景管理器销毁刚创建的实体
        
    函数 setupInstancedMaterialToEntity
        遍历参数实体的子实体, 修改子实体的材质名称(也就是克隆原材质, 然后修改原材质的所有着色程序部分)
            setMaterialName(buildInstancedMaterial(materialName))
    函数 buildInstancedMaterial
        调用 StringUtil::endsWith方法, 来判断参数是否以"/instanced"为结尾, 是的话, 表示该材质已经修改过, 无需再创建, 直接范围该材质字符串
        后面的内容是克隆原材质, 然后修改材质中的着色语言部分, 注意, 如果原材质不存在, 则用 "Instancing" 材质
            p->setVertexProgram("Instancing", false);
            p->setShadowCasterVertexProgram("InstancingShadowCaster");
            
    函数 createStaticGeom
        1. 创建一个实体 ent
        2. 创建一个静态几何体    new StaticGeometry
        3. 设置尺寸 setRegionDimensions
        4. addEntity添加实体, 设置位置
        5. setCastShadows 设置投射阴影
        6. build构建
        7. 在renderStatic容器中保存该静态几何体
        8. 销毁实体 ent
        
    函数 createEntityGeom
        主要是创建节点, 挂接实体, 设置节点位置
        
    void destroyEntityGeom();
    void destroyStaticGeom();
    void destroyInstanceGeom();
    void destroyCurrentGeomOpt();
        各种哦国内清理函数
        注意 destroyCurrentGeomOpt 还需要清除保存的位置容器vector - posMatrices.
    
    函数 burnCPU
        在这个函数里, 不断的循环直到特定时间
        然后计算 在该函数内耗费的时间与当前距离上一次调用该函数结束的时间的百分比
        该百分比为要显示的文本内容
    
    函数 setObjectCount, setBurnedTime, changSelectedMesh, setCurrentGeometryOpt
        监听器类的公有函数, 用于CEGUI界面调用这些函数修改一些值, 实现CEGUI与OGRE程序的互动
        
    函数 mouseMoved, mousePressed, mouseReleased 
        重载这些函数, 注入CEGUI窗口中
        
    函数 requestShutdown
        设置变量 mRequestShutDown 为真, 结束程序
        
    以下几个窗口函数, 可通过CEGUI窗口的root窗口订阅鼠标事件时, 挂接为其处理函数
    函数 handleMouseMove
        如果按下左键, 旋转相机        
        
    函数 handleMouseButtonUp
        显示鼠标, 设置鼠标上次消失的位置
        
    函数 handleMouseButtonDown
        保存鼠标位置, 隐藏鼠标
        
    函数 updateStats
        更新一些窗口的变化
        

重要类和方法

Ogre
    MeshManager 类
        函数 createPlane
            // 创建一个平面
            参数:
                name - 创建出来的平面mesh的名称
                groupname - 分配给该mesh的组的名称
                plane - Plane类对象, 表示该平面的方向和距离
                width - 该平面在世界坐标系中的宽度
                height - 该平面在世界坐标系中的高度
                xsegments - 该平面在X轴方向的片段数
                ysegments - 该平面在Y轴方向的片段数
                normals  - 如果为真, 则创建垂直于平面的法线
                numTexCoordSets - 纹理坐标系的个数
                uTile - 在u轴方向纹理应当重复的次数
                vTile - 在v轴方向纹理应当重复的次数
                upVector - 平面向上的向量
                vertexBufferUsage - 用于创建的平面顶点缓存的标志
                indexBufferUsage - 用于创建的平面索引缓存的标志
                vertexShadowBuffer - 如果为真, 则在系统内存中创建关于阴影的顶点缓存, 允许你更有效的读取该数据
                ndexShadowBuffer - 如果为真, 则在系统内存中创建关于阴影的索引缓存, 允许你更有效的读取该数据
                ySegmentsToKeep - 从屋顶的顶点向下的片段数
    InstancedGeometry 类
        预先转换并批处理meshes, 以便有效的使用一个场景中的 Instanced几何体
        
    GpuProgramManager::SyntaxCodes 类型 - std::set<Ogre::String>
        使用 GpuProgramManager::getSingleton().getSupportedSyntax() 得到支持的句法
    
    Timer 类
        函数 getMicroseconds 
            表示得到自初始化或者重置以来过去的微秒数
            
    InstancedGeometry 类
        函数 setOrigin 
            设置该几何体的起点
            备注:
                这个方法允许你配置这个几何体的世界中心, 从而所有的Batchinstance围绕这个位置. 除非你有一个很大的世界, 否则你可能不需要将mess关联到该起点.
                缺省创建可以拥有一个句柄, 控制一个1024 * mBatchInstanceDimensions的区域, 并当渲染的时候没有任何的内容. 缺省为Vector3(0, 0, 0);
    
    StringUtil 类
        函数 endsWith
            用于判断字符串的尾部是否等于另一字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值