(DirectX : Tutorial) 9. Architecture/SwapChain

Posted by : at

Category : DirectX



Get Code


DXGI 란?

Direct3D기술은 매 시리즈 변경이 된다.(10, 11, 12 …) 하지만 변경되지 않고 유지되어야할 기술 API집합이 있고 이 집합을 DXGI에 넣어둠(예를들어 IDXGISwapChain(스왑체인))

#pragma once
#include "ChiliWin.h"
#include <d3d11.h>

class Graphics
{
public:
	Graphics( HWND hWnd );
	Graphics( const Graphics& ) = delete;
	Graphics& operator=( const Graphics& ) = delete;
	~Graphics();
	void EndFrame();
	void ClearBuffer( float red,float green,float blue ) noexcept;
private:
	ID3D11Device* pDevice = nullptr;            // D3D에 접근하기 위한 포인터
	IDXGISwapChain* pSwap = nullptr;            // SwapChain 포인터
	ID3D11DeviceContext* pContext = nullptr;    // DC(DeviceContext) 포인터
	ID3D11RenderTargetView* pTarget = nullptr;  // 그려지는 버퍼를 읽어오는 포인터
};
#include "Graphics.h"

#pragma comment(lib,"d3d11.lib")

Graphics::Graphics( HWND hWnd )
{
    // SwapChain에 대한 옵션(필요하다면 찾아볼 것)
	DXGI_SWAP_CHAIN_DESC sd = {};
	sd.BufferDesc.Width = 0;
	sd.BufferDesc.Height = 0;
	sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 0;
	sd.BufferDesc.RefreshRate.Denominator = 0;
	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.BufferCount = 1;
	sd.OutputWindow = hWnd;
	sd.Windowed = TRUE;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	sd.Flags = 0;

	// create device and front/back buffers, and swap chain and rendering context
    // D3D를 생성하며 SwapChain을 연결한다
	D3D11CreateDeviceAndSwapChain(
		nullptr,
		D3D_DRIVER_TYPE_HARDWARE,
		nullptr,
		0,
		nullptr,
		0,
		D3D11_SDK_VERSION,
		&sd,
		&pSwap,
		&pDevice,
		nullptr,
		&pContext
	);
	// gain access to texture subresource in swap chain (back buffer)
    // SwapChain의 버퍼를 받아서 랜더타겟에 넘겨준다.
	ID3D11Resource* pBackBuffer = nullptr;
	pSwap->GetBuffer( 0,__uuidof(ID3D11Resource),reinterpret_cast<void**>(&pBackBuffer) );
	pDevice->CreateRenderTargetView(
		pBackBuffer,
		nullptr,
		&pTarget
	);
	pBackBuffer->Release();
}

Graphics::~Graphics()
{
	if( pTarget != nullptr )
	{
		pTarget->Release();
	}
	if( pContext != nullptr )
	{
		pContext->Release();
	}
	if( pSwap != nullptr )
	{
		pSwap->Release();
	}
	if( pDevice != nullptr )
	{
		pDevice->Release();
	}
}

void Graphics::EndFrame()
{
	pSwap->Present( 1u,0u );
}

void Graphics::ClearBuffer( float red,float green,float blue ) noexcept
{
	const float color[] = { red,green,blue,1.0f };
	pContext->ClearRenderTargetView( pTarget,color );
}

이후에 포인터를 아래와 같이 관리하는데

Microsoft::WRL::ComPtr<ID3D11Device> pDevice;
Microsoft::WRL::ComPtr<IDXGISwapChain> pSwap;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> pContext;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> pTarget;

MS용 unique_ptr이라 생각하자


About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links