OGRE 浅析 耿卫东 陈为.

Slides:



Advertisements
Similar presentations
7.1 内置对象概述及分类 JSP 视频教学课程. JSP2.2 目录 1. 内置对象简介 1. 内置对象简介 2. 内置对象分类 2. 内置对象分类 3. 内置对象按功能区分 3. 内置对象按功能区分 4. 内置对象作用范围 4. 内置对象作用范围.
Advertisements

面向侧面的程序设计 方林博士 本文下载地址:
LSF系统介绍 张焕杰 中国科学技术大学网络信息中心
第三章 数据类型和数据操作 对海量数据进行有效的处理、存储和管理 3.1 数据类型 数据源 数据量 数据结构
基于解释性语言的手机跨平台架构 Sloan Yi. Qt MTK.
Oracle数据库 Oracle 子程序.
第14章 c++中的代码重用.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
在PHP和MYSQL中实现完美的中文显示
陈香兰 助教:陈博、李春华 Spring 2009 嵌入式操作系统 陈香兰 助教:陈博、李春华 Spring 2009.
Kvm异步缺页中断 浙江大学计算机体系结构实验室 徐浩.
LSF系统介绍 张焕杰 中国科学技术大学网络信息中心
Hadoop I/O By ShiChaojie.
第二讲 搭建Java Web开发环境 主讲人:孙娜
学习前的准备工作 讲师:burning.
第八章 菜单设计 §8.1 Visual FoxPro 系统菜单 §8.2 为自己的程序添加菜单 §8.3 创建快捷菜单.
SVN服务器的搭建(Windows) 柳峰
走进编程 程序的顺序结构(二).
辅导课程六.
网络常用常用命令 课件制作人:谢希仁.
第11章:一些著名开源软件介绍 第12章:服务安装和配置 本章教学目标: 了解当前一些应用最广泛的开源软件项目 搭建一个网站服务器
DM81X 视频采集处理 ——简单采集显示例程讲解 广州创龙电子科技有限公司
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
以ISI平台为例,为您演示一下如何在Endnote文献中查看该文献的References
PaPaPa项目架构 By:Listen 我在这.
泛型委托 泛型接口、方法和委托.
中国科学技术大学计算机系 陈香兰(0551- ) Spring 2009
Windows 7 的系统设置.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
Gzip编译及调试 曹益华
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
程序设计工具实习 Software Program Tool
SOA – Experiment 2: Query Classification Web Service
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
内容摘要 ■ 课程概述 ■ 教学安排 ■ 什么是操作系统? ■ 为什么学习操作系统? ■ 如何学习操作系统? ■ 操作系统实例
C语言程序设计 主讲教师:陆幼利.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
第四章 团队音乐会序幕: 团队协作平台的快速创建
第1章 c++概述 1.1 C++语言的简史及特点 1.2 简单的C++程序 1.3 C++语言的基本组成
VisComposer 2019/4/17.
Platform Builder使用介绍 WINCE系统应用开发流程说明 ACTION RDC 杨 涛 2005.Dec.3th
姚金宇 MIT SCHEME 使用说明 姚金宇
分裂对象模型 C++ otcl.
实验七 安全FTP服务器实验 2019/4/28.
本节内容 Win32 API中的宽字符 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
JSP实用教程 清华大学出版社 第2章 JSP运行环境和开发环境 教学目标 教学重点 教学过程 2019年5月7日.
iSIGHT 基本培训 使用 Excel的栅栏问题
LOGIX500软件入门 西安华光信息技术有限公司 2008年7月11日.
Chapter 18 使用GRASP的对象设计示例.
Visual Basic程序设计 第13章 访问数据库
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
魏新宇 MATLAB/Simulink 与控制系统仿真 魏新宇
VRP教程 2011.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第9章 多媒体技术 掌握 Windows 画图工具的基本操作; 掌握 Windows 音频工具进行音频播放;
Python 环境搭建 基于Anaconda和VSCode.
本节内容 Windows线程切换_时钟中断切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
MFC的六大核心 机制 命令传递 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang
基于列存储的RDF数据管理 朱敏
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
本节内容 如何调试驱动程序? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
本节内容 进程 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
FVX1100介绍 法视特(上海)图像科技有限公司 施 俊.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
百万行、千万行数据查询教程 老黄牛.
Presentation transcript:

