初期化から描画までの処理
テクスチャーを使って描画するために必要なことは大きくは2点です。
- 頂点データにUV情報の追加
- テクスチャーの読み込みと設定
たったこれだけ対応すればテクスチャーを表示することができます。
VertexBuffer vertexBuffer;
VertexShader vertexShader;
PixelShader pixelShader;
InputLayout inputLayout;
// テクスチャー管理
Texture texture;
// 頂点データ
struct Vertex
{
float x, y, z;
UINT color;
float u, v;
};
bool Initialize(DirectX11& directX11)
{
// 左上から右下まで全体を切り取るようにUV情報を追加
Vertex vertex[4]{
{ -0.5f, -0.5f, 0.0f, 0xffffffff, 1.0f, 1.0f },
{ -0.5f, 0.5f, 0.0f, 0xffffffff, 1.0f, 0.0f },
{ 0.5f, -0.5f, 0.0f, 0xffffffff, 0.0f, 1.0f },
{ 0.5f, 0.5f, 0.0f, 0xffffffff, 0.0f, 0.0f },
};
vertexBuffer.Initialize(directX11, sizeof(vertex), vertex);
if (!vertexShader.Initialize(directX11, "assets/shader.hlsl", "VS"))
{
MessageBox(NULL, "VertexShader", "Error", MB_OK);
return false;
}
if (!pixelShader.Initialize(directX11, "assets/shader.hlsl", "PS"))
{
MessageBox(NULL, "PixelShader", "Error", MB_OK);
return false;
}
// 入力レイアウト(UV値を頂点レイアウトに含める)
D3D11_INPUT_ELEMENT_DESC layout3D[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 4 * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 4, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE(layout3D);
if (!inputLayout.Initialize(directX11, vertexShader, layout3D, numElements))
{
return false;
}
if (!texture.Initialize(directX11, "assets/food.png"))
{
return false;
}
return true;
}
void Finalize()
{
texture.Finalize();
inputLayout.Finalize();
vertexBuffer.Finalize();
vertexShader.Finalize();
pixelShader.Finalize();
}
void RenderTest(DirectX11& directX11)
{
ID3D11DeviceContext* pContext = directX11.GetContext();
ID3D11RenderTargetView* pTarget = directX11.GetRenderTargetView();
D3D11_VIEWPORT ViewPort;
ViewPort.TopLeftX = 0;
ViewPort.TopLeftY = 0;
ViewPort.Width = 1280;
ViewPort.Height = 720;
ViewPort.MinDepth = 0.0f;
ViewPort.MaxDepth = 1.0f;
pContext->OMSetRenderTargets(1, &pTarget, NULL);
pContext->RSSetViewports(1, &ViewPort);
pContext->VSSetShader(vertexShader.GetShader(), NULL, 0);
pContext->PSSetShader(pixelShader.GetShader(), NULL, 0);
auto pView = texture.GetResourceView();
auto pSampler = texture.GetSamplerState();
// テクスチャーとサンプラーステートをスロット(レジスタ)0番に設定
pContext->PSSetShaderResources(0, 1, &pView);
pContext->PSSetSamplers(0, 1, &pSampler);
pContext->IASetInputLayout(inputLayout.GetInputLayout());
pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
UINT offset = 0;
UINT stride = sizeof(Vertex);
ID3D11Buffer* pVBuffer = vertexBuffer.GetBuffer();
pContext->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);
pContext->Draw(4, 0);
}
前回のシェーダを使った描画からそこまで大掛かりな変更は加えていません。
これだけでテクスチャーを使った描画ができるようになります。
実際にこれを実行すると下記のような結果になります。
美味しそうな麻婆麺が表示されましたね!
今回は単純に画像をそのまま表示しているだけです。
ゲームでは1枚のテクスチャーを部分的に切り取って表示することでUIやアニメーション的な処理を行うこともあります。
その辺りは機会があれば別途記事にしていこうかと思います。
サンプルプログラム
今回のテクスチャーの描画までを行ったプロジェクトをアップしています。
必要に応じて参考にしてください。