DirectX11によるポリゴン描画の描画処理実装方法

概要

最終更新日:2020/03/03

DirectX11によるポリゴン描画の描画部分で必要なことを書いています。
この記事は以下の内容を知りたい方に向けて書いています。
  • DirectX11でポリゴンを描画したい
  • ポリゴン描画で必要な設定項目が知りたい
  • 頂点バッファの描画方法が知りたい
  • インデックスバッファの描画方法が知りたい
この描画処理部分で必要な処理を書いた記事です。
描画実装のための準備処理についてはこちらで書いていますので、
準備処理から確認したい方はそちらを確認をお願いします。

サンプル

サンプルはこちらからダウンロードできます。
開発環境については以下の内容です。

開発環境
VSのバージョン VisualStudio 2019
DirectXのバージョン DirectX11


描画で必要な事

ポリゴンの描画で必要なことは適切な情報をGPU側に送信することです。

directx_0161

上の図のオレンジの枠の部分が送信するための情報と設定関数です。
これらを実装することで頂点バッファやインデックスバッファによる描画を行えます。
※この記事では単純なポリゴンの描画の説明なので、
 ジオメトリ、テッセレーションなどのシェーダは図から省略してます。

共通の設定処理

頂点バッファとインデックスバッファの描画を行う上で
以下の処理は共通の設定項目です
  • 頂点バッファの設定
  • 入力レイアウトの設定
  • コンスタントバッファの設定
  • プリミティブの設定
  • シェーダの設定
  • 出力先の設定

頂点バッファの設定

描画の際に最も必須となるのが頂点バッファの設定です。
ID3D11DeviceContextの「IASetVertexBuffers関数」で
レンダリングパイプラインで描画する頂点バッファを指定します。

directx_0152
// 頂点バッファの設置
m_Context->IASetVertexBuffers(
	0, 		// スロット番号
	1, 		// 頂点バッファの数
	&buff,		// 頂点バッファの配列
	&strides,	// 1頂点のサイズの配列
	&offsets);	// オフセットの配列

頂点バッファの設定はBuffer「s」となっているように、
複数の頂点バッファを指定できます。
その為、複数の頂点情報の構成が異なるバッファを描画することができます。

入力レイアウトの設定

描画で使用する入力レイアウトをID3D11DeviceContextの
「IASetInputLayout関数」で設定します。
directx_0151
// 入力レイアウトの設定
m_Context->IASetInputLayout( model->GetInputLayout() );

プリミティブの設定

描画するポリゴンの作成方法をID3D11DeviceContextの
「IASetPrimitiveTopology」で設定します。
プリミティブの種類とはトライアングルリストやトライアングルストリップなどです。

directx_0153
// プリミティブの設定
m_Context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

コンスタントバッファの設定

コンスタントバッファの設定は使用するシェーダ毎に設定をします。
今回のサンプルでは頂点シェーダに設定をしているので、
ID3D11DeviceContextの「VSSetConstantBuffers関数」で設定をしています。
また、設定の前にバッファの更新を行うために「UpdateSubresource関数」も
実行しています。

directx_0154
directx_0155

// コンスタントバッファ更新
m_Context->UpdateSubresource(
	m_ConstantBuffer,		// 更新対象のバッファ
	0,				// インデックス(0)
	NULL,				// 更新範囲(nullptr)
	&m_ConstantBufferData,		// 反映データ
	0,				// データの1行のサイズ(0)
	0);				// 1深度スライスのサイズ(0)

// コンスタントバッファを設定
m_Context->VSSetConstantBuffers(
	0,				// バッファの開始番号
	1,				// バッファの数
	&constant_buffer);		// 設定するコンスタントバッファ

UpdateSubresourceはコンスタントバッファを更新するのではなく、
バッファのSubresourceを更新する関数です。
その為、様々な情報の指定を求められていますが、
今回の更新で重要な引数は第一と第四引数だけです。

シェーダの設定

シェーダの設定は各シェーダ毎に行います。
今回は頂点シェーダとピクセルシェーダを使用していますので、
ID3D11DeviceContextの「VSSetShader関数」と「PSSetShader関数」で設定します。

directx_0141
directx_0142

// 頂点シェーダの設定
m_Context->VSSetShader(m_VertexShader->GetShaderInterface(), NULL, 0);
// ピクセルシェーダの設定
m_Context->PSSetShader(m_PixelShader->GetShaderInterface(), NULL, 0);

出力先の設定

描画処理の出力先ビューの設定をID3D11DeviceContextの
「OMSetRenderTargets関数」で行います。

directx_0156
// 出力先の設定
m_Context->OMSetRenderTargets( 1, &m_RenderTargetView, m_DepthStencilView );

頂点バッファによる描画

頂点バッファによる描画は設定が全て完了後に
ID3D11DeviceContextの「Draw関数」で行います。

directx_0157
// 描画
m_Context->Draw( 
	3,	// 頂点の数 
	0);	// 頂点バッファの描画開始インデックス

関数内でバッファの指定がないのはIASetVertexBuffersで設定が終わっているからです。

インデックスバッファによる描画

インデックスバッファによる描画は設定処理に「インデックスバッファの設定」を
追加して、Draw関数を「DrawIndexed関数」に変更します。

インデックスバッファの設定

頂点バッファと同様にインデックスバッファによる描画の場合は、
インデックスバッファをID3D11DeviceContextの
「IASetIndexBuffer関数」を使って設定します。

directx_0158
// インデックスバッファの設定
m_Context->IASetIndexBuffer(
	index_buffer,		// 設定するインデックスバッファ
	DXGI_FORMAT_R16_UINT,	// インデックスのサイズフォーマット
	0);			// バッファの開始オフセット

第二引数のオフセットはインデックスバッファの要素のサイズです。
「DXGI_FORMAT_R16_UINT」は符号なし2バイトを指しています。

描画(インデックスバッファ)

インデックスバッファによる描画はDrawではなくID3D11DeviceContextの
「DrawIndexed関数」で行います。

directx_0159
// インデックスバッファによる描画
m_Context->DrawIndexed(
	3,	// 描画する頂点の数
	0,	// 描画で使う最初のインデックス番号
	0);	// 頂点バッファの最初の位置

この関数でもインデックスバッファの指定はしていませんが、
IASetIndexBufferで設定済みだからです。