OGRE 浅析 耿卫东 陈为

网上资源 http://sourceforge.net/projects/ogre/ http://www.ogre3d.org/(官方网站)

教学中文资料 OGRE_01a.doc: 从使用者的角度将 OGRE引擎最基本的概念和使用方法做 一个较全面的介绍。隐藏了OGRE引擎 内部的底层内容,力求做到简单、易懂, 是OGRE引擎的入门教程。By Marg小组 Loneststarreading.doc OGRE浅析:by 邹林灿 OGRE中文系列分析:by 盛崇山

OGRE LOGO

本次课程的主要内容 OGRE简介 OGRE的安装 如何用OGRE来进行应用程序的开发

OGRE简介 OGRE: Object-Oriented Graphics Rendering Engine (面向对象的图形渲染引擎) C++开发面向对象且使用灵活的3D引擎。 目的:让开发者方便和直接开发基于3D硬件 设备的应用程序或游戏。 引擎中的类库对更底层的系统库(如: Direct3D和OpenGL)的细节进行了抽象,并 提供了基于现实世界对象的接口和其它类。

OGRE简介 这部分主要介绍: OGRE特点 OGRE中的模块

OGRE特点 效率特性 简单、易用的面向对象接口设计能更容易 渲染3D场景,并使实现产品独立于渲染API (如Direct3D/OpenGL/Glide等)。 可扩展的程序框架(framework) 自动处理常见的需求,如渲染状态管理, hierarchical culling,半透物体排序等。 清晰、整洁的设计加上全面的文档支持。

OGRE特点 平台和3D API支持 支持Direct3D和OpenGL 支持Windows平台,用Visual C++ 6(或Visual C++.Net)和STLport来 编译。 支持Linux平台,用gcc 3+(或gcc 2.9x)和STLport来编译。 材质/Shader支持 支持从PNG、JPEG或TGA这几种文件中加载纹理;自动产生MipMap; 自动调整纹理大小以满足硬件需求。 支持可程序控制的纹理坐标生成(如环境帖图)和转换(平移、扭曲、 旋转)。 材质可以拥有足够多的纹理层,每层纹理支持各种渲染特效,支持动 画纹理。 自动应用多通道渲染和多纹理,从而大幅度提高渲染质量。 支持透明物体和其它场景级别的渲染特效。 通过脚本语言可以不用重新编译就设置和更改高级的材质属性。

OGRE特点 网格Meshes 高效的网格数据格式 提供插件支持从Milkshape3D导出OGRE本 身的.mesh和.skeleton文件格式。 支持骨骼动画(可渲染多个动画的组合) 支持用Bezier样条实现的曲面

OGRE特点 场景特性 拥有高效率和高度可配置性的资源管理器,并支持多 种场景类型。使用系统默认的场景组织方法,或通过 亲自编写插件使用自己的场景组织方法。 通过包围体(如包围盒)实现视域裁剪。 提供的二叉树场景管理器插件可加速室内场景的渲染, 支持加载Quake3关卡和shader脚本分析。 优秀的场景组织体系;场景结点支持物体的附属 (attach),并带动附属物体一起运动,实现了类似于 关节的运动继承体系。

OGRE特点 特效 粒子系统包括可以通过编写插件来扩展的 粒子发射器(emitter)和粒子特效影响器 (affector)。通过脚本语言可以不用重新 编译就设置和更改粒子属性。支持并自动 管理粒子池,从而提升粒子系统的性能。 支持天空盒、天空面和天空圆顶,使用非 常简单。 支持Billboard,以实现特效。 自动管理透明物体(系统自动帮你设置渲 染顺序和深度缓冲)

OGRE特点 其它特性 资源管理和文档加载(ZIP、PK3)。 支持高效的插件体系结构,它允许你不重 新编译就扩展引擎的功能。 运用'Controllers'你可以方便地改变一个数 值。例如动态改变一个带防护罩的飞船的 颜色值。 调试用的内存管理器负责检查内存溢出。

