참고 소스 : DirectX SDK – DirectX 11 Tutorial 02

위 소스를 기반으로 연재를 진행합니다.

연재외에 자세한 내용은 소스와 DX SDK 문서를 참조하시면 도움이 됩니다.

 

안녕하세요. 알콜코더 민군입니다. ^^

지난 연재에서는 DirectX11의 3D 그래픽 디바이스를 생성하는 방법을 배웠습니다. 하지만 3D 디바이스는 어디까지나 그래픽 카드 드라이버의 디바이스의 인터페이스일뿐, 실제로 게임 화면 내용을 렌더링하는 인터페이스는 아닙니다. 실제 게임 화면은 디바이스에 설정된 렌더타겟에 렌더링 됩니다. 저번 연재 내용에서 디바이스와 함께 스왑체인을 생성했기 때문에, 스왑체인의 백버퍼도 당연히 같이 생성이 되었지만, Direct3D의 렌더타겟으로는 아직 설정되지는 않았습니다. 그래서 생성된 스왑체인으로부터 백버퍼를 얻어와서 디바이스의 렌더타겟으로 설정해야만 합니다. 그리고 깊이/스텐실 버퍼를 사용하는 경우에는 렌더타겟의 설정과 동시에 깊이/스텐실 버퍼도 설정합니다.

 

이번 연재에서는 이렇게 실제로 렌더링을 하기위한 렌더타겟으로 사용하기 위해서 백버퍼를 설정 하는 방법에 대해서 이야기 하겠습니다.

 

 


 

 

 

버퍼를 렌더타겟으로 설정하기 위해서는, 우선 버퍼의 '렌더타겟 뷰(RenderTarget View)'를 작성하여, 그 뷰를 디바이스의 렌더타겟으로 설정해야 합니다. 렌더타겟 뷰에는 'ID3D11RenderTargetView 인터페이스'를 사용합니다.


 


우선 스왑체인으로부터 백버퍼의 포인터를 받아와야 합니다. 스왑체인으로부터 백버퍼를 가져오기 위해서는'IDXGISwapChain::GetBuffer()' 메소드를 사용합니다.

다음의 코드에서는 2D텍스쳐(ID3D11Texture2D 인터페이스)로서 백버퍼를 가져옵니다. 백버퍼는 기본적으로2D텍스쳐로 만들어져 있기 때문입니다.

 


 

HRESULT GetBuffer(

[in]       UINT Buffer,

[in]       REFIID riid,

[in, out]  void **ppSurface

);

Buffer

접근할 버퍼의 번호(인덱스)

Riid

백버퍼를 받을 인터페이스의 타입

ppSurface

반환된 인터페이스를 받을 변수의 포인터

 


텍스쳐는 파이프라인으로부터 '뷰(View)'를 통해서 접근이 가능합니다. 렌더타겟도 텍스쳐의 일종이기 때문에 역시 뷰를 이용하여 접근해야 합니다. 렌더타겟에 접근할 때는 '렌더타겟 뷰'를 사용하여 접근할 수 있습니다.

렌더타겟 뷰는 'ID3D11Device::CreateRenderTargetView 메소드'를 이용해서 생성할 수 있으며, 얻어온 렌더타겟 뷰는 'ID3D11RenderTargetView 인터페이스'로서 사용됩니다.

첫번째 인자는 뷰에서 액세스하는 리소스, 두번째 인자는 렌더타겟 뷰의 정의, 3번째 인자는 반환된 렌더타겟뷰의 포인터를 받을 변수의 포인터를 넘겨줍니다.

 

렌더타겟 뷰의 정의는 'D3D11_RENDER_TARGET_VIEW_DESC 구조체'로 정의됩니다. 하지만 일반적인 경우에는 디폴트값으로 NULL을 넘겨주면 됩니다.

 

렌더타겟 뷰가 생성된 이후에는 직접 백버퍼의 포인터에 접근하지 않고, 이 렌더타겟 뷰를 사용합니다. 그렇기 때문에 렌더타겟 뷰의 인터페이스를 얻고 난 이후에는 백버퍼의 포인터를 해제합니다.


 

HRESULT CreateRenderTargetView(

[in]   ID3D11Resource *pResource,

[in]   const D3D11_RENDER_TARGET_VIEW_DESC *pDesc,

[out]  ID3D11RenderTargetView **ppRTView

);

pResource

렌더타겟 뷰에서 엑세스하는 리소스

pDesc

렌더타겟 뷰를 정의하는 'D3D11_RENDER_TARGET_VIEW_DESC'구조체의 포인터. NULL을 넘겨주면, 리소스가 만들어졌을때의 포맷을 그대로 사용하며, 모든 리소스의 밉맵 레벨 0에 액세스하는 뷰를 생성한다.

ppRTView

