비타Cpp

Direct3D의 초기화 - 뷰포트 생성 본문

DirectX12/튜토리얼

Direct3D의 초기화 - 뷰포트 생성

멍C 2021. 10. 9. 14:21

보통은 3차원 장면을 화면 전체에 해당하는 후면 버퍼 또는 창의 클라이언트 영역 전체에 해당하는 후면 버퍼 전체에 그리지만, 필요하다면 3차원 장면을 후면 버퍼의 일부를 차지하는 직사각형 영역에만 그리는 것도 가능하다.

 

장면을 그려 넣고자 하는 후면 버퍼의 부분 직사각형(Subrectangle) 영역을 뷰포트(Viewport)라고 부른다. 다음은 이 뷰포트를 서술하는데 쓰이는 구조체이다.

 

typedef struct D3D12_VIEWPORT {
  FLOAT TopLeftX;
  FLOAT TopLeftY;
  FLOAT Width;
  FLOAT Height;
  FLOAT MinDepth;
  FLOAT MaxDepth;
} D3D12_VIEWPORT;

이 구조체의 처음 네 멤버 변수는 뷰포트 직사각형의 크기를 결정한다. Direct3D에서 깊이 값들은 0 이상 1 이하의 구간으로 정규화된다. MinDepth 멤버와 MaxDepth 멤버는 깊이 구간 [ 0, 1]을 깊이 구간 [MinDepth, MaxDepth]로 변환하는 데 쓰인다. 이러한 깊이 구간 변환을 활용하면 몇 가지 특별한 효과를 구현할 수 있다.

예를 들어 MinDepth = 0, MaxDepth = 0 으로 설정하면 이 뷰포트에 그려진 모든 물체는 깊이 값이 0이 되어서 장면의 다른 모든 객체보다 앞에 나타나게 된다. 그렇지만 보통은 MinDepth를 0으로, MaxDepth를 1로 설정해서 깊이 값들이 바뀌지 않게 한다.

 

D3D12_VIEWPORT 구조체를 모두 채운 후에는 ID3D12CommandList::RSSetViewports 메서드를 이용해서 뷰포트를 Direct3D에 설정한다. 다음은 후면 버퍼 전체에 장면을 그리는 뷰포트를 설정하는 예이다.

D3D12_VIEWPORT mScreenViewport;
mScreenViewport.TopLeftX	= 0;
mScreenViewport.TopLeftY	= 0;
mScreenViewport.Width = static_cast<float>(mClientWidth);
mScreenViewport.Height = static_cast<float>(mClientHeight);
mScreenViewport.MinDepth = 0.0f;
mScreenViewport.MaxDepth = 1.0f;

mCommandList->RSSetViewports(1, &mScreenViewport);

RSSetViewports 메서드의 첫 매개변수는 설정할 뷰포트들의 개수이고, 둘째 매개변수는 뷰포트 구조체들의 배열을 가리키는 포인터이다.

 


하나의 렌더 대상에 여러 개의 뷰포트를 지정할 수는 없다. 다중 뷰포트는 장면을 동시에 여러 개의 렌더 대상에 렌더링 하는 고급 기법들에 쓰인다.

 

CommandList를 재설정(Reset)하면 뷰포트들도 재설정해야 한다.


뷰포트의 용도중 하나는 2인용 모드를 위한 화면 분할이다. 그런 경우 화면 왼쪽 절반을 위한 뷰포트와 화면 오른쪽 절만을 위한 뷰포트를 만들고, 플레이어 1의 관점에서 본 3차원 장면을 왼쪽 뷰포트에, 플레이어 2의 관점에서 본 장면은 오른쪽 뷰포트에 그리면 된다.

Comments