OGRE中的模块 OGRE中由很多模块组成,每个模块互相配合, 共同实现OGRE的强大功能和优秀特性。OGRE 的模块大致可表现为如下结构,这也基本上是 OGRE工程文件的结构: OgreMain PlatformManagers Plugins RenderSystems Tools

OgreMain模块 场景组织体系 Material管理 插件动态加载系统 数学支持库 渲染器和几何管道 网格/几何实体管理 资源管理 天空/背景渲染 公告板系统和粒子系统 日志和异常处理 事件监听器 编解码器和图像加载器 自定义内存管理器 基本动画 骨骼动画 字体渲染/字体加载 覆盖(Overlay)表面,二维元素 相关类 Node, SceneNode, SceneManager, Camera, MovableObject MaterialManager, Material, Material::TextureLayer Root, DynLibManager, DynLib Math, Vector3, Matrix3, Matrix4, Quaternion RenderSystem, RenderQueue, Renderable MeshManager, Mesh, SubMesh, MeshSerializer, PatchSurface ResourceManager, Resource, ArchiveManager, ArchiveEx SceneManager BillboardSet, Billboard, ParticleSystemManager, ParticleSystem, ParticleEmitter, ParticleAffector Exception, LogManager, Log FrameListener, RenderTargetListener Codec, JPGCodec, TGACodec, PNGCodec MemoryManager Animation, AnimationTrack, KeyFrame Skeleton, Bone, Animation, AnimationTrack, KeyFrame FontManager, Font Overlaymanager, Overlay, GuiElement, GuiContainer

Win32平台管理模块 实现了Windows平台的基本平台服务。 特性 输入管理 配置系统 相关类 Win32Input Win32ConfigDialog

BSP场景管理 该插件用BSP树和clusters提供了室内场景 的管理。它可以导入Quake3的关卡。 特性 BSP树 关卡导入 Shader支持

其它模块 文件系统插件 GuiElement插件 OctreeSceneManager插件 提供在文件系统的文件夹中定位资源的能 力。 提供标准的二维表面元素,如文本输入区 和边框。 OctreeSceneManager插件 用八叉树管理标准场景。可用它渲染地形。

其它模块 ParticleFX插件 Direct3D7渲染系统插件 Direct3D9渲染系统插件 此插件提供了标准的粒子发射器和粒子特 效影响器。 Direct3D7渲染系统插件 此插件提供了基于Direct3D7的渲染系统。 Direct3D9渲染系统插件 此插件提供了基于Direct3D9的渲染系统。

其它模块 SDL渲染系统插件 3ds2oof工具 3Dstudio Max导出器 此插件提供了基于OpenGL和SDL的渲染系统。 这个工具可以将3D Studio的网络文件(.3ds)转换 成.oof格式(OGRE以前的网络文件格式)。 这个工具已经被抛弃了。 3Dstudio Max导出器 这是一个3D Studio MAX(版本4或5)的插件,可以将3D Studio的模型数据转换成OGRE的.mesh或.skeleton格式。

其它模块 位图字体创建工具 Milkshape3D导出器 Python接口 能过此工具你可以把二进制字体文件转换成OGRE 的.fontdef文件。 Milkshape3D导出器 这个工具是Milkshape3D(一个建模工具)的插件,它 允许你将模式导出成OGRE支持的.mesh和.skeleton文件 格式。 Python接口 设计这个子工程的目的是以dll的形式提供一个接口, 使Python(一种脚本语言)可以直接驱动OGRE,并且 允许OGRE直接调用Python脚本以实现游戏相关的脚本 语言。

安装OGRE 这部分主要介绍 获取OGRE 支撑环境 编译OGRE 运行DEMO OGRE运行期结构

获取OGRE OGRE是一个开放源码项目,该项目的 网址是ogre.sourceforge.net。在这里可 以获取到OGRE的最新版本和文档,此 外还可以在论坛上与其它开发者交流。

