前回でポリゴンは描画することが出来ました。今回はこのポリゴンを3D空間上で回してみたいと思います。幸いにも DirectXMath が普通に使えるようで、今回は行列をシェーダーに渡す、「定数バッファ(コンスタントバッファ)」を DirectX12 でどのように生成&使用するのかといった点がポイントとなります。
本内容は既に最新環境では正常にコンパイルできません。ご注意ください 2015/5
注意事項
繰り返しの内容となりますが、以下の点をご了承ください。
現時点において DirectX12 の部分はプレビュー版となっています。正式版では大きく変更される可能性があります。よってここの情報は 2015/04 現在の限定された環境でのみ動作するという点をご理解ください。また以下の内容は間違っている点もあるかと思います。その点にはご注意ください。
ポリゴンを回す
知っての通りポリゴンを回すために、ワールド行列、ビュー行列、プロジェクション行列を用います。これらの演算には DirectXMath を使用してしまいます。この行列を格納した定数バッファを準備する必要があるので、ここから確認していきます。
また今回は定数バッファ1つを使う前提で処理します。そのためややこしいディスクリプタヒープ等は使わないで設定する方向でいきます(自分自身あまりまだ理解できていなかったりするので)
定数バッファを作る
定数バッファも基本的には頂点バッファと同じように作成します。 DirectX11 のころからか頂点バッファとか○○バッファとか区別しないで、バッファとなった気がします。ここでは4x4の行列1つを送るためのバッファを用意しました。
// 定数バッファ Matrix4x4を3つ分で確保. dxDevice->CreateCommittedResource( &CD3D12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_MISC_NONE, &CD3D12_RESOURCE_DESC::Buffer(sizeof(XMFLOAT4X4)*3), D3D12_RESOURCE_USAGE_GENERIC_READ, nullptr, IID_PPV_ARGS(constantBuffer.GetAddressOf()) );
定数バッファへの書き込み
書き込みもまた頂点のときと同じように Map/Unmap で処理します。 DirectXMath で用意した行列を定数バッファに書き込んでいるコードは以下のようになります。
world = XMMatrixMultiply(XMMatrixRotationX(count * 0.01f), XMMatrixRotationY(count*0.02f)); XMMATRIX wvp = XMMatrixMultiply(XMMatrixMultiply(world, view), proj); void* pCB; constantBuffer->Map(0, nullptr, &pCB); if (pCB) { XMStoreFloat4x4( (XMFLOAT4X4*)pCB, wvp); constantBuffer->Unmap(0, nullptr); }
定数バッファをコマンドに設定
定数バッファをコマンドリストに登録しなくてはなりません。今回は以下のようにして直接設定してしまうことにしました。別の回で説明できたらと思いますが、今回は規模も小さいため直接設定してしまうことにしました。(直接というのはディスクリプタ経由しないという意味です。たぶん)
commandList->SetGraphicsRootConstantBufferView( 0, constantBuffer->GetGPUVirtualAddress() );
パイプラインステートの設定
今までの部分が簡単だったのは実はパイプラインステートでRootSignatureで直接設定してしまうようにしていたからなのでした。本来はここでディスクリプタテーブルとか出てくるようなので、これはちゃんと理解したあとでまた別の回として載せたいと思います。今回は以下のようにして、 RootSignature を作っています。一応ディスクリプタテーブルを介さない方がパフォーマンスはよい(らしい)です。
// PipelineStateのための RootSignature の作成. D3D12_ROOT_SIGNATURE descRootSignature; descRootSignature.Flags = D3D12_ROOT_SIGNATURE_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; D3D12_ROOT_PARAMETER rootParameters[1]; rootParameters[0].InitAsConstantBufferView(0); descRootSignature.NumParameters = 1; descRootSignature.pParameters = rootParameters; ComPtrrootSigBlob, errorBlob; D3D12SerializeRootSignature( &descRootSignature, D3D_ROOT_SIGNATURE_V1, rootSigBlob.GetAddressOf(), errorBlob.GetAddressOf()); dxDevice->CreateRootSignature( 0, rootSigBlob->GetBufferPointer(), rootSigBlob->GetBufferSize(), IID_PPV_ARGS(rootSignature.GetAddressOf()));
今までは何もしていなかった D3D12_ROOT_PARAMETER が登場しています。これに今回は定数バッファビューを設定するようにしています。
まとめ
このようにしてとりあえずは定数バッファを使うことができました。またいつも通り GitHub に今回のコードを公開しております。ぼちぼちテクスチャを使うようにしてみたいのと、今回何となくで終わらせてしまったディスクリプタテーブル関連の部分をきちんと把握したいです。
本内容は既に最新環境では正常にコンパイルできません。ご注意ください 2015/5