ID3D11RenderTargetView 인터페이스를 받는 변수의 포인터. NULL을 넘겨주게 되면, 다른 인자들의 유효성을 체크할 수 있다.

 

typedef struct D3D11_RENDER_TARGET_VIEW_DESC {

DXGI_FORMAT         Format;

D3D11_RTV_DIMENSION ViewDimension;

union {

D3D11_BUFFER_RTV        Buffer;

D3D11_TEX1D_RTV         Texture1D;

D3D11_TEX1D_ARRAY_RTV   Texture1DArray;

D3D11_TEX2D_RTV         Texture2D;

D3D11_TEX2D_ARRAY_RTV   Texture2DArray;

D3D11_TEX2DMS_RTV       Texture2DMS;

D3D11_TEX2DMS_ARRAY_RTV Texture2DMSArray;

D3D11_TEX3D_RTV         Texture3D;

} ;

D3D11_RENDER_TARGET_VIEW_DESC;

Format

리소스내의 데이터를 해석하는 포맷. 'DXGI_FORMAT_UNKNOWN'을 넘겨주면, 리소스에 설정되어 있는 포맷이 사용된다.

ViewDimension

리소스가 액세스 되는 방법. 이 값에 의해서 아래의 union의 멤버 가운데, 사용할 변수가 결정된다.

Buffer

버퍼 리소스로 접근하는 경우의 정의

(ViewDemension = D3D11_RTV_DIMENSION_BUFFER)

Texture1D

1D텍스쳐로 접근하는 경우의 정의

(ViewDemension = D3D11_RTV_DIMENSION_TEXTURE1D)

Texture1DArray

1D텍스쳐의 배열로 접근하는 경우의 정의

(ViewDemension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY)

Texture2D

2D텍스쳐로 접근하는 경우의 정의

(ViewDemension = D3D11_RTV_DIMENSION_TEXTURE2D)

Texture2DArray

2D텍스쳐의 배열로 접근하는 경우의 정의

(ViewDemension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY)

Texture2DMS

멀티샘플링된 2D텍스쳐로 접근하는 경우의 정의

(ViewDemension = D3D11_RTV_DIMENSION_TEXTURE2DMS)

다만, 멀티샘플링된 2D텍스쳐는 보통 1개의 서브 리소스를 가지고 있기 때문에, 설정은 필요없다.

Texture2DMSArray

멀티샘플링된 2D텍스쳐의 배열로 접근하는 경우의 정의

(ViewDemension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY)

Texture3D

3D텍스쳐로 접근하는 경우의 정의

(ViewDemension = D3D11_RTV_DIMENSION_TEXTURE2D)

각 구조체의 내용에 대해서는 MSDN을 참조하시면 됩니다. 하지만 지금은 딱히 별로 건드릴만한 내용은 없습니다. ^^

 


렌더타겟은 'Ouput-Merger(OM)' 스테이지에 'ID3D11DeviceContext::OMSetRenderTargets 메소드'로 설정합니다.

그리고 렌더타겟은 DX11에서 동시에 최대 8개까지 설정이 가능합니다. 그러나 그럴 경우에도 설정할 수 있는 깊이/스텐실 버퍼는 하나뿐입니다.

 

'OMSetRenderTargets 메소드'에서는 렌더타겟 뷰와 함께 깊이/스텐실 버퍼도 동시에 같이 설정합니다. 이 예제에서는 깊이/스텐실 버퍼를 사용하지 않기 떄문에 NULL을 설정합니다. 깊이/스텐실 버퍼에 관해서는 다음 연재에서 다루겠습니다. ^^;

 

이 메소드는 넘겨진 인터페이스의 참조를 유지합니다. 이것은 'Direct3D 10'과 달라진 부분입니다.

 

 

void OMSetRenderTargets(

[in]  UINT NumViews,

[in]  ID3D11RenderTargetView *const **ppRenderTargetViews,

[in]  ID3D11DepthStencilView *pDepthStencilView

);

NumViews

설정하는 렌더타겟의 개수. 최대 8개까지 설정가능하다.

ppRenderTargetViews

렌더링 파이프라인에 설정하는 렌더타겟 뷰의 배열.

NULL을 넘기면, 렌더타겟이 설정되지 않게 된다.

pDepthStencilView

렌더링 파이프라인에 넘겨주는 깊이/스텐실 뷰의 포인터.

NULL을 넘기면, 깊이/스텐실 버퍼가 설정되지 않게 된다.




알콜코더 민군

언젠가 우즈벡에 미소녀 게임 회사를 차리고 싶은 개발자

3D게임 클라이언트 프로그래머, 살짝 오타쿠…

드래곤볼 온라인 개발, 현재는 네오위즈 서식중

'신입게임 개발자의 서울상경기'와 '초중급 게임개발자 스터디' 운영중