Xna内容管道及Xnb格式解析

来源:互联网 发布:bt网站推荐 知乎 编辑:程序博客网 时间:2024/05/04 01:42

前言:

内容管道的设计十分超前,乃至于至今看来都还算是一个比较新颖的资源处理方式。

本章将深入讲解内容管道的作用及Xnb格式分析。


本章主要内容有:

        1.Xna简介

        2.内容管道简介

        3.内容管道默认支持表

        4.内容管道处理流程

        5.Xnb格式解析




1.什么是Xna?

Xna是基于DirectX的游戏开发环境,是微软对于Managed DirectX的修正及扩充版本。

Xna可以跨平台运行于Windows、Zune、WindowsPhone以及Xbox360上。

2004年在GDC被公布,直至2006年才开放给开发者使用。

最后版本为Xna4.0,于2012年发布。



2.什么是内容管道(ContentPipeline)?

我们以前做游戏时总会遇到资源加载的问题。

众多格式的支持、特殊格式的解析等。

内容管道简而言之就是将所有格式统一处理,生成统一格式的东西。

换言之,就是将格式分类,然后将这些类别不同格式的内容统一处理为一种格式,然后将之保存。

这样做的好处在于,运行时只需要解析一种格式,而这种格式可以不需要太复杂的处理即可。

即减少了IO操作,又加快了运行时速度。

这就是内容管道的作用了。




3.内容管道默认支持表

类型导入器处理器格式图像TextureImporterTextureProcessor所有能被.Net Framework或DirectX支持的图像格式模型XImporter
FbxImporterModelProcessorx
fbx音乐Mp3Importer
WmaImporterSongProcessormp3
wma音效WavImporterSongEffectProcessorwav字体FontDescriptionImporterFontTextureProcessorspritefontShaderEffectImporterEffectProcessorfx数据XmlImporter无xml





4.内容管道处理流程

本节我们将以图像为例,简述内容管道的处理及使用。

假设我们有一张图片1.jpg。

编译阶段:

       1.TextureImporter将1.jpg解压并读取为原始像素数据。

       2.TextureProcessor将原始像素数据包装成Texture2D对象。

       3.通过ContentWriter写入平台附加数据并将二进制序列化后的Texture2D对象写入到文件中。

       4.输出1.xnb文件,编译完成。


游戏运行阶段:

       1.通过ContentReader读取1.xnb文件内的平台数据及反序列化后的Texture2D对象。

       2.程序直接调用Texture2D对象内的原始像素数据,完成图像展示。


从以上流程可以看出,复杂及密集的解压缩、解析过程全部在编译阶段就完成了。

游戏运行阶段只需要简单的读取统一的xnb格式并直接反序列化即可读取数据。

因此得到了加载优化的效果。




5.Xnb格式解析

在第4节中我们提到了ContentWriter、ContentReader及xnb格式。

在本节中,我们将深入讲解Xnb格式的组成。

因为Xna4.0是最后版本,也是使用最为广泛的一个版本,因此我们仅对此版本的Xnb格式进行解析。


首先,Xnb格式前3位Byte值以 'XNB' (没有单引号)作为文件标识头。


紧接着第4位Byte有3个可能的值,代表了文件应用于的平台(不同平台文件内容有少许区别),分别是:

'w' = Windows平台

'm' = WindowsPhone

'x' = Xbox360


第5位Byte代表了Xna格式版本,从1到5分别代表了:

1 = Xna1.0

2 = Xna2.0

3 = Xna3.0

4 = Xna3.1

5 = Xna4.0

这里我们假设值永远为5。


第6位Byte值代表了内容表示方式,分别为:

0x00 = 未压缩,使用Reach配置

0x01 = 未压缩,使用HiDef配置

0x80 = 使用LZX压缩,使用Reach配置

0x81 = 使用LZX压缩,使用HiDef配置


第7位-第10位是一个UInt32值,代表了文件总大小(磁盘真实存储大小),但有如下内容需要注意:

若使用了压缩,此值为压缩后的大小加上所有文件头内容的大小。


(以下内容为分支内容,根据第6位表示是否压缩进行分支,红色表示压缩,蓝色表示未压缩)


第11位-第14位是一个UInt32值,代表了未压缩的文件总大小。


第15位第12位是一个7Bit编码Int值(7BitEncodedInt),代表了类型读取器(Type reader)数量。


根据类型读取器数量进行循环。

循环顺序读取内容如下:

String值,代表了类型读取器名称(Type reader name)

Int32值,代表了类型读取器版本,通常是0。


循环完毕后紧跟着读取一个 7BitEncodedInt,代表共享资源数量。


然后读取原始资源数据,这里就是具体的反序列化内容了,加入第4节中就用了Texture2D作为例子。


原始资源数据读取完毕后,开始循环读取共享资源内容,这里是原始资源数据中所需要的公共内容。

循环内容根据原始资源数据而定。


共享资源内容读取完毕后,将共享资源数据依次绑定回原始资源数据内。


完成文件解析。


在线示例:

美国队长(WebGL示例,用JavaScript解析Xnb格式的模型并绘制)


参考:

http://xbox.create.msdn.com/en-US/sample/xnb_format

0 0