Direct3D 초기화 과정은 크게 다음과 같은 순서로 구성된다.
1.D3D11CreateDevice 함수를 이용해서 ID3D11Device 인터페이스인 장치와 ID3D11DeviceContext 인터페이스인 장치 문맥을 생성한다.
2.ID3D11Device::CheckMultisampleQualityLevels 메서드를 이용해서 4X MSAA(*주 1) 품질 수준 지원 여부를 점검한다.
3.생성할 교환 사슬의 특성을 서술하는 DXGI_SWA_CHAIN_DESC 구조체를 채운다.
4.장치를 생성하는 데 사용했던 IDXGIFactory 인터페이스를 질의해서 IDXGISwapChain 인스턴스를 생성한다.
5.교환 사슬의 후면 버퍼에 대한 렌더 대상 뷰를 생성한다.
6.깊이·스텐실 버퍼와 그에 연결되는 깊이·스텐실 뷰를 생성한다.
7.렌더 대상 뷰와 깊이·스텐실 뷰를 Direct3D가 사용할 수 있도록 렌더링 파이프라인의 출력 병합기 단계에 묶는다.
8.뷰포트를 설정한다.
1.장치와 장치 문맥 생성
Direct3D 초기화의 시작은 Direct3D 11 장치(ID3D11Device)와 장치 문맥(ID3D11DeviceContext)을 생성하는 것이다. 이 두 인터페이스는 Direct3D의 주된 인터페이스로, 그래픽 장치 하드웨어에 대한 소프트웨어 제어기라고 생각하면 된다. 응용 프로그램은 ID3D11Device와 ID3D11DeviceContext를 통해서 하드웨어에게 할 일을 지시한다. 할 일이란 GPU 메모리에 자원 할당, 후면 버퍼 지우기, 자원을 여러 파이프라인 단계에 묶기, 기하구조 그리기 등을 말한다.
ID3D11Device와 ID3D11DeviceContext 인터페이스는 구체적으로 무엇을 담당하는가?
ID3D11Device : 기능 지원 점검과 자원 할당에 쓰인다.
ID3D11DeviceContext : 렌더 대상을 설정하고, 자원을 그래픽 파이프라인에 묶고, GPU가 수행할 렌더링 명령들을 지시하는데 쓰인다.
아래의 코드는 장치와 장치 문맥을 생성하는 함수이다.
HRESULT D3D11CreateDevice(
IDXGIAdapter* pAdapter, //생설할 장치를 나나태는 디스플레이 어댑터를 지정
D3D_DRIVER_TYPE DriverType, //생성할 드라이버의 타입 지정
HMODULE Software, //소프트웨어 구동기를 지정
UINT Flags, //추가적인 장치 플래그들을 지정
CONST D3D_FEATURE_LEVEL* pFeatureLevels, //D3D_FEATURE_LEVEL 원소들의 배열, 기능 수준 점검하는 순서
UINT FeatureLevels, //pFeatureLevels의 D3D_FEATURE_LEVEL 원소의 개수
UINT SDKVersion, //항상 D3D11_SDK_VERSION을 지정
ID3D11Device** ppDevice, //함수가 생성한 장치를 반환
D3D_FEATURE_LEVEL* pFeatureLevel, //pFeatureLevels 배열에서 처음으로 지원되는 기능을 반환
ID3D11DeviceContext** ppImmediateContext //생성된 장치 문맥 반환
);
D3D11CreateDevice 함수의 매개변수들을 정리해보자.
1.pAdater : 생성할 장치를 나타내는 디스플레이 어댑터를 지정한다. 이 매개변수에 널 값(NULL 또는 0)을 지정하면 기본 디스플레이 어댑터가 사용된다.
2.DriverType : 생성할 Direct3D 디바이스의 종류를 지정한다. 일반적으로 렌더링에 3차원 그래픽 가속이 적용되게 하기 위해 D3D_DRIVER_TYPE_HARDWARE를 지정한다. pAdapter에 NULL 이외의 값을 지정한 경우에는 D3D_DRIVER_TYPE_UNKNOWN을 지정한다.
typedef enum D3D_DRIVER_TYPE {
D3D_DRIVER_TYPE_UNKNOWN, //드라이버 유형을 알 수 없다.
D3D_DRIVER_TYPE_HARDWARE, //하드웨어에서 Direct3D 기능을 구현하는 드라이버
D3D_DRIVER_TYPE_REFERENCE, //모든 Direct3D 기능을 지원하는 소프트웨어 구현인 참조 드라이버
D3D_DRIVER_TYPE_NULL, //렌더링 기능이 없는 참조 드라이버
D3D_DRIVER_TYPE_SOFTWARE, //소프트웨어에서 완전히 구현된 드라이버
D3D_DRIVER_TYPE_WARP, //고성능 소프트웨어 래스터라이저
};
3.Software : 소프트웨어 래스터라이저를 구현하는 DLL에 대한 핸들이다. DriverType이 D3D_DRIVER_SOFTWARE인 경우 NULL이 들어와서는 안된다. 그외에는 보통 NULL을 사용한다.
4.Flags : DirectX의 API 레이어를 D3D_CREATE_DEVICE_FLAG 값들을 조합하여 설정한다. 조합은 OR 결합을 사용한다.
typedef enum D3D11_CREATE_DEVICE_FLAG {
D3D11_CREATE_DEVICE_SINGLETHREADED, //단일 스레드
D3D11_CREATE_DEVICE_DEBUG, //디버그 계층을 지원
D3D11_CREATE_DEVICE_SWITCH_TO_REF, //Direct3D 11에서는 사용하지 않는다.
D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, //다수 스레드가 생성되는 것을 방지
D3D11_CREATE_DEVICE_BGRA_SUPPORT, //BGRA 형식을 지원하는 장치를 만든다.
D3D11_CREATE_DEVICE_DEBUGGABLE, //장치와 드라이버가 셰이더 디버깅에 사용할 수 있는 정보를 유지 가능하게 한다.
D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY,
D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT,
D3D11_CREATE_DEVICE_VIDEO_SUPPORT
};
5.pFeatureLevels : D3D_FEATURE_LEVEL 형식 원소들의 배열을 지정한다.
6.FeatureLevels : pFeatureLevels 매개변수 배열의 개수를 지정한다. pFeatureLevels이 NULL이면 이 매개변수는 0으로 지정하면 된다.
7.SDKVersion : 사용하고 있는 DirectX의 SDK 버전을 지정한다. 사실상 D3D11_SDK_VERSION만 사용한다고 생각하면 된다.
8.ppDevice : 생성된 장치 개체에 대한 포인터 주소를 반환한다. 이 매개변수가 NULL이면 ID3D11Device가 반환되지 않는다.
9.pFeatureLevel : 성공하면 성공한 pFeatureLevels 배열에서 첫 번째 D3D_FEATURE_LEVEL을 반환한다. 지원되는 기능 수준을 결정할 필요가 없는 경우 NULL을 사용하면 된다.
10.ppImmediateContext : 생성된 장치 문맥 개체에 대한 포인터 주소 반환한다. 이 매개변수가 NULL이면 ID3D11DeviceContext가 반환되지 않는다.
2.4X MSAA 품질 수준 지원 점검
장치를 생성했으면, 하드웨어가 4X MSAA를 위한 품질 수준을 지원하는지 점검할 수 있다. 모든 Direct3D 11 대응 장치는 모든 렌더 대상 형식에 대해 지원하는 품질 수준이 서로 다르더라도 4X MSAA를 지원한다.
UINT m4xMsaaQuality;
HR(md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_F8G8B8A8_UNORM, 4, &m4xMsaaQuality));
assert(m4xMsaaQuality > 0);
4X MSAA가 항상 지원되므로, 반환된 품질 수준 값은 반드시 0보다 커야 한다.
3.교환 사슬(swap chain)의 설정
품질 수준을 점검했으면, 교환 사슬을 생성해야 한다. 생성하기 이전에 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;
DXGI_SWAP_CHAIN_DESC 구조체의 매개변수들을 정리해보자.
1.BufferDesc : 생성하고자 하는 후면 버퍼의 속성들을 서술하는 구조체이다.
typedef struct DXGI_MODE_DESC {
UINT Width; //해상도 너비
UINT Height; //해상도 높이
DXGI_RATIONAL RefreshRate; //디스플레이 재생빈도(헤르츠 단위)
DXGI_FORMAT Format; //후면 버퍼 픽셀 형식
DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; //디스플레이 스캔라인 모드
DXGI_MODE_SCALING Scaling; //디스플레이 비례 모드
} DXGI_MODE_DESC;
2.SampleDesc : 다중표본화를 위해 추출할 표본 개수와 품질 수준을 서술하는 구조체이다(22.8 참고).
3.BufferUsage : 버퍼의 용도를 서술하는 구조체이다. 일반적으로 후면 버퍼는 렌더링용으로 사용하므로 DXGI_USAGE_RENDER_TARGET_OUTPUT을 사용한다.
#define DXGI_CPU_ACCESS_NONE ( 0 )
#define DXGI_CPU_ACCESS_DYNAMIC ( 1 )
#define DXGI_CPU_ACCESS_READ_WRITE ( 2 )
#define DXGI_CPU_ACCESS_SCRATCH ( 3 )
#define DXGI_CPU_ACCESS_FIELD 15
#define DXGI_USAGE_SHADER_INPUT 0x00000010UL
#define DXGI_USAGE_RENDER_TARGET_OUTPUT 0x00000020UL
#define DXGI_USAGE_BACK_BUFFER 0x00000040UL
#define DXGI_USAGE_SHARED 0x00000080UL
#define DXGI_USAGE_READ_ONLY 0x00000100UL
#define DXGI_USAGE_DISCARD_ON_PRESENT 0x00000200UL
#define DXGI_USAGE_UNORDERED_ACCESS 0x00000400UL
typedef UINT DXGI_USAGE;
4.BufferCount : 교환 사슬에 사용할 후면 버퍼의 개수이다. 일반적으로 후면 버퍼 하나만 사용하므로 1을 지정한다(이중 버퍼링). 삼중 버퍼링을 원하면 2를 지정하면 된다.
5.OutputWindow : 렌더링 결과를 표시할 창의 핸들을 지정한다.
6.Windowed : 렌더링 화면이 창모드인지 여부를 설정한다. 창 모드를 원하면 true, 전체화면 모드를 원하면 false를 지정하면 된다.
7.SwapEffect : 화면을 표시한 후 표시 버퍼의 처리를 설정한다. 일반적으로 후면 버퍼를 사용한 후에 재사용하지 않고 비우므로 DXGI_SWAP_EFFECT_DISCARD를 사용한다.
enum DXGI_SWAP_EFFECT
{
DXGI_SWAP_EFFECT_DISCARD = 0,
DXGI_SWAP_EFFECT_SEQUENTIAL = 1,
DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3,
DXGI_SWAP_EFFECT_FLIP_DISCARD = 4
} DXGI_SWAP_EFFECT;
8.Flags : 추가적인 플래그를 설정한다. DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH를 사용하면 응용 프로그램이 전체 화면으로 전활 될 때 응용 프로그램 창의현재 크기에 잘 맞는 디스플레이 모드를 선택한다.
enum DXGI_SWAP_CHAIN_FLAG
{
DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1,
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2,
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4,
DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT = 8,
DXGI_SWAP_CHAIN_FLAG_RESTRICT_SHARED_RESOURCE_DRIVER = 16,
DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY = 32,
DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT = 64,
DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER = 128,
DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO = 256,
DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO = 512,
DXGI_SWAP_CHAIN_FLAG_HW_PROTECTED = 1024,
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING = 2048,
DXGI_SWAP_CHAIN_FLAG_RESTRICTED_TO_ALL_HOLOGRAPHIC_DISPLAYS = 4096
} DXGI_SWAP_CHAIN_FLAG;
4.교환 사슬(swap chain)의 생성
교환 사슬을 서술하는 구조체를 설정했다면, IDXGIFactory 인스턴스를 통해 IDXGIFactory::CreateSwapChain 메서드를 호출하여 교환 사슬 인터페이스(IDXGISwapChain)를 생성한다.
HRESULT CreateSwapChain(
IUnknown* pDevice, //ID3D11Device를 가리키는 포인터
DXGI_SWAP_CHAIN_DESC* pDesc, //교환 사슬 구조체를 가리키는 포인터
IDXGISwapChain** ppSwapChain //생성된 교환 사슬 인터페이스를 반환
);
IDXGIFactory 인스턴스는 CreateDXGIFactory 함수를 이용해서 얻을 수도 있다. 하지만 CreateDXGIFactory로 얻은IDXGIFactory 인스턴스로 IDXGIFactory::CreateSwapChain을 호출하면 오류가 난다.

