長方体を回転しながら描画する

長方体の頂点座標を定義して、回転しながら描画します。

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

プロジェクトの説明

  1. Common のフォルダーと相対的な位置関係にある場所に、フォルダーを作成して下さい。
    詳細は TEXT を表示する を参照して下さい。
  2. vtx[] が長方体の頂点座標と色の定義です。
    連続する12個の三角形(TRIANGLESTRIP)を使って長方体を定義しています。
    g_Camera はカメラの Object 定義です。
    g_matObj には回転座標を設定します。
        /*********************************************/
        /*  長方体を回転しながら描画する    前田 稔  */
        /*********************************************/
        #include "dxstdafx.h"
        #include "resource.h"
    
        //頂点フォーマット
        #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 }};
    
        // Global variables
        CFirstPersonCamera  g_Camera;               // A model viewing camera
        D3DXMATRIXA16       g_matObj;               // World Matrix
        
  3. CALLBACK 関数の宣言です。
    アプリケーションで必要な CALLBACK 関数だけを宣言しています。
        // Forward declarations 
        HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
        void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
        void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
        void    CALLBACK OnDestroyDevice( void* pUserContext );
        
  4. WinMain() で CALLBACK 関数を設定します。
    InitApp() はアプリケーションの初期化ですが、今回はやることがありません。
    DXUTMainLoop() でメッセージループに入ります。
        //★ Win Main
        INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
        {
            DXUTSetCallbackDeviceReset( OnResetDevice );
            DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
            DXUTSetCallbackFrameRender( OnFrameRender );
            DXUTSetCallbackFrameMove( OnFrameMove );
    
            DXUTSetCursorSettings( true, true );
            InitApp();
    
            DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
            DXUTCreateWindow( L"Text3D" );
    
            DXUTMainLoop();
    
            return DXUTGetExitCode();
        }
        
  5. DirectX の主要な処理は CALLBACK 関数で行います。
    OnCreateDevice() はデバイスを生成するときに呼ばれます。
    ここでカメラの座標と向きを設定します。
        HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                        const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
        {
            D3DXMATRIXA16  matWorld;
            D3DXMatrixIdentity( &matWorld );
            pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
    
            // Setup the camera with view & projection matrix
            D3DXVECTOR3 vecEye(0.0f, 0.0f, -40.0f);
            D3DXVECTOR3 vecAt (0.0f, 0.0f, 0.0f);
            g_Camera.SetViewParams( &vecEye, &vecAt );
            float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
            g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 1.0f, 1000.0f );
    
            return S_OK;
        }
        
  6. フレームの設定です。
    D3DXMatrixRotationAxis() でワールド座標を回転します。
        void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
        {
            // Setup five rotation matrices (for rotating text strings)
            D3DXVECTOR3 vAxis(1.0f,0.0f,0.0f);
            //D3DXVECTOR3 vAxis(1.0f,2.0f,0.0f);
            D3DXMatrixRotationAxis( &g_matObj, &vAxis, (float)fTime );
        }
        
  7. Rendering を行う CALLBACK 関数です。
    View 座標と Proj を設定して、WORLD 座標を回転しながら描画します。
    pd3dDevice->Clear() で viewport と Z buffer をクリアします。
    0x00000000 がクリアする色の設定です。
    vtx[] の定義で色が設定されているので、ライティングしないで描画します。
    描画は DrawPrimitiveUP() で連続する12個の三角形を一度に描画します。
        void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
        {
            D3DXMATRIXA16 matView = *g_Camera.GetViewMatrix();
            D3DXMATRIXA16 matProj = *g_Camera.GetProjMatrix();
    
            pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
            pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
    
            // Clear the viewport
            pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
            //pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00004060, 1.0f, 0L );
    
            // Begin the scene 
            if( SUCCEEDED( pd3dDevice->BeginScene() ) )
            {
                pd3dDevice->SetTransform( D3DTS_WORLD, &g_matObj );
                pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);         //ライティングしない
    
                //デバイスに使用する頂点フォーマットをセットする
                pd3dDevice->SetFVF(D3DFVF_VERTEX);
                //ストリームを使わないで直接データを渡して描画する
                pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,12,vtx,sizeof(D3DVERTEX));
    
                DXUT_EndPerfEvent(); // end of demonstration code
    
                // End the scene
                pd3dDevice->EndScene();
            }
        }
        
  8. 今回はリソースを割り当てていないので、開放処理は不要です。
  9. キーの操作です。
    キー 動作
    Alt+Enterフルスクリーン モードとウィンドウ モードを切り替える
    Esc アプリケーションを終了する

【メモ】

フルスクリーンモードに切り替えるとポリゴンの描画が乱れる現象が起こっています。
何度か繰り返すと、うまく描画できることも結構あり、ビデオカードの問題でしょうか?。
リリースモードでビルドすると、大抵はうまく描画できるようです。

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

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

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