ホーム>DirectXのページ>1.シーンのクラス化 |
1.DirectXのシーンをクラス化する
まずは、表示の一連の流れ、「シーン」をクラス化します。
これは、たとえば、ゲームなどにおいて
ゲーム画面 <−> 設定画面
といった切り替えを容易に行うことを想定して作っています。
DirectX10における「DXUT」ライブラリを用いることを前提にします。
まずは、DirectXにおいて、画面が描画される一連の処理を抽出してみましょう。
・初期化
・画面のリサイズ
・時間の経過
・描画処理
・終了処理
となります。
ソースコードで書くと、
#pragma once #include "DXUT.h" class TDXScene { public: TDXScene(void); virtual ~TDXScene(void); virtual HRESULT Init(ID3D10Device* pd3dDevice) = 0; virtual HRESULT OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ) = 0; virtual HRESULT OnRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ) = 0; virtual HRESULT OnResize( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) = 0; protected: // ID3D10Device* pd3dDevice; //対象となるデバイスへのポインタを持つべきか? //対象となるデバイスは呼び出しの間に変わるかもしれない(画面モードの変更などの理由によって) //よって、これは各呼び出しによって引数で渡されるべき }; |
これは何もしないので抽象クラスです。
次にサンプルに付属する「Tutorial08」と同じものを表示させるクラスを作ってみます。
#pragma once #include "tdxscene.h" class TDXTestScene : public TDXScene { public: TDXTestScene(void); virtual ~TDXTestScene(void); virtual HRESULT Init(ID3D10Device* pd3dDevice); virtual HRESULT OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ); virtual HRESULT OnRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ); virtual HRESULT OnResize( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); protected: ID3D10Effect* g_pEffect; //エフェクト=シェーダプログラムを読ませるところ ID3D10InputLayout* g_pVertexLayout; ID3D10EffectTechnique* g_pTechnique; ID3D10Buffer* g_pVertexBuffer; ID3D10Buffer* g_pIndexBuffer; ID3D10ShaderResourceView* g_pTextureRV; ID3D10EffectMatrixVariable* g_pWorldVariable; ID3D10EffectMatrixVariable* g_pViewVariable; ID3D10EffectMatrixVariable* g_pProjectionVariable; ID3D10EffectVectorVariable* g_pMeshColorVariable; ID3D10EffectVectorVariable* g_pLightDirVariable; ID3D10EffectShaderResourceVariable* g_pDiffuseVariable; D3DXMATRIX g_World; D3DXMATRIX g_View; D3DXMATRIX g_Projection; D3DXVECTOR4 g_vMeshColor; D3DXVECTOR4 g_vLightDir; }; |
ずいぶんとプロテクトメンバが増えました。
Tutorialだとこの辺が全てグローバル変数なのでC++使いには気持ち悪いというのもクラス化の動機の一つです。
ほとんどがシェーダと、シェーダとCPUのやりとりに使われる変数です。
中身は割愛させていただきますが、(Tutorial丸写しになってしまうので)
・コンストラクタは実変数については初期化、ポインタ変数についてはNULLでクリア
・Init()でnewが必要な変数を作成する
・Resize()で
・FrameMove()は・OnRender()は・デストラクタでは
といったところでしょうか。
各メソッドとDirectXの動作との対応は以下のようになると思います。
関数 | 呼び出し元 | コメント |
コンストラクタ | OnCreateDevice | デバイスロストとの対応から。だが、Initと分ける意味がなくなる気もする。 |
デストラクタ | OnDestroyDevice | リソースの解放を忘れずに。 |
Init | OnCreateDevice | ID3D10Deviceのオブジェクトが必要な処理はこちらに分離。 |
FrameMove | OnFrameMove | 描画にかかわらず時間経過によって呼ばれる。ここでアニメーションに必要な処理を行う |
OnRender | OnFrameRender | 実際の描画を行う。新たなパラメータを元に画面を描画する。 |
OnResize | OnResizedSwapChain | 射影行列を初期化する(プログラム内ではg_Projection) |