必威体育Betway必威体育官网
当前位置:首页 > IT技术

QUAKE 3源代码评测:架构

时间:2019-11-04 02:45:50来源:IT技术作者:seo实验室小编阅读:72次「手机版」
 

quake

QUAKE 3源代码评测架构(第1部分,共5部分)>>

由于我在下一个合同前一个星期,我决定完成我的“循环ID”。后末日,末日iPhone,Quake1,Quake2中,德军iPhone和毁灭战士我决定读最后一个代码库我还不审查:

idTech3的3D引擎,权力的Quake III和地震现场。

引擎主要是idTech2的演变,但有一些有趣的新奇。重点可归纳如下:

  • 第2部分:新的双核渲染器与基于物料的着色器(构建在OpenGL固定管道上)。
  • 第3部分:基于快照的新的网络模型
  • 第4部分:新型虚拟机在引擎中扮演重要

    角色,将Quake1 可移植性/安全性与Quake2速度相结合。

  • 第5部分:机器人的新人工智能

我特别印象深刻:

  • 虚拟机的系统和相关的工具链总共占发布的代码的30%。在这种观点下,idTech3是一个小型操作系统,可以提供三个进程的系统调用。
  • 基于快照和内存自省的优雅网络系统。

像往常一样,我写了许多笔记,我已经清理并合成了图纸。我希望能节省时间给一些人,但也鼓励别人阅读更多的代码,成为更好的工程师。

编辑: 感谢您的支持!:)

第一次联系

由于最近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(特别gamecgameq3_ui虚拟机项目),则不是全部使用它们。一些项目永远不会使用(splinesui)。

一个表格最好总结什么项目对哪个模块做出贡献:

项目 类型 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.exerenderer.libbot.libgamecgameq3_ui)的交互如下:

两个重要的事情要理解设计

    1. 每个单个输入(键盘,win32消息,鼠标,UDP套接字)都转换成一个event_t集中的事件队列(sysEvent_t eventQue[256])。这允许其他事情记录(记录)每个输入,以重新创建错误。1998年10月14日在约翰·卡马克的“计划”中详细讨论了这一设计决策。
  1. 客户端和服务器的显式拆分(我在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命令的功能。相反,发生的是:

  1. Quake3.exe向客户端VM发送消息:CG_DRAW_ACTIVE_FRAME哪个表示需要刷新。
  2. 虚拟机执行一些实体剔除和预测,然后通过Quake3系统调用(CG_R_RENDERSCENE)调用OpenGL再现。
  3. 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协议体系结构简介

本文将介绍ZigBee 3.0协议体系结构及各个层的功能服务,让读者对3.0协议体系结构有一个整体把握,以便于后期的开发操作。ZigBee 3.0

TRACE32调试技巧

1. 调试步骤l         连接好 TRACE32-ICD 和目标板,注意不要带电插拔 JTAG ,容易损坏 TRACE32 或目标板,然后依次

【Nginx学习03】nginx: [warn] conflicting server na

当我们在配置nginx server时,如果出现同样的server_name ,我们在nginx -s reload重新加载配置文件的时候,就会出现如下警告。nginx:

暗影精灵3 Pro值得买吗?

惠普暗影精灵系列游戏本自2015年推出至今已经迭代到第三代,一直受到众多游戏发烧友的关注与追捧。从第一代的圆润外观到第三代的&l

折纸(0.08mm)达到珠峰高度(8848.130m)问题

这个方法是百度出来的,原作者不详。我觉得这个方法比较简洁些,就记录下来。 public class test {public static void main(String[]

分享到:

栏目导航

推荐阅读

热门阅读