??xml version="1.0" encoding="utf-8" standalone="yes"?>
好久没更CQ一斚w是年底了Q对于做销售的人来_利用q段旉出出差,拜访拜访l销商以?span>KA客户Q目的是定明年的销售指标,晕。另一个更重要的原因是竟然把密码忘CQ没办法q入我的博客。前天整理东西时候竟然发现写密码的那张纸了,内心狂喜Q哈哈!Q?span>
本来x上次的,写一些关于渲染器斚w的东西,但是因ؓ整个渲染器是依赖?span>BSPq行操作的,而且QUAKE中的撞也是依赖与BSP树的Q因此先写一些关?span>BSP树方面的基础东西Q以利于大家有个比较具体的印象,希望能够写的比较通俗易懂吧?span>
事实上,前天我写了将q?span>500字的BSP~译器的分析的文章,发现好象如果直接写编译器q个核心东西Q可能需要一些关?span>QUAKE?span>BSP的相关理论的和基的东西,特别?span>QQ上有个朋友和我说Q他研究QUAKE2的渲染器代码已经很久了,但是有些函数看了半年q是看不懂,哈哈Q其实这和我以前的感觉一栗ؓ什么呢Q因为实在网l资料很,如果你不?span>Q3MAPq个源代码以及关卡编辑器产生的结果数据和GAME.DLL模块中以SP_开头的函数q行分析的话Q?span>BSP永远都是一知半解的Q那是因Z知道BSP生成的原理,所以很多东襉K看不懂。所以决定了Q先从结果推?span>BSP的编译原理,当然我想q是一个非常大的代码分析,基本上最L可以?span>15000字以上的文章了,呵呵Q反正现在有的是旉Q就慢慢写吧
二:分析生成BSP后的文gl构Q?span>
BSP事实上分Z个部分,W一部分是关卡编辑器生成.map的文件格式(Q3RADIANTQ,W二部分是通过Q3MAP?span>.map的文件格式编译成.BSP格式,对于BSP文g而言,我们可以?span>BSP格式的文件数据分成两个大c?span>,即用于渲染用的数据和用于撞的数据(QUAKE3里面UCؓCLIPMAP),至于~译q程是一个流水线式的操作,要进行多ơ步骤生结?span>. W三部分是操?span>BSP,关于BSP的操?span>,以后我慢慢来?span>,事实上是非常非常重要的和好玩的东?span>.
在这里我只想单说一下ؓ什?span>BSP的文件格式里面包含渲染数据和物理撞数据,那是因ؓQUAKE3的渲染部分和物理撞部分是分ȝQ这L好处是渲染部分是客户端进行调用的,服务器端不需要用到渲染模?span>,然而碰撞检却是服务器端和客户端都要用到的,所以分M后就h很大的灵zL?span>. 事实上服务器是上?span>,定义一切规则和q行物理动力学的计算,而客L使用撞是Zq行同步服务?span>,q行客户端预用的,q是一个网l端~程的概?span>,以后q行C/S架构分析再说?span>
?span>: BSP文gl构代码
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;//l对l典的东西,q是?span>q3map一赯比较有趣Q?span>
int contentFlags;//l对l典的东西,q是?span>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;
//用于撞,不用于渲染模?span>
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
//对表面类型进行ȝQ具体见下面
typedef enum {
MST_BAD,
MST_PLANAR,//很重要的Q说明该表面是一个世界的静态表面,例如墙面Q地板等Q可以?/span>
//q?span>brushside计算出来
MST_PATCH,//二次贝塞表面,要进行相应三角型化,要求速度的话Q可以用前向差?/span>
//法Q二ơ贝塞尔使用9个控制点插D?span>
MST_TRIANGLE_SOUP,//用于BMODEL的表面,可以q行三角形扇或带化或点索引三角?/span>
//如果要了解具体算法,可以参考一些计几何的法Q如果有_
//深厚的功力,参?span>nvstriper相关代码Q还有关于计几何或
//拓拔斚w的知识,|络上有一个很好的?span>ttlQ里面有实现的?/span>
//文,关于gmap概念以及使用半边l构q行各种拓拔查找以及修改Q?/span>
//l对l典的东?span>
MST_FLARE //实际上就是公告版Q因该都会用吧
} 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;
//下面一些变量和静?span>lightmap相关Q事实上现在的图形硬件够快Q静态光照图相关?/span>
//法已有没落的势Q事实上现在比较先进的引擎都是全动态光照,通过BSPq行场景理
//可以非常高效的实玎ͼ使渲染效果大q度提高。这部分是我最感兴的部分Q以后有Z
//可以探讨一下,但是必须要对BSP相关操作有非常的了解才可以深?/span>
int lightmapNum;
int lightmapX, lightmapY;
int lightmapWidth, lightmapHeight;
vec3_t lightmapOrigin;
vec3_t lightmapVecs[3]; // for patches, [0] and [1] are lodbounds
//下面两个变量用于贝塞曲?/span>
int patchWidth;
int patchHeight;
} dsurface_t;// lump13
byte lightBytes; // lump14
byte lightgridData;// lump15
byte visBytes;// lump16
q里我列?/span>bsp文g格式的各?/span>lumpQ除?/span>entityq个比较特别?/span>lumpQ这个留?/span>q3map再说Q是比较特别一个东东。还有就是具体表面,bmodel以及著名?/span>brush/side{之间的关系Q以?/span>shader各个元素q是下次再写把,发现写东西还真是很费脑子的拉Q今天就先到q里?/span>.
目录Q?span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
W一章:QUAKE引擎的整体框架结构:
1Q引擎和API的精定?/span>
2Q整?/span>quake引擎是基?/span>C/S模式
3Q各个模块间的关pd
4Q客L如何与服务器端相q接Q网l消息的传递与响应以及客户端数据库的生)
5Q当客户端连接到服务器后如何q入游戏状态的程Q即玩家的生)
6Q当客户端死亡后重生的流E?/span>
7Q简要说明进入游戏状态后一帧运行的程Q包括各个模块函数调用的C意?/span>
W二章:渲染?/span>(refresh模块)
1. 两个重要的由外部操作的结?/span>(refEntity_t?/span>refdef_t)以及q些l构各个值域的详l解?span lang=EN-US>
2Q渲染器模块导出函数Q?span lang=EN-US>APIQ的分类以及作用(?span lang=EN-US>quake3-1.32b
原代码ؓ?span lang=EN-US>)AQ渲染数据资源管理函数集Q?span lang=EN-US>12个函敎ͼ资源包括BSP世界数据Q模型数据,shader数据Q?span lang=EN-US>skin
数据Q?span lang=EN-US>vis数据以及字体Q?span lang=EN-US> BQ设|渲染命令流水线的函数集Q?span lang=EN-US>4个函敎ͼ
CQ场景管理以及渲染的函数集(7个函敎ͼ
DQ其他函数集Q?span lang=EN-US>6个函敎ͼ总计29个导出函?span lang=EN-US>
3Q?span lang=EN-US>Quake3 渲染器的整体l构Q?span lang=EN-US>
AQ?span lang=EN-US>QUAKE3渲染器是?span lang=EN-US>OPENGL为基q支持双处理器ƈ行运的
BQ?span lang=EN-US>QUAKE3渲染器在渲染q程中可以分为前端部分和后端部分Q图解)Q他们是如何协调h的?span lang=EN-US>
C: QUAKE3是如何支持双处理器ƈ行进行渲?span lang=EN-US>
4Q对quake3模型pȝ的扩展(使用MD5模型格式以及skm模型格式Q?span lang=EN-US>
A: Z么不?span lang=EN-US>MD3模型
BQ?span lang=EN-US>MD5&SKM骨骼模型的格式分?span lang=EN-US>
CQ骨骼动ȝ原理以及应用
Q?Q?span style="FONT: 7pt 'Times New Roman'"> 骨骼动画的分c(boneoffsetcd?span lang=EN-US>vertexoffsetcd的详解以及各自的优缺点)
Q?Q?span style="FONT: 7pt 'Times New Roman'"> 详细分析骨骼动画数学原理
Q?Q?span style="FONT: 7pt 'Times New Roman'"> 在定义骨骼动ȝ时候需要详l考虑的一些问题以及目的,不同的目的会有不同的~码方式
Q?Q?span style="FONT: 7pt 'Times New Roman'"> 重点分析SKM骨骼动画?span lang=EN-US>warsow游戏中的q用以及~码方式
Q?Q?span style="FONT: 7pt 'Times New Roman'"> 骨骼动画?span lang=EN-US>CPU实现?span lang=EN-US>GPU实现的优~点分析以及如何q各自的优~点
Q?Q?span style="FONT: 7pt 'Times New Roman'"> 附我的计划:市面上公开格式的骨骼动M实上在渲染原理上基本差别不是很大Q因此在学习骨骼动画的过E中Q感受很多啊Q现在本人正在进行系l设计,Ҏ骨骼动画的原理,参考相兌料,提炼Z条骨骼动ȝ一渲染水Uѝ完成后公开源代码。系l设计的要求?span lang=EN-US>
QAQ?span style="FONT: 7pt 'Times New Roman'"> 可以直接q入quake3引擎的多核渲染流水线
QBQ?span style="FONT: 7pt 'Times New Roman'"> 使用CPU实现的,?span lang=EN-US>SIMD为基数学q算Q因?span lang=EN-US>CPU实现q行转化后可以直接获得顶Ҏ据再q行阴媄pȝ的绘Ӟ?span lang=EN-US>GPU数据的取回比较麻烦,再说本h也没有支?span lang=EN-US>D3D10版本?span lang=EN-US>GPUQ无法用新增加?/span>stream output statge以及几何shaderQ?/span>
QCQ?span style="FONT: 7pt 'Times New Roman'"> 能够在运行过E中人工控制各个骨头的运?span lang=EN-US>
QDQ?span style="FONT: 7pt 'Times New Roman'"> 使用l一的骨骼动L染流水线Q模型与数据相分离,q且阴qlƈ入该渲染水Uѝ?span lang=EN-US>
5Q?span lang=EN-US>BSP文g格式以及QUAKE3 SHADER文g格式
今天写到目录的前两章,计划在本周内所有章节全部定义出来,然后再填写各个小节的内容
前言Q?/span>
一Q研I?/span>quakepd引擎断断l箋也已l两q有余了Q一直想写点什么,但是真的C那一步,又发现其实很难下W,原因有三Q?/span>1 文笔不流畅,特别是技术性技巧的~ZQ概念难以精定义,无法惛_心的真实表达转换为文字,郁闷啊!Q?/span>2 QUAKEpd引擎的庞大结构以及各个模块的协作关系Q真的想写的时候不知道如何l织Q导致思\极其紊ؕ?/span>3 对于QUAKEpd的深奥部分,列如bsp的编译程序部分的源码q未完全理解Q这是整?/span>QUAKE引擎的核心部分,q是QUAKEpd引擎最核心的部分,可以_整个QUAKEpd引擎是围绕q张图推q的。虽?/span>BSP的生成确实是一个非帔R帔R的难点,好在使用?/span>BSP来相Ҏ较简单,即不知道如何生成,但至可以灵zM用,伟大的慷慨的卡马克?/span>
二:QUAKEpd的引擎源码分析涉及到的引擎包括如下几个:
1 QUAKE1 及其Z QUAKE1框架的扩展引?/span>DARKPLACES
2 QUAKE2 及其Z QUAKE2 框架的扩展引?/span> QFUSION
3 QUAKE3及其Z QUAKE3 框架的扩展引?/span> XREAL/EVQ3
三:Z么要使用上述的扩展引擎?
1 QUAKEpd引擎毕竟旉久远Q现代硬件技术的发展以及渲染斚w的新概念Q新技术的出现Q一些扩展引擎更加脓q当今世界技术发展的潮流。例如这三个引擎都增加了GLSLq行相应的扩展?/span>
2 q些扩展引擎都是非常著名的开源项目,资料比较多,而且都有相应使用q些扩展引擎作成的游戏,可以观看到游戏实时效果?/span>
例如ZDARKPLACES引擎的游?/span>—NEXUIZQ渲染效果极其惊人啊Q!Q?/span>
Z QFUSION 引擎的游?/span>-----WARSOW
Z XREAL/EVQ3引擎的游?/span>-----REVOLUTION
3 对上qC个扩展引擎的感受
A:DARKPLACES使用QUAKE1的框架结构,重写了全部的渲染模块Q网l协议以及传输模?/span>,支持DOOM3cd的光q效,Ҏ我的感觉Q应该是渲染效果最好的开源的目Q用到了相当多的特效(DOOM3光媄Ҏ=Stencil Shadow Volume, Per Pixel Lighting, NormalizationCubeMap, 2D+1D Attenuation Texturing, and Light Projection FilteringQ?span lang=EN-US>.该引擎可以用著名的QUAKECq行服务器端游戏逻辑的开发(相当?span lang=EN-US>QUAKE3中的GAME.DLL模块Q?span lang=EN-US>,同时相对?span lang=EN-US>QUAKE1?span lang=EN-US>QUAKEC内置函数,该引擎扩展了相当多的服务器端QUAKEC函数.更漂亮的是他同时扩展了客L逻辑部分的函?span lang=EN-US>,通过q些函数可以~写客户端游戏逻辑(相当?span lang=EN-US>QUAKE3中的CGAME.DLL模块,但不完全{同).事实上本人是非常喜欢QUAKEC的编码方?span lang=EN-US>,l而强?span lang=EN-US>.
B:QFUSION引擎最大的特点是他的逻辑l构非常清晰,他所扩展的骨骼动ȝl是其最大的特点.本h的感觉是极其漂亮(当然每个人的观点不同,q只是本人的观点|了).他用了skm骨骼动画文g格式.正是通过该引擎的骨骼动画pȝ,让本人完全掌握整个骨骼动ȝ_N,真是收益非浅?/span>!!!而且整个游戏逻辑端非常清?/span>,在代码分析时候主要以该引擎作为原代码基础.
C:xreal/evq3整体框架?/span>quake3变化不大,但是最重要的一Ҏ,本h最喜欢的渲染器l构?/span>quake3?/span>render.dll,直是太完了,quake3的渲染器可以使用双处理器,Z支持双处理器的运?/span>,quake3自己实现了一条渲染命令流水线,及其完美,收益非浅?/span>!!!!又要说一句非帔R要的话了,伟大的慷慨的卡马?/span>.而引xreal/evq3擎完的保留?/span>quake3的渲染器框架l构同时扩展了较多的功能,光媄Ҏ_强大.增加?/span>md5骨骼模型的渲?/span>.在以后渲染器代码分析时?/span>,主要以该扩展引擎为基l合darkplaces引擎的相x?/span>.
M而言, quakepd引擎的整体架构非常漂?/span>,是学习的好材?/span>,q且?/span>quake1?/span>quake3,整体逻辑端代码变化不?/span>, 真正比较有突破性的是渲染引?/span>.本h在学?/span>quake引擎q程中常常敬佩卡马克的想象力,api函数是如此之z?/span>,整体框架是如此之完美,面向对象?/span>c写得如此之漂?/span>,通过quake引擎,可以学到游戏设计的各个概念以及各个模?/span>,外部工具是如何完的l合h,q一Ҏ非常非常重要?/span>.