ゲームフレームワーク的なものを作る。(3)〜Graphicsクラス〜
前回「ゲームフレームワーク的なものを作る。(2)〜Gameクラスに描画機能を追加〜 - while( c++ );」、Gameクラスへ描画機能を追加しました。
このまま画像などの描画機能も追加していくとGameクラスが肥大化するので、以下のように描画機能だけGraphicsクラス的なものに分離してみましょう。
Graphics.h
class Graphics { // ------------------------------------------------------------------------------- // 生成と破棄 // ------------------------------------------------------------------------------- public: /** * コンストラクタ */ Graphics( const WindowWeakPtr& window ); /** * デストラクタ */ ~Graphics(); // ------------------------------------------------------------------------------- // 基本機能 // ------------------------------------------------------------------------------- private: /** * Direct3Dオブジェクトの生成 */ IDirect3D9* CreateDirect3D(); /** * Direct3Dデバイスオブジェクトの生成 */ IDirect3DDevice9* CreateDirect3DDevice(); /** * COMオブジェクト解放用関数オブジェクト */ struct com_deleter { void operator()( IUnknown* p ) { p->Release(); } }; public: /** * シーンのクリア */ void Clear(); /** * シーンのレンダリング開始 */ bool BeginScene(); /** * シーンのレンダリング終了 */ void EndScene(); /** * 画面の更新 */ void Update(); private: WindowWeakPtr window; ///< Graphicsを関連付けたWindow std::shared_ptr< IDirect3D9 > direct3d; ///< Direct3Dオブジェクト std::shared_ptr< IDirect3DDevice9 > device; ///< 描画担当 };
Graphics.cpp
/** * コンストラクタ * * @param window 既存ウィンドウのweak_ptr */ Graphics::Graphics( const WindowWeakPtr& window ) : window( window ) , direct3d( CreateDirect3D(), com_deleter() ) , device( CreateDirect3DDevice(), com_deleter() ) { } /** * デストラクタ */ Graphics::~Graphics() { } /** * Direct3Dオブジェクトの生成 */ IDirect3D9* Graphics::CreateDirect3D() { IDirect3D9* p = Direct3DCreate9( D3D_SDK_VERSION ); if( p == nullptr ) throw std::runtime_error( "Direct3DCreate9" ); return p; } /** * Direct3Dデバイスオブジェクトの生成 */ IDirect3DDevice9* Graphics::CreateDirect3DDevice() { if( WindowPtr w = window.lock() ) //lockの失敗はありえないはず。。。 { IDirect3DDevice9* p = nullptr; D3DPRESENT_PARAMETERS pp = { 0 }; pp.Windowed = TRUE; //ウィンドウモードの場合はTRUEを指定 pp.SwapEffect = D3DSWAPEFFECT_DISCARD; HRESULT hr = direct3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, w->GetHandle(), //ウィンドウハンドルを渡す D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &p ); if( SUCCEEDED( hr ) )return p; } throw std::runtime_error( "CreateDevice" ); } /** * シーンのクリア */ void Graphics::Clear() { const DWORD clear_flag = D3DCLEAR_TARGET; const D3DCOLOR clear_color = D3DCOLOR_XRGB( 0x22, 0x22, 0x22 ); device->Clear( 0, nullptr, clear_flag, clear_color, 1.0f, 0 ); } /** * シーンのレンダリング開始 */ bool Graphics::BeginScene() { return SUCCEEDED( device->BeginScene() ); } /** * シーンのレンダリング終了 */ void Graphics::EndScene() { device->EndScene(); } /** * 画面の更新 */ void Graphics::Update() { device->Present( nullptr, nullptr, nullptr, nullptr ); }
Game.h
class Game { // ------------------------------------------------------------------------------- // 生成と破棄 // ------------------------------------------------------------------------------- public: /** * コンストラクタ */ Game( const WindowWeakPtr& window ); /** * デストラクタ */ ~Game(); // ------------------------------------------------------------------------------- // 基本機能 // ------------------------------------------------------------------------------- public: /** * ゲーム1フレームの処理を行う */ void Run(); private: Graphics graphics; ///< 描画機能 };
Game.cpp
/** * コンストラクタ * * @param window 既存ウィンドウのweak_ptr */ Game::Game( const WindowWeakPtr& window ) : graphics( window ) { //その他のゲームの初期化処理 ; std::cout << "ゲームの初期化成功" << std::endl; } /** * デストラクタ */ Game::~Game() { //その他のゲームの解放処理 ; } /** * ゲーム1フレームの処理を行う */ void Game::Run() { //シーンの実行 ; //バックバッファをクリアし、シーンのレンダリングを開始する //レンダリング終了後、画面を更新する graphics.Clear(); if( graphics.BeginScene() ) { //シーンの描画 ; graphics.EndScene(); } graphics.Update(); }