华南理工大学软件学院游戏引擎实验源码分析-其他文档类资源.docx
《华南理工大学软件学院游戏引擎实验源码分析-其他文档类资源.docx》由会员分享,可在线阅读,更多相关《华南理工大学软件学院游戏引擎实验源码分析-其他文档类资源.docx(11页珍藏版)》请在冰豆网上搜索。
实验二报告
(2018-2019学年第二学期)
3D游戏引擎架构设计基础
(Foundationsof3DGameEngineArchitectureDesign)
学生姓名
学号:
年级16级,班级:
5班
成绩:
任课教师签名:
日期:
实验题目:
目录:
1.实验内容描述:
引擎名称和版本,将分析的引擎模块名称
2.将分析的引擎模块的主要功能描述
3.将分析的引擎模块的主要类和类关系描述
4.类的数据成员和成员函数描述
5.总结
实验报告:
1.
引擎名称:
OGRE版本:
1.11.5
模块名称:
资源模块
2.
游戏资源管理主要做什么?
·资源组织
根据各种资源的特性和使用的方式等,设计资源数据的内存组织方式
·资源管理
统一的资源处理方法,如:
内存分配、资源状态管理、加载和卸载操作、资源调度算法、以及多线程管理等
游戏资源管理目的:
通过有效地组织和管理各类资源,能在合适的时候、快速地提供给游戏程序。
游戏资源管理的种类
l文件管理:
游戏的资源是以文件的形式存储的
·包括文件的加载和卸载,文件解析,格式转换,打包和传输资源文件等。
l内存管理:
使用资源时需要加载到内存
·内存分配
·访问保证
·内存释放
l状态管理:
资源当前的状态,如已定义、已加载、已移除等
l资源调度算法:
在有限的内存中,为使用资源的程序提供最好的方案
·优先队列
·LRU
l多线程处理:
资源管理的并行处理
3.
类和类关系描述
3.1主要类的关系
简单来说,他们之间的关系
Resource、ResourceManager、ResourceGroupManager这三个类是OGRE引擎进行资源管理的三个核心类,Ogre把资源分为“Font”、“GpuProgram”、“Material”、“Mesh”、“Skeleton”和“Texture”等类型,它们分别用Font、GpuProgram、Material、Mesh、Skeleton、Texture等同名的类对象来描述,这些类都直接从Resource基类派生。
Ogre的Resource对象都由ResourceManager来管理。
不同类型资源的管理,分别由不同的资源管理器来实现,比如以上各种类型资源都对应着各自的资源管理器,FontManager、GpuProgramManager、MaterialManager、MeshManager、SkeletonManager、TextureManager等,它们都以ResourceManager作为自已的基类。
各种类型资源类对象的创建、Load/Unload、销毁等操作,都由相应的ResourceManager来完成。
但Ogre的对资源的管理还不仅限于此。
为了更方便资源的使用,提高资源的使用的效率。
Ogre中有一个被称为ResourceGroupManager的类,其中内嵌了一个ResourceGroup的结构定义,很明显定义ResourceGroup只是为了ResourceGroupManager内部使用。
在需要进行3D场景展示的一般应用中,经常会遇到需要进行场景切换的时候,比如游戏中的关卡切换时,虚拟现实中角色由一个地点转换到另一个地点时等等。
而在渲染每个场景时所需的资源往往涉及了所有的资源类型,一旦场景发生切换,当前所使用的大量资源都需要被逐一卸载,而新的场景所需的各类资源要逐一被加载。
在游戏编程时,可以在自已编写的关卡管理器中处理类似工作,这明显会产生额外的工作量,更麻烦的是这部分代码逻辑可能需要在每个应用中被重复编写,而如果借助Ogre提供的ResourceGroup就可以直接方便地实现类似功能了。
Ogre处理一个资源的简单流程:
1、Ogre启动时对外部资源并不了解,通过添加资源名称、组名、文件路径等信息,录入资源信息(通常Ogre通过外面脚本定义资源路径)。
2、将一个资源归入一个资源组,并通过定义的信息,在内存中实例化相应的资源(具体的创建过程是由ResourceManager调用Resource完成的)。
4.
Undefined:
这是程序开始时,所有资源的缺省状态。
除非它们被声明,ogre对程序用到的资源一无所知,手工调用代码ResourceGroupManager:
:
declareResource()或在脚本中被解析之后,资源的状态变为Declared
Declared:
声明就是告诉ogre想要加载某些资源。
ResourceGroupManager:
:
declareResource()
总是有效的,包括在渲染系统初始之前,这与ResourceManager:
:
create()不同,因为后者依赖于渲染系统。
Unloaded:
通过调用
ResourceGroupManager:
:
initialiseAllResourceGroup(),ResourceGroupManager:
:
initialiseResourceGroup(),或Root:
:
initialise()(它会初始化在此调用之前所有声明的资源),资源状态进入到Unloaded,资源会占用一点内存来保存它的定义的实例,但是资源本身还没有加载到内存。
从另一角度看(从Loaded到Unloaded),引起状态变化的调用有:
ResourceManager:
:
unload(),ResourceManager:
:
unloadAll(),ResourceManager:
:
unloadAllUnreferencedResources(),ResourceGroupManager:
:
unloadResourceGroup(),orResource:
:
unload().所有这些调用仍会保存资源实例,但真正的资源数据会从内存中卸载。
Loaded:
这种状态下,所有数据都变得有效。
与此状态有关的调用有Resource:
:
load(),Resource:
:
reload(),ResourceManager:
:
load(),ResourceManager:
:
reload(),ResourceManager:
:
reloadAll(),ResourceManager:
:
reloadAllUnreferencedResources(),andResourceGroupManager:
:
loadResourceGroup().
lResource
该类定义了所有Ogre中可导入资源的统一接口,保存了资源的信息。
该类为抽象类
类的定义如下
///Creator
ResourceManager*mCreator;
///Uniquenameoftheresource
StringmName;
///Thenameoftheresourcegroup
StringmGroup;
///Numerichandleformoreefficientlookupthanname
ResourceHandlemHandle;
///Thesizeoftheresourceinbytes
size_tmSize;
///Optionalmanualloader;ifprovided,dataisloadedfromhereinsteadofafile
ManualResourceLoader*mLoader;
mCreator:
每个资源类都是由ResourceManager创建,该变量保留创建者的指针。
mName/mGroup/mHandle/mSize:
资源类的名称,所属的组名,句柄以及占用内存大小。
mLoader:
一般资源可以有Ogre自动导入,当需要手动进行导入时,需要设置该变量来设定手动导入操作的类,实现不同的导入操作。
mLoadingState:
资源当前状态。
AtomicScalar是一个封装原子操作的模板类,这个为多线程资源管理提供了可能。
资源状态LoadingState枚举如下
enumLoadingState
{
///Notloaded
LOADSTATE_UNLOADED,
///Loadingisinprogress
LOADSTATE_LOADING,
///Fullyloaded
LOADSTATE_LOADED,
///Currentlyunloading
LOADSTATE_UNLOADING,
///Fullyprepared
LOADSTATE_PREPARED,
///Preparingisinprogress
LOADSTATE_PREPARING
};
从上述枚举中可以看出,一个资源有两个非常重要的状态:
load和prepare。
Resource类中的函数基本也就是围绕着这两个状态改变而进行的。
virtualvoidpreLoadImpl(void){}
virtualvoidpostLoadImpl(void){}
virtualvoidpreUnloadImpl(void){}
virtualvoidpostUnloadImpl(void){}
virtualvoidprepareImpl(void){}
virtualvoidunprepareImpl(void){}
virtualvoidloadImpl(void)=0;
virtualvoidunloadImpl(void)=0;
可以看出这些函数的作用就是定义load和prepare前、中。
后需要进行的操作。
这里用到了设计模式的Template模板,定义接口,将所有实现都延迟到了子类中。
同时Resource也提供了更细颗粒度的方法来控制load和prepare过程——监听。
Resource定义了公共内嵌类Listener,可以通过继承该监听类回调函数,灵活地设置资源状态改变时的操作。
引用Resource时,使用的是智能指针。
typedefSharedPtrResourcePtr;
在ResourceManager中都是以这样的形式出现的。
lResourceManager
Resource类是负责具体资源的load和prepare细节,而ResourceManager类是负责创建、删除和调用Resource的,并管理ResourcePool方便同一资源的多次使用。
该类的主要数据结构定义如下:
typedefHashMapResourceMap;
typedefHashMapResourceWithGroupMap;
typedefmap:
:
typeResourceHandleMap;
ResourceMap将资源名称与资源一一对应起来。
ResourceWithGroupMap则是将资源进行一定分组管理。
ResourceHandleMap则是将资源句柄与资源对应。
lResourceGroupManager
如果说ResourceManger是对Resource的管理,那ResourceGroupManager就是对ResourceManger的集中管理。
刚才提到过ResourceManager中将资源进行了分组管理,ResourceGroupManager就针对这每个分组进行了管理。