1. 스왑 체인
DX에서는 렌더링을 하는 작업과 렌더링한 결과물을 화면에 보여주는 작업을 효과적으로 진행하기 위해 스왑 체인을 이용한 페이지 플리핑(page flipping)을 제공해준다.
스왑 체인은 렌더링을 하기 위한 여러 개의 버퍼들을 의미한다. 이 버퍼들은 연속적으로 스왑하면서 화면에 렌더링되는데, 스왑 체인이라는 이름은 이런 동작을 하기 때문에 붙여진 것이다. 스왑 체인을 사용하면 실제 모니터에 출력되기 위한 결과물을 저장한 프론트 버퍼(front buffer)와 DX와 같은 그래픽스 API에서 렌더링 작업을 수행하는 여러 개의 백 버퍼(back buffer)를 가질 수 있고, 매 프레임마다 프론트 버퍼에 저장된 결과물을 화면에 표현(presentation)하게 된다.
이처럼 스왑 체인은 특정 DX 버전에 종속되어 있는 기능이 아니라 일반적인 그래픽스 API라면 대부분 제공해야 하는 기능이기 때문에 DX의 버전에 종속되지 않도록 하기 위해 DXGI
그룹에 포함되어 있다. DX에서 스왑하는 작업은 백 버퍼에 저장된 데이터를 프론트 버퍼에 복사하는 것이 아니라 각각의 버퍼를 가리키는 포인터만 변경하는 것으로 진행된다. 이 작업을 페이지 플리핑이라고 한다.
DX에서 스왑 체인은 DXGI_SWAP_CHAIN_DESC
구조체를 사용해 설정할 수 있다. 해당 구조체는 다음과 같은 멤버를 가지고 있다.
https://learn.microsoft.com/ko-kr/windows/win32/api/dxgi/ns-dxgi-dxgi_swap_chain_desc
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;
BufferDesc
: 백버퍼에 대한 정보를 제공할 구조체다.SampleDesc
: DX에서 제공하는 멀티 샘플링에 대한 설정을 제공할 구조체다.BufferUsage
: 백버퍼를 어떤 용도로 사용할지 지정한다.OutputWindow
: 화면을 출력할 윈도우에 대한 핸들러다.Windowed
: 창모드 설정에 대한 값이다.SwapEffect
: 윈도우 애플리케이션 개발에 설정할 값이다.Flags
: 스왑 체인 동작에 대한 옵션을 나타내는 플래그다.
일반적으로 스왑 체인 구조체의 값을 설정하는 방식은 다음과 같다.
// 구조체 선언
DXGI_SWAP_CHAIN_DESC sd;
// 메모리 초기화: 설정값이 많아 잘못된 값이 전달되지 않도록 하기 위함
ZeroMemory(&sd, sizeof(sd));
// 백버퍼에 대한 설명
sd.BufferDesc.Width = m_screenWidth; // 백버퍼의 너비
sd.BufferDesc.Height = m_screenHeight; // 백버퍼의 높이
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // unsinged normalized int 범위를 가진 32비트 설정
sd.BufferDesc.RefreshRate.Numerator = 60; // fps 분모
sd.BufferDesc.RefreshRate.Denominator = 1; // fps 분자
// 백버퍼의 개수
sd.BufferCount = 2;
// 백버퍼 사용 요도 지정
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // 렌더 타겟의 결과물을 출력하기 위한 용도로 지정
sd.OutputWindow = mHwnd;
sd.Windowed = TRUE;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
이 외의 다양한 설정값들을 통해 스왑 체인을 디테일하게 조절할 수 있다. 이렇게 만들어진 스왑 체인 구조체를 통해 스왑 체인을 생성해주면 된다.(가장 간단하게는 D3D11CreateDeviceAndSwapChain
함수를 호출하면 된다.)
2. 멀티 샘플링
픽셀의 색을 결정하기 위해 여러 번의 샘플링을 하는 것이 멀티 샘플링이다. 이를 통해 안티 앨리어싱을 할 수 있다. DX에서는 스왑 체인이나 깊이 버퍼 등을 만들 때 옵션을 적용해주면 손쉽게 멀티 샘플링 기능을 사용할 수 있다. 멀티 샘플링을 적용하기 위해 사용하고 있는 GPU에서 멀티 샘플링 기능을 지원하는지 확인을 해야 한다.
// https://learn.microsoft.com/ko-kr/windows/win32/api/d3d11/nf-d3d11-id3d11device-checkmultisamplequalitylevels
HRESULT CheckMultisampleQualityLevels(
[in] DXGI_FORMAT Format,
[in] UINT SampleCount,
[out] UINT *pNumQualityLevels
);
Format
: 멀티 샘플링에서 사용할 픽셀의 데이터 형식을 지정한다.SampleCount
: 샘플링의 개수를 정한다.pNumQualityLevels
: 디바이스에서 지원하는 멀티 샘플링 레벨의 값이 저장된다.
pNumQualityLevels
에 저장된 레벨이 사용중인 디바이스에서 지원하는 멀티 샘플링의 레벨이며, 스왑 체인에서 이를 사용하고 싶으면 다음과 같이 SampleDesc
멤버의 값을 지정해주면 된다.
UINT numQualityLevels;
device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &numQualityLevels);
if (numQualityLevels > 0) {
sd.SampleDesc.Count = 4; // how many multisamples
sd.SampleDesc.Quality = numQualityLevels - 1;
} else {
sd.SampleDesc.Count = 1; // how many multisamples
sd.SampleDesc.Quality = 0;
}
'그래픽스 > DirectX11' 카테고리의 다른 글
버텍스 버퍼, 인덱스 버퍼, 컨스턴트 버퍼 (0) | 2024.04.22 |
---|---|
RenderTargetView의 의미 (0) | 2024.04.19 |
ID3D11Device 초기화, 생성 팁 (0) | 2024.04.16 |
DirectX에서의 COM(Component Object Model) (0) | 2024.04.15 |
DirectX 11 도형 출력(버텍스 버퍼, 버텍스 쉐이더, 픽셀 쉐이더 설정) (0) | 2024.04.12 |