前回は背景色の変更までだったので、今回は三角形を表示させます。
三角形を表示させるだけですが、今回も道のりは長い…
1:ルートシグネチャの作成
2:シェーダーの準備
3:グラフィックスパイプラインステートの作成
4:三角形の表示
ヘッダーファイル
前回のGraphic.hに追加します。
class Graphic
{
//省略
// ルートシグネチャの作成
bool CreateRootSignature();
// パイプラインステートの作成
bool CreatePipelineState();
// 省略
ID3D12RootSignature* m_pRootSignature;
ID3D12PipelineState* m_pPipelineState;
D3D12_VIEWPORT m_Viewport;
D3D12_RECT m_ScissorRect;
}
作成の関数はコマンドリスト作成の前に呼び出します。
ルートシグネチャ
まずはルートシグネチャの作成です。
CreateRootSignatureを使用します。
まずD3D12SerializeRootSignatureでシリアル化します。
// ルートシグネチャの作成
bool Graphic::CreateRootSignature()
{
// 空のルートシグネチャを作成
D3D12_ROOT_SIGNATURE_DESC desc;
// 空なので0
desc.NumParameters = 0;
desc.pParameters = nullptr;
desc.NumStaticSamplers = 0;
desc.pStaticSamplers = nullptr;
// オプションの設定(入力アセンブラー)
desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
ID3DBlob* pSignature;
ID3DBlob* pError;
// シリアル化
D3D12SerializeRootSignature(
&desc,
D3D_ROOT_SIGNATURE_VERSION_1, // ver.1
&pSignature,
&pError
);
// ルートシグネチャの作成
HRESULT result = m_pDevice->CreateRootSignature(
0, // GPUアダプターが1つなら0
pSignature->GetBufferPointer(),
pSignature->GetBufferSize(),
IID_PPV_ARGS(&m_pRootSignature)
);
IS_S_FALSE(result);
SAFE_RELEASE(pError);
SAFE_RELEASE(pSignature);
return true;
}
作成が完了したら、ID3DBlobは開放します。
エラーが出る場合はpErrorに文字列がセットされているはずなので、それで原因を調べることが可能です。
ルートシグネチャの設定
コマンドリストのリセット ~ レンダーターゲットビュー設定の間に行います。
void Graphic::SetRenderTarget()
{
m_pCommandList->SetGraphicsRootSignature(m_pRootSignature);
m_pCommandList->RSSetViewports(1, &m_Viewport);
m_pCommandList->RSSetScissorRects(1, &m_ScissorRect);
// リソースバリア
// レンダーターゲットビューを設定
}
ビューポートとシザー
上記でついでに設定していますが、とりあえずウィンドウ幅と高さを設定していれば問題ないです。
// ビューポート
m_Viewport = {};
m_Viewport.Width = static_cast<FLOAT>(WINDOW_WIDTH);
m_Viewport.Height = static_cast<FLOAT>(WINDOW_HEIGHT);
m_Viewport.MaxDepth = 1.0f;
// シザー
m_ScissorRect = {};
m_ScissorRect.right = WINDOW_WIDTH;
m_ScissorRect.bottom = WINDOW_HEIGHT;
シェーダー
次はグラフィックスパイプラインステートの作成ですが、シェーダーが必要なのでシェーダーから作成していきます。
ファイルの追加
新しい項目の追加から「頂点シェーダー」と「ピクセルシェーダー」(hlsl)ファイルを追加します。
頂点シェーダー
struct VSOutput
{
float4 pos : SV_POSITION;
float4 color : COLOR;
};
VSOutput VSMain( float4 pos : POSITION, float4 color : COLOR )
{
VSOutput output;
output.pos = pos;
output.color = color;
return output;
}
ピクセルシェーダー
struct PSInput
{
float4 pos : SV_POSITION;
float4 color : COLOR;
};
float4 PSMain( PSInput input ) : SV_TARGET
{
return input.color;
}
プロパティの設定
シェーダー最低限の機能を入れたら、プロパティの設定を行います。
関数名を変更した場合は「エントリポイント名」の変更も必要です。
ピクセルシェーダーのプロパティも同じように変更します。
シェーダーのコンパイル
シェーダーをコンパイルします。
D3DCompileFromFileを使用します。
インクルードとリンクが必要です。
#include <d3dcompiler.h>
#pragma comment(lib, "d3dcompiler.lib")
// パイプラインステートの作成
bool Graphic::CreatePipelineState()
{
// まずシェーダを準備する
ID3DBlob* pVertexShader;
ID3DBlob* pPixelShader;
ID3DBlob* pError;
#ifdef _DEBUG
// デバッグの出力と最適化のスキップ
UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#else
UINT compileFlags = 0;
#endif
// シェーダーをコンパイル
D3DCompileFromFile(
L"VertexShader.hlsl",
nullptr, // シェーダーマクロを使用しない
nullptr, // インクルードを使用しない
"VSMain", // エントリポイント関数の名前
"vs_5_0", // シェーダーモデル
compileFlags, // オプション
0, // オプション
&pVertexShader,
&pError // エラーメッセージ
);
// ピクセルシェーダー
D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pPixelShader, nullptr);
// パイプラインステートの作成
SAFE_RELEASE(pPixelShader);
SAFE_RELEASE(pVertexShader);
SAFE_RELEASE(pError);
}
全ての作成が完了したら、ID3DBlobは開放します。
エラーが出る場合はpErrorに文字列がセットされているはずなので、それで原因を調べることが可能です。
次はグラフィックスパイプラインステートの作成
コメント