XNA中, ResourcePool枚举类型由MDX中的4个改为了2个, 分别是Automatic和Manual, 枚举名称也改为了ResourceManagmentMode。其中Automatic对应mdx中的Managed,Manual对应Default。
以Manual方式创建的资源被储存在video memory或AGP memory中。而Automatic类型的资源则储存在系统内存中,在需要使用的时候自动复制到显存里,默认情况下,xna中的资源都储存为Automatic方式。两者的区别在于由于Manual类资源分配在显存中,因此,每当重置设备之后,显存中的这些数据都会丢失,因此需要手动重新加载;由于重置并不会改变device的属性,所以储存在系统内存中的资源仍然是可用的,xna会自动管理这些资源。这里,会引起重置设备的操作通常包括改变窗口大小,最小化窗口,在窗口和全屏模式直接切换。以Manual方式创建的资源通常有更好的性能,xna会把这些资源放到最利于device访问的位置,但如果需要频繁重置设备,那么就必须反复加载这些资源。当然,对于xbox来说,重置设备的情况发生的比较少。按照xna team的建议,应该尽可能使用Automatic方式来创建资源。
在编写程序时,应该把创建Automatic和Manual资源的代码分开:
LoadAutomaticResource();
LoadManualResource();
在DeviceCreate事件触发时,应该同时调用这2个方法:
{
LoadAutomaticResource();
LoadManualResource();
}
graphicsDevice.reset += new System.EventHandler(OnDeviceReset)
而在Reset事件触发时,只需调用LoadManualResource()方法。
在XNA游戏框架中,不需要直接连接事件处理代码,Game类的LoadGraphicsContent方法简化了这个过程。
在创建和重置设备时,会自动调用LoadGraphicsContent方法,并且根据loadAllContent标志来选择创建哪些代码,所以我们只要把加载资源的代码放到适当位置:
{
if (loadAllContent)
{
// TODO: Load any ResourceManagementMode.Automatic content
// TODO: Load any ResourceManagementMode.Manual content
}
此外,对于用Content PipeLine加载的资源来说,不需要对这些资源编写dispose方法。Content PipeLine会为我们管理这些资源,在需要释放这些资源时只需要调用UnLoad()方法就可以了。
content.Load<model>(“house”);
// do something with terrain and house
content.UnLoad();
Content PipeLine在编译期间会对所加载的资源进行预处理,所有资源文件(比如.jpg,.fbx,.x,.tga)都被重新打包为.xnb作为后缀名的二进制文件。对于加载模型来说,不需要显示加载所需纹理,Content PipeLine会自动加载所需纹理,但需要保证这些纹理和模型文件在同一目录下,或其他Content PipeLine能找到的地方。加载模型时,如果不同模型使用了同一个纹理,那么这张纹理只会被加载一次。假设我们为使用Content PipeLine创建的资源编写了dispose方法,那么对于使用了同一张纹理的不同模型来说,dispose其中一个模型,将带来一些问题。
注意,一个程序中可以创建多个Content PipeLine对象,比如我们可以为每个关卡创建一个,这样我们就能在创建新关卡时加载所有资源,而在离开时保证清理了所有资源。
总的来说,xna大大简化了加载和管理资源的难度,让我们可以把更多注意力放到游戏性上^^
- 本文固定链接: http://www.wy182000.com/2009/02/15/在xna中管理资源/
- 转载请注明: wy182000 于 Studio 发表