支撑环境 OGRE是一个比较大的项目,不可能每 个功能都独立完成。OGRE的编译和使 用需要一些其它库作为支撑环境。在 Windows环境下编译和安装OGRE需要 如下支撑环境: STLport4.5.3 DirectX 9 SDK 其它第三方库

编译OGRE 在VC6环境里打开OGREOGRE的最新版本的 ogrenew文件夹下的Ogre.dsw工作区文件,执行 Batch Build指令,该指令会自动处理OGRE中各 个工程的依赖关系,正确完成全部的编译构建。 在VC7环境里打开OGREOGRE的最新版本的 ogrenews文件夹下的Ogre.sln工作区文件,执行 Batch Build指令,该指令会自动处理OGRE中各 个工程的依赖关系,正确完成全部的编译构建。

运行DEMO 在ogrenew\Samples\Common\bin\ Debug下可以看到Debug方式编译的全 部DEMO。

OGRE运行期结构 运行完DEMO之后,注意查看 ogrenew\Samples\Common\bin\Debug文 件夹中的内容,从这里可以看到OGRE 程序的运行环境。 除了DEMO的可执行文件外,该文件夹 中还包括如下的动态链接库:

OGRE运行期结构 OgreMain.dll OgrePlatform.dll RenderSystem_Direct3D7.dll RenderSystem_SDL.dll Plugin_GuiElements.dll Plugin_BspSceneManager.dll Plugin_OctreeSceneManager.dll Plugin_FileSystem.dll Plugin_ParticleFX.dll Devil.dll SDL.dll 其它:机器上还必须包括DirectX 8.1和STLport的动态链接库, 一般系统会将它们自动安装到Windows系统文件夹下。

OGRE运行期结构 OGRE的运行还需要如下的配置文件: ogre.cfg:OGRE的显示模式配置文件 Plugins.cfg:插件配置文件,在这里指定插 件的路径和插件文件名。上一个表中以 Plugin_开头的dll文件都是插件,它们可以 放在其它文件夹里,但必须在本文件里指 定路径。 resources.cfg:资源配置文件,设置资源搜索 路径,Zip文件也作为搜索路径对待。 quake3settings.cfg:quake3地图配置文件。 terrain.cfg:室外地形场景配置文件。

OGRE运行期结构 OGRE程序的资源路径在resources.cfg里指定。 OGRE DEMO的资源都放在 \ogrenew\Samples\Media及其下的Zip文件里。资 源文件包括以下内容: .skeleton骨骼动画的骨骼定义文件 .particle粒子模板定义文件 .overlay二维及三维界面定义文件.mesh模型文件 .material材质定义文件 .fontdef字体定义文件 .jpg图片文件 .png图片文件

准备用OGRE开发 从FrameWork开始 第一个3D程序 FrameWork与实际应用程序的关系 ExampleApplication类 ExampleFrameListener类 第一个3D程序

FrameWork 假设以Demo_EnvMapping工程为例,观察一下OGRE 的Demo程序的代码结构,可以发现在本工程中其实只 有两个文件:EnvMapping.h和EnvMapping.cpp。 查看本工程的Settings,在C/C++选项卡中打开 PreProcessor分类,可以看到有三个附加包含路径,其 中..\include是本工程的头文件路 径,..\..\Common\include是Demo程序公共的头文件路 径,..\..\..\OgreMain\include是OGRE引擎的头文件路径。 在..\..\Common\include中可以发现两个头文件: ExampleApplication.h和ExampleFrameListener.h。这两 个文件定义了简单OGRE程序的应用框架,它们封装了 简单OGRE程序的基本要素和运行过程。

FrameWork与实际应用程序的关系 在创建我们自己的OGRE程序时,只需要继承OGRE FrameWork中的类并做少量改动就可以了。OGRE FrameWork与实际应用的关系如下图所示:

ExampleApplication类 该类定义了如下数据成员: // 指向Root对象的指针 Root *mRoot; // 指向程序中摄像机的指针 Camera* mCamera; // 指向场景管理器的指针 SceneManager* mSceneMgr; // 指向“帧监听器”的指针 FrameListener* mFrameListener; // 指向渲染窗口的指针 RenderWindow* mWindow;

