2Dテクスチャの対応が続きますが、今回は表示位置を分かりやすくしてみます。
今は-1~1のウィンドウ座標なので、0~ウィンドウサイズのスクリーン座標で表示の設定ができるように対応を行います。
そのために頂点シェーダーで行列の計算をするので、まずは定数(コンスタント)バッファーを作成します。
P1:定数バッファーの準備
定数バッファーの作成
定数バッファービューの作成
P2:表示クラスの修正
スクリーン→ウィンドウ座標に変換して描画
定数バッファーの準備
頂点シェーダーで定数バッファーを使用するための処理を追加していきます。
まずはルートシグネチャの設定からです。
ルートシグネチャの設定
ルートパラメーターに定数バッファーの設定を追加しましょう。
テクスチャーも必要なので、2つルートパラメーターを用意して、D3D12_ROOT_SIGNATURE_DESCのNumParametersも2に修正します。
サンプラーの設定は前回から変更なしです。
// ディスクリプタの範囲
D3D12_DESCRIPTOR_RANGE range[2] = {};
// シェーダーリソースビュー
range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
// 数
range[0].NumDescriptors = 1;
// t0
range[0].BaseShaderRegister = 0;
// レジスタ領域
range[0].RegisterSpace = 0;
// 記述子テーブルの先頭からのオフセット
range[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
// コンスタントバッファービュー
range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
// 数
range[1].NumDescriptors = 1;
// b0
range[1].BaseShaderRegister = 0;
// レジスタ領域
range[1].RegisterSpace = 0;
// 記述子テーブルの先頭からのオフセット
range[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
// ルートパラメーター
D3D12_ROOT_PARAMETER rootParameters[2] = {};
// パラメータのタイプ
rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
// 範囲の数
rootParameters[0].DescriptorTable.NumDescriptorRanges = 1;
// ディスクリプタの範囲
rootParameters[0].DescriptorTable.pDescriptorRanges = &range[0];
// アクセスできるシェーダー
rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
// パラメータのタイプ
rootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
// 範囲の数
rootParameters[1].DescriptorTable.NumDescriptorRanges = 1;
// ディスクリプタの範囲
rootParameters[1].DescriptorTable.pDescriptorRanges = &range[1];
// アクセスできるシェーダー
rootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
// サンプラーの設定
D3D12_STATIC_SAMPLER_DESC samplerDesc = {};
// サンプリングのフィルター
samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
// uvwが範囲外のときの動作
samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
// ミップマップレベルのオフセット
samplerDesc.MipLODBias = 0;
// 指定のフィルターの場合に使うクランプ値
samplerDesc.MaxAnisotropy = 0;
// 比較オプション
samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
// D3D12_TEXTURE_ADDRESS_MODE_BORDERの場合に使用する色
samplerDesc.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
// ミップマップの範囲
samplerDesc.MinLOD = 0.0f;
samplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
// t0
samplerDesc.ShaderRegister = 0;
// レジスタ領域
samplerDesc.RegisterSpace = 0;
// サンプラーの可視性
samplerDesc.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
// ルートシグネチャの設定
D3D12_ROOT_SIGNATURE_DESC desc;
// ルートパラメーターをセット
desc.NumParameters = 2;
desc.pParameters = rootParameters;
// サンプラーをセット
desc.NumStaticSamplers = 1;
desc.pStaticSamplers = &samplerDesc;
// オプションの設定(入力アセンブラー)
desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
この設定でルートシグネチャを作成すれば、頂点シェーダーで定数バッファーがピクセルシェーダーでテクスチャーが使用できるようになります。
頂点シェーダーの修正
シェーダーに定数バッファーを追加しましょう。
cbuffer ~ register(b〇) に増やしたいデータを書きます。今回は行列だけです。
struct VSOutput
{
float4 pos : SV_POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD;
};
// 定数バッファー
cbuffer myMat : register(b0)
{
matrix mat;
};
VSOutput VSMain( float4 pos : POSITION, float4 color : COLOR, float2 uv : TEXCOORD )
{
VSOutput output;
output.color = color;
output.pos = mul(pos, mat);
output.uv = uv;
return output;
}
用意した行列はposと乗算させておきます。
行列は乗算の順番が違うと結果が異なるので注意です。
定数バッファーの作成
作成は頂点、インデックスバッファーとほぼほぼ同じですが、1つ違うポイントとして定数バッファーのサイズは256の倍数でないといけません。
UINT64 size = sizeof(XMMATRIX);
// 定数バッファーは256でアラインメントする
size = (size + 0xff) & ~0xff;
// ヒープのプロパティ
D3D12_HEAP_PROPERTIES prop;
// ヒープの種類
prop.Type = D3D12_HEAP_TYPE_UPLOAD; // cpuは書き込み、gpuは読み取り
// CPUページプロパティ
prop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; // プロパティ不明
// メモリプール
prop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; // プール不明
// マルチアダプター関連
prop.CreationNodeMask = 1;
prop.VisibleNodeMask = 1;
// リソースの設定
D3D12_RESOURCE_DESC desc;
// リソースのディメンション
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
// 配置の指定
desc.Alignment = 0;
// バッファーサイズ
desc.Width = size;
desc.Height = 1;
// リソース深さ
desc.DepthOrArraySize = 1;
// MIPレベル
desc.MipLevels = 1;
// リソースデータの形式
desc.Format = DXGI_FORMAT_UNKNOWN; // バッファーはこれでいい
// マルチサンプリングの設定
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
// テクスチャのレイアウト
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; // データを連続して配置する
// オプション
desc.Flags = D3D12_RESOURCE_FLAG_NONE; // なし
// インデックスバッファーを作成
result = pDevice->CreateCommittedResource(
&prop,
D3D12_HEAP_FLAG_NONE, // オプションなし
&desc,
D3D12_RESOURCE_STATE_GENERIC_READ, // 読み取り状態
nullptr, // クリアカラー
IID_PPV_ARGS(pConstantBuffer)
);
定数バッファービューの作成
作成したバッファーを使って、CreateConstantBufferViewでバッファービューを作成します。
// CBVを作成
D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
cbvDesc.BufferLocation = m_pConstantBuffer->GetGPUVirtualAddress();
cbvDesc.SizeInBytes = static_cast<UINT>(m_pConstantBuffer->GetDesc().Width);
pDevice->CreateConstantBufferView(&cbvDesc, handle);
あとは定数バッファーをMapしてデータ更新すれば、頂点シェーダーで使用することができます。
次ページ:表示の対応です。
コメント