OGRE 3D
海外ゲーム技術勉強会#1 資料   @minahito
本日のお話

OGREを使う

OGREの拡張性

OGREのレンダリング

Plugin アーキテクチャ/Reference App Layer
OGRE 3D
Object-oriented Graphics
Rendering Engine

シーングラフベースの描画システム

抽象化によりDirectX/OpenGLに両
対応

MITライセンス

                           ちょっとだけ紹介してます↑
OGRE 3D
2001-2002年頃開発開始、2005年リリース

当時まだそれほどジャスティスではなかった STL
を多用、主要なジャンプはほぼvtable経由、なにこ
れ重い!(2001年)→PCの発展で超余裕に

個人ではなくチームでメンバーを刷新しながら開
発、コミュニティも充実
OGRE 3D
2001-2002年頃開発開始、2005年リリース

当時まだそれほどジャスティスではなかった STL
を多用、主要なジャンプはほぼvtable経由、なにこ
れ重い!(2001年)→PCの発展で超余裕に

個人ではなくチームでメンバーを刷新しながら開
        最近のバージョンでは、毎フレーム解放再確保
発、コミュニティも充実
      するようなコンテナは自前の効率の良いアロ
        ケータを使うようになっている
OGRE 3D

オープンソースプロジェクトなので特定タイトル向
けの設計傾向を極力排除できる

設計>速度(製品作ってご飯食べるわけじゃない
から)

Game Engine Architecture などでも紹介
お話ししたいこと
オブジェクト指向でエンジンを提供すると、なにが
できて、コード面はどうなっちゃうのか

OGRE はOOの利点をゲームタイトルにおける部分
的改造と追加、そしてそのre-useに利用

タイトル非特化フレームワークやエンジンの開発ミッ
ションを背負ってる方の参考情報のひとつに
お話ししたいこと
オブジェクト指向でエンジンを提供すると、なにが
できて、コード面はどうなっちゃうのか

OGRE はOOの利点をゲームタイトルにおける部分
的改造と追加、そしてそのre-useに利用

タイトル非特化フレームワークやエンジンの開発ミッ
ションを背負ってる方の参考情報のひとつに
 描画エンジン的観点では見るべき点は少ないです!
お話ししたいこと
オブジェクト指向でエンジンを提供すると、なにが
できて、コード面はどうなっちゃうのか

 OGRE はOOの利点をゲームタイトルにおける部分
 的改造と追加、そしてそのre-useに利用
     得られるものもありますが、今の時期を考える
     と、 OGRE をじっくり見るより、まずなにより
タイトル非特化フレームワークやエンジンの開発ミッ
     DX11 を触っておくべき時期だと思います!
ションを背負ってる方の参考情報のひとつに
 描画エンジン的観点では見るべき点は少ないです!
OGREを使う
本題じゃないのでさらっと
ExampleApplication
ExampleApplication は即
OGREアプリを作るための
簡易フレームワーク

下位ライブラリと明確に分
けられている

使わなくても良い
ExampleApplication
ExampleApplication は即
OGREアプリを作るための
簡易フレームワーク

下位ライブラリと明確に分
けられている
                        導入開始時のMAINが短いのは
使わなくても良い
                         使う側にはありがたい
シーングラフの構築
シーングラフの構築




   UnityのTransformコンポーネントみたいなもの
MovableObject


エンティティ、ライト、カメラ等はシーンノードの継承
クラスではない→ノードにアタッチして使う

アタッチ可能IF : MovableObject を継承

シーングラフノードとMovableObjectを別系統で拡張可
能
MovableObject


エンティティ、ライト、カメラ等はシーンノードの継承
クラスではない→ノードにアタッチして使う
       ゲームオブジェクトは自前で定義することにな
          る。これら MovableObject を継承拡張して
アタッチ可能IF : MovableObject を継承
          ゲームオブジェクトを定義するというより、コ
       ンポーネント扱いして、コンポジットして作る
シーングラフノードとMovableObjectを別系統で拡張可
能         のが一般的。
フレーム前後の処理




FrameEvent の中に⊿時間なども入っている
フレーム前後の処理


        OGREはかなり多くのクラスが専用のリスナー
        を備えており、前後処理のフックや特定イベン
        トの通知を受け取れる。

        クラスを書き換えなくて済むし、インスタンス
        単位で別の処理ができるし、拡張されたクラス
            に対しても共通のリスナーを食わせられる。
