Direct3D11初期化&画面クリア 続き
間が空いてしまいましたが、前回の続きを書いていきたいと思います。
画面クリア
画面クリアの手順を見ていきましょう。
1.バックバッファのリサイズ処理
IDXGISwapChain::ResizeBuffers 関数でクライアント領域に合わせて、
バックバッファのリサイズを行っています。
// SampleApp::CreateBackBuffer(const Size2D& newSize) // バッファのサイズを変更 HRESULT hr = m_SwapChain->ResizeBuffers( m_BufferCount, static_cast<UINT>(newSize.width), static_cast<UINT>(newSize.height), m_BufferFormat, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ); if (FAILED(hr)) { return false; }
IDXGISwapChain::ResizeBuffers 関数
HRESULT ResizeBuffers(
UINT BufferCount,
UINT Width,
UINT Height,
DXGI_FORMAT NewFormat,
UINT SwapChainFlags
);
BufferCount
スワップチェインのバッファ数です。
作成した時と同じ値を指定しておけば問題ないでしょう。
Width
バック バッファーの新しい幅です。
0 が指定された場合、ターゲット ウィンドウのクライアント領域の幅が使用されます。
Height
バック バッファーの新しい高さです。
0 が指定された場合、ターゲット ウィンドウのクライアント領域の高さが使用されます。
NewFormat
バック バッファーの新しいフォーマットです。
DXGI_FORMAT の値を指定できます。
変更しない場合は作成時と同じ値を指定します。
SwapChainFlags
スワップチェインの動作オプションです。
DXGI_SWAP_CHAIN_FLAG の値を指定できます。
変更しない場合は作成時と同じ値を指定します。
2.バックバッファを取得
IDXGISwapChain::GetBuffer 関数でバックバッファを取得します。
// SampleApp::CreateBackBuffer(const Size2D& newSize) ComPtr<ID3D11Texture2D> backBuffer; hr= m_SwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); if (FAILED(hr)) { return false; }
IDXGISwapChain::GetBuffer 関数
HRESULT GetBuffer(
UINT Buffer,
REFIID riid,
void **ppSurface
);
Buffer
取得したいバッファーのインデックスです。
レンダーターゲットを作成する場合は 0 で問題ないでしょう。
riid
バッファーの操作に使用するインターフェイスの種類です。
ppSurface
バック バッファー インターフェイスへのポインターです。
※引数の指定の仕方について
IID_PPV_ARGS マクロを使用すると簡潔に記述できます。
m_SwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer));
3.レンダーターゲットを作成
ID3D11Device::CreateRenderTargetView 関数でレンダーターゲットを作成します。
// SampleApp::CreateBackBuffer(const Size2D& newSize) hr = m_Device->CreateRenderTargetView( backBuffer.Get(), nullptr, &m_RenderTargetView ); if (FAILED(hr)) { return false; }
ID3D11Device::CreateRenderTargetView 関数
HRESULT CreateRenderTargetView(
ID3D11Resource *pResource,
const D3D11_RENDER_TARGET_VIEW_DESC *pDesc,
ID3D11RenderTargetView **ppRTView
);
pResource
レンダー ターゲットを表す ID3D11Resource へのポインターです。
このリソースは、D3D11_BIND_RENDER_TARGET フラグを使用してあらかじめ作成しておく必要があります。
ここでは、IDXGISwapChain::GetBuffer 関数で取得した値を指定しています。
pDesc
レンダー ターゲット ビューの記述を表す D3D11_RENDER_TARGET_VIEW_DESC へのポインターです。
バックバッファのレンダーターゲットの場合 NULL を指定できます。
ppRTView
作成されたレンダーターゲットを表す ID3D11RenderTargetView へのポインターのアドレスです。
4.レンダーターゲットを設定
ID3D11DeviceContext::OMSetRenderTargets 関数を使用して設定します。
// SampleApp::CreateBackBuffer(const Size2D& newSize) ID3D11RenderTargetView* pRenderTargetViews[] = { m_RenderTargetView.Get() }; m_Context->OMSetRenderTargets( _countof(pRenderTargetViews), pRenderTargetViews, nullptr );
ID3D11DeviceContext::OMSetRenderTargets 関数
void OMSetRenderTargets(
UINT NumViews,
ID3D11RenderTargetView *const *ppRenderTargetViews,
ID3D11DepthStencilView *pDepthStencilView
);
NumViews
バインドするレンダー ターゲットの数です (範囲は 0 ~ D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT)。
ppRenderTargetViews の要素数です。
ppRenderTargetViews
デバイスにバインドするレンダー ターゲットの配列へのポインターです。
このパラメーターが NULL の場合、レンダー ターゲットはバインドされません。
pDepthStencilView
デバイスにバインドする深度ステンシル ビューへのポインターです。
このパラメーターが NULL の場合、深度ステンシル ステートはバインドされません。
5.ビューポートの設定
D3D11_VIEWPORT 構造体で設定を記述し、
ID3D11DeviceContext::RSSetViewports 関数で設定します。
// SampleApp::CreateBackBuffer(const Size2D& newSize) D3D11_VIEWPORT viewport; viewport.Width = static_cast<FLOAT>(newSize.width); viewport.Height = static_cast<FLOAT>(newSize.height); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; m_Context->RSSetViewports(1, &viewport);
6.画面クリア
ID3D11DeviceContext::ClearRenderTargetView 関数を使用して画面をクリアします。
// SampleApp::Render() // 指定色でクリア FLOAT clearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha m_Context->ClearRenderTargetView(m_RenderTargetView.Get(), clearColor);
7.バックバッファを画面に反映
IDXGISwapChain::Present 関数でバックバッファを画面に反映します。
// SampleApp::Render() // 結果をウインドウに反映 HRESULT hr = m_SwapChain->Present(0, 0); if (FAILED(hr)) // Error! }
最後の方が説明不足な気がしますが、これで画面クリアができました。
長かったです。