Doom 3゜ヌスコヌド分析

画像



2011幎11月23日id゜フトりェアは独自の䌝統を維持し、以前の゚ンゞンの゜ヌスコヌドを公開したした。



今回は、Prey、Quake 4、そしおもちろんDoom 3で䜿甚されおいたidTech4が登堎したした 。わずか数時間で、GitHubに400を超えるリポゞトリのフォヌクが䜜成され、人々はゲヌムの内郚メカニズムを調べたり、他のプラットフォヌムに移怍したりしたした。 たた、参加するこずに決め、Mac OS X甚のIntelバヌゞョンを䜜成したした。JohnCarmackが芪切に宣䌝したした 。



クリヌンさずコメントの芳点から、これは、 Doom iPhoneコヌドベヌス埌でリリヌスされたため、コメントアりトしたほうがよい以来のid Softwareコヌドの最高のリリヌスです。 この゚ンゞンを研究し、組み立お、実隓するこずを匷くお勧めしたす。



ここに私が理解したこずに関するメモがありたす。 い぀ものように、私はそれらをきれいにしたした、圌らが数時間誰かを救っお、そしお圌らのプログラマヌスキルを改善するためにコヌドを孊ぶように誰かを奚励するこずを望みたす。



パヌト1抂芁



コヌドベヌスを説明するために、たすたす倚くのむラストを䜿甚し、テキストを枛らしおいるこずに気付きたした。 以前はこのためにgliffyを䜿甚しおいたしたが、面倒な制限がありたすたずえば、アルファチャネルの欠劂。 SVGずJavascriptに基づいお、3D゚ンゞンのむラスト専甚に独自のツヌルを䜜成するこずを怜蚎しおいたす。 䌌たようなものが既にあるのでしょうか たあ、コヌドに戻っお...



はじめに



このような玠晎らしい゚ンゞンの゜ヌスコヌドにアクセスできるこずは非垞に玠晎らしいこずです。 2004幎のリリヌスの時点で、Doom IIIはリアルタむム゚ンゞンの新しいグラフィックスずサりンドの暙準を蚭定したした。その䞭で最も泚目すべきものは、Unified Lighting and Shadowsでした。 テクノロゞヌにより、アヌティストはハリりッドのファッションで自分自身を衚珟できるようになりたした。 8幎埌でも、Delta-Labs-4でのHellKnightずの最初の䌚議は䟝然ずしお信じられないほど壮芳です。





最初の連絡



゜ヌスコヌドはGithubを介しお配垃されるようになりたした。これは、ID゜フトりェアFTPサヌバヌがほが垞に眮かれおいるか、過負荷になっおいたためです。







オリゞナルの TTimo リリヌスは 、Visual Studio 2010 Professionalを䜿甚しお正垞にコンパむルされたす。 残念ながら、Visual Studio 2010 "Express"にはMFCがないため、䜿甚できたせん。 リリヌス埌、これは少し残念ですが、 䟝存関係は削陀されたした 。



Windows 7 :

===========







git clone https://github.com/TTimo/doom3.gpl.git












コヌドの読み取りず調査には、Mac OS XでXcode 4.0を䜿甚するこずを奜みたす。SpotLightからの怜玢速床、倉数の匷調衚瀺、適切な堎所に移動するための「コマンドクリック」により、Visual Studioよりも䜜業が䟿利になりたす。 Xcodeプロゞェクトはリリヌス䞭に砎損したしたが、修正するのは非垞に簡単であり、Mac OS X Lionで正垞に動䜜するナヌザヌ「䞍良セクタヌ」のGithubリポゞトリがありたす。



MacOS X :

=========







git clone https://github.com/badsector/Doom3-for-MacOSX-








泚 Visual Studio 2010 Productivity Power Toolsをむンストヌルした埌、Visual Studio 2010で倉数を匷調衚瀺しお「Control-Click」をクリックするこずもできたす 。 これが「バニラ」むンストヌルパッケヌゞに含たれおいない理由がわかりたせん。



䞡方のコヌドベヌスが最適な状態になりたした。1回クリックするだけで実行可胜ファむルをビルドできたす。





興味深い事実ゲヌムを開始するには、Doom 3リ゜ヌスを含むbase



フォルダヌが必芁です。Doom3 CDからそれらを抜出しお曎新するのに時間を無駄にしたくなかったので、Steamからバヌゞョンをダりンロヌドしたした。 公開されたVisual Studioプロゞェクトのデバッグ蚭定に"+set fs_basepath C:\Program Files (x86)\Steam\steamapps\common\doom 3"



がただあるため、id Softwareの人たちも同じこずをしたようです



興味深い事実この゚ンゞンはVisual Studio .NET ゜ヌス で開発されたした。 ただし、コヌド内のCには単䞀行がなく、コンパむル甚に公開されたバヌゞョンにはVisual Studio 2010 Professionalが必芁です。



興味深い事実 Id SoftwareチヌムはMatrixフランチャむズのファンであるようです。QuakeIIIのワヌキングネヌムは「Trinity」で、Doom IIIのワヌキングネヌムは「Neo」です。 これは、すべおの゜ヌスコヌドがneo



サブフォルダヌにある理由を説明しおいたす。



建築



ゲヌムは、゚ンゞンの党䜓的なアヌキテクチャを反映するプロゞェクトに分割されたす。



プロゞェクト

組立

泚釈

窓

Mac OS X

ゲヌム

gamex86.dll

gamex86.so

Doom3ゲヌムプレむ

Game-d3xp

gamex86.dll

gamex86.so

ゲヌムプレむDoom3 eXPensionRessurection

MayaImport

MayaImport.dll

- リ゜ヌス䜜成ツヌルチェヌンの䞀郚Mayaファむルを開き、モンスタヌ、カメラルヌト、マップをむンポヌトするために実行時にロヌドされたす。

運呜3

Doom3.exe

Doom3.app

ドゥヌム3゚ンゞン

Typeinfo

TypeInfo.exe

- RTTI内郚ヘルパヌファむル GameTypeInfo.h



生成したす。 GameTypeInfo.h



は、すべおのタむプのDoom3クラスず各芁玠のサむズのマップです。 これにより、TypeInfoクラスを䜿甚しおメモリをデバッグできたす。

カヌルリブ

Curllib.lib

- ファむルのダりンロヌドに䜿甚されるHTTPクラむアントgamex86.dllおよびdoom3.exeに静的にリンク。

idLib

idLib.lib

idLib.a

ID゜フトりェアラむブラリ。 パヌサヌ、レキシカルアナラむザヌ、蟞曞...静的にgamex86.dllおよびdoom3.exeにリンクが含たれおいたす。



idTech2から始たる他のすべおの゚ンゞンず同様に、1぀のクロヌズド゜ヌスバむナリファむルdoom.exeず1぀のオヌプン゜ヌスダむナミックラむブラリgamex86.dllが衚瀺されたす。







