Graphics/DirectX

Direct X - *디바이스 생성

MOLOKINI 2014. 6. 19. 14:38
디바이스 생성을 해보겠다.

기본이지만 가장 중요한 디바이스 객체다.
이것이 바로 DX라고 해도 과언이 아니다.



/**-----------------------------------------------------------------------------
 * \brief 디바이스 생성
 * 파일: CreateDevice.cpp
 *
 * 설명: D3D 디바이스를 생성하고, 이를 사용해서 화면을 지우는 방법에 대해서
 *       공부하게 된다.
 *
 **-----------------------------------------------------------------------------
 */
/// Direct3D9를 사용하기 위한 헤더
#include <d3d9.h>

/**-----------------------------------------------------------------------------
 * 전역변수
 *------------------------------------------------------------------------------
 */
LPDIRECT3D9             g_pD3D       = NULL; /// D3D 디바이스를 생성할 D3D객체변수
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; /// 렌더링에 사용될 D3D디바이스

/**-----------------------------------------------------------------------------
 * Direct3D 초기화
 *------------------------------------------------------------------------------
 */
HRESULT InitD3D( HWND hWnd )
{
    /// 디바이스를 생성하기위한 D3D객체 생성
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    D3DPRESENT_PARAMETERS d3dpp;                /// 디바이스 생성을 위한 구조체
    ZeroMemory( &d3dpp, sizeof(d3dpp) );        /// 반드시 ZeroMemory()함수로 미리 구조체를 깨끗이 지워야 한다.
    d3dpp.Windowed = TRUE;                      /// 창모드로 생성
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;   /// 가장 효율적인 SWAP효과
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;    /// 현재 바탕화면 모드에 맞춰서 후면버퍼를 생성

    /// 디바이스를 다음과 같은 설정으로 생성한다.
    /// 1. 디폴트 비디오카드를 사용(대부분은 비디오카드가 1개 이다.)
    /// 2. HAL디바이스를 생성한다.(HW가속장치를 사용하겠다는 의미)
    /// 3. 정점처리는 모든 카드에서 지원하는 SW처리로 생성한다.(HW로 생성할경우 더욱 높은 성능을 낸다.)
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
 
    {
        return E_FAIL;
    }

    /// 디바이스 상태정보를 처리할경우 여기에서 한다.
    return S_OK;
}

CreateDevice 구조체의 전달인자
Adapter : 디바이스를 생성할 화면의 순서 번호, 모니터가 두대 이상일 때만 필요하다. Default
DeviceType : 출력 디바이스의 종류를 결정한다. D3DDEVTYPE_HAL이 하드웨어 가속을 지원한다.
hFocusWindow : 디바이스가 출력할 윈도우의 핸들, 전체화면일 경우 최상위 윈도우(부모가 없는 윈도우)만 가능
BehaviorFlags : 여러가지가 있지만, D3DCREATE_HARDWARE_VERTEXPROCESSING과 D3DCREATE_SOFTWARE_VERTEXPROCESSING이 가장 중요하다. Direct 9.x의 가장 강력한 기능인 정점셰이더를 사용할 때 하드웨어 가속을 사용할지, 소프트웨어적으로 지원할 것인지를 결정하는 것이다. D3DCREATE_MIXED_VERTEX_PROCESSING을 사용할 경우에는 하드웨어 가속과 소프트웨어 가속을 실행중에 전환할 수 있다.
pPresentationParameter : 앞에서 선언한 구조체의 포인터다
ppReturnedDeviceInterface : 우리가 얻고싶은 그 값이다, IDirect3DDevice9의 인터페이스를 갖고 있는 포인터가 담겨서 들어온다.

/**-----------------------------------------------------------------------------
 * 초기화된 객체들을 소거한다.
 *------------------------------------------------------------------------------
 */
VOID Cleanup()
{
    if( g_pd3dDevice != NULL) 
        g_pd3dDevice->Release();

    if( g_pD3D != NULL)
        g_pD3D->Release();
}

/**-----------------------------------------------------------------------------
 * 화면을 그린다.
 *------------------------------------------------------------------------------
 */
VOID Render()
{
    if( NULL == g_pd3dDevice )
        return;

    /// 후면버퍼를 파란색(0,0,255)으로 지운다.
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
    
    /// 렌더링 시작
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        /// 실제 렌더링 명령들이 나열될 곳
    
        /// 렌더링 종료
        g_pd3dDevice->EndScene();
    }

    /// 후면버퍼를 보이는 화면으로!
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

1. 화면을 깨끗히 지운다.(Clear())
2. 폴리곤을 그리겠다고 D3D에게 알린다.(BeginScene())
3. 폴리곤을 다 그렸다고 D3D에게 알린다.(EndScene())
4. 화면에 나타나게 한다. (Present())
2번과 3번사이에서 폴리곤을 그리게 된다.

/**-----------------------------------------------------------------------------
 * 윈도우 프로시져
 *------------------------------------------------------------------------------
 */
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;

        case WM_PAINT:
            Render();
            ValidateRect( hWnd, NULL );
            return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

/**-----------------------------------------------------------------------------
 * 이 프로그램의 시작점
 *------------------------------------------------------------------------------
 */
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    /// 윈도우 클래스 등록
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, 
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      "D3D Tutorial", NULL };
    RegisterClassEx( &wc );

    /// 윈도우 생성
    HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 01: CreateDevice", 
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

    /// Direct3D 초기화
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    { 
        /// 윈도우 출력
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );

        /// 메시지 루프
        MSG msg; 
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }

    /// 등록된 클래스 소거
    UnregisterClass( "D3D Tutorial", wc.hInstance );
    return 0;
}


D3D의 구동순서
1. RegisterClassEx()로 생성하고자 하는 윈도우의 클래스를 등록한다.
2. CreateWindow()로 윈도우를 생성한다
3. InitD3D() 함수에서 Direct3D를 초기화한다
4. ShowWindow(), UpdateWindow()로 윈도우를 화면에 표시한다
5. GetMessage(), TranslateMessage(), DispatchMessage()로 이루어진 메시지 루프를 수행한다.
6. 메시지루프를 빠져나올 경우 초기화한 Direct3D를 메모리에서 해제한다.
7. 프로그램을 종료한다.

 

 

'Graphics > DirectX' 카테고리의 다른 글

Direct X - *행렬  (0) 2014.06.19
Direct X - *정점  (0) 2014.06.19
Direct X - 최초 세팅 작업  (0) 2014.06.19
Direct X - 기초용어와 이론  (0) 2014.06.19
Direct X - 19. 모델의 이동, 회전, 확대, 축소  (0) 2014.06.09