【DX12を学びたい】デバイス作成~背景の色を変更する

背景色の変更 DirextX

前ページでデバイスを作成しました。

このデバイスで描画に必要なものを作成していきます。

1:デバッグレイヤーの有効化
2:デバイスの作成
3:その他諸々の作成

 :コマンドキュー
 :スワップチェーン
 :レンダーターゲットビュー
 :コマンドリスト
 :フェンス

4:バックカラー変更の実装

スポンサーリンク

コマンドキュー

コマンドキューの作成です。
CreateCommandQueueを使用します。

// コマンドキューの作成
bool Graphic::CreateCommandQueue()
{
	D3D12_COMMAND_QUEUE_DESC queueDesc;
	// GPU が実行できるコマンドバッファー
	queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

	// 優先度は通常
	queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;

	// 既定のコマンドキュー
	queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;

	// GPUアダプターが1つなら0
	queueDesc.NodeMask = 0;

	// キューの作成
	HRESULT result = m_pDevice->CreateCommandQueue(
		&queueDesc,
		IID_PPV_ARGS(&m_pCommandQueue)
	);
	IS_S_FALSE(result);

	return true;
}

 

スワップチェーン

次はスワップチェーンの作成です。
CreateSwapChainForHwndを使用します。

DXGI_SWAP_CHAIN_DESC1は適宜設定を行います。WidthやHeightが0ですが、ウィンドウサイズを設定します。

// スワップチェーンの作成
bool Graphic::CreateSwapChain(HWND hwnd)
{
	// DXGIオブジェクトを作成するためのもの
	HRESULT result = CreateDXGIFactory1(IID_PPV_ARGS(&m_pFactory));
	IS_S_FALSE(result);

	DXGI_SWAP_CHAIN_DESC1 desc = {};
	desc.Width = 0;
	desc.Height = 0;
	desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	desc.Stereo = false;
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0;
	desc.BufferUsage = DXGI_USAGE_BACK_BUFFER;
	desc.BufferCount = BACK_BUFFER_NUM;	// ダブルバッファー
	desc.Scaling = DXGI_SCALING_STRETCH;
	desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
	desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
	desc.Flags = 0;

	// スワップチェーンの作成
	result = m_pFactory->CreateSwapChainForHwnd(
		m_pCommandQueue,
		hwnd,
		&desc,
		nullptr,		// ウィンドウモードはnull
		nullptr,		// とりあえずnull
		(IDXGISwapChain1**)&m_pSwapChain
	);
	IS_S_FALSE(result);

	// 今のバックバッファーのインデックス
	m_FrameIndex = m_pSwapChain->GetCurrentBackBufferIndex();

	return true;
}

 

レンダーターゲットビュー

続いてレンダーターゲットビューの作成です。
CreateRenderTargetViewを使用します。

がその前に・・・

 

ディスクリプタヒープ

レンダーターゲットビューを作るために、ディスクリプタヒープの作成です。
CreateDescriptorHeapを使用します。

ディスクリプタ=記述子。記述子は「構造や内容の要約、属性などが記されたもの」とのこと。

// レンダーターゲットの作成
bool Graphic::CreateRenderTarget()
{
	D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};

	// レンダーターゲットビュー
	heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;

	// ダブルバッファー
	heapDesc.NumDescriptors = BACK_BUFFER_NUM;

	// デフォルト
	heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;

	// GPUアダプターが1つなら0
	heapDesc.NodeMask = 0;

	// ディスクリプタヒープの作成
	HRESULT result = m_pDevice->CreateDescriptorHeap(
		&heapDesc,
		IID_PPV_ARGS(&m_pRenderTargetHeap)
	);
	IS_S_FALSE(result);

	// 先頭のアドレス
	D3D12_CPU_DESCRIPTOR_HANDLE handle = m_pRenderTargetHeap->GetCPUDescriptorHandleForHeapStart();
	m_RTVIncrementSize = m_pDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

	for (int i = 0; i < BACK_BUFFER_NUM; ++i)
	{
		// スワップチェーンのバッファーを取得
		result = m_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&m_pRenderTargets[i]));
		IS_S_FALSE(result);

		// レンダーターゲットビューの作成
		m_pDevice->CreateRenderTargetView(
			m_pRenderTargets[i],
			nullptr,	// とりあえずnull
			handle
		);

		// 次へずらす
		handle.ptr += m_RTVIncrementSize;
	}

	return true;
}

 

コマンドリスト

お次はコマンドリストの作成です。
CreateCommandListを使用します。

 

コマンドアロケータ

コマンドリストにはコマンドアロケータの作成が必要になります。
CreateCommandAllocatorで作成します。

// コマンドリストの作成
bool Graphic::CreateCommandList()
{
	// コマンドアロケータの作成
	HRESULT result = m_pDevice->CreateCommandAllocator(
		D3D12_COMMAND_LIST_TYPE_DIRECT,	// GPUが実行できるコマンドリスト
		IID_PPV_ARGS(&m_pCommandAllocator)
	);
	IS_S_FALSE(result);

	// コマンドリストの作成
	result = m_pDevice->CreateCommandList(
		0,		// GPUアダプターが1つなら0
		D3D12_COMMAND_LIST_TYPE_DIRECT,
		m_pCommandAllocator,
		nullptr,	// パイプライン状態
		IID_PPV_ARGS(&m_pCommandList)
	);
	IS_S_FALSE(result);

	// 閉じておく
	m_pCommandList->Close();

	return true;
}

 

フェンス

フェンスの作成です。
CreateFenceを使用します。

フェンスはコマンドの処理が完了したかを確認するためのもの。
今回はCreateEventと組み合わせて使用します。

// フェンスの作成
bool Graphic::CreateFence()
{
	// フェンスの生成
	HRESULT result = m_pDevice->CreateFence(
		0,
		D3D12_FENCE_FLAG_NONE,
		IID_PPV_ARGS(&m_pFence)
	);
	IS_S_FALSE(result);
	m_FenceValue = 1;

	// イベントの生成
	m_pFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
	if (m_pFenceEvent == nullptr) {
		return false;
	}

	return true;
}

 

作成処理をまとめる

これまでの作成処理をまとめておきます。

// 初期化
bool Graphic::Initialize(HWND hwnd)
{
	// デバッグ有効
	EnableDebugLayer();

	// 色々作成
	if (CreateDevice() == false) {
		return false;
	}
	if (CreateCommandQueue() == false) {
		return false;
	}
	if (CreateSwapChain(hwnd) == false) {
		return false;
	}
	if (CreateRenderTarget() == false) {
		return false;
	}
	if (CreateCommandList() == false) {
		return false;
	}
	if (CreateFence() == false) {
		return false;
	}

	return true;
}

 

次は作成したもので、描画を実装していきます。

かれいど

ゲームをしたり、作ったり
色々な事に挑戦していきたい!

サッカー観戦も趣味で
主にJ1リーグを観ています。

かれいどをフォローする
DirextX
スポンサーリンク
シェアする

コメント