(轉)Delta3D源碼分析


最近學習Delta3D,  2.4版忙着發布,一直不能成功編譯SimCore, 索性靜下心來看看源碼,官網上竟然提供了幾個重要組建的軟件設計說明書(SDD),雖說基本都是2005版了,不過我看了后覺得主要構架仍然沒有改變, 這幾份SDD對於學習Delta3D具有很好的參考價值。

分析源碼要從頂層着手,所以在看了GM部分的SDD后,我翻出源碼看了下,順便畫幾張序列圖,算是做個筆記。

分析主要根據TankTargetTutorial(這也是我現在唯一能跑的DEMO),源碼版本是09-10-12日的SVN。

Delta3D上層構架主要由 GameManager, GameActor, GameActorProxy, Components這幾個組建構成:

  Delta3D源碼分析(轉) - zhanglei2752 - 心靜如水
總體構架圖
由上圖可看出 GameActor,Components等其他組建都統一由GM(GameManager 下同)管理。
GameManage: 統一管理游戲中的各種資源。完成程序運行時消息處理配送等重要工作,是一個樞紐類
  Delta3D源碼分析(轉) - zhanglei2752 - 心靜如水
GM處理消息
GameActor:主要是游戲中的實際對象,如坦克,飛機等,它需要完成處理與自己相關的消息,更新自我狀態等任務。 

GameActorProxy: 和GameActor是一對一的關系,既用戶每定義一個GameActor,就需要定義一個預期相關的GameActorProxy。其主要任務是提供一個統一的對GameActor的各個屬性進行存取操作的接口。接口的統一方便了GM的實現。同時在GM構架中GameActorProxy還起到了消息處理中間層的重要作用。

Components: 是一些游戲的輔助系統,主要功能是在一個較高層次上統一對系統中的信息進行處理(如實現網絡通信,用戶輸入處理等)。

簡單的說,使用Delta3D編寫游戲,我們只需要實現自己的GameActor,以及Components以完成本應用需要的特定任務,然后按照一定的接口規范將其交給GM管理即可。我們來看一下大致的情況

第一步: 導入Actor

在現有系統下,Delta3D要求用戶將自己的GameActor編譯成插件形式(Windows下為DLL文件),進而實現能動態載入系統的功能。
Delta3D源碼分析(轉) - zhanglei2752 - 心靜如水
導入Actor
   上圖顯示了Delta3D導入用戶定義的GameActor的流程,用戶除了要實現自己的GameActor外,還需實現一個ActorPluginRegistry類來作為插件的接口來完成插件注冊的工作。很自然,一個ActorPluginRegistry類可以包含多個GameActor對象。

第二步:創建Actor
通過第一步我們將GameActor集以插件的形式導入進來,這時程序就可以創建我們需要的GameActor對象了。
   
Delta3D源碼分析(轉) - zhanglei2752 - 心靜如水
創建Actor
   從上圖我們可以看出創建GameActor又分兩步,第一步是CreateActor, 這一步目的是從剛才導入並注冊到系統的插件中找到並創建一個我們想要的GameActor對象。
第二部為AddCreate, 這一步可以理解為將得到的Actor對象加入到游戲場景中。在這一步我們需要完成該GameActor對象的初始化操作, 最重要的任務是對該GameActor需要處理的消息注冊到GM中。這一步也是由用戶完成的,這樣加強了一定的靈活性。

第三步:消息處理流程
有了上面兩步,這一步基本上就是Delta3D自己的事情了,我們來看一下Delta3D是如何處理消息的。
Delta3D源碼分析(轉) - zhanglei2752 - 心靜如水
消息處理
   上圖顯示了Delta3D在GM構架下處理消息的流程(僅僅是GameActor接受消息部分)。 一般處理是流程1,這是是GM維護一個消息和GameActor的映射關系表。
然而Delta3D也提供了一定的靈活性,允許GameActor自己同時也維護一個消息和自身的映射表來更靈活的處理消息。如流程2是所示。Delta3D有兩套消息處理框架,一套是較低層的以Application類為核心的處理機制,大部分源碼包中的Example采用該機制。 一套是較高層的以GameManager類為核心的處理機制,為源碼中的Demo所采用。

所有基於Delta3D的程序都要有一套Application處理機制,我們來看下它的實現。

Delta3D源碼分析(轉) - zhanglei2752 - 心靜如水
類圖
      在上圖中需要說明的是, 低層消息基於Base類的消息傳送機制(BASE類消息機制可見OSGCHINA社區Delta3D版的一篇文章), BaseABC是一個抽象類,定義了四個純虛函數。其OnMessage函數執行了將消息分配到這四個函數的工作。 Application類通過實現該四個純虛函數完成消息處理,同時Application擁有鍵盤和鼠標的監聽器,通過實現並注冊相應的回調函數完成鍵盤,鼠標的輸入響應。 GameApplication與Application類的唯一區別就是引入了GM。
程序運行時,GameApplication除了完全照搬執行Application的消息循環外,還通過GM進行高層消息處理循環,也即其同時擁有兩套消息機制。
需要注意的是,GM繼承自Base,他在構建時向System類進行消息注冊,可以直接和系統底層消息隊列打交道。
  Delta3D采用OSG進行渲染工作。我們來看一下其低層接口是如何設計的。
Delta3D源碼分析(轉) - zhanglei2752 - 心靜如水
接口類圖
上圖中綠色的類直接提供了對OSG相關對象的封裝。 DeltaDrawable類是Delta3D中所有可顯示對象的基類(例如Actor, GameActor,Object等),它封裝了一個osg:Node。

Delta3D通過Scene類進行場景管理,可以看到Scene和View繼承自Base,因而也都擁有了接受,發送低層消息的能力。 因為Delta3D在低層內置了ODE進行物理模擬,Scene類在初始化時向System進行了注冊,現在主要是進行接受每幀System發出的消息,調用ODE接口完成物理計算操作。而View類沒有通過封裝osg::View進行相關視口顯示工作,沒有重載OnMessage函數,因而不接受消息,主要工作配合Application類處理用戶交互的輸入。


程序啟動時, 有關函數進行關聯操作,來看下序列圖:
Delta3D源碼分析(轉) - zhanglei2752 - 心靜如水
Scene啟動配置
從圖中可以看到有來該流程有兩次綁定工作,第一次將Scene的根節點傳給Viewer類,建立了OSG需要的渲染數據鏈接關系。第二次通過將Viewer對象綁定到Application的CompositeViewer成員,每幀由Application相應的函數執行渲染操作(調用CompositeViewer的Frame函數)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM