QUAKE系列引擎以及基于QUAKE扩展引擎的源代码全面分析(三) --bsp文件格式分析1

QUAKE系列引擎以及基于QUAKE扩展引擎的源代码全面分析(三) --bsp文件格式分析1

 

一:一些废话  
   
好久没更新了,一方面是年底了,对于做销售的人来说,利用这段时间出出差,拜访拜访经销商以及KA客户,目的是确定明年的销售指标,晕。另一个更重要的原因是竟然把密码忘记了,没办法进入我的博客。前天整理东西时候竟然发现写密码的那张纸了,内心狂喜,哈哈!!
    
本来想接上次的,写一些关于渲染器方面的东西,但是因为整个渲染器是依赖与BSP进行操作的,而且QUAKE中的碰撞检测也是依赖与BSP树的,因此先写一些关于BSP树方面的基础东西,以利于大家有个比较具体的印象,希望能够写的比较通俗易懂吧。
    
事实上,前天我写了将近500字的BSP编译器的分析的文章,发现好象如果直接写编译器这个核心东西,可能需要一些关于QUAKEBSP的相关理论的和基础的东西,特别是QQ上有个朋友和我说,他研究QUAKE2的渲染器代码已经很久了,但是有些函数看了半年还是看不懂,哈哈,其实这和我以前的感觉一样。为什么呢,因为实在网络资料很少,如果你不从Q3MAP这个源代码以及关卡编辑器产生的结果数据和GAME.DLL模块中以SP_开头的函数进行分析的话,BSP永远都是一知半解的,那是因为不知道BSP生成的原理,所以很多东西都看不懂。所以决定了,先从结果推导BSP的编译原理,当然我想这是一个非常大的代码分析,基本上最起码可以写15000字以上的文章了,呵呵,反正现在有的是时间,就慢慢写吧
二:分析生成BSP后的文件结构:
     BSP
事实上分为三个部分,第一部分是关卡编辑器生成.map的文件格式(Q3RADIANT),第二部分是通过Q3MAP.map的文件格式编译成.BSP格式,对于BSP文件而言,我们可以将BSP格式的文件数据分成两个大类,即用于渲染用的数据和用于碰撞检测的数据(QUAKE3里面称为CLIPMAP),至于编译过程就是一个流水线式的操作,要进行多次步骤产生结果. 第三部分是操作BSP,关于BSP的操作,以后我慢慢来写,事实上是非常非常重要的和好玩的东东.
   
在这里我只想简单说一下为什么BSP的文件格式里面包含渲染数据和物理碰撞数据,那是因为QUAKE3的渲染部分和物理碰撞部分是分离的,这样的好处是渲染部分是客户端进行调用的,服务器端不需要用到渲染模块,然而碰撞检测却是服务器端和客户端都要用到的,所以分离以后就具有很大的灵活性事实上服务器是上帝,定义一切规则和进行物理动力学的计算,而客户端使用碰撞检测是为了进行同步服务器,进行客户端预测使用的,这是一个网络端编程的概念,以后进行C/S架构分析再说吧
: BSP文件结构代码

 typedef struct {
 int  fileofs, filelen;
} lump_t;

typedef struct {
 int   ident;
 int   version;
 lump_t  lumps[HEADER_LUMPS];
} dheader_t;//

typedef struct {
 char  shader[MAX_QPATH];
 int   surfaceFlags;//
绝对经典的东西,还是和q3map一起说比较有趣,
 int   contentFlags;//
绝对经典的东西,还是和q3map一起说比较有趣
} dshader_t; //               lump1

// planes x^1 is allways the opposite of plane x

typedef struct {
 float  normal[3];
 float  dist;
} dplane_t; //              lump2

typedef struct {
 int   planeNum;
 int   children[2]; // negative numbers are -(leafs+1), not nodes
 int   mins[3];  // for frustom culling
 int   maxs[3];
} dnode_t; //                lump3

