ティーポットを Camera で操作

ティーポットを Camera で操作

ティーポットを生成して Camera で操作します。

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

プログラムの説明

  1. Visual C++ 2010 Express & June2010 の環境で DXUTCreateTeapot() でティーポットを生成して、Camera で操作(モデルの回転/カメラの回転)をします。
    DirectX Sample Browser で MultiMon10 のプロジェクトを作成して下さい。
    MultiMon10 のプロジェクトをコンパイルして、正常に実行されることを確かめて下さい。
    エラーが発生するときや、正常に実行出来ないときは、残念ながら現在の構成は相性が悪いようです。
  2. MultiMon10 のプロジェクトを使ってティーポットを生成して自動回転しながら操作します。
    モデルの操作には ArcBall を使う方法と Camera を使う方法があります。
    ArcBall を使う方法は ティーポットを ArcBall で操作 を参照して下さい。
    プログラムは「ティーポットを ArcBall で操作」をベースに修正します。
  3. #include と領域の宣言です。
    CModelViewerCamera を使うので "DXUTcamera.h" を include して下さい。
    g_pMesh がティーポットのメッシュです。
    g_Camera がモデルを回転する CModelViewerCamera です。
    g_World, g_View, g_Projection は g_Camera の領域を使うので不要です。
    #include "DXUTcamera.h"
    
    ID3DX10Mesh*                g_pMesh = NULL;
    CModelViewerCamera          g_Camera;
    //D3DXMATRIX                  g_World;
    //D3DXMATRIX                  g_View;
    //D3DXMATRIX                  g_Projection;
    
  4. OnD3D10FrameRender() では g_Camera の領域から g_World, g_View, g_Projection, g_Colors を Shader に設定して描画します。
    g_Camera で回転すると g_Camera の中の World 座標と View 座標が回転します。
    void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
    {
        // Clear render target and the depth stencil 
        float ClearColor[4] = { 0.176f, 0.196f, 0.667f, 0.0f };
        pd3dDevice->ClearRenderTargetView( DXUTGetD3D10RenderTargetView(), ClearColor );
        pd3dDevice->ClearDepthStencilView( DXUTGetD3D10DepthStencilView(), D3D10_CLEAR_DEPTH, 1.0, 0 );
    
        // Update variables
        g_pWorldVariable->SetMatrix((float*)&(*g_Camera.GetWorldMatrix()));
        g_pViewVariable->SetMatrix((float*)&(*g_Camera.GetViewMatrix()));
        g_pProjectionVariable->SetMatrix((float*)&(*g_Camera.GetProjMatrix()));
        g_pColorVariable->SetFloatVector( (float*)&g_Colors[0] );
    
        D3D10_TECHNIQUE_DESC techDesc;
        g_pRender->GetDesc( &techDesc );
    
        UINT NumSubsets;
        g_pMesh->GetAttributeTable( NULL, &NumSubsets );
    
        pd3dDevice->IASetInputLayout( g_pLayout );
    
        for( UINT p=0; p<techDesc.Passes; p++ )
        {
            g_pRender->GetPassByIndex(p)->Apply(0);
    
            for( UINT s=0; sDrawSubset(s);
            }
        }
    }
    
  5. OnD3D10CreateDevice() はデバイスを生成するときに呼ばれます。
    DXUTCreateTeapot() でティーポットを生成します。
    &vEye, &vLook をパラメータとして g_Camera.SetViewParams() を設定します。
    HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc,
                                          void* pUserContext )
    {
            :
            :
        DXUTCreateTeapot( pd3dDevice, &g_pMesh );
            :
            :
        D3DXVECTOR3 vEye(0,4,-4);
        D3DXVECTOR3 vLook(0,0,0);
        g_Camera.SetViewParams( &vEye, &vLook );
    
        return S_OK;
    }
    
  6. OnD3D10ResizedSwapChain() では、縦横比を計算して g_Camera.SetProjParams() を設定します。
    次に g_Camera を使ってティーポットをマウスで回転します。
    マウスで回転するプログラムは結構面倒なのですが、g_Camera を使うと g_Camera.SetWindow() を呼び出すだけです。
    マウスの左ドラッグでモデルが回転し、右ドラッグでカメラが回転します。
    HRESULT CALLBACK OnD3D10ResizedSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain,
                    const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
    {
        float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;
        g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1f, 1000.0f );
        g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
    
        return S_OK;
    }
    
  7. OnFrameMove() で g_Camera.FrameMove() を呼び出します。
    void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
    {
        g_Camera.FrameMove( fElapsedTime );
    }
    
  8. MsgProc() で g_Camera.HandleMessages() を呼び出します。
    LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                              bool* pbNoFurtherProcessing, void* pUserContext )
    {
        g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
        return 0;
    }
    

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