Root:OGRE系统的入口点 Root对象在程序中必须最先创建和最后释放。 OGRE引擎是通过Root将其它部分“串”起来 的,通过Root对象可以调出配置对话框以配置 渲染系统(RenderSystem); 通过Root对象可以获取到引擎其它部分的指针, 如SceneManager、RenderSystem、Resource managers等; Root对象还提供一个startRendering方法来开始 一个连续渲染过程,对该方法的调用在 ExampleApplication类中就可以见到。

Camera:摄象机 渲染结果实际上就是摄象机最后“看” 到的结果。

SceneManager:场景管理器 普通场景、室外封闭场景、室外无限场景和室内场景: enum SceneType { ST_GENERIC, ST_EXTERIOR_CLOSE, ST_EXTERIOR_FAR, ST_INTERIOR }; 室内场景采用BSP场景管理方式,室外场景采用八叉树场 景管理方式。初学者使用ST_GENERIC普通场景类型。 对于复杂室内和室外场景,OGRE分两部分:基本上固定 不变的“世界”,对于这部分采用BSP或Octree等特殊算 法提高渲染效率;场景中的可移动物体,它们的创建和控 制需要开发人员自己来完成。

FrameListener:帧监听器 监听最终用户的控制信息(鼠标、键盘、 遥控杆等),对摄象机、场景物体等进 行控制.

RenderWindow:渲染窗口 渲染结果所在的窗口,其中包括渲染真 正的目的地:视口Viewport。

启动 OGRE //继承自 ExampleApplication 类 EnvMapApplication app; try { app.go(); } catch( Exception& e ) { …… 以Demo_EnvMapping 工程为例,工程中有两个文件,EnvMapping.h和EnvMapping.cpp。EnvMapping.h 中定义了一个派生自ExampleApplication 类的EnvMapApplication类。在后来的代码分析中可以看出,ExampleApplication 类封装了简单OGRE程序的基本要素和运行过程。而EnvMapApplication所要做的就是override ExampleApplication 类的createScene函数,然后调用go函数,整个程序就运行起来了。 从这个DEMO可以发现,利用OGRE写一个DEMO是很简单的一件事情,程序员无需接触底层的渲染系统,不用关心用OpenGL 还是 Direct3D。

启动 OGRE // 启动引擎 virtual void go(void) { if (!setup()) return; mRoot->startRendering(); } go函数很简单,调用setup函数来初始化OGRE内部的各个组件,如果函数调用成功,即OGRE初始化成功,则整个OGRE开始工作。 调用mRoot成员的startRendering方法。

go函数 virtual void go(void): 该函数是ExampleApplication类除构造和析构函数以外唯 一的public函数,它一调用,程序就正式开始运行了。代 码如下: virtual void go(void) { if (!setup()) return; mRoot->startRendering(); } 从代码可以看出,先调用setup( )函数完成渲染前的准备, 如果setup成功,就由mRoot调用startRendering()开始渲染, 如果不成功则退出。

setup函数 Setup函数完成一个OGRE应用程序的开始渲染前 的准备工作。实际步骤如下: 首先创建Root类的对象。 加载资源路径setupResources(void ) 弹出config对话框,配置RenderSystem 选择场景管理器类型 创建并初始化摄像机 创建窗口中的视口 创建场景 创建帧监听器

