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

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

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

 

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

그동안 연재를 본의 아니게 많이 쉬었습니다. 거의 두달만에 다시 연재를 재개하는 것 같네요..OTL

회사 프로젝트가 바쁜데다가 여러 가지 발표와 행사가 겹쳐서 너무 오래 연재를 쉰 것 같네요. 그럴리는 없겠지만… 혹시나 이런 허접한 연재를 기다리신 분들에게는 죄송합니다. T^T 앞으로는 더욱 열심히 자주 업데이트 하도록 하겠습니다. ^^;;

이번 연재에서는 저번 연재 마지막에 언급했던 DX11 디바이스와 스왑 체인을 생성하는 방법에 대해서, 좀더 자세히 알아볼까 합니다. DX를 이용한 모든 프로그램에서는 DX 디바이스를 생성하는 것이 가장 기본이 됩니다. 그전까지의 과정들은 전부 디바이스를 생성하기 위한 준비단계에 해당합니다. 그리고 DX10 버전부터는 DXGI 기반 구조로 변경되면서 스왑체인(SwapChain)과 디바이스 컨텍스트를 생성해야 합니다. 스왑체인에 대한 설명은 이전 연재를 참조하시면 됩니다.

 

 

디바이스와 스왑체인의 생성

 

디바이스와 스왑체인은 'D3D11CreateDeviceAndSwapChain' 함수를 이용해서 동시에 생성합니다.

이때 실제 렌더링에 사용하는 백버퍼인 Device Context 역시 함께 생성됩니다.


 

함수는 위와 같은 형태로 사용됩니다. 들어가는 인자들이 꽤 많죠. ^^

DX11의 가장 기본이자 핵심인 함수이기 때문에 세팅을 해야하는 내용들이 꽤 많습니다.

이제부터 하나하나 들어갈 인자들을 설명해 드리겠습니다.

여기에 들어가는 인자들을 만드는 방법은 이전 연재를 참고하시면 됩니다.

 

함수 원형 및 인자들에 대한 설명은 아래와 같습니다.


HRESULT D3D11CreateDeviceAndSwapChain(

__in   IDXGIAdapter               *pAdapter,

__in   D3D_DRIVER_TYPE      DriverType,

__in   HMODULE                     Software,

__in   UINT                                Flags,

__in   const D3D_FEATURE_LEVEL *pFeatureLevels,

__in   UINT                               FeatureLevels,

__in   UINT                               SDKVersion,

__in   const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,

__out  IDXGISwapChain        **ppSwapChain,

__out  ID3D11Device             **ppDevice,

__out  D3D_FEATURE_LEVEL *pFeatureLevel,

__out  ID3D11DeviceContext **ppImmediateContext

);

pAdapter 

표시할 '디스플레이 디바이스(비디오 카드)'의 'IDXGIAdapter 인터페이스'를 설정합니다. 이것은 DXGI의 인터페이스입니다. NULL을 지정하면 최초에 발견한 디바이스를 사용합니다. 비디오카드를 지정할 필요가 있을때를 제외하고는 기본적으로 NULL로 설정하면 됩니다

DriverType 

생성할 DX11 디바이스의 종류를 지정합니다. 보통은 하드웨어 가속을 사용하기 위해서 'D3D_DRIVER_TYPE_HARDWARE'를 지정합니다. pAdapter에 NULL 이외의 값을 지정한 경우에는'D3D_DRIVER_TYPE_UNKNOWN'을 지정합니다.

Software 

소프트웨어 래스터라이저가 구현되어 있는 DLL이 핸들을 지정합니다.보통은 NULL을 설정하면 됩니다.

Flags 

사용할 DX11의 API 레이어를 D3D_CREATE_DEVICE_FLAG 값들을 조합하여 설정합니다.

pFeatureLevels

피처레벨(지원 기능 레벨) 배열을 설정합니다. 우선 순위가 높은 순서대로 배열을 채웁니다. 만약 NULL로 설정하면 DX11->DX10->DX9 순으로 모든 레벨을 설정합니다.

FeatureLevels 

위에서 설정한 피처레벨 배열의 개수를 입력합니다

SDKVersion

사용하고 있는 DX SDK의 버전을 넘겨줍니다.

pSwapChainDesc 

스왑체인의 설정값들을 저장한 구조체의 포인터를 넘겨줍니다.

ppSwapChain 

생성된 스왑체인 인터페이스의 포인터를 담을 변수를 설정합니다.

ppDevice 

생성된 디바이스 인터페이스의 포인터를 담을 변수를 설정합니다.

pFeatureLevel 

생성에 성공한 경우에는 pFeatureLevels에서 지정했던 배열의 처음값을 돌려줍니다. 실패한 경우에는 0이 반환됩니다.

ppImmediateContext 

생성된 디바이스 컨텍스트 인터페이스의 포인터를 담을 변수를 설정합니다.

 

D3D_DRIVER_TYPE

D3D_DRIVER_TYPE_HARDWARE

하드웨어 드라이버 (HAL 드라이버)

D3D_DRIVER_TYPE_REFERENCE 

레퍼런스 레스터라이저 (REF 드라이버)

D3D_DRIVER_TYPE_NULL 

NULL 디바이스, 렌더링이 불가능한 레퍼런스 드라이버

D3D_DRIVER_TYPE_SOFTWARE 

예약만 되어있음. 사용하지 않습니다.

D3D_DRIVER_TYPE_WARP 

고속 퍼포먼스의 소프트웨어 레스터라이저(WARP). 피처레벨 9_1 ~ 10_1을 지원합니다.

