quake
QUAKE 3源代码评测:架构(第1部分,共5部分)>>
由于我在下一个合同前一个星期,我决定完成我的“循环ID”。后末日,末日iPhone,Quake1,Quake2中,德军iPhone和毁灭战士我决定读最后一个代码库我还不审查:
idTech3的3D引擎,权力的Quake III和地震现场。
引擎主要是idTech2的演变,但有一些有趣的新奇。重点可归纳如下:
- 第2部分:新的双核渲染器与基于物料的着色器(构建在OpenGL固定管道上)。
- 第3部分:基于快照的新的网络模型。
- 第4部分:新型虚拟机在引擎中扮演重要
角色,将Quake1 可移植性/安全性与Quake2速度相结合。
- 第5部分:机器人的新人工智能。
我特别印象深刻:
像往常一样,我写了许多笔记,我已经清理并合成了图纸。我希望能节省时间给一些人,但也鼓励别人阅读更多的代码,成为更好的工程师。
编辑: 感谢您的支持!:)
第一次联系
由于最近ftp.idsoftware.com最近退役,代码可以在id的GitHub帐户中找到 :
git clone https://github.com/id-Software/Quake-III-Arena.git
当谈到一个巨大的代码库,我更喜欢使用XCode:SpotLight速度,command-click查找定义和字符串高亮使得该工具比Visual Studio更强大。但是打开Quake III项目表明,代码腐烂并不总是关于代码,还涉及到这些工具:XCode 4.0无法打开Quake III XCode 2.0项目。
最后我在windows 8上使用Visual Studio 2010 Professional:安装Visual Studio 2010生产力电动工具后 ,工具集实际上很愉快。
第一个引人注目的是Visual Studio工作区不是由一个项目组成的,而是八个。如果构建是DEBUG或RElease(特别game
是cgame
和q3_ui
虚拟机项目),则不是全部使用它们。一些项目永远不会使用(splines
和ui
)。
一个表格最好总结什么项目对哪个模块做出贡献:
项目 | 类型 | DEBUG构建 | RELEASE构建 | 注释 |
botlib | 静态库 | botlib.lib | botlib.lib | ai |
在CGame | 动态的Libary / Bytecode | cgamex86.dll | - | |
游戏 | 动态的Libary / Bytecode | qagamex86.dll | - | |
q3_ui | 动态的Libary / Bytecode | uix86.dll | - | |
QUAKE3 | 可执行文件 | quake3.exe | quake3.exe | |
渲染 | 静态库 | renderer.lib | renderer.lib | 基于OpenGL的 |
样条曲线 | 静态库 | Splines.lib | Splines.lib | 使用NOWHERE! |
UI | 动态的Libary / Bytecode | uix86_new.dll | - | 用于Quake III Arena。 |
琐事: idTech3的工作题目是“三位一体”。由于idTech4被称为“Neo”,我认为它是从“Matrix”专营权...但是id软件在接受firingsquad.com的采访时指出,它以“达拉斯的三一河”命名:
约翰:就研究而言,我有几件引擎的事情正在进行中。 FS:那是三位一体呢?我认为“三位一体”有点混乱。 约翰:我从来没有真的确定这是如何像所有人一样混乱。震后,何时 我开始使用新的渲染技术和一切,每个人都称之为“下一个引擎” 管他呢。迈克尔·阿布拉斯(Michael Abrash)建议,我们只是采取英特尔在一条河附近命名您的下一个项目 您。我们在达拉斯拥有三一河,所以就像“三位一体引擎”一样,下一步。
编辑(2012年7月7日): Jeremiah Sypult在发表本文后联系了我:他用“XCode 4.0”项目为“Quake3”Mac OS X构建“不动”。我已经进一步修复了,你可以在github上得到它。您将需要Quake
III Arenabaseq3
(而不是演示版),并确保使用参数"+set
vm_game 0 +set vm_cgame 0 +set vm_ui 0"
以使用dylib虚拟机。打开/code/quake3.xcworkspace
它建立在一个点击!
建筑
了解架构的一个方便的方法是首先将软件视为接收输入(左上箭头)和生成输出(底部箭头)的黑盒子:
然后查看输入如何以白盒方式与6个模块流向输出(quake3.exe
,renderer.lib
,bot.lib
,game
,cgame
和q3_ui
)的交互如下:
两个重要的事情要理解设计:
- 客户端和服务器的显式拆分(我在John Carmack的Q&A中概述了):
Fabien Sanglard:您认为如何总结idTech3的主要创新之外: - 机器人IA - 虚拟机:结合QuakeC可移植性和Quake2 dll速度。 - SMP&着色器渲染器。 - 新的网络代码。 约翰·卡马克:明确将网络划分为客户端演示端和服务器逻辑端,这是真的对 要做的事。我们退出了在末日3和大部分愤怒,但我们正在迁移回去。所有的Tech3 许可证持有者被迫做更多的工作,以分裂架构实现单人效应,但事实证明 执法纪律确实有一个有价值的回报。
- 服务器端负责维护游戏状态,确定客户需要什么,并通过网络传播。它是静态联系的,
bot.lib
因为它是一个单独的项目,因为它的“开始的大师”第275页提到的混乱的发展历史:更糟糕的是,游戏的一个基本要素 - 漫游器 - 失踪了。机器人 是由电脑控制的字符。一个好的机器人会与动作和肉体相融合 像机器人的额外的场景,以及与玩家的互动。对于Quake III,死亡 只有游戏,机器人是单人游戏动作所必需的。它们是隐含的复杂因为它们 不得不像人一样行事。 卡马克决定第一次将创建这些机器人的工作委托给另一个机器人 程序员在公司。但他没有跟进。卡马克再次错了 每个人都像自己一样自我激励和擅长。他错了 当Graeme努力控制工作时,发现机器人完全无效。 他们根本不喜欢人类。他们的行为基本上就像机器人一样。工作人员开始恐慌。 到1999年3月,他们有理由害怕。 [..] 最后,机器人已经被种植到荷兰知名的模具制造商,英国人带来了这个制造商 他们生活 (Fab的注释:这是Mr.Elusive:Jan Paul van Waveren)。
- 客户端负责预测实体在哪里(延迟补偿)并呈现视图。它与
renderer
项目静态链接:一个单独的项目,允许Direct3D甚至软件渲染器被非常容易地插入。
- 服务器端负责维护游戏状态,确定客户需要什么,并通过网络传播。它是静态联系的,
代码
从代码的角度来看,这是一个部分展开的循环,用于说明客户端和服务器的事件生产和消耗:
int WinMain(Hinstance hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { Com_Init NET_Init 而(1) { //通用代码 IN_Frame() //将Win32操纵杆和鼠标输入作为event_t添加到统一的事件队列中。 { IN_JoyMove IN_ActivateMouse IN_MouseMove } Com_Frame { //通用代码 Com_EventLoop //将win32消息,UDP套接字和控制台命令的泵送到队列(sysEvent_t eventQue [256]) Cbuf_Execute //服务器代码 SV_Frame { SV_BotFrame //在bot.lib中跳转 VM_Call(gvm,GAME_RUN_FRAME,svs.time) //在游戏虚拟机中跳转,执行游戏逻辑 SV_CheckTimeouts SV_SendClientmessages //向连接的客户端发送快照或增量快照 } //通用代码 Com_EventLoop Cbuf_Execute //客户端代码 CL_Frame { CL_SendCmd //泵送事件队列并发送命令到服务器。 SCR_UpdateScreen VM_Call(cgvm,CG_DRAW_ACTIVE_FRAME); //发送消息到客户端虚拟机(做预测)。 要么 VM_Call(uivm,UI_DRAW_CONNECT_SCREEN); //如果菜单可见,则会将消息发送到UI虚拟机。 S_Update //更新声音缓冲区 } } } }
这是一个完全展开的循环,我在挖掘源代码时使用了一个地图。
一个有趣的事情要注意到,这完全说明了虚拟机的重要性:没有任何地方可以看到RE_RenderScene
:执行剔除和发出OpenGL命令的功能。相反,发生的是:
- Quake3.exe向客户端VM发送消息:
CG_DRAW_ACTIVE_FRAME
哪个表示需要刷新。 - 虚拟机执行一些实体剔除和预测,然后通过Quake3系统调用(
CG_R_RENDERSCENE
)调用OpenGL再现。 - Quake3.exe接收系统调用,实际调用
RE_RenderScene
。
OpenGL Quake3.exe客户端虚拟机 -------- ---------- ---------------------- | | | | | | | VM_Call(CG_DRAW_ACTIVE_FRAME)-----------------> CG_DrawActiveFrame | | CG_DrawActive | | trap_R_RenderScene | | 系统调用(CG_R_RENDERSCENE,fd) | RE_RenderScene <-------------------------------------- | | | | | <---------------------- | | | | |
统计
这里有一些来自cloc的统计资料:
-------------------------------------------------- --------------------------------------------- 文件空白评论代码 -------------------------------------------------- --------------------------------------------- cloc-1.56.exe代码共享559 48630 73501 233952 cloc-1.56.exe lcc 116 2270 1513 28067 cloc-1.56.exe q3asm q3map 44 4987 5565 22877 cloc-1.56.exe q3radiant 206 11870 13113 54922 -------------------------------------------------- --------------------------------------------- 共计919 68293 95509 341994 -------------------------------------------------- ---------------------------------------------
在饼图上,我们可以生动地看到这个比例是多么的不寻常,因为30%的代码库专门用于工具:
部分原因是因为idtech3具有ANSI C编译器:开源Little C Compiler(LCC)用于为虚拟机生成字节码。
内存分配
两个定制分配器在这里工作:
- 区域分配器:负责运行时,小型和短期内存分配。
- Hunk分配器:负责从pak文件(几何,地图,纹理,动画)的级别负载,大型和长期分配。
更美好的明天
有了这个代码审查,似乎我跑出了伟大的3D引擎源代码阅读。但是CG世界正在走很多伟大的事情。我特别期待着Occulus Rift VR工具包:
构建,编码和 理解测试台将会很有趣。它应该在7月下旬直到那时止:快乐的黑客!
文章最后发布于: 2017-07-29 19:05:55
相关阅读
本文将介绍ZigBee 3.0协议体系结构及各个层的功能服务,让读者对3.0协议体系结构有一个整体把握,以便于后期的开发操作。ZigBee 3.0
1. 调试步骤l 连接好 TRACE32-ICD 和目标板,注意不要带电插拔 JTAG ,容易损坏 TRACE32 或目标板,然后依次
【Nginx学习03】nginx: [warn] conflicting server na
当我们在配置nginx server时,如果出现同样的server_name ,我们在nginx -s reload重新加载配置文件的时候,就会出现如下警告。nginx:
惠普暗影精灵系列游戏本自2015年推出至今已经迭代到第三代,一直受到众多游戏发烧友的关注与追捧。从第一代的圆润外观到第三代的&l
这个方法是百度出来的,原作者不详。我觉得这个方法比较简洁些,就记录下来。 public class test {public static void main(String[]