공부중

[DirectX12]Hello Wolrd Sample - D3D12HelloWindow - 5 본문

Programing/DirectX

[DirectX12]Hello Wolrd Sample - D3D12HelloWindow - 5

곤란 2018. 4. 11. 22:46
반응형
        // 명령 대기열을 설명하고 작성하십시오.
	D3D12_COMMAND_QUEUE_DESC queueDesc = {};
	queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
	queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

	ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));

명령 대기열(Command Queue)부분인데 .

이 튜토리얼에서는 Init만 하고 딱히 명령을 내리는 부분이 없으므로(삼각형도 띄우지 않음) 자세한 내용은 다음 튜토리얼에서 때가 되면

정리해볼 예정이다.

 

        // 스왑 체인(swap chain)을 기술하고 생성하십시오.
	DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
	swapChainDesc.BufferCount = FrameCount;
	swapChainDesc.Width = m_width;
	swapChainDesc.Height = m_height;
	swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
	swapChainDesc.SampleDesc.Count = 1;

	ComPtr<IDXGISwapChain1> swapChain;
	ThrowIfFailed(factory->CreateSwapChainForHwnd(
		m_commandQueue.Get(),		// 스왑 체인은 강제로 플러시되도록 큐를 필요로합니다.
		Win32Application::GetHwnd(),
		&swapChainDesc,
		nullptr,
		nullptr,
		&swapChain
		));

교환 사슬이라고 해석되는 이 스왑체인(SwapChain)을... 어디서부터 설명해야될까...

이것을 읽는 사람이 경험이 있을지는 모르겠지만 애니메이션이 껌벅이는 현상을 겪어본적이 있는지 모르겠다

 

위의 영상은 자바로 더블버퍼링(double buffering)이라는것을 구현하는 내용인것 같다.

내용을 자세히 볼 필요는 없고 깜박거림의 경험이 없는 사람에게 보여주려고 영상을 찾다보니 위의 영상을 찾은것이다.

더블 버퍼링 적용 전 : 영상 5초

더블 버퍼링 적용 후 : 영상 11초

 

위의 영상을 보고 아 저렇게 깜박거린다는거를 이제 알았다면 더블버퍼링이라는게 뭔지 뭐길래 위의 영상도 그렇고 글에서도 적었는지

궁금해질텐데

아는 사람은 패스해도 된다.

 

더블버퍼링은 이름 그대로 2개의 버퍼가 필요하다

이 2개의 버퍼로 어떻게 처리하는가!

 

일단 2개의 버퍼는 전면버퍼(front buffer)와 후면 버퍼(back buffer)로 이루어져 있는데

우선 애니메이션의 한 프레임 전체를 화면 바깥의 텍스쳐에 그리는데 이것을 후면 버퍼(back buffer)라고 부른다.

말은 화면 바깥이라고 적었지만 그냥 화면에 안보이는 작업이라고 생각하면 된다. 

(컴퓨터 모니터에서 안보이는 임의의 공간에서 그린다는 말이 아니고 모니터에 출력하기 전에 그린다고 이해하면 된다.)

그리고 이 후면 버퍼를 모니터에 출력하게 되면 이제 이것이 전면 버퍼가 되는것이다. (이름만 바뀐다고 생각하면 된다.)

이 움짤을 보고 이해가 갔으면 좋겠다..... 만드는데 힘들었다 ㅠ

 

아무튼 이러한 전면 버퍼(front buffer)와 후면 버퍼(back buffer)는 하나의 교환 사슬(swap chain)을 형성한다. 라고 말한다.

2개의 버퍼로 하는것을 이중버퍼링 3개로 하면 삼중버퍼링... 이런식으로 되나 보통 이중 버퍼링으로 커버가 된다고 한다.

추후 먼 미래가 되어서 혹은 이중 버퍼링으로도 커버가 안되면 삼중 이상의 버퍼링을 사용하면 될것 같다.

 

이제 더블버퍼링이라는것도 알고 스왑 체인이라는것도 알았으니 코드로 들어가보자

 

먼저 스왑체인을 만들정보를 입력하고 CreateSwapChainForHwnd함수를 이용해서 만들고 있는데

만들 스왑 체인 정보를 DXGI_SWAP_CHAIN_DESC1의 구조체에 저장해서 넘겨준다.

DXGI_SWAP_CHAIN_DESC1은 아래와 같다.

 

typedef struct DXGI_SWAP_CHAIN_DESC1
    {
    UINT Width;
    UINT Height;
    DXGI_FORMAT Format;
    BOOL Stereo;
    DXGI_SAMPLE_DESC SampleDesc;
    DXGI_USAGE BufferUsage;
    UINT BufferCount;
    DXGI_SCALING Scaling;
    DXGI_SWAP_EFFECT SwapEffect;
    DXGI_ALPHA_MODE AlphaMode;
    UINT Flags;
    } 	DXGI_SWAP_CHAIN_DESC1;

 

이 멤버변수들 설명에 대해서는 MSDN을 참고하도록 하자. - 링크

 

작성된 것만 살펴보면

BufferCount는 이중버퍼링을 할지 삼중버퍼링을 할지 정수의 숫자를 넣어주는데 FrameCount라는 변수는 아래와 같이 선언 되어있다.

 

//
// FileName : D3D12HelloWindow.h
//
class D3D12HelloWindow : public DXSample
{

// 중략...

private:
	static const UINT FrameCount = 2;

//중략 ...

결론은 이중 버퍼링을 사용 할것이고. 멤버변수로 저장해 둔 너비와 높이를 대입해 주었다.

Format은... 이 텍스쳐를 어떤 방식의 텍스쳐를 사용할 것인가를 알려달라는 것이다. (화면에 보여지는 버퍼들은 최종적으로 한장의 그림이므로....)

DXGI_FORMAT_R8G8B8A8_UNORM : 알파(A)를 포함하여 채널당 8 비트를 지원하는 4 컴포넌트 32 비트 부호없는 정규화 된 정수 형식입니다.

이것도 종류가 엄청 많다. MSDN을 참조하자..  - 링크

 

BufferUsage 는 버퍼를 어디에 쓸것인가?를 지정해 주어야 한다. 

여기에는 DXGI_USAGE_RENDER_TARGET_OUTPUT의 매크로를 지정해 주었는데 

"표면 또는 자원을 출력 렌더 타겟으로 사용하십시오."

라는 뜻이다. 이것 관련해서도 종류가 엄청 많으니 MSDN을 참고하자 - 링크

 

SwapEffect는 말그대로 스왑 효과인데.... 효과라고해서 휘양 찬란한 ppt넘길때 효과 이런것은 아니고 버퍼를 언제 비워줄것인지

아니면 버퍼를 비우지 않고 뭐 여러가지가 있다.

자세한 내용은 역시 MSDN을 참고하도록 하자. - 링크

 

SampleDesc(다중 표본화)는 게임 옵션에서 보면 "안티엘리언싱" 이라는 기능을 보았을 것이다. 그것에 관련된 설정이라고 이해를 하면 될 것이다.

 

 

 

이제 구조체의 멤버들을 채워넣고 CreateSwapChainForHwnd함수를 통해서 스왑 체인을 만들어주는것으로 끝이 났다.

 

 

다음 글에서...

 

 - 요즘 허리를 무리했더니 앉기가 너무나도 힘드네요 ㅠ... 

(디스크 탈출로 인해서 일도 못하고 공부만 하고 있긴 하지만...)

 

업데이트가 늦을수도 있습니다. ㅠㅠ

 

 

 

 

 

 

반응형