View 座標を回転しながら描画する

長方体に色を設定して、DirectX の SetTransform(D3DTS_VIEW,&matView) で自動的に View 座標を回転しながら描画します。

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

プログラムの説明

  1. 空の新規プロジェクト(ViewRot)を作成して下さい。
  2. #include と #pragma と Direct3D の領域です。
    timeGetTime() で時刻を取得するので mmsystem.h をインクリードして winmm.lib をリンクして下さい。
    g_pD3D は Direct3D のオブジェクトです。
    g_p3DDev は Direct3D のデバイスです。
        /********************************************************/
        /*  View 座標を回転しながら長方体を描画する    前田 稔  */
        /********************************************************/
        #define     NAME        "View Rotate"
        #include    <d3d9.h>
        #include    <d3dx9.h>
        #include    <mmsystem.h>
    
        #pragma once
        #pragma comment(lib,"dxguid.lib")
        #pragma comment(lib,"d3d9.lib")
        #pragma comment(lib,"d3dx9.lib")
        #pragma comment(lib,"winmm.lib")
    
        #define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
    
        //DirectXオブジェクト
        LPDIRECT3D9             g_pD3D;
        LPDIRECT3DDEVICE9       g_p3DDev;
        
  3. 頂点フォーマットの設定です。
    立方体の6個の面を三角形を組み合わせた12個の連続する TRIANGLESTRIP で定義します。
    最初は、各面を三角形を組み合わせた矩形として定義していたのですが、生徒が立方体を12個の TRIANGLESTRIP で定義する方法を見つけてくれました。
    各面ごとに色を設定することは出来ないのですが、こちらの方がソースコードも少なくて合理的です。
        //頂点フォーマット
        #define D3DFVF_VERTEX  (D3DFVF_XYZ | D3DFVF_DIFFUSE)
        typedef struct _D3DVERTEX_
        {   float   x,y,z;
            DWORD   color;
        }   D3DVERTEX;
    
        D3DVERTEX vtx[]={
        { -10,  7,  5, 0xffff8080 },
        {  10, -7,  5, 0xffff8080 },
        {  10,  7,  5, 0xffff8080 },
        {  10,  7, -5, 0xffffff80 },
        { -10,  7,  5, 0xffffff80 },
        { -10,  7, -5, 0xffffff80 },
        { -10, -7, -5, 0xff80ff80 },
        {  10,  7, -5, 0xff80ff80 },
        {  10, -7, -5, 0xff80ff80 },
        {  10, -7,  5, 0xff80ffff },
        { -10, -7, -5, 0xff80ffff },
        { -10, -7,  5, 0xff80ffff },
        { -10,  7,  5, 0xff8080ff },
        {  10, -7,  5, 0xff8080ff }};
        
  4. WinMain() 関数です。
    参照しないパラメータ名は省略しています。
    Init3DDev() 関数でグラフィックスを初期化します。
    詳細は Back Buffer を取得して円を描画する を参照して下さい。
    Draw() 関数で立方体を描画します。
        int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
        {   MSG     msg;
    
            WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,MainWndProc,0L,0L,hInst,
                              NULL,NULL,NULL,NULL,NAME,NULL };
            if (RegisterClassEx(&wc)==0)    return FALSE;
            HWND  hWnd = CreateWindowEx(0,NAME,NAME,WS_OVERLAPPEDWINDOW,
                                        0,0,640,480,NULL,NULL,hInst,NULL);
            if (FAILED(Init3DDev(hWnd,&g_pD3D,&g_p3DDev)))    return FALSE;
    
            ShowWindow(hWnd,SW_SHOWDEFAULT);
            UpdateWindow(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;
        }
        
  5. 長方体を描画する Draw(void) 関数です。
    Clear() で画面をクリアします。
    BeginScene() でシーンの開始を設定します。
    SetupMatrices() は描画環境を設定する関数です。
    SetFVF() で頂点フォーマットをセットします。
    DrawPrimitiveUP() で12個の三角形(立方体)を描画します。
    EndScene() でシーンの処理を終了します。
    Present() で作成したシーンを描画します。
        void Draw(void)
        {
            if (!g_pD3D || !g_p3DDev)   return;
            //黒で塗りつぶして消去
            g_p3DDev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0,0);
            //描画の開始
            g_p3DDev->BeginScene();
            //描画環境の設定
            SetupMatrices();
            //デバイスに使用する頂点フォーマットをセットする
            g_p3DDev->SetFVF(D3DFVF_VERTEX);
            //ストリームを使わないで直接データを渡して描画する
            g_p3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,12,vtx,sizeof(D3DVERTEX));
            g_p3DDev->EndScene();
            g_p3DDev->Present(NULL,NULL,NULL,NULL);
        }
        
  6. 描画環境を設定する関数です。
    View 座標を、時刻を取得して自動的に回転させています。
    D3DXMatrixTranslation() の 0,0,50 がカメラの元の座標で、w を掛けて回転座標を求めます。
    このままではワールド座標の回転と同じように見えますが、ライティングすると違いは一目瞭然です。
        void  SetupMatrices(void)
        {   D3DXMATRIX      matView;
            D3DXMATRIX      matProj;
            D3DXMATRIX      w;
    
            //View 座標の回転
            D3DXMatrixRotationY(&w,timeGetTime()/1000.0f);
            //D3DXMatrixRotationX(&w,timeGetTime()/1000.0f);
            D3DXMatrixTranslation(&matView,0,0,50);
            matView= w*matView;
            g_p3DDev->SetTransform(D3DTS_VIEW,&matView);
            //透視変換の設定
            D3DXMatrixPerspectiveFovLH(&matProj,D3DXToRadian(45.0),1.0f,0,100);
            g_p3DDev->SetTransform(D3DTS_PROJECTION,&matProj);
            //描画設定
            g_p3DDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);   //反時計回りの面を消去
            g_p3DDev->SetRenderState(D3DRS_LIGHTING,FALSE);         //ライティングしない
            g_p3DDev->SetRenderState(D3DRS_ZENABLE,D3DZB_FALSE);    //Zバッファ使わない
        }
        

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

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

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