MyD3D Class でティーポットを描画する

MyD3D Object Class を使うと簡単にティーポットを光源で照らして描画することができます。
DirectX の D3DXCreateTeapot でティーポットメッシュを生成して LPD3DXMESH->DrawSubset で光源で照らして描画します。

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

プログラムの説明

  1. [ファイル] [新規作成] [プロジェクト]から空のプロジェクト(Teapot)を作成して下さい。
    プロジェクト/既存項目の追加からプログラムファイルとヘッダファイルをプロジェクトに追加して下さい。
    myd3d.h と myd3d.cpp は Object Class Library から取得して下さい。
    ファイル名 ファイルの説明
    Teapot.cpp 「プログラムの説明」を参考に作成して下さい
    myd3d.h MyD3D Object Class ヘッダファイル
    myd3d.cpp MyD3D Object Class プログラムファイル
  2. #define と #include と Global Area の定義です。
    *myd3d が MyD3D Object Class の定義です。
    g_hWnd はウインドウのハンドルを保持する領域です。
    g_pDEV は Direct3D のデバイスです。
    g_pMesh はティーポットのオブジェクトです。
    g_bActive はウインドウが Active 状態のフラグです。
    ViewForm は View(カメラ)の座標で、球を正面から写すように -5.0f の距離を置いて配置します。
        #define     NAME       "MyDX9 Teapot"
        #include    "MyD3D.h"
    
        //Global Area
        MyD3D                   *myd3d   = NULL;     // MyD3D Object Class
        HWND                    g_hWnd   = NULL;     // ウインドウ・ハンドル
    
        //Direct3D Area
        LPDIRECT3DDEVICE9       g_pDEV   = NULL;
        LPD3DXMESH              g_pMesh  = NULL;
        bool                    g_bActive= false;   // アクティブ状態
        D3DXVECTOR3             ViewForm(0.0f,0.0f,-5.0f);
        
  3. WinMain() 関数です。
    InitGraphics() でグラフィックスを初期化して、ティーポットの生成とマテリアルの設定を行います。
    メッセージループでは Draw() を呼び出してティーポットを描画します。
        int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
        {   MSG     msg;
    
                :
    
            if (FAILED(InitGraphics()))    return FALSE;
    
            ShowWindow(g_hWnd,SW_SHOWDEFAULT);
            UpdateWindow(g_hWnd);
            ZeroMemory(&msg,sizeof(msg));
            while(msg.message!=WM_QUIT)
            {   if (PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
                {   TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                else    Draw();
            }
            Cleanup();
            UnregisterClass(NAME,wc.hInstance);
            return 0;
        }
        
  4. DirectX Graphics の初期化です。
    new MyD3D(g_hWnd) で Object Class をインスタンス化します。
    InitD3D(&g_pDEV) で DirectX のデバイスを取得します。
    D3DXCreateTeapot() でティーポットメッシュを生成します。
    SetMaterial() でティーポットにディフェーズ色を設定します。
    0.8f, 0.7f, 0.0f は順に「赤緑青」の色レベルです。
    ティーポットの色の設定は SetLight() で光源に色を設定する方法もあります。
    SetLight() でライトを設定します。
    Material や Light の状態を変えながら描画するときは SetupMatrices() 関数の中で設定して下さい。
    マテリアルの詳しい説明は 球をライトで照らして View 座標を回転する を参照して下さい。
        HRESULT InitGraphics(void)
        {
            myd3d= new MyD3D(g_hWnd);
            myd3d->InitD3D(&g_pDEV);
            //ティーポットの生成
            D3DXCreateTeapot(g_pDEV,&g_pMesh,NULL);
            myd3d->SetMaterial(0.8f,0.6f,0.0f);
            myd3d->SetLight();
            return  S_OK;
        }
        
  5. メッシュを描画する関数です。
    デバイスが取得されていないときと、ウインドウが Active で無いときはリターンします。
    Clear() で画面をクリアします。
    D3DCOLOR_XRGB(0,0,150) が背景の色です。
    BeginScene() でシーンの開始を設定します。
    SetupMatrices() は描画環境を設定する関数です。
    g_pMesh->DrawSubset(0) でティーポットのメッシュを描画します。
    EndScene() でシーンの処理を終了します。
    Present() で作成したシーンを描画します。
        void Draw(void)
        {
            if (!g_pDEV || !g_bActive)  return;
            g_pDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,150),1.0f,0);
            if (SUCCEEDED(g_pDEV->BeginScene()))
            {   //描画環境の設定
                SetupMatrices();
                g_pMesh->DrawSubset(0);
                g_pDEV->EndScene();
            }
            g_pDEV->Present(NULL,NULL,NULL,NULL);
        }
        
  6. 描画環境を設定する関数です。
    GetClientRect() で Window Size を取得して、アスペクト比を保ちます。
    D3DXMatrixRotationY() でY軸を中心にして World 座標を回転します。
    timeGetTime()/1000.0f で回転速度が決まります。
    スペックの低いマシンで回転しないときは、この値を2桁ぐらい小さくして試してみて下さい。
    SetTransform() で World 座標を設定します。
    D3DXMatrixLookAtLH() で View 座標を計算して SetTransform() で設定します。
    D3DXMatrixPerspectiveFovLH() で透視変換の設定をします。
    g_pDEV->SetRenderState(D3DRS_AMBIENT,0x00080808) は環境光の設定です。
    ティーポットを明るくするときは 0x00FFFFFF などを使って下さい。
        void  SetupMatrices(void)
        {   RECT            rect;
            D3DXMATRIX      matWorld;
            D3DXMATRIX      matView;
            D3DXMATRIX      matProj;
    
            GetClientRect(g_hWnd,&rect);
            //World 座標をY軸を中心に自動回転
            D3DXMatrixRotationY(&matWorld,timeGetTime()/1000.0f);
            g_pDEV->SetTransform(D3DTS_WORLD,&matWorld);
            //View 座標の設定
            D3DXMatrixLookAtLH(&matView,&ViewForm,
                               &D3DXVECTOR3(0.0f,0.0f,0.0f),&D3DXVECTOR3(0.0f,1.0f,0.0f));
            g_pDEV->SetTransform(D3DTS_VIEW,&matView);
            //透視変換の設定
            D3DXMatrixPerspectiveFovLH(&matProj,D3DXToRadian(45.0f),(float)rect.right/(float)rect.bottom,1,50);
            g_pDEV->SetTransform(D3DTS_PROJECTION,&matProj);
            g_pDEV->SetRenderState(D3DRS_AMBIENT,0x00080808);
        }
        
  7. オブジェクトを開放する関数です。
    取得したインターフェースやオブジェクトは必ず開放して下さい。
        void Cleanup(void)
        {
            SAFE_RELEASE(g_pMesh);
            SAFE_DELETE(myd3d);
        }
        
  8. CALLBACK 関数です。
    WM_ACTIVATE: で g_bActive フラグを設定します。
    [ESCAPE キー] でプログラムを終了します。
        LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam)
        {
            switch(msg)
            {   case WM_ACTIVATE:
                    g_bActive= (LOWORD(wParam)!=0);
                    break;
                case WM_SETCURSOR:          // カーソルを非表示
                    SetCursor(NULL);
                    return TRUE;
                case WM_KEYDOWN:
                    switch(wParam)
                    {   case VK_ESCAPE:     // [ESCAPE]キーでウインドウを閉じる
                            PostMessage(hWnd,WM_CLOSE,0,0);
                            break;
                    }
                    break;
                case WM_CLOSE:
                case WM_DESTROY:
                    PostQuitMessage(0);
                    return 0L;
            }
            return DefWindowProc(hWnd,msg,wParam,lParam);
        }
        

超初心者の方のために全ソースコードを掲載します。 (^_^;)
全ソースコード

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

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

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