FrameEvent の中に⊿時間なども入っている
OGREの拡張性
OGREの拡張性
既存のクラスを継承拡張する

 →RenderSystem

 →SceneManagerでよくやる

OGREが持っていない機能を単に追加

特定役割のオブジェクトを差し替える(後述)
OGREの拡張性
既存のクラスを継承拡張する

 →RenderSystem

 →SceneManagerでよくやる

OGREが持っていない機能を単に追加

特定役割のオブジェクトを差し替える(後述)
RenderSystem
                          Ogre::Root
                +   getSceneManager(name)
                +   getRenderSystem()
                +   getRenderManager()
                +   getMeshManager()




                     Ogre::RenderSystem




   Ogre::RenderSystem_GL        Ogre::RenderSystem_Direct3D9




起動時に環境にあわせてひとつ選択する
OGREの拡張性
既存のクラスを継承拡張する

 →RenderSystem

 →SceneManagerでよくやる

OGREが持っていない機能を単に追加

特定役割のオブジェクトを差し替える(後述)
ディアブロタイプ        フライトゲーム



ゲームによって空間管理やカリングが異なる


標準、BSP、ページベース、四分木、八分木などの
シーンマネージャを入手可能
SceneManager
                            Ogre::Root
                  +   getSceneManager(name)
                  +   getRenderSystem()
                  +   getRenderManager()
                  +   getMeshManager()




                       Ogre::SceneManager




  Ogre::OctreeSceneManager           Ogre::BSPSceneManager




レベルに合わせて変更するためにスイッチ可能
Observer/Visitor 再び
OGRE全般に行き渡っているポリシー

例) 標準シーンマネージャとOctTreeシーンマネー
ジャでは、異なる型のシーンノードを生成する

 SceneNode::Listener を使えばどちらのノードに
 もフックできる

Visitorも同様の貢献をする(詳しくは後述)
OGREの拡張性
既存のクラスを継承拡張する

 →RenderSystem

 →SceneManagerでよくやる

OGREが持っていない機能を単に追加

特定役割のオブジェクトを差し替える(後述)
OGREの拡張性
既存のクラスを継承拡張する

 →RenderSystem

 →SceneManagerでよくやる

OGREが持っていない機能を単に追加

特定役割のオブジェクトを差し替える(後述)
          モジュール的に追加するならプラグインがよい
plugin.cfg

この情報に従ってDLLをロー
ドする

起動したサブシステムは
Ogre::Root からアクセス可能
pluginとRefAppLayer

pluginはOgre::Rootからアプローチ可能なシステム
を追加する共通の段取り

Reference Application Layer ... OGREと3rd Libを
強烈に関係させる例(物理エンジンなど)

本日は割愛!(超重要) すみませんすみません...
換装できないものもある
ResourceManager はそれ単体の拡張性はあるが、
MyResourceManager 等と取り替えることは不可

 TextureManager、MeshManagerなども同様

ただしOGRE内部で依存性の低いサブシステムは
「標準のものは使わずに追加したプラグインのも
のを使う」ことができる
OGREのレンダリング
抽象化の下でのレンダリング
シーングラフ中の MovableObject から Renderable
を収集して描画する

 MovableObject ≠ Renderable ... ボリューム、音
 源、ライト、カメラ、etc...

MovableObject、Renderableはタイトル側で拡張
されていることが多いが、インターフェイスを通
じて Renderable を集めることができる
抽象化の下でのレンダリング
シーングラフ中の MovableObject から Renderable
を収集して描画する

 MovableObject ≠ Renderable ... ボリューム、音
 源、ライト、カメラ、etc...

            MovableObject は複数の Renderable を持つこ
MovableObject、Renderableはタイトル側で拡張
            とができる(そして持つことになる)。キュー
されていることが多いが、インターフェイスを通
            の受け入れは1回だが、受け入れ時に複数積む
じて Renderable を集めることができる
          ことができる。ソートはお任せ。
Ogre::Root
         + renderOneFrame()




Root::renderOneFrame() がキックされて描画開始
Ogre::Root
        + renderOneFrame()



             1...*
         Ogre::RenderTarget
        + update()




