空から構築して立方体を描画

空から構築して立方体を描画

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

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

プロジェクトの説明

  1. プロジェクトの作成方法は 空のプロジェクトから構築する を参照して下さい。
    プロジェクトのフォルダーに次のファイルを格納して下さい。
    directx.ico はその辺に転がっているのを拾ってきて下さい。
    ファイル名 説明
    EmptyBox.zip 圧縮ファイル
  2. ソリューションエクスプローラのソースファイルを選択して[プロジェクト][既存項目の追加]から次のファイルを追加します。
    ・Main.cpp
    ・Main.rc
  3. [プロジェクト/Main のプロパティ/構成プロパティ/文字セット]から「Unicode文字セットを使用する」を選択します。
    コンパイル&実行で、頂点に色を設定した立方体が回転しながら描画されます。
  4. 立方体を描画するプログラムファイル(Main.cpp)です。
    ライブラリは #pragma を使って取り込んでいます。
    /****************************************************/
    /*  DirectX10  立方体を回転しながら描画    前田 稔  */
    /****************************************************/
    #include <windows.h>
    #include <d3d10.h>
    #include <d3dx10.h>
    
    #pragma once
    #pragma comment(lib,"d3d10.lib")
    #pragma comment(lib,"d3dx10.lib")
    
    // 頂点フォーマット
    struct SimpleVertex
    {
        D3DXVECTOR3 Pos;  
        D3DXVECTOR4 Color; 
    };
    
    
    // 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;
    ID3D10Effect*               g_pEffect = NULL;
    ID3D10EffectTechnique*      g_pTechnique = NULL;
    ID3D10InputLayout*          g_pVertexLayout = NULL;
    ID3D10Buffer*               g_pVertexBuffer = NULL;
    ID3D10Buffer*               g_pIndexBuffer = NULL;
    ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
    ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
    ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
    D3DXMATRIX                  g_World;
    D3DXMATRIX                  g_View;
    D3DXMATRIX                  g_Projection;
    
  5. アイコンは resource.h を使わずに、ID(L"IDI_MYICON")を直接指定しています。
    // Window の初期化
    HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
    {
        // Register class
        WNDCLASSEX wcex =
        {   sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, 
            hInstance, LoadIcon(hInstance, L"IDI_MYICON"), LoadCursor(NULL, IDC_ARROW),
            (HBRUSH)(COLOR_WINDOW+1), NULL, L"WindowClass", LoadIcon(hInstance, L"IDI_MYICON")
        };
            ・・・
    
  6. InitDevice() で Direct 3D の Device と swap chain を設定します。
    g_pd3dDevice に Direct 3D の Device を取得します。
    L"Tutorial04.fx" を入力して Shader を作成します。
    "Render", "World", "View", "Projection" を設定します。
    layout で頂点座標と色を設定します。
    vertices[] が頂点座標の定義で、indices[] がその Index です。
    &g_World, &g_View, &g_Projection を設定します。
    // Create Direct3D device and swap chain
    HRESULT InitDevice()
    {
        HRESULT hr = S_OK;
            ・・・
        D3D10_DRIVER_TYPE driverTypes[] = 
        {
            D3D10_DRIVER_TYPE_HARDWARE,
            D3D10_DRIVER_TYPE_REFERENCE,
        };
        UINT numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]);
            ・・・
        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;
            ・・・
        hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID*)&pBuffer );
        if( FAILED(hr) )    return hr;
            ・・・
        // Create the effect
        DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
        hr = D3DX10CreateEffectFromFile( L"Tutorial04.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
                g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
            ・・・
        // Obtain the technique
        g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
    
        // Obtain the variables
        g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
        g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
        g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    
        // Define the input layout
        D3D10_INPUT_ELEMENT_DESC layout[] =
        {
            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },  
            { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }, 
        };
        UINT numElements = sizeof(layout)/sizeof(layout[0]);
            ・・・
        // Create vertex buffer
        SimpleVertex vertices[] =
        {   { D3DXVECTOR3( -1.0f,  1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ) },
            { D3DXVECTOR3(  1.0f,  1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 1.0f ) },
            ・・・
            { D3DXVECTOR3( -1.0f, -1.0f,  1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) },
        };
            ・・・
        // Create index buffer
        DWORD indices[] =
        {   3,1,0,
            2,1,3,
            ・・・
            6,4,5,
            7,4,6,
        };
            ・・・
        // Initialize the world matrix
        D3DXMatrixIdentity( &g_World );
    
        // Initialize the view matrix
        D3DXVECTOR3 Eye( 0.0f, 1.0f, -5.0f );
        D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
        D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
        D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
    
        // Initialize the projection matrix
        D3DXMatrixPerspectiveFovLH( &g_Projection, (float)D3DX_PI * 0.5f, width/(FLOAT)height, 0.1f, 100.0f );
    
        return S_OK;
    }
    
  7. モデルを描画する Render() 関数です。
    D3DXMatrixRotationY() でY軸を中心に自動回転しながら描画します。
    // Render a frame
    void Render()
    {
        // Update our time
        static float t = 0.0f;
        if( g_driverType == D3D10_DRIVER_TYPE_REFERENCE )
        {   t += (float)D3DX_PI * 0.0125f;  }
        else
        {   static DWORD dwTimeStart = 0;
            DWORD dwTimeCur = GetTickCount();
            if( dwTimeStart == 0 )
                dwTimeStart = dwTimeCur;
            t = ( dwTimeCur - dwTimeStart) / 1000.0f;
        }
    
        // Animate the cube
        D3DXMatrixRotationY( &g_World, t );
    
        // 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 );
    
        // Update variables
        g_pWorldVariable->SetMatrix( (float*)&g_World );
        g_pViewVariable->SetMatrix( (float*)&g_View );
        g_pProjectionVariable->SetMatrix( (float*)&g_Projection );
    
        // Renders a triangle
        D3D10_TECHNIQUE_DESC techDesc;
        g_pTechnique->GetDesc( &techDesc );
        for( UINT p = 0; p < techDesc.Passes; ++p )
        {   g_pTechnique->GetPassByIndex( p )->Apply(0);
            g_pd3dDevice->DrawIndexed( 36, 0, 0 );  // 36 vertices needed for 12 triangles
        }
    
        // Present our back buffer to our front buffer
        g_pSwapChain->Present( 0, 0 );
    }
    

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