
デモフレームワーク作成
★ 1.はじめに…
DXUTがなくなってしまったので,やむを得ず自分でフレームワークを作成してみました。


★ 2.デモフレームワーク
デモフレームワークと言っても,大したものではありません。ウィンドウを立ち上げるとかその程度です。
フォント描画とかもちゃんと作ろうかと思ったのですが,DirectXTKがあるのでフォント描画やテクスチャ読み込みはDirectXTK使ってください。
asdxライブラリの作りですが,Applicationクラスがあって,あとは実装する側で継承して,適当にカスタマイズしてね。…という感じにしています。
asdxライブラリ自体はDirectXTKには非依存になっています。
まずファイル構成ですが,下のような感じになっています。

さて,肝心なのは使い方です。まず,Applicationクラスにウィンドウの作成・制御,ID3D11Deviceの作成等の大事な処理が含まれています。Applicationクラスの定義は以下のようになっています。
実際に使用する側の例は下記のような感じになります。
あとは,これのオーバーライドした処理を実際に自分で使いやすいようにコーディングしていきます。
コーディング例は下記のような感じです。
フォント描画とかもちゃんと作ろうかと思ったのですが,DirectXTKがあるのでフォント描画やテクスチャ読み込みはDirectXTK使ってください。
asdxライブラリの作りですが,Applicationクラスがあって,あとは実装する側で継承して,適当にカスタマイズしてね。…という感じにしています。
asdxライブラリ自体はDirectXTKには非依存になっています。
まずファイル構成ですが,下のような感じになっています。