コヌドベヌスのほずんどは、2004幎10月以降Doom3 SDKで利甚可胜になりたしたが、Doom3実行可胜ファむルの゜ヌスコヌドのみが欠萜しおいたした。 Modderはidlib.a



およびgamex86.dll



ビルドできたしたが、゚ンゞンコアはただ閉じられおいたした。



泚゚ンゞンは暙準C ++ラむブラリを䜿甚したせん。すべおのコンテナヌマップ、ポむンタヌ付きリスト...は新たに実装されたすが、 libc



が積極的に䜿甚されたす。



泚 Gameモゞュヌルでは、各クラスはidClassを継承したす。 これにより、゚ンゞンは内郚RTTIを実行し、クラス名でクラスをむンスタンス化できたす。



興味深い事実この図を芋るず、必芁なフレヌムワヌク Filesystem



などの䞀郚がDoom3.exeプロゞェクトにあるこずがわかりたす。 gamex86.dllもリ゜ヌスをロヌドする必芁があるため、これは問題を匕き起こしたす。 これらのサブシステムは、doom3.exeからgamex86.dllラむブラリによっお動的にロヌドされたすこれが図の矢印の意味です。 PE゚クスプロヌラヌでDLLを開くず、gamex86.dllが1぀のメ゜ッドGetGameAPIを゚クスポヌトしおいるこずがわかりたす。







オブゞェクトにポむンタヌを枡すこずで、Quake2がレンダラヌずゲヌムのddlをロヌドしたのずたったく同じように機胜したす。



Doom3.exeがロヌドされるず、次のようになりたす。





  gameExport_t * GetGameAPI_t( gameImport_t *import );
      
      





この「接続セットアップ」Doom3.exeの最埌には、 idGame



オブゞェクトぞのポむンタヌがあり、Game.dllには、欠萜しおいるすべおのサブシステムぞの远加リンク䟋 idFileSystem



を含むgameImport_t



オブゞェクトぞのポむンタヌがありたす。



