DirectX11では昔(DirectX 8の時代)のやり方が通用しなかったのでメモ。
行列の管理のあたり。
1、モデルごとに行列を設定する方法
まずは結論のコードから。
VisualStudio Express12が吐き出したDirectXのスケルトンコードに対して変更を加えるならば、次のとおり。
このコードをモデルごとに実行すればよい。
(ただし、VisualStudioのスケルトンに対してこのコードを追加すると、多数のモデルを表示する場合の効率が悪い)
XMMATRIX tmp = XMMatrixMultiply(rotx, roty); XMMATRIX tmp2 = XMMatrixMultiply(tmp, rotz); XMMATRIX tmp3 = XMMatrixMultiply(scale, pos); XMMATRIX all = XMMatrixMultiply(tmp3, tmp2); XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(all)); d3dContext->UpdateSubresource( constantBuffer, // コピー先リソース 0, // コピー先リソースのインデックス番号 NULL, // コピー先サブリソース部分を定義する3Dボックス constantBufferData, // コピー元のアドレス 0, // コピー元データの一行のサイズ 0 // コピー元データの深度スライスのサイズ );
2、コードの詳細
1、モデル、ビュー、プロジェクション変換行列を格納するための構造体を宣言
2、1で定義した構造体の領域をシステムメモリ上に確保
3、2で確保した構造体にパラメータをセット(上記コード)
4、3でセットした情報をVRAMに転送(UpdateSubresource)
5、頂点シェーダで演算を行う
この動作のうち、上記コードでは3~4を行っている。
これ以外は、VisualStudioが吐き出したスケルトンにコードが含まれている。
今回の簡単な改造では効率(ソフトウェア品質・時間効率性)がよろしくない。
というのも、複数のモデルを表示するために変更が必要なのはmodel行列のみのはずである。
ところがUpdateSubresourceで「model, view, projection」すべてがVRAMに転送される。(上記コードには現れてはいないが、constantBufferDataの型を参照するとわかる。)
改善案としては、model, view, projectionをそれぞれ個別の定数バッファに格納してやる方法が考えられる。
modelをどう扱うかは設計方針によると思われる。
(モデルごとに定数バッファをVRAM上に取るか、定数バッファは1つとしモデルごとに使いまわす)
シェーダーのことも考えると、時間効率性か資源効率性かという話になるのかもしれない。