D3D_DRIVER_TYPE_UNKNOWN 

종류 불명

 

D3D11_CREATE_DEVICE_FLAG

D3D11_CREATE_DEVICE_SINGLETHREADED

싱글 스레드 지원의 디바이스를 지정. 억지로 스레드 세이프 레이어를 무효로 하고 싶은 경우에 지정합니다.

D3D11_CREATE_DEVICE_DEBUG

디버그 레이어를 사용합니다.

D3D11_CREATE_DEVICE_SWITCH_TO_REF

레퍼런스 타입으로 교체할 수 있는 레이어를 사용합니다.

D3D11_CREATE_DEVICE_PREVENT_

INTERNAL_THREADING_OPTIMIZATIONS

복수의 스레드가 만들어지지 않도록 한다. 일반적으로는 사용되지 않습니다.

D3D11_CREATE_DEVICE_BGRA_SUPPORT

Direct2D 와 Direct3D 리소스의 상호운영을 가능하게 합니다.

 

 

디버그용 디바이스

 

'D3D11CreateDeviceAndSwapChain' 함수의 3번째 인자에는 D3D_CREATE_DEVICE_FLAG 의 조합이 들어가게 됩니다. 이 조합된 플래그값으로 게임에서 사용할 Direct3D11의 API 레이어를 지정할 수 있습니다. 여기서 디버그용 디바이스 플래그도 설정이 가능합니다. 아래와 같이 디버그용 버전에서는 디버그 레이어를 켜두면 여러가지 디버그 정보들을 확인할 수 있습니다.


위와 같이 설정하고 D3D11CreateDeviceAndSwapChain 함수의 3번째 인자에 위 플래그를 설정해주면, 디버그 버전으로 컴파일 되는 경우에만 디버그 레이어를 사용할 수 있습니다. 디버그 레이어를 사용 가능하게 해두면 프로그램의 성능이 떨어지기 때문에, 릴리즈에서는 사용하면 안됩니다.

 

 

WARP 디바이스의 생성

 

DX11에서는 하드웨어 드라이버가 사용할 수 없는 환경에서도, 높은 퍼포먼스의 소프트웨어 레스터라이저인 WARP(D3D_DRIVER_TYPE_WARP) 디바이스를 사용할 수 있습니다. 이전 DX 버전에서는 하드웨어가 지원되지 않는 경우 100% 소프트웨어 레스터라이저인 레퍼런스 디바이스를 사용해야 했는데, DX11과 윈도우 비스타 이상에서는 윈도우의 기본적인 아키텍쳐가 하드웨어 가속이 지원 되기 때문에 이 WARP 디바이스를 사용하면 훨씬 더 고속의 렌더링을 할 수 있습니다. 즉, 프로그램이 실행되는 환경의 그래픽 카드가 피처레벨이 지원되지 않는 그래픽카드라고 할지라도, DX11 SDK로 WARP 디바이스를 생성하면 DX11 프로그램을 동작시킬 수 있습니다. 하지만 WARP 디바이스가 지원하는 피처레벨은 'D3D_FEATURE_LEVEL_9_1' ~ 'D3D_FEATURE_LEVEL_10_1' 까지입니다.

WARP 디바이스는 윈도우 비스타이상에서만 사용 가능합니다.


 

 

레퍼런스 디바이스의 생성

 

앞서 이야기한 WARP는 고속이긴 하지만, DX10 버전의 기능들까지만 지원하기 때문에 DX11의 기능들은 사용할 수가 없습니다. 하지만 프로그램을 개발할 때 DX11 지원 그래픽카드가 없는 환경에서, DX11의 모든 기능을 테스트 해보기 위해서는 DX11의 모든 기능들이 구현되어 있는 레퍼런스 디바이스를 사용해야 합니다. 주의할 점은 레퍼런스 드라이버는 'DirectX SDK'가 인스톨되어있는 환경에서만 사용 가능합니다.

튜터리얼의 소스 코드에서는 DX11을 지원하지 않는 그래픽카드를 위해서 '하드웨어 디바이스 -> WARP 디바이스 -> 레퍼런스 디바이스' 순으로 생성을 해보는 코드가 포함되어 있습니다. 그래서 만약 성공했다면 그 디바이스를 사용하고, 만약 앞의 단계에서 생성에 실패했다면 다음 단계의 디바이스를 생성해 보게 됩니다. 그래서 DX11을 지원하지 않는 그래픽 카드를 가지고 있어도 샘플 코드의 실행이 가능합니다. 만약 윈도우 비스타 이하 버전에 DX11을 지원하지 않는 그래픽카드를 사용하고 있다면, WARP를 사용할 수 없기 때문에 레퍼런스 디바이스가 생성됩니다. (물론 DX11 지원 그래픽 카드라면 당근 하드웨어 디바이스가 생성되겠죠)


 

 

다음 시간에는…

 

다음 연재에서는 위와 같이 방법으로 생성한 스왑체인으로 백버퍼를 가져와서, 렌더 타겟 뷰를 생성하고, 생성된 렌더타겟뷰를 디바이스 컨텍스트에 설정하는 방법을 다루겠습니다. 즉, 실제로 게임 화면을 렌더링하는 백버퍼를 생성하는 단계에 대해서 이야기 해보겠습니다. ^^

 

Ps. 조금이라도 도움이 되셨다면, 응원의 리플을~~!!! 굽신~굽신~~

 

알콜코더 민군

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

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

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

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