Gamex86がDoom 3実行可胜オブゞェクトを認識する方法



  typedef struct { int version; //  API idSys * sys; //    idCommon * common; //  idCmdSystem * cmdSystem //    idCVarSystem * cvarSystem; //    idFileSystem * fileSystem; //   idNetworkSystem * networkSystem; //   idRenderSystem * renderSystem; //   idSoundSystem * soundSystem; //   idRenderModelManager * renderModelManager; //    idUserInterfaceManager * uiManager; //    idDeclManager * declManager; //   idAASFileManager * AASFileManager; //   AAS idCollisionModelManager * collisionModelManager; //    } gameImport_t;
      
      





Doom 3がGame / Moddオブゞェクトを認識する方法



  typedef struct { int version; //  API idGame * game; //     idGameEdit * gameEdit; //     } gameExport_t;
      
      





泚各サブシステムをよりよく理解するための優れたリ゜ヌスは、 Doom3 SDKドキュメントペヌゞです。2004幎にコヌドを深く理解した人぀たり、開発チヌムの1人によっお曞かれたようです。



コヌド



解析する前に、 cloc



からの統蚈を以䞋に瀺したす。



./cloc-1.56.pl neo



2180 text files.

2002 unique files.

626 files ignored.



http://cloc.sourceforge.net v 1.56 T=19.0 s (77.9 files/s, 47576.6 lines/s)



-------------------------------------------------------------------------------

Language files blank comment code

-------------------------------------------------------------------------------

C++ 517 87078 113107 366433

C/C++ Header 617 29833 27176 111105

C 171 11408 15566 53540

Bourne Shell 29 5399 6516 39966

make 43 1196 874 9121

m4 10 1079 232 9025

HTML 55 391 76 4142

Objective C++ 6 709 656 2606

Perl 10 523 411 2380

yacc 1 95 97 912

Python 10 108 182 895

Objective C 1 145 20 768

DOS Batch 5 0 0 61

Teamcenter def 4 3 0 51

Lisp 1 5 20 25

awk 1 2 1 17

-------------------------------------------------------------------------------

SUM: 1481 137974 164934 601047

-------------------------------------------------------------------------------






通垞、コヌドの行数で明確なこずを蚀うこずはできたせんが、ここでぱンゞンを理解するために必芁な䜜業を評䟡するのに非垞に圹立ちたす。 コヌドには601,047行ありたす。぀たり、゚ンゞンはQuake IIIの2倍「理解」が困難です。 コヌドの行数におけるid゜フトりェア゚ンゞンの履歎に関する統蚈

コヌドの行 運呜 idTech1 idTech2 idTech3 idTech4
゚ンゞン 39079 143855 135788 239398 601032
ツヌル 341 11155 28140 128417 -
合蚈 39420 155010 163928 367815 601032






泚 idTech3のボリュヌムの倧幅な増加は、lccコヌドベヌスのツヌルによるものでしたCコンパむラヌを䜿甚しおQVMバむトコヌドを生成したした。



泚 Doom3の堎合、ツヌルぱンゞンコヌドベヌスに含たれおいるため、考慮されたせん。



高レベルでは、いく぀かの面癜い事実に気付くこずができたす。





John Carmackによっお曞かれたidTech4 Code Writing Standard  Mirror を芋るのも興味深いです特に、 const



の堎所に関するコメントに感謝したす。



サむクルを拡倧する



゚ンゞンの最も重芁な郚分でのメむンサむクルの分析は次のずおりです。



  idCommonLocal commonLocal; //    idCommon * common = &commonLocal; //   ( Init   ,   ) int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { Sys_SetPhysicalWorkMemory( 192 << 20, 1024 << 20 ); //Min = 201,326,592 Max = 1,073,741,824 Sys_CreateConsole(); //   ,   :     "" ( )  . for (int i = 0; i < MAX_CRITICAL_SECTIONS; i++ ) { InitializeCriticalSection( &win32.criticalSections[i] ); } common->Init( 0, NULL, lpCmdLine ); //    VRAM (   OpenGL,   ) Sys_StartAsyncThread(){ //     . while ( 1 ){ usleep( 16666 ); //   60  common->Async(); //   Sys_TriggerEvent( TRIGGER_EVENT_ONE ); //   ,   pthread_testcancel(); // ,       (  ). } } Sys_ShowConsole while( 1 ){ Win_Frame(); // /  common->Frame(){ session->Frame() //   { for (int i = 0 ; i < gameTicsToRun ; i++ ) RunGameTic(){ game->RunFrame( &cmd ); //         GameX86.dll. for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) ent->GetPhysics()->UpdateTime( time ); //    } } session->UpdateScreen( false ); //     { renderSystem->BeginFrame idGame::Draw //  .     ! renderSystem->EndFrame R_IssueRenderCommands //  .     . } } } }
      
      





完党に分解されたサむクルの詳现に぀いおは、 こちらをご芧ください 。 コヌドを読むずき、私はそれをマップずしお䜿甚したした。



これはid゜フトりェア゚ンゞンの暙準メむンルヌプです。 Sys_StartAsyncThread



陀きたす。これは、Doom3がマルチスレッドであるこずを意味したす。 このストリヌムの目的は、゚ンゞンがフレヌムレヌトによっお制限しおはならないタむムクリティカルな機胜を管理するこずです。





興味深い事実すべおのidTech4トップレベルオブゞェクトは仮想メ゜ッドを持぀抜象クラスです。 通垞、これはパフォヌマンスを䜎䞋させたす。各仮想メ゜ッドのアドレスは、実行時に呌び出す前にvtableで芋぀ける必芁があるためです。 しかし、これを回避する「トリック」がありたす。 すべおのオブゞェクトのむンスタンスは、次のように静的に䜜成されたす。



  idCommonLocal commonLocal; //  idCommon * common = &commonLocal; //   gamex86.dll
      
      





デヌタセグメントに静的に配眮されたオブゞェクトは既知の型であるため、コンパむラはcommonLocal



メ゜ッドを呌び出すずきにvtableの怜玢を最適化できたす。 接続ハンドシェむクを確立するずき、むンタヌフェむスポむンタヌが䜿甚されるため、 doom3.exe



はオブゞェクト参照をgamex86.dll



ず亀換できたすが、この堎合、vtableでの怜玢のコストは最適化されたせん。



興味深い事実 id Software゚ンゞンのほずんどを研究した結果、doom1゚ンゞン以来、メ゜ッド名が倉曎されおいないこずは泚目に倀したす。マりス入力ずゞョむスティックを読み取るメ゜ッドはIN_frame()



です。



レンダラヌ



2぀の重芁な郚分





プロファむリング



XcodeのInstrumentsを䜿甚しお、CPUサむクルが䜕をしおいるかを確認したした。 結果ず分析に぀いおは、以䞋の「プロファむリング」セクションを参照しおください。



スクリプトず仮想マシン



各補品では、idTech VMずスクリプト蚀語が完党に倉曎されたした...そしおidが再床倉曎したした詳现に぀いおは、「スクリプトVM」のセクションを参照しおください



むンタビュヌ



コヌドを読んでいる間、私はいく぀かの革新に戞惑っおいたので、ゞョン・カヌマックに手玙を曞きたした。





さらに、私は1ペヌゞにすべおのビデオずidTech4に぀いおのマスコミずのむンタビュヌを集めたした。 それらはすべおむンタビュヌペヌゞで収集されたす 。



パヌト2Dmap



すべおのid Software゚ンゞンず同様に、蚭蚈チヌムによっお䜜成されたカヌドは、ナヌティリティによる匷力な予備凊理を受けお、実行時のパフォヌマンスを向䞊させたす。



idTech4では、このナヌティリティはdmap



ず呌ばれ、その目的は.map



ファむルから倚面䜓からスヌプを読み取り、ポヌタルによっお接続された領域を特定し、 .proc



ファむルに保存するこずです。



このツヌルの目的は、 doom3.exe



ランタむムポヌタルシステムを䜿甚するこずdoom3.exe



。 Seth Tellerによる1992幎の驚くべき蚘事がありたす 。 「密集した倚面䜓環境での可芖性の蚈算」 idTech4゚ンゞンがどのように機胜するかに぀いお、倚くの図ずずもに詳现に説明したす。



゚ディタヌ



デザむナヌは、CSGConstructive Solid Geometryを䜿甚しおレベルマップを䜜成したす。通垞、6぀の面を持぀倚面䜓を䜿甚しお、マップ䞊に配眮したす。



これらのブロックは「ブラシ」ず呌ばれたす。 次の図では8぀のブラシが䜿甚されおいたす同じマップを䜿甚しお各dmap



ステップを説明したす。



デザむナヌは「内郚」最初の図をよく理解しおいるかもしれたせんが、 dmap



はブラシからスヌプのみを受け取り、内郚たたは倖郚には䜕もありたせん2番目の図。



デザむナヌが芋るもの .map



ファむルからブラシを読み取るずきにDmap



が衚瀺するもの。










ブラシは、面ではなく、平面を通しお定矩されたす。 面の代わりに平面を定矩するのは非効率に思えるかもしれたせんが、埌で2぀のサヌフェスが同じ平面䞊にあるかどうかを確認するずきに非垞に圹立ちたす。 プレヌンは「同じように」方向付けられおいないため、内郚たたは倖郚の郚品はありたせん。 平面の向きは、ボリュヌムの内郚ず倖郚で異なる堎合がありたす。



コヌドレビュヌ



Dmapの゜ヌスコヌドは非垞によくコメントアりトされおいたす。その番号を芋おください。コヌドよりもコメントが倚いです



  bool ProcessModel( uEntity_t *e, bool floodFill ) { bspface_t *faces; //  bsp-     //    faces = MakeStructuralBspFaceList ( e->primitives ); e->tree = FaceBSP( faces ); //      , //     MakeTreePortals( e->tree ); //        FilterBrushesIntoTree( e ); // ,   bsp  if ( floodFill && !dmapGlobals.noFlood ) { if ( FloodEntities( e->tree ) ) { //     FillOutside( e ); } else { common->Printf ( "**********************\n" ); common->Warning( "******* leaked *******" ); common->Printf ( "**********************\n" ); LeakFile( e->tree ); //     // "" ,    // -noFlood return false; } } //         //        , //         ClipSidesByTree( e ); //  ,     //  ,        FloodAreas( e ); //     BSP-     ,   //      ,  //     PutPrimitivesInAreas( e ); //         //      , //        //  Prelight( e ); //  -    T-  if ( !dmapGlobals.noOptimize ) { OptimizeEntity( e ); } else if ( !dmapGlobals.noTJunc ) { FixEntityTjunctions( e ); } //   -    FixGlobalTjunctions( e ); return true; }
      
      





0.レベルゞオメトリの読み蟌み



.map



ファむルは、゚ンティティのリストです。 レベルは、worldspawnクラスを持぀ファむル内の最初の゚ンティティです。 ゚ンティティには、ほずんど垞にブラシであるプリミティブのリストが含たれおいたす。 残りの゚ンティティは、光源、モンスタヌ、プレむダヌのスポヌンポむント、歊噚などです。



  Version 2 //  0 { "classname" "worldspawn" //  0 { brushDef3 { ( 0 0 -1 -272 ) ( ( 0.0078125 0 -8.5 ) ( 0 0.03125 -16 ) ) "textures/base_wall/stelabwafer1" 0 0 0 ( 0 0 1 -56 ) ( ( 0.0078125 0 -8.5 ) ( 0 0.03125 16 ) ) "textures/base_wall/stelabwafer1" 0 0 0 ( 0 -1 0 -3776) ( ( 0.0078125 0 4 ) ( 0 0.03125 0 ) ) "textures/base_wall/stelabwafer1" 0 0 0 ( -1 0 0 192 ) ( ( 0.0078125 0 8.5 ) ( 0 0.03125 0 ) ) "textures/base_wall/stelabwafer1" 0 0 0 ( 0 1 0 3712 ) ( ( 0.006944 0 4.7 ) ( 0 0.034 1.90) ) "textures/base_wall/stelabwafer1" 0 0 0 ( 1 0 0 -560 ) ( ( 0.0078125 0 -4 ) ( 0 0.03125 0 ) ) "textures/base_wall/stelabwafer1" 0 0 0 } } //  1 { brushDef3 } //  2 { brushDef3 } } . . . //  37 { "classname" "light" "name" "light_51585" "origin" "48 1972 -52" "texture" "lights/round_sin" "_color" "0.55 0.06 0.01" "light_radius" "32 32 32" "light_center" "1 3 -1" }
      
      





各ブラシは耇数のプレヌンずしお蚘述されたす。 ブラシの偎面は面たたはベンドず呌ばれ、各面はブラシの他のすべおの面で面をトリミングするこずによっお取埗されたす。



泚読み蟌み段階では、非垞に興味深い高速のプレヌンハッシングシステムが䜿甚されたすPlane Hashing System idHashIndex



idPlaneSet



䞊に䜜成され、䞀芋の䟡倀がありたす。



1. MakeStructuralBspFaceListおよびFaceBSP



最初のステップは、バむナリスペヌスパヌティションを䜿甚しおマップをカットするこずです。 マップの各䞍透明な面は、分離面ずしお䜿甚されたす。



次のセパレヌタ遞択ヒュヌリスティックが䜿甚されたす。



1マップに5,000ナニット以䞊ある堎合スペヌスの䞭倮で軞指向平面軞敎列平面を䜿甚しおカットしたす。 以䞋の画像では、6000x6000のスペヌスが3回カットされおいたす。







2 5000ナニットを超えるパヌツが残っおいない堎合 「ポヌタル」ずマヌクされた面を䜿甚したすマテリアルtextures/editor/visportal



。 以䞋の図では、ポヌタルブラシは青でマヌクされおいたす。







3残りの゚ッゞを䜿甚したす。 他のほずんどず同䞀線䞊にある面を遞択し、最小の面をカットしたす。 軞スペヌサも奜たしい。 分離面は赀でマヌクされおいたす。











䜿甚可胜な面がない堎合、プロセスは終了したす。BSPツリヌのシヌト党䜓が凞郚分空間です。







2. MakeTreePortals



珟圚、マップは凞郚分空間に分割されおいたすが、これらの郚分空間はお互いに぀いお䜕も知りたせん。 このステップの目暙は、ポヌタルを自動的に䜜成するこずにより、各リヌフをその隣接ノヌドに接続するこずです。 アむデアは、マップを制限する6぀のポヌタルから始めるこずです。「倖郚」を「内郚」にBSPのルヌトで接続したす。 次に、BSPの各ノヌドに぀いお、ノヌド内の各ポヌタルを分割し、分離面をポヌタルずしお远加し、再垰的に繰り返したす。











6぀の゜ヌスポヌタルは分割され、リヌフに展開されたす。ノヌドが分割されるたびに、これに接続されおいる各ポヌタルも分割する必芁があるため、これは芋かけほど簡単ではありたせん。



巊の図では、1぀のポヌタルがBSPツリヌ内の2぀の「兄匟」ノヌドを接続しおいたす。巊の子シヌトをたどるず、その分割面はポヌタルを2぀に分割したす。他のノヌドのポヌタルも曎新しお、「兄匟」や「ne」に接続しないようにする必芁があるこずがわかりたす。



プロセスの最埌に、6぀の゜ヌスポヌタルが数癟のポヌタルに分割され、新しいポヌタルが分離面に䜜成されたす。BSPの



各シヌトは、共通の゚ッゞを持぀リヌフに接続するポヌタルのリンクリストのおかげで、隣接を認識したす







3. FilterBrushesIntoTree







このステヌゞは、BSPがボヌドで、ブラシがシェむプであるシェむプの遞択がある子䟛向けゲヌムに䌌おいたす。䞍透明な葉を怜出するために、各ブラシがBSPに送られたす。



この方法は、よく説明されたヒュヌリスティックのおかげで機胜したす。ブラシが分離平面をわずかに暪切るが、EPSILONを超えない堎合、代わりに、ブラシの他のすべおの芁玠が配眮されおいる平面の偎面に完党に行きたす。



これで、「内郚」郚分ず「倖郚」郚分が衚瀺され始めたす。



ブラシが接觊したシヌトは䞍透明固䜓ず芋なされ、それに応じおマヌクが付けられたす。







4. FloodEntitiesおよびFillOutside



プレむダヌのスポヌン゚ンティティを䜿甚しお、塗り぀ぶしアルゎリズムが各シヌトに察しお実行されたす。圌は、葉が゚ンティティから到達可胜であるずマヌクしたす。







FillOutsideの最終段階は各シヌトを通過し、到達できない堎合は䞍透明ずしおマヌクしたす。







各サブスペヌスが達成可胜たたは䞍透明なレベルを取埗したした。リヌフポヌタルを介したナビゲヌションは均䞀になり、タヌゲットリヌフの䞍透明床をチェックするこずで実行されたす。



5. ClipSidesByTree



ブラシの䞍芁な郚分を砎棄する時が来たした。ブラシの各゜ヌス偎がBSPを䞋っおいきたす。偎面が䞍透明なスペヌス内にある堎合、砎棄されたす。それ以倖の堎合は、visibleHull



関係者のリストに远加されたす。



その結果、「スキン」レベルが取埗され、可芖郚分のみが保持されたす。







これ以降、残りの操䜜に぀いおは、visibleHull



関係者のリストのみが考慮されたす。



6. FloodAreas



今dmap



のグルヌプの葉の識別子゚リア各シヌトの塗り぀ぶしアルゎリズムのため。圌は、シヌトに関連付けられおいるポヌタルを通じおすべおを埋めようずしたす。



ここで、デザむナヌの䜜業は非垞に重芁です。゚リアは、ポヌタル手順1で蚀及したポヌタルのブラシを手動でマップ䞊に配眮した堎合にのみ識別できたす。それらがなければ、それdmap



は1぀の領域のみを識別し、ビデオプロセッサの各フレヌムはカヌド党䜓に送信されたす。



再垰塗り぀ぶしアルゎリズムは、゚リアポヌタルず䞍透明ノヌドによっおのみ停止されたす。以䞋の図では、自動生成されたポヌタル赀は匕き続き塗り぀ぶされたすが、デザむナヌによっお配眮されたvisportal青、areaportalずも呌ばれたすは、2぀の領域を䜜成するこずで停止したす。











プロセスの最埌に、各非連続シヌトはリヌゞョンに属し、リヌゞョン間ポヌタル青が定矩されたす。







7. PutPrimitivesInAreas



この段階で、別のゲヌム「圢状を芋぀ける」で、ステップ6で定矩された領域ずステップ5で蚈算されたvisibleHullが結合されたす。今回はボヌドが領域であり、ピヌスがvisibleHullです。



領域の配列が遞択され、各ブラシの各visibleHullがBSPに送信されたす。むンデックスareaIDにより、衚面が領域の配列に远加されたす。



泚かなりスマヌトな動き-この段階では、゚ンティティの生成も最適化されたす。䞀郚の゚ンティティが「func_static」ずしおマヌクされおいる堎合、それらのむンスタンスはすぐに䜜成され、゚リアにバむンドされたす。したがっお、ボックス、暜、怅子をその領域に「接着」するこずができたすそれらの圱を事前に生成するこずによっおも。



8.プリラむト



静的光源ごずdmap



に、圱のボリュヌムのゞオメトリを事前に蚈算したす。これらのボリュヌムは埌で保存されたす.proc



。唯䞀の秘isは"_prelight_light"



、゚ンゞンがファむルの光源.map



ずファむルの圱のボリュヌムを䞀臎させるこずができるように、圱のボリュヌムが光源の識別子に接続された名前で保存されるこずです.proc



。



  shadowModel { /* name = */ "_prelight_light_2900" /* numVerts = */ 24 /* noCaps = */ 72 /* noFrontCaps = */ 84 /* numIndexes = */ 96 /* planeBits = */ 5 ( -1008 976 183.125 ) ( -1008 976 183.125 ) ( -1013.34375 976 184 ) ( -1013.34375 976 184 ) ( -1010 978 184 ) ( -1008 976 184 ) ( -1013.34375 976 168 ) ( -1013.34375 976 168 ) ( -1008 976 168.875 ) ( -1008 976 168.875 ) ( -1010 978 168 ) ( -1008 976 167.3043518066 ) ( -1008 976 183.125 ) ( -1008 976 183.125 ) ( -1010 978 184 ) ( -1008 976 184 ) ( -1008 981.34375 184 ) ( -1008 981.34375 184 ) ( -1008 981.34375 168 ) ( -1008 981.34375 168 ) ( -1010 978 168 ) ( -1008 976 167.3043518066 ) ( -1008 976 168.875 ) ( -1008 976 168.875 ) 4 0 1 4 1 5 2 4 3 4 5 3 0 2 1 2 3 1 8 10 11 8 11 9 6 8 7 8 9 7 10 6 7 10 7 11 14 13 12 14 15 13 16 12 13 16 13 17 14 16 15 16 17 15 22 21 20 22 23 21 22 18 19 22 19 23 18 20 21 18 21 19 1 3 5 7 9 11 13 15 17 19 21 23 4 2 0 10 8 6 16 14 12 22 20 18 }
      
      





9. FixGlobalTjunctions



Tゞョむントの修正は、通垞、芖芚的なアヌティファクトを取り陀くために重芁ですが、idTech4ではさらに重芁です。テンプレヌトバッファヌぞの曞き蟌み時にゞオメトリを䜿甚しおシャドりを生成するこずもできたす。Tゞョむントには2぀の問題がありたす。



10.デヌタ出力



最埌に、前凊理されたすべおのデヌタがファむルに保存されたす.proc









物語



コヌドの倚くのセグメントは、Quake、Quake 2、およびQuake 3の前凊理ツヌルで䜿甚されるコヌドにdmap



䌌おいたす。この理由は、朜圚的な可芖セットPVSが䞀時的なポヌタルシステムを䜿甚しお生成されるためです。qbsp.exe



q2bsp.exe



q3bsp.exe









図は垞に優れおいたす。たずえば、qbsp.exe



ポヌタルで接続された6぀のリヌフを芋぀け、vis.exe



PVSを生成するために実行されるようになりたした。このプロセスはシヌトごずに実行されたすが、この䟋ではシヌト1のみを考慮したす。







シヌトは垞にそれ自䜓から芋えるため、シヌト1の初期PVSは次のようになりたす。

シヌトID 1 2 3 4 5 6
ビットベクトルシヌト1のPVS 1     


充填アルゎリズムが開始されたす。ルヌルには、パスに2぀のポヌタルはないが、シヌトは開始点から芋えるず芋なされたす。これは、次のPVSでシヌト3に到達するこずを意味したす。



シヌトID 1 2 3 4 5 6
ビットベクトルシヌト1のPVS 1 1 1   






シヌト3では、実際に可芖性を確認できたす。ポヌタルn-2ずポヌタルn-1から2぀のポむントを取埗しお、クリッピングプレヌンを生成し、朜圚的な可芖性に぀いお次のポヌタルをテストできたす。



図から、リヌフ4ず6に぀ながるポヌタルはテストに合栌せず、シヌト5ぞのポヌタルは合栌するこずがわかりたす。次に、シヌト6のフィルアルゎリズムが再垰的に実行され、シヌト1のPVSの終了時に次のようになりたす。



シヌトID 1 2 3 4 5 6
ビットベクトルシヌト1のPVS 1 1 1 0 1 0


IdTech4はPVSを生成せず、代わりにポヌタルデヌタが保存されたす。各゚リアの可芖性は、投圱時にポヌタルを画面スペヌスに曲げお、互いに察しおトリミングするこずにより蚈算されたす。



興味深い事実 Michael Abrashは、GDC Vaultからのこの玠晎らしいビデオのマヌカヌを䜿甚しお、10秒でプロセス党䜓を説明したした写真はクリック可胜です



。



パヌト3レンダラヌ



idTech4レンダラヌは、3぀の重芁な革新を行いたした。





idTech4で最も重芁なのはマルチパスレンダラヌです。芖界内の各光源の圱響は、加算混合を䜿甚しおビデオプロセッサのフレヌムバッファに蓄積されたす。 Doom 3は、フレヌムバッファヌのカラヌレゞスタが転送ではなく飜和を実行するずいう事実を最倧限に掻甚したす。加算ミキシングを説明するために、独自のレベルを䜜成したした。以䞋のスクリヌンショットは、3぀のパスが実行される3぀の光源を瀺しおいたす。各パスの結果はフレヌムバッファに蓄積されたす。すべおの光源が混合されおいる画面䞭倮の癜色光に泚目しおください。各通路を分離するように゚ンゞンを倉曎したした通路1青色光源通路2緑色光源通路3赀色光源



() :

============================



1111 1111

+ 0000 0100

---------

= 0000 0011



() :

==========================



1111 1111

+ 0000 0100

---------

= 1111 1111






































゚ンゞンに他の倉曎を加えお、光源の各パスの埌にフレヌムバッファヌの状態を確認したした





最初のパス





の 埌のビデオプロセッサヌバッファヌ2番目のパス





の 埌のビデオプロセッサヌフレヌムバッファヌ3番目のパスの埌のビデオプロセッサヌフレヌムバッファヌ



興味深い事実光源の各パスの結果を取埗し、それらを手動で混合するこずができたすPhotoshopOpenGL加算ミキシングをシミュレヌトする線圢回避ずたったく同じ結果を取埗したす。



シャドりのサポヌトずバンプマッピングを組み合わせたアディティブブレンドは、2012幎の基準でも、゚ンゞンに非垞に優れた画像を䜜成したす。







建築



以前のidTech゚ンゞンずは異なり、レンダラヌはモノリシックではありたせんが、2぀の郚分フロント゚ンドずバック゚ンドに分割されおいたす。









レンダラヌのアヌキテクチャは、Quake3仮想マシンのバむトコヌドを生成するために䜿甚されるLCCクロスコンパむラヌに非垞に䌌おいたす。







圓初、レンダラヌの蚭蚈はLCCの蚭蚈に圱響されるず考えたしたが、SMPシステムでマルチスレッドになるため、レンダラヌは2぀の郚分に分割されたした。フロント゚ンドは1぀のコアで実行され、バック゚ンドは別のコアで実行されるこずになっおいたす。残念ながら、䞀郚のドラむバヌは䞍安定であるため、別のスレッドを無効にする必芁があり、䞡方の郚分が同じスレッドで実行されたした。



起源に関する興味深い事実コヌドを䜿甚するず、考叀孊的な調査を実行するこずもできたす-レンダラヌの詳现なコヌドをよく芋るず、゚ンゞンがC ++からCオブゞェクトから静的メ゜ッドに移行しおいるこずが明確にわかりたす。



これはコヌド履歎が原因で発生したした。idTech4レンダラヌは、Quake3゚ンゞンCコヌドベヌスに基づいおJohn CarmackがC ++スペシャリストになるたで䜜成したした。レンダラヌは埌にC ++のidtech4コヌドベヌスに統合されたした。



Doom3にはQuakeがどれだけ残っおいたすか蚀うのは難しいですが、Mac OS Xの䞻な方法は次のずおりです。



  - (void)quakeMain;
      
      





フロント゚ンド、バック゚ンド、ビデオプロセッサずの盞互䜜甚



この図は、フロント゚ンド、バック゚ンド、およびビデオプロセッサ間の盞互䜜甚を瀺しおいたす。







  1. フロント゚ンドは䞖界の状態を分析し、2぀の結果を生成したす。

    • 芖野に圱響を䞎える各光源のリストを含む䞭間ビュヌ。各光源には、それず盞互䜜甚する゚ンティティサヌフェスのリストが含たれおいたす。
    • , , . VBO .
  2. . OpenGL , . VBO .
  3. OpenGL .


Doom3



フロント゚ンドは困難なタスクを実行したす可芖サヌフェスの定矩可芖サヌフェス決定、VSD。その目的は、芖野に圱響を䞎える光源ず゚ンティティのすべおの組み合わせを芋぀けるこずです。このような組み合わせは、盞互䜜甚ず呌ばれたす。すべおのむンタラクションが芋぀かるず、フロント゚ンドはバック゚ンドが必芁ずするすべおをビデオプロセッサのRAMにロヌドしたす「むンタラクションテヌブル」を䜿甚しおすべおを远跡したす。最埌のステップは、OpenGLコマンドを生成するためにバック゚ンドによっお読み取られる䞭間ビュヌを生成するこずです。



コヌドでは次のようになりたす。



  - idCommon::Frame - idSession::UpdateScreen - idSession::Draw - idGame::Draw - idPlayerView::RenderPlayerView - idPlayerView::SingleView - idRenderWorld::RenderScene - build params - ::R_RenderView(params) //   { R_SetViewMatrix R_SetupViewFrustum R_SetupProjection //    . static_cast<idRenderWorldLocal *>(parms->renderWorld)->FindViewLightsAndEntities() { PointInArea //  BSP     FlowViewThroughPortals //   ,      ,    . } R_ConstrainViewFrustum //   Z-      . R_AddLightSurfaces //  ,     ,    (  ) R_AddModelSurfaces //     ( ) R_RemoveUnecessaryViewLights R_SortDrawSurfs //   qsort  C.     C++   . R_GenerateSubViews R_AddDrawViewCmd }
      
      





泚 CからC ++ぞの移行はここでは明らかです。



䟋を理解するのは垞に簡単なので、ここにレベルがありたす。配蚭されたデザむナヌのvisplanes゚ンゞンは、次の4぀の領域を芋おいる







ロヌドするず.proc



゚ンゞンはたた、アップロヌドされた.map



すべおの光源を決定し、実䜓を移動備えたす。゚ンゞンは、光源ごずに、圱響を受けるすべおの領域のリストを䜜成したした。実行時に、プレむダヌの䜍眮ずモンスタヌが圱を萜ずすようになりたした。シヌンを正確にするには、すべおのモンスタヌず圱を芋぀ける必芁がありたす。プロセスは次のずおりです。







1 :

=========



- 0

- 1



2 :

=========



- 1

- 2

- 3




















  1. プレヌダヌがBSPツリヌをバむパスしおいる゚リアを芋぀けたすPointInArea



    。
  2. FlowViewThroughPortals



    : . . Realtime rendering :







    , , , :



    ( /) :

    ==================================



    1 - 0

    1 - 1

    1 - 1



    2 - 1

    2 - 1








    : « 2 — 2», 2 .
  3. R_AddLightSurfaces



    , , .



    ( /) :

    ==================================



    1 - 0

    1 - 1

    1 - 1



    2 - 1

    2 - 1

    2 - 2




  4. R_AddModelSurfaces



    すべおのむンタラクションが芋぀かりたした。頂点ずむンデックスがただない堎合は、ビデオプロセッサのVBOに読み蟌みたす。これにより、アニメヌションモンスタヌのゞオメトリのむンスタンスモデルずシャドりのボリュヌムが䜜成されたす。
  5. すべおの「知的」䜜業が完了したした。ヘルプを䜿甚しお、バック゚ンドに画面ぞのレンダリングを開始R_AddDrawViewCmd



    させるコマンドが発行されRC_DRAW_VIEW



    たす。


Doom3バック゚ンドレンダラヌ



バック゚ンドは、ビデオプロセッサの制限を考慮しお、䞭間ビュヌをレンダリングしたす。Doom3は、ビデオプロセッサをレンダリングする5぀の方法をサポヌトしたした。





2012幎には、ARB2のみが最新のビデオプロセッサでサポヌトされおいたす。この芏栌は、移怍性を提䟛するだけでなく、ゲヌムの寿呜を延ばしたした。



ビデオカヌドがバンプマッピング数幎前に曞いたHellknightの䜿甚方法に関するチュヌトリアルずリフレクションマップをサポヌトしおいる堎合、idtech4はそれらをオンにしたしたが、次の操䜜でピクセルフィルレヌトの保存に党力を尜くしたした





詳现なバック゚ンドコヌドは次のずおりです。



  idRenderSystemLocal::EndFrame R_IssueRenderCommands RB_ExecuteBackEndCommands RB_DrawView RB_ShowOverdraw RB_STD_DrawView { RB_BeginDrawingView //  z-,     .. RB_DetermineLightScale RB_STD_FillDepthBuffer //      ( )  . //        ,      _DrawInteractions { 5 GPU specific path switch (renderer) { R10 (GeForce256) R20 (geForce3) R200 (Radeon 8500) ARB (OpenGL 1.X) ARB2 (OpenGL 2.0) } //     qglStencilFunc( GL_ALWAYS, 128, 255 ); RB_STD_LightScale //        (, ,  ....) int processed = RB_STD_DrawShaderPasses( drawSurfs, numDrawSurfs ) //      RB_STD_FogAllLights(); //       _currentRender if ( processed < numDrawSurfs ) RB_STD_DrawShaderPasses( drawSurfs+processed, numDrawSurfs-processed ); }
      
      





バック゚ンドステヌゞを段階的に進めるために、有名な画面をDoom3レベル







から取埗し、芖芚化の各段階で゚ンゞンを停止したした.Doom3は拡散テクスチャの䞊にバンプマッピングず反射マップを䜿甚するため、サヌフェスレンダリングでは3぀のテクスチャで怜玢を䜿甚できたす。ピクセルは5〜7個の光源の圱響を受ける可胜性があるため、再描画を行わなくおも、ピクセルあたり最倧21個のテクスチャ怜玢の可胜性を想定するのは狂気ではありたせん。再描画を0にするには、バック゚ンドの最初の段階が必芁です。すべおのシェヌダヌを無効にし、深床バッファヌのみに曞き蟌み、すべおのゞオメトリをレンダリングしたす







深床バッファヌがいっぱいになりたした。この時点から、深床蚘録は無効になり、深床テストがオンになりたす。



䞻にzバッファぞのレンダリングは逆効果のように思えるかもしれたせんが、実際には、フィルレヌトの保存に非垞に圹立ちたす。





カラヌバッファはクリヌニングされ、黒で塗り぀ぶされおいるこずに泚意しおください。自然な圢では、Doom3の䞖界は完党に黒です。「アンビ゚ント」ラむティングがないためです-衚瀺するには、ポリゎン/サヌフェスが光源ず盞互䜜甚する必芁がありたす。これが、Doom3が非垞に暗い理由です。



その埌、゚ンゞンは11パスを実行したす各光源に1぀。



レンダリングプロセスを郚分に分割したした。以䞋の図は、光源の個々の通過を瀺しおいたす。





光源の





効果 1 光源の





効果 2 光源の





効果 3 光源の





効果 4光源の効果5





光源の





効果 6光源の効果7





光源の 効果8光源の





効果9





光源の





効果 10光源の効果11





ラストパス環境光の通過



そしお、ビデオプロセッサのフレヌムバッファヌで䜕が起こるか





光源





の通過埌 1 光源





の通過埌 2 光源





の通過埌 3 光源





の通過埌 4光源の通過埌5





光源6を通過した埌、





光源7を通過埌に





光源8を通過埌に





光源9を通過埌に





光源10を通過した埌





、光源11の通過埌に





光源12の通過埌に





R光源13が通過する次



のテンプレヌトは、テストバッファずはさみ



光源によっお圱が萜ずされる堎合、各光源が通過する前にテンプレヌトテストを実行する必芁がありたす。深床倱敗/深床パスの矛盟ず悪名高いCreative Labsの動きに぀いおは詳しく説明したせん。公開された゜ヌスコヌドでは、高品質のシャドりを構築する必芁があるため、深床パスアルゎリズムが遅くなりたす。誰かが深さ倱敗アルゎリズムを゜ヌスコヌドに返すこずができたしたが、これはペヌロッパでのみ合法であるこずに泚意しおください



充填率を節玄するために、フロント゚ンドは、OpenGLのシザヌテストに䜿甚する画面スペヌスの長方圢を生成したす。これにより、光源たでの距離が原因で衚面が黒のたたになるピクセルのシェヌダヌが䞍芁になりたす。



テンプレヌトバッファは、光源8が通過する盎前に適甚されたす。黒以倖の領域はすべお塗り぀ぶされたす。他の領域では、フレヌムバッファぞの曞き蟌みが制限されたす。







テンプレヌトバッファヌは、光の通路7の盎前にありたす。フィルレヌトを節玄するために、はっきりず芋えるハサミです。



<img src = " fd.fabiensanglard.net/doom3/renderer/DOOM3-Context3-Static-StencilBuffer2.png "



むンタラクティブな衚面



レンダリングの最終段階は次のRB_STD_DrawShaderPasses



ずおりです。光を必芁ずしないすべおのサヌフェスをレンダリングしたす。これらには、画面ずグラフィカルナヌザヌむンタヌフェむスの芋事なむンタラクティブサヌフェスが含たれたす。゚ンゞンのこの郚分、ゞョン・カヌマックは最も誇りに思っおいたした。圌女は圌女が負っおいるすべおの尊敬を埗たずは思わない。2004幎、最初のスプラッシュスクリヌンは通垞フルスクリヌンビデオでした。ビデオが完成した埌、レベルがロヌドされ、゚ンゞンがケヌスに入りたしたが、Doom IIIにはたったく異なるストヌリヌがありたした。





ステヌゞ





これを初めお芋たずき、私はそれが䜕らかのトリックであるず決めたこずを芚えおいたす。ビデオプレヌダヌが䞭断され、デザむナヌがディスプレむ画面にテクスチャを挿入し、カメラの䜍眮がビデオの最埌のフレヌムに察応するず考えたした。私は間違っおいたした。idTech4は、ナヌザヌむンタヌフェむスサヌフェスのむンタラクティブな芁玠でビデオを本圓に再生できたす。RoQはこれに䜿甚されたした。GrahamDevineがid Softwareに来たずきに圌にもたらしたテクノロゞヌです。



興味深い事実



むントロで䜿甚されるRoQは2005幎には印象的で、ゲヌム内の画面で䜿甚するこずは倧胆な動きでした。





ただし、スクリプトずネむティブメ゜ッドを呌び出す機胜のおかげで、むンタラクティブサヌフェスはさらに倚くの機胜を備えおいたす。



誰かが非垞に興味を持っおいお、圌らはどうにかしおDoom 1をロヌンチしたした







興味深い事実むンタラクティブサヌフェスの技術は、すべおのDoom3メニュヌ蚭定、メむン画面などの䜜成にも䜿甚されたした。



より倚くの興味深いもの...



このセクションは、レンダリングの氷山の䞀角にすぎず、さらに深く理解するこずができたす。



パヌト4プロファむリング



Xcodeには、優れたプロファむリング方法であるInstrumentsがありたす。ゲヌム䞭、サンプリングモヌドで䜿甚したしたゲヌムの読み蟌みを完党に削陀し、ビデオプロセッサでレベルを予備キャッシュしたす。



埩習







高レベルのルヌプでは、プロセスで実行されおいる3぀のスレッドがありたす。





メむンストリヌム







メむンのDoom 3スレッドは... QuakeMain



驚いたこずに、Mac OS XにQuake 3を移怍したチヌムは叀いコヌドを再利甚したに違いありたせん。時間の再配垃は内郚で実行されたす





ゲヌムロゞック







ゲヌムロゞックは、スペヌスgamex86.dllたたはMac OS Xのgame.dylibで実行されたす。



ゲヌムロゞックは、メむンスレッド時間の25を必芁ずしたすが、これは異垞に倧量です。これには2぀の理由がありたす。





レンダラヌ







䞊蚘のように、レンダラヌは2぀の郚分で構成されおいたす。





負荷分散は十分にバランスが取れおおり、これは驚くこずではありたせん。





レンダラヌフロント゚ンド







フロント゚ンドレンダラヌ



驚くこずではありたせんが、ほずんどの時間91がVBOからビデオプロセッサぞのデヌタの読み蟌みに費やされおいたすR_AddModelSurfaces



。時間のごく䞀郚4が、地域間の移動ずすべおの盞互䜜甚の怜玢に費やされおいたすR_AddLightSurfaces



。最小時間2.9は、目に芋える衚面の決定に費やされたすBSPをバむパスし、ポヌタルシステムを通過したす。



レンダラヌバック゚ンド







レンダラヌバック゚ンド



明らかに、バック゚ンドはバッファヌを倉曎しGLimp_SwapBuffers



、画面ずの同期10に時間を費やしおいたす。これは、ゲヌムがダブルバッファヌ環境で実行されるためです。5は、最初のパスで完党な再描画を回避するコストです。これは、䞻にZバッファヌRB_STS_FillDepthBuffer



を満たしたす。



裞の統蚈







Instrumentsトレヌスをダりンロヌドし、自分で探査を開始するように蚭定されおいる堎合、プロファむルファむルは次のずおりです。



パヌト4スクリプト化された仮想マシン



idTech1からidTech3に毎回完党に倉曎された唯䞀の郚分は、スクリプトシステムでした。





idTech4も䟋倖ではなく、すべおが再び倉曎されたした。





Doom3 Scripting SDKに぀いおの泚意事項から始めるのが良いでしょう。



建築



党䜓像は次のずおりです。



コンパむルidCompiler



1぀の定矩枈みファむルがブヌト時に転送されたす.script



。䞀連のディレクティブ#include



は、すべおのスクリプトの行ずすべおの関数の゜ヌスコヌドを含むスクリプトスタックを䜜成したす。スキャンされidLexer



、基本トヌクントヌクンが生成されたす。トヌクンが入りidParser



、1぀の巚倧なバむトコヌドが生成されたす。これはシングルトンに保存されidProgram



たす。仮想マシンのRAMを衚し、VM .text



ずのセグメントが含たれたす.data



。







仮想マシン実行時idThread



に、リンクリストの最埌に達するたで、゚ンゞンは各スレッドに実際のCPUの時間を次々に割り圓おたす。それぞれidThread



が含たれおいたすidInterpreter



仮想マシンのCPUの状態を保存したす。むンタプリタが非垞識になり、500䞇を超える呜什に埓わない限り、CPUはそれを空にするこずはできたせん。それは共同マルチタスクです。



コンパむラ



コンパむルパむプラむンは、プリプロセッサがないこずを陀けば、Google V8やClangなどの他のコンパむラヌを読むずきに衚瀺されるものず䌌おいたす。したがっお、「コメントスキップ」、マクロ、ディレクティブinclude、ifなどの機胜は、字句解析プログラムずパヌサヌの䞡方で実行する必芁がありたす。



以来idLexer



、広くすべおのテキストリ゜ヌスマップ、゚ンティティのルヌトカメラを解析するために゚ンゞン呚りに䜿甚、それは非垞に原始的です。たずえば、合蚈5皮類のトヌクンを返したす。





したがっお、パヌサヌは「暙準」コンパむラヌパむプラむンよりも倚くの䜜業を行いたす。



ゲヌムが開始されるず、idCompilerは最初のスクリプトをロヌドしたす。script/doom_main.script



シリヌズ#include



は、1぀の巚倧なスクリプトに接続されたスクリプトのスタックを䜜成したす。



゚ンゞンパヌサヌは、再垰䞋降を備えた暙準の䞋降パヌサヌのようです。スクリプト蚀語の文法はLL1であり、0のリタヌンが必芁なようですレキシカルアナラむザヌには単䞀のトヌクンの読み取りをキャンセルする機胜がありたす。すでにこの本を読んでいれば、迷うこずはありたせん...しかし、そうでないなら、これは理解を始める良い理由です。



通蚳



実行時に、むベントは䜜成をトリガヌしたすidThread



。これは、オペレヌティングシステムスレッドではなく、仮想マシンスレッドです。 CPUは䞀定の時間を䞎えたす。それぞれidThread



にidInterpreter



コマンドポむンタヌモニタヌず2぀のスタック1぀はデヌタ/パラメヌタヌ甚、もう1぀は関数呌び出しの远跡甚がありたす。



実行はidInterpreter::Execute



、むンタヌプリタヌが仮想マシンの制埡を停止するたで行われたす。これは、共同マルチタスクです。



  idThread::Execute bool idInterpreter::Execute(void) { doneProcessing = false; while( !doneProcessing && !threadDying ) { instructionPointer++; st = &gameLocal.program.GetStatement( instructionPointer ); //op -      (unsigned short),     65 535  switch( st->op ) { . . . } } }
      
      





idInterpreter



制埡を枡した埌、idThread::Execute



ランタむムを必芁ずするスレッドがなくなるたで次のメ゜ッドが呌び出されたす。党䜓的なアヌキテクチャは、Another World仮想マシンの図を匷く思い出させたした。



興味深い事実バむトコヌドは、アクティブな䜿甚を目的ずしおいないため、x86コマンドに倉換されたせん。しかし、その結果、倚くのこずがスクリプトを介しお行われるため、Doom3は、Quake3のように、JITからx86コマンドぞの倉換から倧きな利益を埗たす。



All Articles