Rootは1つ以上のプライオリティ付け済みのレン
ダーターゲットを抱えてる。


順番に更新
1...*
       Ogre::RenderTarget
      + update()




            1...*
          Ogre::Viewport
         +update()




レンダーターゲット更新にあたり、ビューポート
を1つ以上持ってるので、すべて更新する
1...*
       Ogre::RenderTarget
      + update()




            1...*
          Ogre::Viewport
         +update()




レンダーターゲット更新にあたり、ビューポート
      このレンダーターゲットとビューポートのアプ
を1つ以上持ってるので、すべて更新する
       ローチだけを見ても、DX11の特性を生かした
       対応はこのままでは難しいでしょう。
1...*
                       Ogre::Viewport
                      +update()




            Ogre::Camera
  ?   + renderScene(Viewport*)




ビューポートにはカメラが割り振られているの
で、レンダリングを依頼
1...*
                       Ogre::Viewport
                      +update()




            Ogre::Camera
  ?   + renderScene(Viewport*)




ビューポートにはカメラが割り振られているの
で、レンダリングを依頼

         このカメラはシーンマネージャによって型が異
         なる可能性がある。
Ogre::Camera
?
    + renderScene(Viewport*)




                                    Ogre::SceneManager
                      ?
                               + renderScene(Camera*, Viewp




    カメラは自身のクリエイターであるシーンマネー
    ジャと協働でレンダリングを開始する
RenderQueue
シーングラフ中の MovableObject から、
SceneManager のポリシーでカメラから見えてい
る Renderable を収集

空の RenderQueue が、 Renderable をエンキュー
してもらう旅に旅立つ(始発駅: ルートノード)

カスタム RenderQueue を作って差し替え可
RenderQueue
シーングラフ中の MovableObject から、
SceneManager のポリシーでカメラから見えてい
る Renderable を収集

空の RenderQueue が、 Renderable をエンキュー
してもらう旅に旅立つ(始発駅: ルートノード)

カスタム RenderQueue を作って差し替え可
   RENDERQUEUEはエンキュー時にソートを行う
RenderQueue
 この話です

シーングラフ中の MovableObject から、
SceneManager のポリシーでカメラから見えてい
る Renderable を収集

空の RenderQueue が、 Renderable をエンキュー
してもらう旅に旅立つ(始発駅: ルートノード)

カスタム RenderQueue を作って差し替え可
   RENDERQUEUEはエンキュー時にソートを行う
QueueへのVisitor(おまけ)
                                          Ogre::RenderQueue
Ogre::QueuedRenderableVisitor                     系
                                                              ?


                                 Ogre::QueuedRenderableCollection
 ?       xxxVisitor
                                + acceptVisitor()

      ↑
やっぱこれも差し替え可能


VisitorにRenderableが渡された先からカメラが割
り振られているので、レンダリングを依頼
最後に
まとめ
ExampleApplication のようなフレームワークは任意
導入なのであると嬉しい

Observer と Visitor で各クラスの責任範囲をシンプ
ルにしたまま、その方向性で拡張できる

DX11の威力発揮が難しい設計とはいえ、描画シー
ケンスは基底クラスに手出しすることなく、短い
コードで深いカスタマイズができる
今日やらなかった重要話
Reference Application Layer

アニメーションシステム

描画上の”レイヤー”とその制御方法

リソースマネージャ

  ゲームエンジンアーキテクチャにちょい情報有
今日やらなかった重要話
Reference Application Layer

アニメーションシステム

描画上の”レイヤー”とその制御方法

リソースマネージャ

  ゲームエンジンアーキテクチャにちょい情報有
              また機会があれば!
問題点

抽象化のベースモデルが Direct X8 の時代からさし
て進んでない

メニーコアや GPU オフロード

描画トリック

 例) Deferred + Forward, ベロシティマップ, etc...
おまけ話
DX11 への(効果的な)対応策を打ってくると信じ
ており、設計を楽しみにしています

Ogreはアプリ側やプラグイン側でも計算コードが
畳み込まれるようにインライン関数が非常に多く
なっています

 のけぞらないように……
ご静聴ありがとうございました




    Twitter: @minahito

海外ゲーム技術勉強会#1 OGRE3D