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

テクスチャーの管理クラス

テクスチャーを読み込んで使用するために、先ずはTextureクラスを作成していきます。
今回のクラスでは下記の機能を実装いていきます。

  • 画像データの読み込み
  • シェーダリソースの作成
  • サンプラーステートの作成

サンプラーステートは別途管理した方がいい場合もありますが、今回はまとめて実装していきます。

Texture.h
// テクスチャーの初期化
class Texture
{
public:
	Texture();
	// 初期化、解放
	bool Initialize(DirectX11& directX11, const char* pFilename);
	void Finalize();

	ID3D11ShaderResourceView* GetResourceView() {
		return  m_pShaderResourceView.Get();
	}
	ID3D11SamplerState* GetSamplerState() {
		return m_pSamplerState.Get();
	}
	UINT GetWidth() { return m_Width; }
	UINT GetHeight() { return m_Height; }

private:
	// サンプラーステートの作成
	bool CreateSampler(DirectX11& directX11);

private:
	ComPtr<ID3D11ShaderResourceView> m_pShaderResourceView;
	ComPtr<ID3D11SamplerState> m_pSamplerState;
	DXGI_FORMAT m_Format;
	UINT m_Width;
	UINT m_Height;
};

今回は、テクスチャークラスの管理にComPtrを使用しています。
これはスマートポインタと呼ばれるものでCOMオブジェクトの生存管理をしてくれます。

DirectXはCOMオブジェクトとして実装されています。
なのでComPtrを使用することで管理を楽にすることができます。

使い方は簡単です。

#include <wrl.h>

using namespace Microsoft::WRL;

上記のようにwrl.hのインクルードとネームスペースを省略するためのusingを書けば完了です。

 

ではこの調子でクラスの実装部分も見ていきましょう。

Texture.cpp
#include "Texture.h"
#include <DirectXTex/DirectXTex.h>

// DirectXTexのライブラリをリンク
#if _DEBUG
#pragma comment(lib, "DirectXTex/x64/Debug/DirectXTex.lib")
#else
#pragma comment(lib, "DirectXTex/x64/Release/DirectXTex.lib")
#endif

using namespace DirectX;

Texture::Texture()
	: m_pShaderResourceView(nullptr)
	, m_pSamplerState(nullptr)
	, m_Width(0)
	, m_Height(0)
{}

bool Texture::Initialize(DirectX11& directX11, const char* pFilename)
{
	auto pDevice = directX11.GetDevice();

	Finalize();

	const char* pExtension = "";
	for (size_t i = strlen(pFilename); i == 0; i--)
	{
		if (pFilename[i-1] == '.')
		{
			pExtension = &pFilename[i];
		}
	}

	WCHAR path[256];
	size_t len = 0;
	mbstowcs_s(&len, path, 256, pFilename, _TRUNCATE);

	TexMetadata metadata;
	ScratchImage image;
	HRESULT hr;
	// DDSファイルの読み込み
	if (strcmp(pExtension, "dds") == 0)
	{
		hr = LoadFromDDSFile(path, DDS_FLAGS::DDS_FLAGS_NONE, &metadata, image);
	}
	// TGAファイルの読み込み
	else if (strcmp(pExtension, "tga") == 0)
	{
		hr = LoadFromTGAFile(path, &metadata, image);
	}
	// WICファイル(bmp, jpg, png等)の読み込み
	else
	{
		hr = LoadFromWICFile(path, WIC_FLAGS::WIC_FLAGS_NONE, &metadata, image);
	}

	if (FAILED(hr))
	{
		return false;
	}

	ComPtr<ID3D11ShaderResourceView> pView;
	// 画像からシェーダリソースViewの作成
	hr = CreateShaderResourceView(pDevice, image.GetImages(), image.GetImageCount(), metadata, &pView);
	if (FAILED(hr)) {
		return false;
	}
	if (!CreateSampler(directX11)) {
		return false;
	}
	m_Format = metadata.format;
	m_Width = static_cast(metadata.width);
	m_Height = static_cast(metadata.height);
	m_pShaderResourceView.Swap(pView);

	return true;
}

void Texture::Finalize()
{
	m_pShaderResourceView.Reset();
	m_pSamplerState.Reset();
}

bool Texture::CreateSampler(DirectX11& directX11)
{
	auto pDevice = directX11.GetDevice();
	// SamplerState作成
	D3D11_SAMPLER_DESC sampDesc{};
	sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
	sampDesc.MinLOD = 0;
	sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
	ComPtr<ID3D11SamplerState> pSamplerState;
	HRESULT hr = pDevice->CreateSamplerState(&sampDesc, &pSamplerState);
	if (FAILED(hr)) {
		return false;
	}
	m_pSamplerState.Swap(pSamplerState);
	return true;
}

一気に記述していきましたが、これでテクスチャーの管理が行えます。
ComPtrを使用しているのでFinalizeは無くても解放はされます。
ただ解放タイミングの制御するためにはあった方が無難です。

対応しているファイルはbmp, png, jpgなどからddsやtga辺りまで対応しています。

1 2 3 4

コメントを残す

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