空から構築する

空のプロジェクトから構築する

空のプロジェクトから構築して、ウインドウを表示します。
この方法を取ると、極めてシンプルなプロジェクトを構築することが出来ます。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの説明

  1. Sample Brower を使うと便利なのですが、直接関係しないファイルや余分なフォルダーが組み込まれてしまいます。
    その内これらのフォルダーやファイルでハードディスクが占有されることになりかねません。
    そこで本当に必要なファイルだけを格納した「極めてシンプルなプロジェクト」を構築する方法を説明します。
    また DXUT を組み込まないのでブラックボックスが少なく、DirectX の基本を理解するのに適しています。
  2. 空のプロジェクトから作成します。
    1. Visual Studio(VC++ 2010 Express など)を起動します。
    2. [ファイル/新規作成/プロジェクト] から [空のプロジェクト Visual C++] を選択します。
      ソリューションのディレクトリを作成のチェックは外して下さい。
      プロジェクト名は "Main" にして下さい。(後から幾らでも変更することが出来ます)
    3. プロジェクトのフォルダーに Main.cpp を格納します。
      Main.cpp は、この後に掲載しています。
    4. ソリューションエクスプローラのソースファイルを選択して[プロジェクト][既存項目の追加]から Main.cpp を追加します。
      [プロジェクト/Main のプロパティ/構成プロパティ/文字セット]から「Unicode文字セットを使用する」を選択します。
    5. アプリケーションに必要なライブラリをリンクします。
      メニューバーから [プロジェクト] [プロパティ] [リンカ] [入力] から設定します。
      今回のアプリケーションで追加が必要なライブラリは d3d10.lib だけです。
      下記の画像は Sample Brower で構築したときのもので、今回のアプリケーションとは無関係です。
      ライブラリは #pragma を使って取り込むこともできます。

    6. プロジェクトのフォルダーに格納する最小限必要なものは、次のファイルだけです。
      ・Main.cpp
      ・Main.sln
      ・Main.vcxproj(vcproj)
  3. Visual Studio のバージョンによっては、この状態でコンパイル&実行をすることが出来ます。
    VC++ 2010 Express では、プロジェクトのプロパティから DirectX のインクルードとライブラリのパスを追加する必要があります。
    詳細は Windows Guid から「パスの設定」を参照して下さい。
    1. ソリューションエクスプローラのソースファイルを選択して [プロジェクト/Main のプロパティ/構成プロパティ/すべての構成/VC++ディレクトリ]を表示します。

    2. インクルードディレクトリに DirectX の Include パスを追加します。
      ライブラリディレクトリに DirectX の Lib\x86 パスを追加します。
      表示中のパスをクリックして、下三角マークから<編集...>でパスを追加して下さい。
      フォルダアイコンをクリックして、C:\ から辿ることが出来ます。
  4. コンパイル&実行で、空のウインドウが表示されます。
    Sample Brower を利用したときに比べて「極めてシンプルなプロジェクト」が完成です。
  5. 空のウインドウを表示するプログラムファイル(Main.cpp)です。
    /***************************************************/
    /*  DirectX10 Graphics  空のウインドウ    前田 稔  */
    /***************************************************/
    #include <windows.h>
    #include <d3d10.h>
    
    // Global Variables
    HINSTANCE               g_hInst = NULL;
    HWND                    g_hWnd = NULL;
    D3D10_DRIVER_TYPE       g_driverType = D3D10_DRIVER_TYPE_NULL;
    ID3D10Device*           g_pd3dDevice = NULL;
    IDXGISwapChain*         g_pSwapChain = NULL;
    ID3D10RenderTargetView* g_pRenderTargetView = NULL;
    
    // Function Prototype
    HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
    HRESULT InitDevice();
    void CleanupDevice();
    LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
    void Render();
    
    //★ Win Main
    int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
    {
        if( FAILED( InitWindow( hInstance, nCmdShow ) ) )   return 0;
    
        if( FAILED( InitDevice() ) )
        {   CleanupDevice();
            return 0;
        }
    
        // Main message loop
        MSG msg = {0};
        while( WM_QUIT != msg.message )
        {   if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
            {   TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
            else
            {   Render();  }
        }
        CleanupDevice();
    
        return ( int )msg.wParam;
    }
    
    // Window の初期化
    HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
    {
        // Register class
        WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, 
                          hInstance, NULL, LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW+1),
                          NULL, L"WindowClass", LoadIcon(wc.hInstance, L"IDI_MYICON")
                        };
        if( !RegisterClassEx( &wc ) )   return E_FAIL;
    
        // Create window
        g_hInst = hInstance;
        RECT rc = { 0, 0, 640, 480 };
        AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
        g_hWnd = CreateWindow( L"WindowClass", L"Direct3D 10  Window を表示", WS_OVERLAPPEDWINDOW,
                               CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
                               NULL, NULL, hInstance, NULL );
        if( !g_hWnd )   return E_FAIL;
        ShowWindow( g_hWnd, nCmdShow );
    
        return S_OK;
    }
    
    // Create Direct3D device
    HRESULT InitDevice()
    {
        HRESULT hr = S_OK;
        RECT rc;
    
        GetClientRect( g_hWnd, &rc );
        UINT width = rc.right - rc.left;
        UINT height = rc.bottom - rc.top;
    
        UINT createDeviceFlags = 0;
    #ifdef _DEBUG
        createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
    #endif
    
        D3D10_DRIVER_TYPE driverTypes[] =
        {
            D3D10_DRIVER_TYPE_HARDWARE,
            D3D10_DRIVER_TYPE_REFERENCE,
        };
        UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );
    
        DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory( &sd, sizeof( sd ) );
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;
    
        for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
        {
            g_driverType = driverTypes[driverTypeIndex];
            hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,
                                                D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
            if( SUCCEEDED( hr ) )   break;
        }
        if( FAILED( hr ) )  return hr;
    
        // Create a render target view
        ID3D10Texture2D* pBuffer;
        hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&pBuffer );
        if( FAILED( hr ) )  return hr;
    
        hr = g_pd3dDevice->CreateRenderTargetView( pBuffer, NULL, &g_pRenderTargetView );
        pBuffer->Release();
        if( FAILED( hr ) )  return hr;
    
        g_pd3dDevice->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
    
        return S_OK;
    }
    
    // Clean up the objects we've created
    void CleanupDevice()
    {
        if( g_pd3dDevice ) g_pd3dDevice->ClearState();
        if( g_pRenderTargetView ) g_pRenderTargetView->Release();
        if( g_pSwapChain ) g_pSwapChain->Release();
        if( g_pd3dDevice ) g_pd3dDevice->Release();
    }
    
    // Called every time the application receives a message
    LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
        PAINTSTRUCT ps;
        HDC hdc;
    
        switch( message )
        {   case WM_PAINT:
                hdc = BeginPaint( hWnd, &ps );
                EndPaint( hWnd, &ps );
                break;
            case WM_DESTROY:
                PostQuitMessage( 0 );
                break;
            default:
                return DefWindowProc( hWnd, message, wParam, lParam );
        }
    
        return 0;
    }
    
    // Render a frame
    void Render()
    {
        // Clear the back buffer 
        float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alpha
        g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
    
        // Present the information rendered to the back buffer to the front buffer (the screen)
        g_pSwapChain->Present( 0, 0 );
    }
    
  6. プログラムは DirectX9 で空の新規プロジェクトから作成した時と同じ要領です。
    D3D で三角形を描画する などを参照して下さい。
    このプロジェクトは、空から作成するときのテンプレートになります。
    新しいプロジェクトを作成するときは、フォルダーごとコピーしてプロジェクト名(フォルダー名)を変更して下さい。

超初心者のプログラム入門(DirectX10 game program)