typedef struct {
 int   cluster;   // -1 = opaque cluster (do I still store these?)
 int   area;
 int   mins[3];   // for frustum culling
 int   maxs[3];
 int   firstLeafSurface;
 int   numLeafSurfaces;
 //
用于碰撞检测,不用于渲染模块
 int   firstLeafBrush;
 int   numLeafBrushes;
} dleaf_t; //                lump4

int leafsurfaces; // lump5
int leafbrushes; //lump6

typedef struct {
 float          mins[3], maxs[3];
 int   firstSurface, numSurfaces;

//下面的变量用于碰撞检测用
 int   firstBrush, numBrushes;
} dmodel_t;//        lump7

typedef struct {
 int   firstSide;
 int   numSides;
 int   shaderNum;   // the shader that determines the contents flags
} dbrush_t;// lump8

typedef struct {
 int   planeNum; // positive plane side faces out of the leaf
 int   shaderNum;
} dbrushside_t;// lump9

 

typedef struct {
 vec3_t  xyz;
 float  st[2];
 float  lightmap[2];
 vec3_t  normal;
 byte  color[4];
} drawVert_t;//      lump10

int drawIndexes; // lump11

typedef struct {
 char  shader[MAX_QPATH];
 int   brushNum;
 int   visibleSide; // the brush side that ray tests need to clip against (-1 == none)
} dfog_t;//        lump12

//对表面类型进行总结,具体见下面

typedef enum {
 MST_BAD,
 MST_PLANAR,//
很重要的,说明该表面是一个世界的静态表面,例如墙面,地板等,可以通

//brushside计算出来
 MST_PATCH,//
二次贝塞尔表面,要进行相应三角型化,要求速度的话,可以使用前向差分

//算法,二次贝塞尔使用9个控制点插值计算
 MST_TRIANGLE_SOUP,//
用于BMODEL的表面,可以进行三角形扇或带化或顶点索引三角形

//如果要了解具体算法,可以参考一些计算几何的算法,如果有足够

//深厚的功力,建议参考nvstriper相关代码,还有关于计算几何或

//拓拔方面的知识,网络上有一个很好的库ttl,里面有篇实现的论

//文,关于gmap概念以及使用半边结构进行各种拓拔查找以及修改,

//绝对经典的东西
 MST_FLARE //
实际上就是公告版,因该都会使用吧
} mapSurfaceType_t;

typedef struct {
 int   shaderNum;//
索引指向shaderlump
 int   fogNum;//
索引指向foglump
 int   surfaceType;// mapSurfaceType_t,
具体说明见上

 int   firstVert;//索引指向drawVert_tlump
 int   numVerts;

 int   firstIndex;//索引指向顶点索引lump
 int   numIndexes;

//下面一些变量和静态lightmap相关,事实上现在的图形硬件足够快,静态光照图相关算

//法已有没落的趋势,事实上现在比较先进的引擎都是全动态光照,通过BSP进行场景管理

//可以非常高效的实现,使渲染效果大幅度提高。这部分是我最感兴趣的部分,以后有机会

//可以探讨一下,但是必须要对BSP相关操作有非常的了解才可以深入

 int   lightmapNum;
 int   lightmapX, lightmapY;
 int   lightmapWidth, lightmapHeight;

 vec3_t          lightmapOrigin;
 vec3_t          lightmapVecs[3];   // for patches, [0] and [1] are lodbounds

//下面两个变量用于贝塞尔曲面

 int   patchWidth;
 int   patchHeight;
} dsurface_t;//       lump13

byte lightBytes; //        lump14

byte lightgridData;//      lump15

byte visBytes;//          lump16

 

这里我列出 bsp 文件格式的各个 lump ,除了 entity 这个比较特别的 lump ,这个留到 q3map 再说,是比较特别一个东东。还有就是具体表面, bmodel 以及著名的 brush/side 等之间的关系,以及 shader 各个元素还是下次再写把,发现写东西还真是很费脑子的拉,今天就先到这里了 .

你可能感兴趣的:(QUAKE系列引擎以及基于QUAKE扩展引擎的源代码全面分析(三) --bsp文件格式分析1)