【DirectX11】テクスチャーを使った描画

初期化から描画までの処理

テクスチャーを使って描画するために必要なことは大きくは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やアニメーション的な処理を行うこともあります。

その辺りは機会があれば別途記事にしていこうかと思います。

 

サンプルプログラム

今回のテクスチャーの描画までを行ったプロジェクトをアップしています。
必要に応じて参考にしてください。

Download

1 2 3 4

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です