비타Cpp

Direct3D의 초기화 - 5. 교환 사슬(Swapchain)의 서술과 생성 본문

DirectX12/튜토리얼

Direct3D의 초기화 - 5. 교환 사슬(Swapchain)의 서술과 생성

멍C 2021. 10. 2. 12:45

초기화 공정 다음 단계는 교환 사슬(Swap Chain)을 생성하는 것이다. 이를 위해서는 DXGI_SWAP_CHAIN_DESC구조체 인스턴스의 멤버들을 지금 생성하고자 하는 교환 사슬에 맞게 설정해야 한다.

이 구조체의 정의는 다음과 같다.

https://docs.microsoft.com/en-us/windows/win32/api/dxgi/ns-dxgi-dxgi_swap_chain_desc

 

DXGI_SWAP_CHAIN_DESC (dxgi.h) - Win32 apps

Describes a swap chain.

docs.microsoft.com

typedef struct DXGI_SWAP_CHAIN_DESC {
  DXGI_MODE_DESC   BufferDesc;
  DXGI_SAMPLE_DESC SampleDesc;
  DXGI_USAGE       BufferUsage;
  UINT             BufferCount;
  HWND             OutputWindow;
  BOOL             Windowed;
  DXGI_SWAP_EFFECT SwapEffect;
  UINT             Flags;
} DXGI_SWAP_CHAIN_DESC;

 

위에 나온 DXGI_MODE_DESC 형식은 다음과 같다.

https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/bb173064(v=vs.85) 

 

DXGI_MODE_DESC structure (Windows)

DXGI_MODE_DESC structure 05/18/2018 2 minutes to read In this article --> Describes a display mode. Syntax typedef struct DXGI_MODE_DESC { UINT                     Width; UINT                     Height; DXGI_RATIONA

docs.microsoft.com

typedef struct DXGI_MODE_DESC {
  UINT                     Width;				//버퍼 해상도 너비(가로)
  UINT                     Height;				//버퍼 해상도 높이(세로)
  DXGI_RATIONAL            RefreshRate;
  DXGI_FORMAT              Format;				//버퍼 디스플레이 형식
  DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;			//순차 주사 대 비월 주사
  DXGI_MODE_SCALING        Scaling;				//이미지를 모니터에 맞게 확대/축소 하는 방식
} DXGI_MODE_DESC;

 

DXGI_SWAP_CHAIN_DESC의 멤버 변수에 대한 설명

1. BufferDesc : 이 구조체는 생성하고자 하는 후면 버퍼의 속성들을 서술한다. 지금 수준에서 중요한 속성은 너비와 높이, 그리고 픽셀 형식(Format)이다.
2. SampleDesc : 다중 표본화 표본 개수와 품질 수준을 서술하는 구조체이다.
3. BufferUsage : 후면 버퍼에 렌더링 할 것이므로 이 멤버에는 DXGI_USAGE_RENDER_TARGET_OUTPUT을 지정한다.
4. BufferCount : 교환 사슬이 사용할 버퍼 개수이다. 이중 버퍼링에서는 2를 지정한다.
5. OutputWindow : 렌더링 결과가 표시될 창의 핸들.
6. Windowed : 창모드 여부.
7. SwapEffect : 백버퍼를 스왑 할 때 처리효과를 지정합니다. 교환 후의 백 버퍼를 버리기 위해 DXGI_SWAP_EFFECT_FLIP_DISCARD로 지정한다.
8. Flags : 추가적인 플래그들. 여기에 DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH를 지정하면, 응용 프로그램이 전체 화면으로 전환될 때 Direct3D는 응용 프로그램 창의 현재 크기에 가장 잘 맞는 디스플레이 모드를 선택한다. 이 플래그를 지정하지 않으면, 응용 프로그램이 전체 화면으로 전환될 때 Direct3D는 현재 데스크톱 디스플레이 모드를 사용한다.

 

다음 코드는 CreateSwapChain의 예제이다.

void D3DApp::CreateSwapChain()
{
	/새 교환 사슬을 만들기 위해, 기존에 있던 교환 사슬을 해제한다.
	mSwapChain.Reset();

	DXGI_SWAP_CHAIN_DESC sd;
	sd.BufferDesc.Width = mClientWidth;
	sd.BufferDesc.Height = mClientHeight;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferDesc.Format = mBackBufferFormat;
	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	sd.SampleDesc.Count = m4xMsaaState ? 4 : 1;
	sd.SampleDesc.Quality = m4xMsaaState ? (m4xMsaaQuality - 1) : 0;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.BufferCount = SwapChainBufferCount;
	sd.OutputWindow = mhMainWnd;
	sd.Windowed = true;
	sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
	sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
    //참고: 교환 사슬은 명령 대기열을 이용해서 방출(Flush)를 수행한다.

	ThrowIfFailed(mdxgiFactory->CreateSwapChain(
		mCommandQueue.Get(), 
		&sd, 
		mSwapChain.GetAddressOf()));
}

위의 예제 코드에서는 이 함수가 여러번 호출돼도 문제없도록 기존의 교환 사슬을 먼저 해제한 후에 새 교환 사슬을 생성한다. 이 덕분에 실행 도중 다중 표본화 설정을 변경할 수 있다.

 

Comments