DirectX 에서는
기본적인 화면 초기화와 draw를 하기 위해
여러가지 base 객체들을 생성하고 설정해주어야 한다.
Device, DeviceContext,
RenderTargetView, SwapChain
위 4개의 객체가 d3d를 사용하기 위한 필수 base객체이다.
Device와 DeviceContext에 대해서는
따로 글을 쓰지는 않을 것이다.
쉽게 Device는 여러 객체들을 생성해주는 리소스 관리자이고,DeviceContext는 render pipeline의 stage에 값들을 바인딩하고 Draw명령을 내리는 역할을 한다.
오늘은 RTV와 SwapChain에 대해서 정리해보려고 한다.
DXGI (DirectXGraphics Infrastructure)
DirectX 객체들을 설명하기 전 DXGI에 대해서 먼저 알아야 한다. DXGI는 DirectX와 GPU, 모니터를 연결해주는 인프라로, 여러 GPU와 다중 모니터 환경을 관리하고 있다. DirectX에서 Draw함수를 통해 이루어 지는 작업은 BackBuffer에 프레임을 기록하는 것이고 실제 화면에 출력하는 것은 이 DXGI가 담당한다. 오늘 설명할 SwapChain이 바로 이 DXGI의 역할에 속해있는 개념인데, DXGI 의 SwapChain을 통해 BackBuffer <-> FrontBuffer를 교체하여 실제 화면에 보여주게 된다.
Render Target view (RTV)
렌더타겟뷰(RTV)는 D3D에서 PixelShader의 출력을 받을 목적지(BackBuffer)를 연결하는 뷰이다. 헷갈리기 쉬운 부분이 RTV가 최종 렌더링할 결과물을 기록하는 BackBuffer 인가? 하는건데 RTV는 BackBuffer가 아니다. RTV에는 렌더링 결과가 저장되지 않으며, GPU가 BackBuffer Texture를 렌더링 대상으로 인식할 수 있도록 감싸주는 객체가 RTV인 것이다. RTV는 SwapChain의 BackBuffer를 참조하고 있어 Draw함수들은 RTV를 통해 BackBuffer에 그림을 그리게 된다.
- BackBuffer Textrue : SwapChain에서 관리하는 GPU 텍스쳐로, Direct3D가 그릴 대상이 되는 실제 메모리 버퍼.
- RenderTargerView : BackBuffer를 GPU가 렌더링할 수 있게 바인딩 해주는 뷰 객체
RTV는 SwapChain의 BackBuffer를 참조하여 생성하고, 파이프라인데 Bind해서 사용한다.
그 과정을 풀어서 이야기한다면 다음과 같다.
- SwapChain에서 현재 백버퍼(ID3D11Texture2D)를 얻음
- 그 텍스처를 기반으로 RenderTargetView 생성
- OMSetRenderTargets로 파이프라인 Output Merger 스테이지에 바인딩
- Draw 호출 → 픽셀 셰이더 결과가 RTV(=백버퍼)에 기록됨
- SwapChain->Present → 백버퍼를 화면에 보여줌
SwapChain
SwapChain은 더블 버퍼링/ 트리플 버퍼링을 위한 여러 BackBuffer를 관리하며, Device가 렌더링한 프레임을 실제 화면에 표시(Present)하는 역할을 한다. 즉, BackBuffer에 기록된 이번 프레임의 결과를 화면에 출력하기 위해 FrontBuffer와 BackBuffer를 교체(Swap)하는 것이다. Swap의 방식에는 2가지 모드가 있는데 현재는 성능 측면에서 대부분 Flip Mode를 사용한다.
Swap 방식
1. BilBlt (복사, Old 방식)
: BackBuffer의 내용을 FrontBuffer로 복사하여 화면에 출력한다. 오래된 방식이며 복사 비용이 높아 성능이 저하된다.
2. Flip (포인터 교체)
: BackBuffer와 FrontBuffer의 포인터를 교체하는 방식으로, 메모리 복사 없이 화면에 바로 출력된다. 현재 대부분의 DirectX11/ 12에서 Filp 모드를 사용중이다.
Present( , )
Present()는 swapchain객체의 멤버함수로 BackBuffer를 화면에 표시하는 함수이다. Present()는 2개의 인수를 요구하는데 첫번째 인수는 몇 번의 화면 수직동기화 주기마다 Present를 할지에 대한 값이며 0이면 수직동기화를 끄고 가능하면 바로 Present하라는 의미이다. 보통 모니터 주사율에 맞게 1 : 1로 present되는 1을 쓴다. 2번째 인수는 Present 동작 방식을 제어하는 플래그인데 그냥 0을 쓰면 된다.
swapChain->Present(1, 0);
wooj22 - Overview
🎮 Game Programmer. wooj22 has 22 repositories available. Follow their code on GitHub.
github.com
양우정
www.youtube.com
'Programming > 컴퓨터그래픽스 (DX 11)' 카테고리의 다른 글
| [DirectX 11] 상수버퍼(Constant Buffer) CPU 구조체와 HLSL 구조체 정렬 맞추기 (0) | 2025.09.16 |
|---|---|
| [DirectX 11] DirectXMath vs SimpleMath 어떤 자료형을 사용해야할까? (0) | 2025.09.15 |
| [Lighting] 난반사(Diffuse Reflection)와 램버튼 법칙(Lambert's cosine law) (0) | 2025.09.15 |
| [DirectX 11] 2D 변환 행렬 (0) | 2025.06.11 |
| [DirectX 11] DirectX의 행렬 활용을 위한 2D 기본 행렬 복습 (0) | 2025.06.11 |