따라서 이 오류를 피하기 위해선 장치의 생성에 쓰인 IDXGIFactory 인스턴스를 사용해야 한다. 이 인스턴스를 얻기 위해선 일련의 COM 질의 과정을 거쳐야 한다.
IDXGIDevice* dxgiDevice = 0;
HR(md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice));
IDXGIAdapter* dxgiAdapter = 0;
HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter));
IDXGIFactory* dxgiFactory = 0;
HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory));
IDXGISwapChain* mSwapChain;
HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain));
ReleaseCom(dxgiDevice);
ReleaseCom(dxgiAdapter);
ReleaseCom(dxgiFactory);
5.렌더 대상 뷰의 생성
어떤 자원을 파이프라인의 단계에 직접 묶는 것은 아니다. 대신 반드시 자원에 대한 뷰를 생성하고 그 뷰를 파이프라인 단계에 묶어야 한다. 구체적으로, 후면 버퍼를 파이프라인의 출력 병합기(Output Merger : OM) 단계에 묶으려면 우선 후면 버퍼에 대한 렌더 대상 뷰를 생성해야 한다.
ID3D11RenderTargetView* mRenderTargetView;
ID3D11Texture2D* backBuffer;
mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer));
md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
ReleaseCOM(backBuffer);
위 코드에서 mSwapChain의 함수 GetBuffer는 교환 사슬을 가리키는 포인터를 얻는다. dxgi.h에 들어가면 찾을 수 있다.
HRESULT GetBuffer(UINT Buffer, REFIID riid, void** ppSurface);
1.Buffer : 사용할 후면 버퍼의 인덱스이다. 일반적으로 후면 버퍼는 1개를 사용하므로 주로 0을 지정한다.
2.rrid : 버퍼를 조작하는 데 사용되는 인터페이스 유형이다. 쉽게 말해서 사용될 인터페이스나 클래스의 종류이다.
3.ppSurface : 후면 버퍼 인터페이스에 대한 포인터이다.
위 코드에서 md3dDevice의 함수 CreateRenderTargetView는 렌더 대상 뷰를 생성한다. dxgi.h에 들어가면 찾을 수 있다.
HRESULT CreateRenderTargetView(
ID3D11Resource *pResource,
const D3D11_RENDER_TARGET_VIEW_DESC *pDesc,
ID3D11RenderTargetView **ppRTView
);
1.pResource : 렌더 대상으로 사용할 자원이다.
2.pDesc : 자원에 담긴 원소들의 자료 형식을 서술하는 구조체이다. 이 매개변수에 널 값(NULL 또는 0)으로 설정하면 밉맵 수준 0의 모든 하위 리소스에 액세스하는 뷰를 만든다.
3.ppRTView : 생성된 렌더 타겟 뷰를 반환한다.
6.깊이·스텐실 버퍼와 뷰 생성
깊이 버퍼는 그저 깊이 정보를 담는 2차원 텍스처이다. 스텐실을 사용하는 경우엔 스텐실 정보도 담는다. 2차원 텍스처를 생성할 때에는 생성할 텍스처를 서술하는 D3D11_TEXTURE2D_DESC 구조체를 생성하고 ID3D11Device::CreateTexture2D 메서드를 호출해야 한다.
typedef struct D3D11_TEXTURE2D_DESC
{
UINT Width; //텍스처의 너비(텍셀 단위)
UINT Height; //텍스처의 높이(텍셀 단위)
UINT MipLevels; //밈맵 수준의 개수. 깊이/스텐실 버퍼를 위한 텍스처에는 하나만 있으면 된다.
UINT ArraySize; //텍스처 배열의 텍스처 개수. 깊이/스텐실 버퍼의 경우 텍스처 하나만 있으면 된다.
DXGI_FORMAT Format; //텍셀의 형식
DXGI_SAMPLE_DESC SampleDesc; //다중 표본 개수와 품질 수준
D3D11_USAGE Usage; //텍스처의 용도
UINT BindFlags; //자원을 파이프라인에 어떤 식으로 묶을 것인지 지정한다. 결합하여 복수도 가능
UINT CPUAccessFlags; //CPU가 자원에 접근하는 방식을 결정
UINT MiscFlags; //기타 플래그. 깊이/스텐실 버퍼에는 적용되지 않으므로 0을 지정하면 된다.
} D3D11_TEXTURE2D_DESC;
후면 버퍼와 마찬가지로, 깊이·스텐실 버퍼를 사용하려면 깊이·스텐실 뷰를 생성하고 파이프라인에 붙여야 한다. 그 과정은 렌더 타겟 뷰와 비슷하다.
D3D11_TEXTURE2D_DESC depthStencilDesc;
depthStencilDesc.Width = mClientWidth;
depthStencilDesc.Height = mClientHeight;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORAMT_D24_UNORM_S8_UINT;
if (mEnable4xMsaa)
{
depthStencilDesc.SampleDesc.Count = 4;
depthStencilDesc.SampleDesc.Quality = m4xMsaaQuality - 1;
}
else
{
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
}
depthStencilDesc.Usage = D3D11_USAGE_DEFUALT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags =0;
depthStencilDesc.MiscFlags = 0;
ID3D11Texture2D* mDepthStencilBuffer;
ID3D11DepthStencilView* mDepthStencilView;
HR(md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer));
HR(md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView));
위 코드에서 md3dDevice의 CreateTexture2D 함수는 2D 텍스처 배열을 만든다. d3d11.h에서 찾을 수 있다.
HRESULT CreateTexture2D(
const D3D11_TEXTURE2D_DESC* pDesc,
const D3D11_SUBRESOURCE_DATA* pInitialData,
ID3D11Texture2D** ppTexture2D;
);
1.pDesc : 2D 텍스처 리소스를 설명하는 D3D11_TEXTURE2D_DESC 구조체에 대한 포인터이다.
2.pInitialData : 2D 텍스처 리소스에 대한 하위 리소스를 설명하는 D3D11_SUBRESOURCE_DATA 구조체의 배열에 대한 포인터이다. 텍스처에 채울 초기 자료를 가리키는 포인터라고 생각하면 된다. 깊이·스텐실은 채울 필요가 없다.
3.ppTexture2D : 생성된 텍스처를 반환한다.
위 코드에서 md3dDevice의 CreateDepthStencilView 함수는 리소스 데이터에 액세스하기 위한 깊이·스텐실 뷰를 만든다. d3d11.h에서 찾을 수 있다.
HRESULT CreateDepthStencilView(
ID3D11Resource* pResource,
const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc,
ID3D11DepthStencilView** ppDepthStencilView;
);
1.pResource : 깊이·스텐실 표면(*주 2)으로 사용할 리소스에 대한 포인터이다. 뷰를 생성하고자 하는 자원이라고 생각하면 된다. 이 리소스는 D3D11_BIND_DEPTH_STENCIL 플래그로 생성되어야 한다.
2.pDesc : 자원 원소의 자료 형식을 서술하는 D3D11_DEPTH_STENCIL_VIEW_DESC 구조체를 가리키는 포인터이다. 형식을 완전히 지정해서 자원을 생성했다면 널 값을 지정해도 되는데, 널 값을 넣은 경우 주어진 자원을 생성했을 때 지정한 형식을 적용해서 자원의 첫 번째 밉맵 수준(밉맵 0레벨)에 대한 뷰를 생성한다.
3.ppDepthStencilView : 깊이·스텐실 뷰를 반환한다.
7.뷰들을 출력 병합기(Output Merger : OM) 단계에 묶기
후면 버퍼와 깊이·스텐실 버퍼에 대한 뷰들을 파이프라인의 출력 병합기 단계에 묶어야 한다. 이 과정을 거쳐야 자원들이 파이프라인의 렌더 대상과 깊이·스텐실 버퍼로 작용하게 된다.
md3dImmediateContext->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
위 코드에서 OMSetRenderTargets 함수의 선언은 아래와 같다.
void OMSetRenderTargets(
UINT NumViews,
ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView
);
1.NumViews : 바인드할 렌더 타겟의 수 이다.
2.ppRenderTargetViews : 파이프라인에 바인딩할 렌더 대상을 나타내는 ID3D11RenderTargetView의 배열에 대한 포인터이다. 이 매개변수가 NULL이고 NumViews가 0이면 렌더 타겟이 바인딩되지 않는다.
3.pDepthStencilView : 파이프라인에 바인딩할 깊이·스텐실 뷰이다. 이 매개변수가 NULL이면 깊이·스텐실 뷰가 바인딩되지 않는다.
8.뷰포트 설정
일반적으로 렌더링할 화면을 후면 버퍼 전체에 그린다. 하지만 화면을 후면 버퍼의 일부만 그리는 것도 가능하다. 쉽게 설명하자면 전체 그림에서 임의의 구역만 그릴 수 도 있다는 뜻이다. 임의의 구역이라고 하지만 직사각형으로 한정되어 있는 것 같다. 이런 후면 버퍼의 임의의 구역을 뷰포트(viewport)라고 한다.
typedef struct D3D11_VIEWPORT
{
FLOAT TopLeftX; //상단 좌측 x좌표
FLOAT TopLeftY; //상돤 좌측 y좌표
FLOAT Width; //너비
FLOAT Height; //높이
FLOAT MinDepth; //최소 깊이 버퍼 값
FLOAT MaxDepth; //최대 깊이 버퍼 값
} D3D11_VIEWPORT;
MinDepth와 MaxDepth에서 생각해야 할 것은 Direct3D에서 깊이 버퍼 값의 범위는 0 ~ 1이다. 그러므로 특수한 효과를 바라는 것이 아니라면 MinDepth는 0으로, MaxDepth는 1로 설정한다.
D3D11_VIEWPORT 구조체를 생성한 후, ID3D11DeviceContext::RSSetViewports 메서드를 호출하여 Direct3D에게 뷰포트를 알려줘야 한다.
D3D11_VIEWPORT vp;
md3dImmediateContext->RSSetViewports(1, &vp);
첫 번째 변수는 묶을 뷰포트 개수이고, 두 번째 변수는 뷰포트 배열을 가리키는 포인터이다.
뷰포트는 2인용 모드에서 사용할 것이다. It Take Two라던가 A Way Out를 생각하면 된다.
(*주 1) 4X MSAA
4X는 4배수를 의미하고 MSAA는 multisample anti-aliasing의 약자이다. 즉, 4배 다중표본화를 이용한 앨리어싱 제거를 뜻한다.
(*주 2) 표면(surface)
Direct3D에서 표면은 주로 2D 이미지 데이터를 보관하는데 이용하는 픽셀의 행렬을 말한다.
'서적 정리 > DirectX11을 이용한 3D 게임 프로그래밍 입문' 카테고리의 다른 글
29.Direct3D의 초기화 요약 (0) | 2022.01.20 |
---|---|
28.Direct3D 응용 프로그램의 디버깅 (0) | 2022.01.20 |
27.예제 응용 프로그램 프레임워크 (0) | 2022.01.20 |
26.타이밍과 애니메이션 (0) | 2022.01.20 |
24.Direct3D 기본지식 (0) | 2022.01.20 |
23.변환 요약 (0) | 2022.01.20 |
22.XNA Math 라이브러리의 관련 함수들 (0) | 2022.01.20 |
21.변환 행렬 대 좌표 변경 행렬 (0) | 2022.01.20 |
댓글