DirectX11 – 디바이스 객체

Microsoft DirectX11 AI

[DirectX11] 환경 구축를 통해서 프로젝트의 생성까지 모두 끝나고 빌드하면 다음과 같은 화면을 볼 수 있다.

빈 프로그램 창

하지만 아직 DirectX를 통해 렌더링되는 화면은 아니다. 이제부터 DirectX11 API를 이용해 빈 화면을 우선 렌더링 해보도록 하자.

디바이스 객체들을 만들자


DirectX11 API를 이용하기 위해서 우선적으로 생성해야 하는 객체들이 있다. ID3D11Device, ID3D11DeviceContext, IDXGISwapChain 인터페이스 객체 3개가 필요하다. 편의상 이들을 통칭해서 디바이스 객체들이라고 하자. 이들은 렌더링에 필요한 리소스를 생성하고 렌더링 파이프라인에 연결하고 백 버퍼를 갱신하기 위한 객체들이라고 보면 된다.

 

디바이스 객체들의 역할

각 디바이스 객체가 제공하는 인터페이스 함수들을 보면 대략적으로 어떤 역할들을 하는지 알 수 있다. 마이크로 소프트 공식 홈페이지에서 자세히 설명이 되어 있다. 일단은 간략하게 각 객체가 어떤 역할들을 하는지 알아보자.

 

ID3D11Device

ID3D11Device는 대체적으로 리소스나 쉐이더 객체등을 생성할 수 있는 함수들을 제공한다.

  • CreateBuffer, CreateTexture2D, CreateRenderTargetView, CreateVertexShader, CreateComputeShader

 

ID3D11DeviceContext

ID3D11DeviceContext는 렌더링 파이프라인에 리소스나 쉐이더를 연결하는 함수들을 제공한다. 함수들의 네이밍에 앞 2글자 ( IA, VS, HS등 )는 렌더링 파이프라인 스테이지의 약어이다.

  • IASetIndexBuffer, IASetInputLayout, VSSetConstantBuffers, HSSetSamplers, DSSetShader

 

IDXGISwapChain

IDXGISwapChain은 백 버퍼와 관련된 함수들을 제공한다.

  • Present, ResizeBuffers, SetFullscreenState

이 스왑 체인을 만들기 위해선 Description Structure를 통해서 어떤 스왑 체인을 만들지 결정을 해야 한다. 이는 DXGI_SWAP_CHAIN_DESC를 통해서 전달한다. 레퍼런스는 DXGI_SWAP_CHAIN_DESC에서 확인할 수 있다. 주로 버퍼의 갯수, 버퍼의 용도, 버퍼의 포맷등을 결정하게 된다.

 

 

디바이스 객체 생성 코드

디바이스 객체를 생성하는 코드는 다음과 같다.

DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory( &scd, sizeof( DXGI_SWAP_CHAIN_DESC ) );

scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = hWnd;
scd.SampleDesc.Count = 4;
scd.Windowed = True;

D3D11CreateDeviceAndSwapChain( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, nullptr, nullptr, nullptr, D3D11_SDK_VERSION, &scd, &Swapchain, &Device, nullptr, &DeviceContext );
C++

D3D11CreateDeviceAndSwapChain함수에 대한 레퍼런스는 D3D11CreateDeviceAndSwapChain에서 자세히 알 수 있다. 이 함수를 통해 3개의 객체를 모두 생성하면 이제 비로소 DirectX11 API를 이용하기 위한 준비가 끝난 것이다.

CRD11Device


위에서 설명한 코드들을 가지고 클래스로 만들어보자.

//---------------------------------------------------------------------------------------------------------------------  
/// CRD11Device  
//---------------------------------------------------------------------------------------------------------------------  
class CRD11Device  
{  
private:  
    ID3D11Device*        DevicePtr        = nullptr;  
    ID3D11DeviceContext* DeviceContextPtr = nullptr;  
    IDXGISwapChain*      SwapChainPtr     = nullptr;  
  
public:  
    /// Constructor  
    CRD11Device() = default;  
      
    /// Create Dx11 device ojects.  
    bool Create( HWND hWnd );  
      
    //-----------------------------------------------------------------------------------------------------------------  
    /// Getter    
    //-----------------------------------------------------------------------------------------------------------------
    /// Get Dx11 device object.
    ID3D11Device* GetDevice() const { return DevicePtr; }  
  
    /// Get Dx11 device context object.  
    ID3D11DeviceContext* GetDeviceContext() const { return DeviceContextPtr; }  
  
    /// Get Dx11 swap chain object.  
    IDXGISwapChain* GetSwapChain() const { return SwapChainPtr; }  
};
C++

 

Create에서 윈도우 핸들을 전달받아 객체들을 생성해준다.

//---------------------------------------------------------------------------------------------------------------------  
/// Create  
//---------------------------------------------------------------------------------------------------------------------  
bool CRD11Device::Create( HWND hWnd )  
{  
    DXGI_SWAP_CHAIN_DESC scd;  
    ZeroMemory( &scd, sizeof( DXGI_SWAP_CHAIN_DESC ) );  
  
    scd.BufferCount       = 1;  
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;  
    scd.BufferUsage       = DXGI_USAGE_RENDER_TARGET_OUTPUT;  
    scd.OutputWindow      = hWnd;  
    scd.SampleDesc.Count  = 1;  
    scd.Windowed          = true;  
  
    HRESULT hr = D3D11CreateDeviceAndSwapChain  
    (  
       nullptr,  
       D3D_DRIVER_TYPE_HARDWARE,  
       nullptr,  
       0,  
       nullptr,  
       0,  
       D3D11_SDK_VERSION,  
       &scd,  
       &SwapChainPtr,  
       &DevicePtr,  
       nullptr,  
       &DeviceContextPtr  
    );  
  
    if ( FAILED( hr ) ) return false;  
         
    return true;  
}
C++

 

이 함수는 윈도우 핸들이 생성되는 시점에서 호출해주면 끝이다.

//---------------------------------------------------------------------------------------------------------------------  
/// wWinMain  
//---------------------------------------------------------------------------------------------------------------------  
int APIENTRY wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow )  
{  
    // 코드 생략

    HWND hWnd = CreateWindowW( szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr );  
    if ( !hWnd ) return false;  
  
    GD11.Create( hWnd );

    // 코드 생략
}
C++

 

이렇게 일단 1차적인 준비가 끝났다. 다음엔 DirectX11 API를 이용해서 빈 화면을 렌더링 해보자.

이전글 : [DirectX11] 환경 구축

다음글 : [DirectX11] API를 이용한 빈 화면 렌더링

0 답글

댓글을 남겨주세요

Want to join the discussion?
Feel free to contribute!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다