3D游戏之神-——约翰.卡马克

常用链接

统计

最新评论

置顶随笔 #

[置顶]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各个元素还是下次再写把,发现写东西还真是很费脑子的拉,今天就先到这里了.

posted @ 2008-01-27 21:48 落魄江湖 阅读(5430) | 评论 (7)编辑 收藏

[置顶]QUAKE系列引擎以及基于QUAKE扩展引擎的源代码全面分析(二)

    本来想直接进入quake源码分析,但发现如果没有好的写作框架,就凭QUAKE引擎这么大的代码群,真的很难写的,所以决定先搭一个分析框架,定义好各个章节,争取在本周内全部完成该工作,然后从下个礼拜开始就往分析框架里面填写内容了!哈哈!!
     声明:1。本人从未进入程序员行列,只是喜好才写这些文章的,所以在文章写作过程中,有任何技术性的错误,以及没有甬道正确的术语,请见谅(因为很多quake中的术语都是我自己定义的)
                2。在整体的分析过程中,并不一定按照目录所定义好的顺序来写的,想到什么就写什么,这就是博客的精神把!!整个目录框架是分析的思路,可能会改变。
                3。在目录各个章节都是主题的定义,我会在空闲时间慢慢的填进去的,希望能够最终坚持下来形成一整套关于quake系列比较系统的文挡。
                4。 本人的目的是在中国形成一个比较活跃的以quake为基础的社群,希望更多的人了解quake的精神,我想在中国研究quake引擎的人应该很多,高手更是不少,但是在中国的网络上却看不到系统的quake源码分析,不知道为什么??所以由本人,一个不在程序员序列的图形学爱好者来稍微引导一下。由于本人不属于程序员,因此也更本没有所谓违反某个软件公司的知识产权,具有更大的灵活性,希望其他地方的各个quake高手进行完善与修整本人所写的东东。
             5。 本人渴望与从事游戏行业的程序员进行交流。由于本人的生活圈子与程序员根本不搭界,所以没有机会和从事游戏设计的人员进行交流,很郁闷啊。很想了解一下现在的图形学在中国处于什么状态,各个游戏公司底层的引擎是自己开发的还是使用开源的或则是购买世界著名的游戏引擎。希望能有机会与各位交流,本人的qq号码是47178234,本人生活在上海,如果有上海的高手,我们可以多多交流,时而可以face to face的交流拉,以增加对程序员生活的真正了解!! 

目录:

 第一章:QUAKE引擎的整体框架结构:

         1.引擎和API的精确定义

         2.整个quake引擎是基于C/S模式

         3.各个模块间的关系图

         4.客户端如何与服务器端相连接(网络消息的传递与响应以及客户端数据库的产生)

         5.当客户端连接到服务器后如何进入游戏状态的流程(即玩家的产生)

         6.当客户端死亡后重生的流程

         7.简要说明进入游戏状态后一帧运行的流程,包括各个模块函数调用的示意图                  

 第二章:渲染器(refresh模块)

         1. 两个重要的由外部操作的结构(refEntity_trefdef_t)以及这些结构各个值域的详细解释

         2.渲染器模块导出函数(API)的分类以及作用(quake3-1.32b原代码为准)

            A:渲染数据资源管理函数集(12个函数,资源包括BSP世界数据,模型数据,shader数据,skin数据,vis数据以及字体)

            B:设置渲染命令流水线的函数集(4个函数)

            C:场景管理以及渲染的函数集(7个函数)

            D:其他函数集(6个函数)总计29个导出函数

         3Quake3 渲染器的整体结构:

            AQUAKE3渲染器是以OPENGL为基础并支持双处理器并行运算的

            BQUAKE3渲染器在渲染过程中可以分为前端部分和后端部分(图解),他们是如何协调起来的。

            C: QUAKE3是如何支持双处理器并行进行渲染

         4.对quake3模型系统的扩展(使用MD5模型格式以及skm模型格式)

            A: 为什么不用MD3模型

            BMD5&SKM骨骼模型的格式分析

            C:骨骼动画的原理以及应用

(1)       骨骼动画的分类(boneoffset类型和vertexoffset类型的详解以及各自的优缺点)

(2)       详细分析骨骼动画数学原理

(3)       在定义骨骼动画的时候需要详细考虑的一些问题以及目的,不同的目的会有不同的编码方式

(4)       重点分析SKM骨骼动画在warsow游戏中的运用以及编码方式

(5)       骨骼动画的CPU实现和GPU实现的优缺点分析以及如何平衡各自的优缺点

(6)       附我的计划:市面上公开格式的骨骼动画事实上在渲染原理上基本差别不是很大,因此在学习骨骼动画的过程中,感受很多啊,现在本人正在进行系统设计,根据骨骼动画的原理,参考相关资料,提炼出一条骨骼动画统一渲染流水线。完成后公开源代码。系统设计的要求是

(A)       可以直接并入quake3引擎的多核渲染流水线

(B)       使用CPU实现的,以SIMD为基础数学运算(因为CPU实现进行转化后可以直接获得顶点数据再进行阴影系统的绘制,而GPU数据的取回比较麻烦,再说本人也没有支持D3D10版本的GPU,无法使用新增加的stream output statge以及几何shader

(C)       能够在运行过程中人工控制各个骨头的运动

(D)       使用统一的骨骼动画渲染流水线,使模型与数据相分离,并且将阴影系统并入该渲染流水线。

 

         5BSP文件格式以及QUAKE3 SHADER文件格式


今天就写到目录的前两章,计划在本周内将所有章节全部定义出来,然后再填写各个小节的内容
                                                                                
           

 

posted @ 2007-11-20 16:28 落魄江湖 阅读(5474) | 评论 (8)编辑 收藏

仅列出标题