- asdxApp →ウィンドウの生成,制御など処理。
- asdxCamera →カメラデータを格納するクラスなどを定義
- asdxCameraUpdater →マウス操作等でカメラを更新するクラスを定義
- asdxDepthBuffer →深度ステンシルバッファの作成補助クラスを定義
- asdxLog →ログ出力処理などを定義
- asdxMath →算術演算関係の処理
- asdxMesh →メッシュデータを格納するクラスなどを定義
- asdxRenderTarget →描画ターゲットの作成補助クラスを定義
- asdxShader →シェーダ補助クラスを定義
- asdxTimer →タイマー関係の処理
- asdxUtil →デバッグ補助など便利クラス・メソッドなどを定義
さて,肝心なのは使い方です。まず,Applicationクラスにウィンドウの作成・制御,ID3D11Deviceの作成等の大事な処理が含まれています。Applicationクラスの定義は以下のようになっています。
00116: //////////////////////////////////////////////////////////////////////////////////////////////
00117: // Application class
00118: //////////////////////////////////////////////////////////////////////////////////////////////
00119: class Application
00120: {
00121: //========================================================================================
00122: // list of friend classes and methods.
00123: //========================================================================================
00124: /* NOTHING /*
00125:
00126: public:
00127: //========================================================================================
00128: // public variables.
00129: //========================================================================================
00130: /* NOTHING /*
00131:
00132: //========================================================================================
00133: // public methods.
00134: //========================================================================================
00135:
00136: //----------------------------------------------------------------------------------------
00137: //! @brief コンストラクタです.
00138: //----------------------------------------------------------------------------------------
00139: Application();
00140:
00141: //----------------------------------------------------------------------------------------
00142: //! @brief 引数付きコンストラクタです.
00143: //!
00144: //! @param [in] title タイトル名.
00145: //----------------------------------------------------------------------------------------
00146: Application( LPSTR title );
00147:
00148: //----------------------------------------------------------------------------------------
00149: //! @brief デストラクタです.
00150: //----------------------------------------------------------------------------------------
00151: virtual ~Application();
00152:
00153: //----------------------------------------------------------------------------------------
00154: //! @brief アプリケーションを実行します.
00155: //----------------------------------------------------------------------------------------
00156: void Run();
00157:
00158: protected:
00159: //========================================================================================
00160: // protected variables
00161: //========================================================================================
00162: HINSTANCE m_hInst; //!< インスタンスハンドルです.
00163: HWND m_hWnd; //!< ウィンドウハンドルです.
00164: D3D_DRIVER_TYPE m_DriverType; //!< ドライバータイプです.
00165: D3D_FEATURE_LEVEL m_FeatureLevel; //!< 機能レベルです.
00166: UINT m_MultiSampleCount; //!< マルチサンプリングのカウント数です.
00167: UINT m_MultiSampleQuality; //!< マルチサンプリングの品質値です.
00168: UINT m_SwapChainCount; //!< スワップチェインのバッファ数です.
00169: DXGI_FORMAT m_SwapChainFormat; //!< スワップチェインのバッファフォーマットです.
00170: DXGI_FORMAT m_DepthStencilFormat; //!< 深度ステンシルバッファのフォーマットです.
00171: ID3D11Device* m_pDevice; //!< デバイスです.
00172: ID3D11DeviceContext* m_pDeviceContext; //!< デバイスコンテキスト(イミディエイトコンテキスト)です.
00173: IDXGISwapChain* m_pSwapChain; //!< スワップチェインです.
00174: RenderTarget2D m_RenderTarget2D; //!< 描画ターゲットです.
00175: DepthStencilBuffer m_DepthStencilBuffer; //!< 深度ステンシルバッファです.
00176: ID3D11RasterizerState* m_pRasterizerState; //!< ラスタライザーステートです.
00177: ID3D11DepthStencilState* m_pDepthStencilState; //!< 深度ステンシルステートです.
00178: ID3D11BlendState* m_pBlendState; //!< ブレンドステートです.
00179: FLOAT m_BlendFactor[ 4 ]; //!< ブレンドファクターです.
00180: UINT m_SampleMask; //!< サンプルマスクです.
00181: UINT m_StencilRef; //!< ステンシル参照です.
00182: FLOAT4 m_ClearColor; //!< 背景のクリアカラーです.
00183: UINT m_Width; //!< 画面の横幅です.
00184: UINT m_Height; //!< 画面の縦幅です.
00185: FLOAT m_AspectRatio; //!< 画面のアスペクト比です.
00186: LPSTR m_Title; //!< アプリケーションのタイトル名です.
00187: Timer m_Timer; //!< タイマーです.
00188:
00189:
00190: //========================================================================================
00191: // protected methods.
00192: //========================================================================================
00193:
00194: //----------------------------------------------------------------------------------------
00195: //! @brief 初期化時に実行する処理です.
00196: //!
00197: //! @note 派生クラスにて実装を行います.
00198: //----------------------------------------------------------------------------------------
00199: virtual bool OnInit ();
00200:
00201: //----------------------------------------------------------------------------------------
00202: //! @brief 終了時に実行する処理です.
00203: //!
00204: //! @note 派生クラスにて実装を行います.
00205: //----------------------------------------------------------------------------------------
00206: virtual void OnTerm ();
00207:
00208: //----------------------------------------------------------------------------------------
00209: //! @brief フレーム遷移時に実行する処理です.
00210: //!
00211: //! @param [in] time アプリケーション開始からの相対時間です.
00212: //! @param [in] elapsedTime 前のフレームから経過時間です.
00213: //! @note 派生クラスにて実装を行います.
00214: //----------------------------------------------------------------------------------------
00215: virtual void OnFrameMove ( double time, double elapsedTime );
00216:
00217: //----------------------------------------------------------------------------------------
00218: //! @brief フレーム描画時に実行する処理です.
00219: //!
00220: //! @param [in] time アプリケーション開始からの相対時間です.
00221: //! @param [in] elapsedTime 前のフレームからの経過時間です.
00222: //! @note 派生クラスにて実装を行います.
00223: //----------------------------------------------------------------------------------------
00224: virtual void OnFrameRender( double time, double elapsedTime );
00225:
00226: //----------------------------------------------------------------------------------------
00227: //! @brief リサイズ時に実行する処理です.
00228: //!
00229: //! @param [in] param リサイズイベントパラメータです.
00230: //! @note 派生クラスにて実装を行います.
00231: //----------------------------------------------------------------------------------------
00232: virtual void OnResize ( const ResizeEventParam& param );
00233:
00234: //----------------------------------------------------------------------------------------
00235: //! @brief キーイベント通知時に実行する処理です.
00236: //!
00237: //! @param [in] param キーイベントパラメータです.
00238: //! @note 派生クラスにて実装を行います.
00239: //----------------------------------------------------------------------------------------
00240: virtual void OnKey ( const KeyEventParam& param );
00241:
00242: //----------------------------------------------------------------------------------------
00243: //! @brief マウスイベント通知時に実行する処理です.
00244: //!
00245: //! @param [in] param マウスイベントパラメータです.
00246: //! @note 派生クラスにて実装を行います.
00247: //----------------------------------------------------------------------------------------
00248: virtual void OnMouse ( const MouseEventParam& param );
00249:
00250: //----------------------------------------------------------------------------------------
00251: //! @brief 描画停止フラグを設定します.
00252: //!
00253: //! @param [in] isStopRendering 描画を停止するかどうか.停止する場合はtrueを指定します.
00254: //----------------------------------------------------------------------------------------
00255: void SetStopRendering( bool isStopRendering );
00256:
00257: //----------------------------------------------------------------------------------------
00258: //! @brief 描画停止フラグを取得します.
00259: //!
00260: //! @retval true 描画処理を呼び出しません.
00261: //! @retval false 描画処理を呼び出します.
00262: //----------------------------------------------------------------------------------------
00263: bool IsStopRendering() const;
00264:
00265: //----------------------------------------------------------------------------------------
00266: //! @brief フレームカウントを取得します.
00267: //!
00268: //! @return フレームカウントを返却します.
00269: //----------------------------------------------------------------------------------------
00270: DWORD GetFrameCount() const;
00271:
00272: //----------------------------------------------------------------------------------------
00273: //! @brief FPSを取得します.
00274: //!
00275: //! @return FPSを返却します.
00276: //----------------------------------------------------------------------------------------
00277: FLOAT GetFPS() const;
00278:
00279: private:
00280: //========================================================================================
00281: // private variables.
00282: //========================================================================================
00283: bool m_IsStopRendering; //!< 描画を停止するかどうかのフラグ. 停止する場合はtrueを指定.
00284: DWORD m_FrameCount; //!< フレームカウントです.
00285: FLOAT m_FPS; //!< FPS(1秒あたりのフレーム描画回数)です.
00286: DOUBLE m_LatestUpdateTime; //!< 最後の更新時間です.
00287:
00288: //========================================================================================
00289: // private methods.
00290: //========================================================================================
00291: Application ( const Application& ); // アクセス禁止.
00292: void operator = ( const Application& ); // アクセス禁止.
00293:
00294: //----------------------------------------------------------------------------------------
00295: //! @brief アプリケーションの初期化処理です.
00296: //!
00297: //! @retval true 初期化に成功.
00298: //! @retval false 初期化に失敗.
00299: //! @note このメソッドは内部処理で,InitWnd(), InitD3D()を呼び出します.
00300: //----------------------------------------------------------------------------------------
00301: bool InitApp();
00302:
00303: //----------------------------------------------------------------------------------------
00304: //! @brief アプリケーションの終了処理です.
00305: //!
00306: //! @note このメソッドは内部処理で, TermD3D(), TermWnd()を呼び出します.
00307: //----------------------------------------------------------------------------------------
00308: void TermApp();
00309:
00310: //----------------------------------------------------------------------------------------
00311: //! @brief ウィンドウの初期化処理です.
00312: //!
00313: //! @retval true 初期化に成功.
00314: //! @retval false 初期化に失敗.
00315: //----------------------------------------------------------------------------------------
00316: bool InitWnd();
00317:
00318: //----------------------------------------------------------------------------------------
00319: //! @brief ウィンドウの終了処理です.
00320: //----------------------------------------------------------------------------------------
00321: void TermWnd();
00322:
00323: //----------------------------------------------------------------------------------------
00324: //! @brief Direct3Dの初期化処理です.
00325: //!
00326: //! @retval true 初期化に成功.
00327: //! @retval false 初期化に失敗.
00328: //----------------------------------------------------------------------------------------
00329: bool InitD3D();
00330:
00331: //----------------------------------------------------------------------------------------
00332: //! @brief Direct3Dの終了処理です.
00333: //----------------------------------------------------------------------------------------
00334: void TermD3D();
00335:
00336: //----------------------------------------------------------------------------------------
00337: //! @brief メインループ処理です.
00338: //----------------------------------------------------------------------------------------
00339: void MainLoop();
00340:
00341: //----------------------------------------------------------------------------------------
00342: //! @brief キーイベントを処理します.
00343: //!
00344: //! @param [in] nChar キーコード.
00345: //! @param [in] isKeyDown キーが押されているかどうか. キーが押されていればtrueを指定します.
00346: //! @param [in] isAltDown ALTキーが押されているかどうか. ALTキーが押されていればtrueを指定します.
00347: //! @note このメソッドは内部処理で,OnKey()を呼び出します.
00348: //! また,このメソッドはウィンドウプロシージャからのアクセス専用メソッドですので,
00349: //! アプリケーション側で呼び出しを行わないでください.
00350: //----------------------------------------------------------------------------------------
00351: void KeyEvent ( UINT nChar, bool isKeyDown, bool isAltDown );
00352:
00353: //----------------------------------------------------------------------------------------
00354: //! @brief リサイズイベントを処理します.
00355: //!
00356: //! @param [in] width 画面の横幅.
00357: //! @param [in] height 画面の縦幅.
00358: //! @note このメソッドは内部処理で, OnResize()を呼び出します.
00359: //! また,このメソッドはウィンドウプロシージャからのアクセス専用メソッドですので,
00360: //! アプリケーション側で呼び出しを行わないでください.
00361: //----------------------------------------------------------------------------------------
00362: void ResizeEvent( UINT width, UINT height );
00363:
00364: //----------------------------------------------------------------------------------------
00365: //! @brief マウスイベントを処理します.
00366: //!
00367: //! @param [in] x カーソルのX座標です.
00368: //! @param [in] y カーソルのY座標です.
00369: //! @param [in] wheelDelta マウスホイールの移動方向です.
00370: //! @param [in] isLeftButtonDown 左ボタンが押されたかどうか.押されていればtrueを指定します.
00371: //! @param [in] isRightButtonDown 右ボタンが押されたかどうか.押されていればtrueを指定します.
00372: //! @param [in] isMiddleButtonDown 中ボタンが押されたかどうか.押されていればtrueを指定します.
00373: //! @param [in] isSideButton1Down X1ボタンが押されたかどうか.押されていればtrueを指定します.
00374: //! @param [in] isSideButton2Down X2ボタンが押されたかどうか.押されていればtrueを指定します.
00375: //! @note このメソッドは内部処理で, OnMouse()を呼び出します.
00376: //! また,このメソッドはウィンドウプロシージャからのアクセス専用メソッドですので,
00377: //! アプリケーション側で呼び出しを行わないでください.
00378: //----------------------------------------------------------------------------------------
00379: void MouseEvent(
00380: int x,
00381: int y,
00382: int wheelDelta,
00383: bool isLeftButtonDown,
00384: bool isRightButtonDown,
00385: bool isMiddleButtonDown,
00386: bool isSideButton1Down,
00387: bool isSideButton2Down );
00388:
00389: //----------------------------------------------------------------------------------------
00390: //! @brief ウィンドウプロシージャです.
00391: //!
00392: //! @param [in] hWnd ウィンドウハンドル.
00393: //! @param [in] uMsg メッセージ.
00394: //! @param [in] wp メッセージの追加情報.
00395: //! @param [in] lp メッセージの追加情報.
00396: //----------------------------------------------------------------------------------------
00397: static LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp );
00398: };
00399:
00400:
00401: } // namespace asdx
基本的な使い方は,上記のApplicationクラスを継承して,protectedメソッドで変更したいものがあったらオーバーライドして自分用に書き直すという具合です。実際に使用する側の例は下記のような感じになります。
00053: ////////////////////////////////////////////////////////////////////////////////////////
00054: // SampleApplication
00055: ////////////////////////////////////////////////////////////////////////////////////////
00056: class SampleApplication : public asdx::Application
00057: {
00058: //==================================================================================
00059: // list of friend classes and methods.
00060: //==================================================================================
00061: /* NOTHING /*
00062:
00063: private:
00064: //===================================================================================
00065: // private variables.
00066: //===================================================================================
00067: DirectX::SpriteBatch* m_pSprites; //!< スプライトバッチです.
00068: DirectX::SpriteFont* m_pFont; //!< スプライトフォントです.
00069: asdx::CameraUpdater m_Camera; //!< カメラです.
00070: ID3D11Buffer* m_pVB; //!< 頂点バッファです.
00071: ID3D11Buffer* m_pIB; //!< インデックスバッファです.
00072: ID3D11Buffer* m_pMB; //!< マテリアルバッファです.
00073: ID3D11Buffer* m_pTB; //!< 変換パラメータバッファです.
00074: ID3D11InputLayout* m_pIL; //!< 入力レイアウトです.
00075: ID3D11VertexShader* m_pVS; //!< 頂点シェーダです.
00076: ID3D11PixelShader* m_pPS; //!< ピクセルシェーダです.
00077: asdx::UINT m_Stride; //!< ストライドです.
00078: asdx::UINT m_Offset; //!< オフセットです.
00079: asdx::UINT m_SubsetCount; //!< サブセット数です.
00080: SimpleSubset* m_pSubset; //!< サブセットです.
00081: TransformParam m_TransformParam; //!< 変換パラメータです.
00082: wchar_t m_FpsText[ 20 ]; //!< FPSテキストです.
00083:
00084: //==================================================================================
00085: // private methods.
00086: //==================================================================================
00087:
00088: //----------------------------------------------------------------------------------
00089: //! @brief テキスト描画時の処理です.
00090: //----------------------------------------------------------------------------------
00091: void OnDrawText();
00092:
00093: //----------------------------------------------------------------------------------
00094: //! @brief メッシュ描画時の処理です.
00095: //----------------------------------------------------------------------------------
00096: void OnDrawMesh();
00097:
00098: protected:
00099: //==================================================================================
00100: // protected varaibles
00101: //==================================================================================
00102: /* NOTHING /*
00103:
00104: //==================================================================================
00105: // protected methods.
00106: //==================================================================================
00107:
00108: //----------------------------------------------------------------------------------
00109: //! @brief 初期化時の処理です.
00110: //!
00111: //! @retval true 初期化に成功.
00112: //! @retval false 初期化に失敗.
00113: //----------------------------------------------------------------------------------
00114: bool OnInit();
00115:
00116: //----------------------------------------------------------------------------------
00117: //! @brief 終了時の処理です.
00118: //----------------------------------------------------------------------------------
00119: void OnTerm();
00120:
00121: //----------------------------------------------------------------------------------
00122: //! @brief フレーム繊維時の処理です.
00123: //!
00124: //! @param [in] time アプリケーション開始してからの相対時間です.
00125: //! @param [in] elapsedTime 前フレームからの経過時間です.
00126: //----------------------------------------------------------------------------------
00127: void OnFrameMove ( double time, double elapsedTime );
00128:
00129: //----------------------------------------------------------------------------------
00130: //! @brief フレーム描画時の処理です.
00131: //!
00132: //! @param [in] time アプリケーション開始してからの相対時間です.
00133: //! @param [in] elapsedTime 前フレームからの経過時間です.
00134: //----------------------------------------------------------------------------------
00135: void OnFrameRender( double time, double elapsedTime );
00136:
00137: //----------------------------------------------------------------------------------
00138: //! @brief リサイズ時の処理です.
00139: //!
00140: //! @param [in] param リサイズイベントパラメータです.
00141: //----------------------------------------------------------------------------------
00142: void OnResize ( const asdx::ResizeEventParam& param );
00143:
00144: //----------------------------------------------------------------------------------
00145: //! @brief キーイベント時の処理です.
00146: //!
00147: //! @param [in] param キーイベントパラメータです.
00148: //----------------------------------------------------------------------------------
00149: void OnKey ( const asdx::KeyEventParam& param );
00150:
00151: //----------------------------------------------------------------------------------
00152: //! @brief マウスイベント時の処理です.
00153: //!
00154: //! @param [in] param マウスイベントパラメータです.
00155: //----------------------------------------------------------------------------------
00156: void OnMouse ( const asdx::MouseEventParam& param );
00157:
00158: public:
00159: //==================================================================================
00160: // public variables.
00161: //==================================================================================
00162: /* NOTHING /*
00163:
00164: //==================================================================================
00165: // public methods.
00166: //==================================================================================
00167:
00168: //----------------------------------------------------------------------------------
00169: //! @brief コンストラクタです.
00170: //----------------------------------------------------------------------------------
00171: SampleApplication();
00172:
00173: //----------------------------------------------------------------------------------
00174: //! @brief デストラクタです.
00175: //----------------------------------------------------------------------------------
00176: virtual ~SampleApplication();
00177: };
00178:
初期化時,終了時,フレーム遷移時,フレーム描画時等に頂点バッファを作ったり,シェーダをコンパイルしたりとごちゃごちゃやりたいので,OnInit(), OnTerm(), OnFrameMove(), OnFrameRender()をオーバーライドしています。あとはカメラ処理でマウスとキー処理もオーバーライドするためにOnKey(), OnMouse()も定義。ウィンドウサイズが変更されたときは射影行列も更新する必要があるので,OnResize()もオーバーライドしています。あとは,これのオーバーライドした処理を実際に自分で使いやすいようにコーディングしていきます。
コーディング例は下記のような感じです。
00047: //---------------------------------------------------------------------------------------
00048: // 初期化時の処理です.
00049: //---------------------------------------------------------------------------------------
00050: bool SampleApplication::OnInit()
00051: {
00052: // スプライトバッチを生成.
00053: m_pSprites = new DirectX::SpriteBatch( m_pDeviceContext );
00054: if ( m_pSprites == nullptr )
00055: {
00056: ELOG( "Error : Memory Allocate Failed." );
00057: return false;
00058: }
00059:
00060: // 瀬戸フォントミニ-Pを読み込みスプライトフォントを作成.
00061: m_pFont = new DirectX::SpriteFont( m_pDevice, L"../res/SetoMini-P.spritefont" );
00062: if ( m_pFont == nullptr )
00063: {
00064: ELOG( "Error : Memory Allocate Failed." );
00065: return false;
00066: }
00067:
00068: // メッシュをロードします.
00069: asdx::Mesh mesh;
00070: if ( !mesh.LoadFromFile( "../res/dosei.msh" ) )
00071: {
00072: ELOG( "Error : Mesh Load Failed." );
00073: return false;
00074: }
00075:
00076: HRESULT hr = S_OK;
00077: {
00078: ID3DBlob* pVSBlob = nullptr;
00079:
00080: // 頂点シェーダをコンパイル.
00081: hr = asdx::ShaderHelper::CompileShaderFromFile(
00082: L"../res/SimpleVS.fx",
00083: "VSFunc",
00084: asdx::ShaderHelper::VS_4_0,
00085: &pVSBlob
00086: );
00087: if ( FAILED( hr ) )
00088: {
00089: ELOG( "Error : CompileShaderFromFile() Failed." );
00090: return false;
00091: }
00092:
00093: // 頂点シェーダを生成.
00094: hr = m_pDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &m_pVS );
00095: if ( FAILED( hr ) )
00096: {
00097: pVSBlob->Release();
00098: pVSBlob = nullptr;
00099:
00100: ELOG( "Error : ID3D11Device::CreateVertexShader() Failed." );
00101: return false;
00102: }
00103:
00104: // 入力レイアウトを生成.
00105: hr = m_pDevice->CreateInputLayout(
00106: asdx::Mesh::INPUT_ELEMENTS,
00107: asdx::Mesh::NUM_INPUT_ELEMENT,
00108: pVSBlob->GetBufferPointer(),
00109: pVSBlob->GetBufferSize(),
00110: &m_pIL );
00111:
00112: pVSBlob->Release();
00113: pVSBlob = nullptr;
00114:
00115: if ( FAILED( hr ) )
00116: {
00117: ELOG( "Error : ID3D11Device::CreateInputLayout() Failed." );
00118: return false;
00119: }
00120: }
00121:
00122: {
00123: ID3DBlob* pPSBlob = nullptr;
00124:
00125: // ピクセルシェーダをコンパイル.
00126: hr = asdx::ShaderHelper::CompileShaderFromFile(
00127: L"../res/SimplePS.fx",
00128: "PSFunc",
00129: asdx::ShaderHelper::PS_4_0,
00130: &pPSBlob
00131: );
00132: if ( FAILED( hr ) )
00133: {
00134: ELOG( "Error : CompileShaderFromFile() Failed." );
00135: return false;
00136: }
00137:
00138: // ピクセルシェーダを生成.
00139: hr = m_pDevice->CreatePixelShader(
00140: pPSBlob->GetBufferPointer(),
00141: pPSBlob->GetBufferSize(),
00142: nullptr,
00143: &m_pPS
00144: );
00145:
00146: pPSBlob->Release();
00147: pPSBlob = nullptr;
00148:
00149: if ( FAILED( hr ) )
00150: {
00151: ELOG( "Error : ID3D11CreatePixelShader() Failed." );
00152: return false;
00153: }
00154: }
00155:
00156: {
00157: // 頂点バッファの設定.
00158: D3D11_BUFFER_DESC bd;
00159: ZeroMemory( &bd, sizeof( D3D11_BUFFER_DESC ) );
00160: bd.Usage = D3D11_USAGE_DEFAULT;
00161: bd.ByteWidth = sizeof( asdx::Mesh::Vertex ) * mesh.GetVertexCount();
00162: bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
00163: bd.CPUAccessFlags = 0;
00164:
00165: m_Stride = sizeof( asdx::Mesh::Vertex );
00166: m_Offset = 0;
00167:
00168: // 頂点データを設定.
00169: D3D11_SUBRESOURCE_DATA sd;
00170: ZeroMemory( &sd, sizeof( D3D11_SUBRESOURCE_DATA ) );
00171: sd.pSysMem = mesh.GetVertices();
00172:
00173: // 頂点バッファを生成.
00174: hr = m_pDevice->CreateBuffer( &bd, &sd, &m_pVB );
00175: if ( FAILED( hr ) )
00176: {
00177: ELOG( "Error : ID3D11Device::CreateBuffer() Failed." );
00178: return false;
00179: }
00180:
00181: // インデックスバッファの設定.
00182: ZeroMemory( &bd, sizeof( D3D11_BUFFER_DESC ) );
00183: ZeroMemory( &sd, sizeof( D3D11_SUBRESOURCE_DATA ) );
00184: bd.Usage = D3D11_USAGE_DEFAULT;
00185: bd.ByteWidth = sizeof( asdx::UINT ) * mesh.GetIndexCount();
00186: bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
00187: bd.CPUAccessFlags = 0;
00188:
00189: // インデックスデータを設定.
00190: sd.pSysMem = mesh.GetIndices();
00191:
00192: // インデックスバッファを生成.
00193: hr = m_pDevice->CreateBuffer( &bd, &sd, &m_pIB );
00194: if ( FAILED( hr ) )
00195: {
00196: ELOG( "Error : ID3D11Device::CreateBuffer() Failed." );
00197: return false;
00198: }
00199:
00200: // マテリアルバッファの設定.
00201: ZeroMemory( &bd, sizeof( D3D11_BUFFER_DESC ) );
00202: bd.Usage = D3D11_USAGE_DEFAULT;
00203: bd.ByteWidth = sizeof( SimpleMaterial );
00204: bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
00205: bd.CPUAccessFlags = 0;
00206:
00207: // マテリアルバッファを生成.
00208: hr = m_pDevice->CreateBuffer( &bd, nullptr, &m_pMB );
00209: if ( FAILED( hr ) )
00210: {
00211: ELOG( "Error : ID3D11Device::CreateBuffer() Failed." );
00212: return false;
00213: }
00214:
00215: // 変換パラメータバッファの設定.
00216: ZeroMemory( &bd, sizeof( D3D11_BUFFER_DESC ) );
00217: bd.Usage = D3D11_USAGE_DEFAULT;
00218: bd.ByteWidth = sizeof( TransformParam );
00219: bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
00220: bd.CPUAccessFlags = 0;
00221:
00222: // 変換パラメータバッファを生成.
00223: hr = m_pDevice->CreateBuffer( &bd, nullptr, &m_pTB );
00224: if ( FAILED( hr ) )
00225: {
00226: ELOG( "Error : ID3D11Device::CreateBuffer() Failed." );
00227: return false;
00228: }
00229:
00230: // アスペクト比を算出.
00231: float aspectRatio = (float)m_Width/(float)m_Height;
00232:
00233: // カメラの設定.
00234: m_Camera.GetCamera().SetPosition( asdx::FLOAT3( 0.0f, 0.0f, -50.0f ) );
00235: m_Camera.GetCamera().SetTarget( asdx::FLOAT3( 0.0f, 0.0f, 0.0f ) );
00236: m_Camera.GetCamera().SetUpward( asdx::FLOAT3( 0.0f, 1.0f, 0.0f ) );
00237: m_Camera.GetCamera().Preset();
00238: m_Camera.GetCamera().Update();
00239:
00240: // 変換パラメータを設定.
00241: m_TransformParam.Light = asdx::FLOAT4( 0.0f, -1.0f, 1.0f, 0.0f );
00242: m_TransformParam.Proj = asdx::CreatePerspectiveFieldOfView( asdx::F_PIDIV4, aspectRatio, 0.1f, 100000.0f );
00243: m_TransformParam.View = m_Camera.GetView();
00244: m_TransformParam.World.Identity();
00245:
00246: }
00247:
00248: // サブセットを組み立てる.
00249: {
00250: m_SubsetCount = mesh.GetSubsetCount();
00251: m_pSubset = new SimpleSubset[ mesh.GetSubsetCount() ];
00252: if ( m_pSubset == nullptr )
00253: {
00254: ELOG( "Error : Memory Allocate Failed." );
00255: return false;
00256: }
00257:
00258: SimpleMaterial material;
00259: for( asdx::UINT i=0; i<mesh.GetSubsetCount(); ++i )
00260: {
00261: asdx::Mesh::Subset subset = mesh.GetSubset( i );
00262: asdx::Mesh::Material mat = mesh.GetMatrial( subset.MaterialID );
00263:
00264: // 拡散反射色設定.
00265: material.Diffuse.x = mat.Diffuse.x;
00266: material.Diffuse.y = mat.Diffuse.y;
00267: material.Diffuse.z = mat.Diffuse.z;
00268:
00269: // 透過度設定.
00270: material.Diffuse.w = mat.Alpha;
00271:
00272: // 鏡面反射色設定.
00273: material.Spcular.x = mat.Specular.x;
00274: material.Spcular.y = mat.Specular.y;
00275: material.Spcular.z = mat.Specular.z;
00276: material.Spcular.w = mat.Power;
00277:
00278: // サブセット設定.
00279: m_pSubset[ i ].IndexCount = subset.IndexCount;
00280: m_pSubset[ i ].IndexOffset = subset.IndexOffset;
00281: m_pSubset[ i ].Material = material;
00282: }
00283:
00284: // 不要なメモリを解放.
00285: mesh.Release();
00286: }
00287:
00288: return true;
00289: }
00290:
00291: //---------------------------------------------------------------------------------------
00292: // 終了時の処理です.
00293: //---------------------------------------------------------------------------------------
00294: void SampleApplication::OnTerm()
00295: {
00296: // スプライトバッチを解放.
00297: if ( m_pSprites )
00298: {
00299: delete m_pSprites;
00300: m_pSprites = nullptr;
00301: }
00302:
00303: // スプライトフォントを解放.
00304: if ( m_pFont )
00305: {
00306: delete m_pFont;
00307: m_pFont = nullptr;
00308: }
00309:
00310: // 頂点シェーダを解放.
00311: if ( m_pVS )
00312: {
00313: m_pVS->Release();
00314: m_pVS = nullptr;
00315: }
00316:
00317: // ピクセルシェーダを解放.
00318: if ( m_pPS )
00319: {
00320: m_pPS->Release();
00321: m_pPS = nullptr;
00322: }
00323:
00324: // 入力レイアウトを解放.
00325: if ( m_pIL )
00326: {
00327: m_pIL->Release();
00328: m_pIL = nullptr;
00329: }
00330:
00331: // 頂点バッファを解放.
00332: if ( m_pVB )
00333: {
00334: m_pVB->Release();
00335: m_pVB = nullptr;
00336: }
00337:
00338: // インデックスバッファを解放.
00339: if ( m_pIB )
00340: {
00341: m_pIB->Release();
00342: m_pIB = nullptr;
00343: }
00344:
00345: // マテリアルバッファを解放.
00346: if ( m_pMB )
00347: {
00348: m_pMB->Release();
00349: m_pMB = nullptr;
00350: }
00351:
00352: // 変換パラメータバッファを解放.
00353: if ( m_pTB )
00354: {
00355: m_pTB->Release();
00356: m_pTB = nullptr;
00357: }
00358:
00359: // サブセットを解放.
00360: if ( m_pSubset )
00361: {
00362: delete [] m_pSubset;
00363: m_pSubset = nullptr;
00364: }
00365:
00366: // カウントをゼロに設定.
00367: m_Stride = 0;
00368: m_Offset = 0;
00369: m_SubsetCount = 0;
00370: }
00371:
00372: //---------------------------------------------------------------------------------------
00373: // フレーム遷移時の処理です.
00374: //---------------------------------------------------------------------------------------
00375: void SampleApplication::OnFrameMove( double time, double elapsedTime )
00376: {
00377: // ビュー行列を更新.
00378: m_TransformParam.View = m_Camera.GetView();
00379:
00380: // FPSテキストを更新.
00381: swprintf_s( m_FpsText, L"FPS : %.02f", GetFPS() );
00382: }
00383:
00384: //---------------------------------------------------------------------------------------
00385: // テキスト描画時の処理です.
00386: //---------------------------------------------------------------------------------------
00387: void SampleApplication::OnDrawText()
00388: {
00389: // 設定をクリアします.
00390: m_pDeviceContext->VSSetShader( nullptr, nullptr, 0 );
00391: m_pDeviceContext->GSSetShader( nullptr, nullptr, 0 );
00392: m_pDeviceContext->DSSetShader( nullptr, nullptr, 0 );
00393: m_pDeviceContext->HSSetShader( nullptr, nullptr, 0 );
00394: m_pDeviceContext->PSSetShader( nullptr, nullptr, 0 );
00395:
00396: // テキスト描画処理です.
00397: m_pSprites->Begin();
00398: {
00399: DirectX::XMFLOAT2 pos;
00400: pos.x = 5.0f;
00401: pos.y = 5.0f;
00402:
00403: m_pFont->DrawString( m_pSprites, m_FpsText, pos );
00404: }
00405: m_pSprites->End();
00406: }
00407:
00408: //---------------------------------------------------------------------------------------
00409: // メッシュ描画時の処理です.
00410: //---------------------------------------------------------------------------------------
00411: void SampleApplication::OnDrawMesh()
00412: {
00413: // シェーダの設定.
00414: m_pDeviceContext->VSSetShader( m_pVS, nullptr, 0 );
00415: m_pDeviceContext->GSSetShader( nullptr, nullptr, 0 );
00416: m_pDeviceContext->HSSetShader( nullptr, nullptr, 0 );
00417: m_pDeviceContext->DSSetShader( nullptr, nullptr, 0 );
00418: m_pDeviceContext->PSSetShader( m_pPS, nullptr, 0 );
00419:
00420: // 頂点バッファを設定.
00421: m_pDeviceContext->IASetVertexBuffers( 0, 1, &m_pVB, &m_Stride, &m_Offset );
00422:
00423: // 入力レイアウトを設定.
00424: m_pDeviceContext->IASetInputLayout( m_pIL );
00425:
00426: // 変換パラメータバッファを更新.
00427: m_pDeviceContext->UpdateSubresource( m_pTB, 0, nullptr, &m_TransformParam, 0, 0 );
00428:
00429: // 頂点シェーダに定数バッファを設定.
00430: m_pDeviceContext->VSSetConstantBuffers( 1, 1, &m_pTB );
00431:
00432: // インデックスバッファを設定.
00433: m_pDeviceContext->IASetIndexBuffer( m_pIB, DXGI_FORMAT_R32_UINT, 0 );
00434:
00435: // プリミティブトポロジーを設定.
00436: m_pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
00437:
00438: // サブセット数だけループ.
00439: for( asdx::UINT i=0; i<m_SubsetCount; ++i )
00440: {
00441: // マテリアルバッファを更新.
00442: m_pDeviceContext->UpdateSubresource( m_pMB, 0, nullptr, &m_pSubset[ i ].Material, 0, 0 );
00443:
00444: // ピクセルシェーダに定数バッファを設定.
00445: m_pDeviceContext->PSSetConstantBuffers( 0, 1, &m_pMB );
00446:
00447: // インデックス付きで描画.
00448: m_pDeviceContext->DrawIndexed( m_pSubset[ i ].IndexCount, m_pSubset[ i ].IndexOffset, 0 );
00449: }
00450: }
00451:
00452: //---------------------------------------------------------------------------------------
00453: // 描画時の処理です.
00454: //---------------------------------------------------------------------------------------
00455: void SampleApplication::OnFrameRender( double time, double elapsedTime )
00456: {
00457: // レンダーターゲットビュー・深度ステンシルビューを取得.
00458: ID3D11RenderTargetView* pRTV = m_RenderTarget2D.GetRTV();
00459: ID3D11DepthStencilView* pDSV = m_DepthStencilBuffer.GetDSV();
00460:
00461: // NULLチェック.
00462: if ( pRTV == nullptr )
00463: { return; }
00464: if ( pDSV == nullptr )
00465: { return; }
00466:
00467: // 出力マネージャに設定.
00468: m_pDeviceContext->OMSetRenderTargets( 1, &pRTV, pDSV );
00469:
00470: // クリア処理.
00471: m_pDeviceContext->ClearRenderTargetView( pRTV, m_ClearColor );
00472: m_pDeviceContext->ClearDepthStencilView( pDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 );
00473:
00474: // ステートを設定.
00475: m_pDeviceContext->RSSetState( m_pRasterizerState );
00476: m_pDeviceContext->OMSetBlendState( m_pBlendState, m_BlendFactor, m_SampleMask );
00477: m_pDeviceContext->OMSetDepthStencilState( m_pDepthStencilState, m_StencilRef );
00478:
00479: // 描画処理.
00480: {
00481: // メッシュを描画.
00482: OnDrawMesh();
00483:
00484: // テキストを描画.
00485: OnDrawText();
00486: }
00487:
00488: // コマンドを実行して,画面に表示.
00489: m_pSwapChain->Present( 0, 0 );
00490: }
00491:
00492: //---------------------------------------------------------------------------------------
00493: // リサイズイベントの処理です.
00494: //---------------------------------------------------------------------------------------
00495: void SampleApplication::OnResize( const asdx::ResizeEventParam& param )
00496: {
00497: // 射影行列を更新.
00498: m_TransformParam.Proj = asdx::CreatePerspectiveFieldOfView( asdx::F_PIDIV4, param.AspectRatio, 0.1f, 1000.0f );
00499: }
00500:
00501: //---------------------------------------------------------------------------------------
00502: // キーイベントの処理です.
00503: //---------------------------------------------------------------------------------------
00504: void SampleApplication::OnKey( const asdx::KeyEventParam& param )
00505: {
00506: // カメラ処理.
00507: m_Camera.OnKey( param.KeyCode, param.IsKeyDown, param.IsAltDown );
00508: }
00509:
00510: //---------------------------------------------------------------------------------------
00511: // マウスインベント時の処理です.
00512: //---------------------------------------------------------------------------------------
00513: void SampleApplication::OnMouse( const asdx::MouseEventParam& param )
00514: {
00515: // カメラ処理.
00516: m_Camera.OnMouse(
00517: param.X,
00518: param.Y,
00519: param.WheelDelta,
00520: param.IsLeftButtonDown,
00521: param.IsRightButtonDown,
00522: param.IsMiddleButtonDown,
00523: param.IsSideButton1Down,
00524: param.IsSideButton2Down
00525: );
00526: }
アプリケーション側のコーディングが終わったら,あとはmain関数から継承して作成したアプリケーションクラスを実行する処理を呼び出せばウィンドウが表示されます。実行するためにはRun()メソッドをコールします。
00017: //--------------------------------------------------------------------------------------------
00018: //! @brief メインエントリーポイントです.
00019: //--------------------------------------------------------------------------------------------
00020: int main( int argc, char** argv )
00021: {
00022: _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
00023: {
00024: SampleApplication app;
00025:
00026: app.Run();
00027: }
00028:
00029: return 0;
00030: }
★ 3.終わりに
本当は,ガチな説明を書くつもりでいたのですが,いざ書こうと思うと数週間以上かかりそうなのでやめちゃいました。
GUIとかも作りたいのですが,個人的な事情で今はあまり時間が取れないので,ゆくゆくは時間とってちゃんと整備しようかと思います。
GUIとかも作りたいのですが,個人的な事情で今はあまり時間が取れないので,ゆくゆくは時間とってちゃんと整備しようかと思います。
★ Download
DirectXTKについては,Microsoft Public Lisenceに準じます。
詳細は,http://directxtk.codeplex.com/をご覧ください。
瀬戸フォントミニ-Pは,瀬戸のぞみさんの著作物です。
詳細は,http://nonty.net/item/font/をご覧下さい。
本ソースコードおよびプログラムはMIT Licenseに準じます。ただし,DirectXTKは除きます。
プログラムの作成にはMicrosoft Visual Studio 2012 Express Editionを用いています。
詳細は,http://directxtk.codeplex.com/をご覧ください。
瀬戸フォントミニ-Pは,瀬戸のぞみさんの著作物です。
詳細は,http://nonty.net/item/font/をご覧下さい。
本ソースコードおよびプログラムはMIT Licenseに準じます。ただし,DirectXTKは除きます。
プログラムの作成にはMicrosoft Visual Studio 2012 Express Editionを用いています。