setup函数代码 步骤的代码如下: virtual bool setup(void) { mRoot = new Root(); //首先创建Root类的对象。 setupResources(); //加载资源路径 bool carryOn = configure(); //弹出config对话框,配置RenderSystem if (!carryOn) return false; chooseSceneManager(); //选择场景管理器类型 createCamera(); //创建并初始化摄像机 createViewports(); //创建窗口中的视口 // Set default mipmap level (NB some APIs ignore this) TextureManager::getSingleton().setDefaultNumMipMaps(5); createScene(); //创建场景 createFrameListener(); //创建帧监听器 return true; }

setup函数 至此,setup()函数结束,它已完成 渲染之前的全部准备工作,接下来就由 Root对象调用startRendering()函数指 挥渲染系统开始连续的渲染过程。

OGRE 消息处理机制 消息机制的设计一般总要设计到三个部分:消息的 产生、消息的传递和消息的处理。 OGRE中的消息处理者的抽象类主要是listener类,而 listener必须是对应特定的target的,所以可以认为是 由listener和target两个抽象类组成。而消息传递由 Dispatcher和Processor组成。

FrameListener FrameListener类中有两个很重要的虚函数。 frameStarted和frameEnded。 class _OgreExport FrameListener { public: // 帧渲染之前的事件处理方法 virtual bool frameStarted(const FrameEvent& evt) { return true; } // 帧渲染之后的事件处理方法 virtual bool frameEnded(const FrameEvent& evt) { return true; } virtual ~FrameListener() {} } 以FrameListener为例 OGRE初始化的最后一步就是创建一个FrameListener。 OGRE在渲染每帧前会自动调用frameStarted,每帧结束后自动调用frameEnded。mFrameListener就是一个继承自FrameListener的ExampleFrameListener的实例指针,这样,mFrameListener只要实现这两个虚函数,就可以在每帧前后加入需要的控制操作。 值得一提的是,frameStarted和frameEnded函数的参数是FrameEvent类型。 FrameEvent类中定义了两个变量 timeSinceLastEvent 和 timeSinceLastFrame。这两个变量记录了两个帧之间间隔的一些时间参数。

ExampleFrameListener ExampleFrameListener继承自FrameListener。 它包装实现了一个帧监听器常用的功能。 OGRE对事件的处理方法有两种模式,立即 模式和缓冲模式。 ExampleFrameListener中有一个 mEventProcessor变量,它是用来处理缓冲模 式的事件的。 而在默认的非缓冲模式中, ExampleFrameListener实现了基本输入操作。 如:键盘WASD控制视点前后左右移动,鼠 标控制视点的旋转等等。 一般来讲立即模式适合于3D场景漫游过程,当在每帧渲染之前,系统捕获输入设备状态,并根据这些状态对场景中的物体和摄象机进行控制。而缓冲模式适合于GUI界面的情况(如设置菜单),输入设备状态可以被发送到各GUI元素进行处理(如按钮被按下)。 在实际运用中,可以从ExampleFrameListener中派生自己的myFrameListener类,重新实现frameStarted函数,以实现更复杂的功能,如让3D物体运动等等。当然最后不要忘了调用基类ExampleFrameListener中的frameStarted函数。否则,基本的键盘鼠标控制就没了。 非缓冲模式下的按键处理,相当于查询操作,每次都查看一下有无相应的键按下,并没有利用到OGRE中的消息处理机制。 分析一下缓冲模式下的消息处理机制。

EventProcessor EventProcessor类继承了FrameListener类, OGRE引擎自动在每帧前调用EventProcessor 的frameStarted函数。 EventProcessor类还继承了KeyTarget, MouseTarget,MouseMotionTarget。作为消息 传送目标的EventProcessor ,因此才有可能处 理这些消息。 缓冲模式下,OGRE把缓冲模式下的消息处理交给了EventProcessor类。 KeyTarget又继承自EventTarget。

键盘消息处理机制 Event Listener isMulticaster KeyXX(KeyEvent)=0 InputEvent EventTarget* mSource KeyEvent int mKey Event EventTarget virtual processKeyEvent()=0 KeyTarget processKeyEvent() add/remove KeyListener KeyListener Target Listener OGRE中有关键盘消息处理的有以下三个主要的类,EventTarget, EventListener, InputEvent. 如图: 可以看到EventListener类能过调用EventTarget的add/remove KeyListener可以注册到EventTarget上,当有消息到达时,EventTarget负责调用相应EventListener的处理函数。同时,消息本身被封装成InputEvent类。

EventProcessor的设置 //创建一个EventProcessor mEventProcessor = new EventProcessor(); //初始化 mEventProcessor->initialise(win); //开始处理消息 mEventProcessor->startProcessingEvents(); //将ExampleFrameListener作为按键消息的监听者注册 mEventProcessor->addKeyListener(this); 现在回到ExampleFrameListener在缓冲模式中的初始化情况。 在initialise中做了以下几个事情: cleanup()。清除mEventQueue, mdispatchList, mInputDevice等。 创建新的mEventQueue 创建新的mInputDevice. mEventQuue = InputDevice中的mEventQueue。 在startProcessingEvents中做了以下的事情: addFrameListener(this)。这个this指的是EventProcessor。这就是在OGRE中将EventProcessor注册为一个FrameListener。 在addKeyListener(this)这个this指的是ExampleFrameListener。因为mEventProcessor继承了KeyTarget。所以可以调用addKeyListener。这时候ExampleFrameListener就被当成是一个KeyListener了。因此,ExampleFrameListener必须声明或实现KeyListener中的一些函数,如keyClicked, keyPressed, keyReleased。 这时候EventProcess就初始化结束了,OGRE会在每帧的开始的时候调用EventProcess的frameStarted(evt)函数。

EventProcessor的运行 bool EventProcessor::frameStarted(const FrameEvent& evt) { mInputDevice->capture(); while (mEventQueue->getSize() > 0) InputEvent* e = mEventQueue->pop(); processEvent(e); delete e; } return true; 看一下EventProcess中的frameStarted函数,可以了解到实际中EventProcess是如何捕捉到消息输入并作出处理的。 如果有键盘消息的话, capture函数会产生键盘事件,保存在事件队列 mEventQueue中。 processEvent(e) 先遍历event dispatcher list, 处理这个事件。 如果事件没有被处理,遍历event target list 来处理这个事件。 最后手工判别消息的类别,再调用processXXXEvent(e),这些函数是EventProcessor父类XXXTarget中的函数。它们会调用注册在其上面的XXXListener中相应的处理函数。 OGRE中的键盘处理的过程就是如此。其它的消息处理机制与此类似。

第一个3D程序 OGRE的应用框架中定义好了 ExampleApplication与 ExampleFrameListener类,已封装了3D 应用程序的全部要素,应用开发者所要 做的工作主要有2点: 派生出自己的应用程序类,重新实现 createScene函数以创建场景。 派生出自己的监听器类,如果需要的话, 重新实现frameStarted函数以进行特殊的输 入控制和动画控制。

第一个3D程序 打开Demo_EnvMapping工程,这是一 个非常简单易懂的程序实例。 这个程序只有两个文件EnvMapping.h和 EnvMapping.cpp。 EnvMapping.h文件定义了 ExampleApplication类的派生类 EnvMapApplication,并重新实现了 createScene函数创建出一个亮闪闪的具 有环境帖图的食人魔头像。

class EnvMapApplication : public ExampleApplication { public: EnvMapApplication() {} protected: // 重新实现createScene函数,创建实际场景 void createScene(void) // 设置环境光 mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // 创建点光源l Light* l = mSceneMgr->createLight("MainLight"); // 设置点光源l的位置,缺省颜色为白色 l->setPosition(20,80,50); // 读入ogrehead.mesh模型文件,创建为一个Entity。 Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh"); // 设置食人魔Entity的材质为指定材质(环境贴图) ent->setMaterialName("Examples/EnvMappedRustySteel"); // 将食人魔Entity连接到场景根节点上。 mSceneMgr->getRootSceneNode()->createChild()->attachObject(ent); } };

第一个3D程序 一个基本的场景包括光、摄象机和模型等。 ExampleApplication类中创建了缺省摄象机(见 FrameWork部分)。 每个模型文件载入后被创建成Entity。为了便于 对场景的管理,OGRE引入了场景节点的概念, 所有场景节点组合成一棵节点树,全部Entity挂 在这棵节点树中的不同节点上。场景管理器 mSceneMgr通过对节点树的操控来完成对场景物 体的操控。 场景建立好之后,接下来处理应用程序的入口问 题,这部分代码在EnvMapping.cpp里.

EnvMapping程序

课后工作 安装OGRE 熟悉OGRE的变换和光照部分 熟悉OGRE的文件格式和场景管理模式 预习OGRE中的纹理映射