Frame Rate を設定する

Frame Rate を設定してティーポットを回転しながら描画します。

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

プログラムの説明

  1. 1秒間に描画するフレーム数を FPS(frames per second)と言います。
    コンシューマゲームでは、垂直同期信号に合わせてフレームを描画する方法などが用いられますが、 Windows の環境ではマシンの性能や設定により同期信号の周波数が異なります。
    そこでマシンによる違いが出ないように、タイマーを使って FPS を揃えます。
    タイマー割り込みを16ミリ秒(1/60秒)ごとに設定して、描画フラグをセットします。
    1/60 秒は「チラツキを感じさせないで画面を切り替える」間隔で、テレビ画像と同じです。
    ティーポットの3Dモデルを描画するプログラムを材材にして Frame Rate を設定します。
    3Dモデルの描画は別のページに譲るとして、 Frame Rate の設定に的を絞って参照して下さい。
  2. フレームレートに関係する設定と領域の定義です。
    mmsystem.h をインクルードして winmm.lib をリンクして下さい。
    TimerID はタイマーのIDです。
    FpsFlag は描画フラフで、この値が true に設定された時に描画します。
        #include    <mmsystem.h>
    
        #pragma once
        #pragma comment(lib,"winmm.lib")
    
        int         TimerID;    // タイマーのID
        bool        FpsFlag;    // 描画フラグ
        
  3. WinMain() 関数で Direct3D の初期化が終わったあとで、16ミリ秒(1/60秒)ごとに割り込みタイマーを設定します。
    timeSetEvent() が割り込みタイマーを設定する関数で、16 が割り込みの間隔で、TimerProc がタイマー割り込みで起動される CALLBACK 関数です。
    プログラムを終了する前に タイマーを解除して下さい。
            ・・・
        if (FAILED(InitDevices()))    return FALSE;
    
        // FPS を16ミリ秒(1/60秒)に設定
        timeBeginPeriod(1);             // 分解能を設定
        TimerID = timeSetEvent(16,1,TimerProc,0,TIME_PERIODIC);
        if (!TimerID)	return FALSE;
            ・・・
        timeKillEvent(TimerID);         // タイマーを解除する
        timeEndPeriod(1);               // 分解能を元に戻す
            ・・・
        
  4. TimerProc() 関数では16ミリ秒ごとにフラグを設定するだけです。
        void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser,DWORD dw1, DWORD dw2)
        {
            FpsFlag = true;
        }
        
  5. Draw() で FpsFlag が true のときにティーポットを回転しながら描画します。
    SetupMatrices() でワールド座標を回転しながら DrawSubset() で描画します。
        void Draw(void)
        {
            if (FpsFlag)
            {   FpsFlag = false;
                //黒で塗りつぶして消去
                g_pDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
                if (SUCCEEDED(g_pDEV->BeginScene()))
                {   //描画環境の設定
                    SetupMatrices();
                    g_pMesh->DrawSubset(0);
                    g_pDEV->EndScene();
                }
                g_pDEV->Present(NULL,NULL,NULL,NULL);
            }
        }
        
  6. ティーポットのワールド座標を回転する SetupMatrices() です。
        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);
        }
        

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