Mission6: テクスチャを使ったキャラクタ表示。


【ステップ1 プログラム改造】

Direct3Dでこのテクスチャーを読み込むルーチンを作ります。

【ステップ1−1 画面表示ルーチン】
解説

ワークスペース(左図の部分)から、
d3dmain.cpp をダブルクリックして開きます。

すると画面は、図2の様になったはずです。
図1 ワークスペース


図2 d3dmain.cpp



次に、図8のようにして編集メニューから検索コマンドを選びます。

すると、図9のようなダイアログウィンドウが出てきます、

ここでは、UpdateScreen というキーワードで検索を実行。

図4 検索ウィンドウ
図3 検索コマンド


改造前
void    UpdateScreen()
{
    float    timeElapsed;
    HRESULT    hr;
    if (g_pHighResTimer == NULL)
        return;
    if (0.5 > g_pHighResTimer->GetElapsedTime())
        return;
    timeElapsed=g_pHighResTimer->GetElapsedTimeAndReset();
    // Test the cooperative level to see if it's okay to render
    if( FAILED( hr = g_lpD3DDEV->TestCooperativeLevel() ) )
    {
        // If the device was lost, do not render until we get it back
        if( D3DERR_DEVICELOST == hr )
            return;

        // Check if the device needs to be resized.
        if( D3DERR_DEVICENOTRESET == hr )
        {
            // If we are windowed, read the desktop mode and use the same format for
            // the back buffer
            if( g_bWindowed )
            {
                D3DAdapterInfo* pAdapterInfo = &g_Adapters[g_dwAdapter];
                g_lpD3D->GetAdapterDisplayMode( g_dwAdapter, &pAdapterInfo->d3ddmDesktop );
                g_d3dprm.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format;
            }

            if( FAILED( hr = Resize3DEnvironment() ) )
                return;
        }
        return;
    }

    if (g_bUseDepthBuffer)
        g_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,g_bgColor,1.0f,0);
    else
        g_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET,g_bgColor,1.0f,0);

    g_lpD3DDEV->BeginScene();
    SetDefaultRenderState(g_lpD3DDEV);

    // ※ここを改造

    g_lpD3DDEV->EndScene();

    if (FAILED(g_lpD3DDEV->Present(NULL,NULL,NULL,NULL))){
        Resize3DEnvironment();
    }
}

リスト1a

解説
関数 UpdateScreen は、OnIdle 関数から呼び出している関数で、
I/O入力、座標計算などのアニメーション、あたり判定、画面表示
など(初期化と終了処理を除く)ゲームのメインとなるプログラムを
想定しています。

その為、ゲームのキャラクタの表示ルーチンなどはここに記入すれば
良い事になります。

改造後

void    UpdateScreen()
{
    float    timeElapsed;
    HRESULT    hr;
    if (g_pHighResTimer == NULL)
        return;
    if (0.5 > g_pHighResTimer->GetElapsedTime())
        return;
    timeElapsed=g_pHighResTimer->GetElapsedTimeAndReset();
    // Test the cooperative level to see if it's okay to render
    if( FAILED( hr = g_lpD3DDEV->TestCooperativeLevel() ) )
    {
        // If the device was lost, do not render until we get it back
        if( D3DERR_DEVICELOST == hr )
            return;

        // Check if the device needs to be resized.
        if( D3DERR_DEVICENOTRESET == hr )
        {
            // If we are windowed, read the desktop mode and use the same format for
            // the back buffer
            if( g_bWindowed )
            {
                D3DAdapterInfo* pAdapterInfo = &g_Adapters[g_dwAdapter];
                g_lpD3D->GetAdapterDisplayMode( g_dwAdapter, &pAdapterInfo->d3ddmDesktop );
                g_d3dprm.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format;
            }

            if( FAILED( hr = Resize3DEnvironment() ) )
                return;
        }
        return;
    }

    if (g_bUseDepthBuffer)
        g_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,g_bgColor,1.0f,0);
    else
        g_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET,g_bgColor,1.0f,0);

    g_lpD3DDEV->BeginScene();
    SetDefaultRenderState(g_lpD3DDEV);

    //    描画方法の設定
    
    g_lpD3DDEV->SetRenderState( D3DRS_ALPHABLENDENABLE,   TRUE );
    g_lpD3DDEV->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
    g_lpD3DDEV->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
    if (g_bCanGreaterEqual){
        g_lpD3DDEV->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
        g_lpD3DDEV->SetRenderState( D3DRS_ALPHAREF,        0x08 );
        g_lpD3DDEV->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
    }
    //    アニメーションの為の座標計算
    int    x,y;
    static double d1=0,d2=0;
    d1 += 0.07*timeElapsed;
    d2 += 0.05*timeElapsed;
    if (d1 > (D3DX_PI*2))
        d1 -= D3DX_PI*2;

    if (d2 > (D3DX_PI*2))
        d2 -= D3DX_PI*2;

    y = (int)(100*sin(d1));
    y += 240;
    x = (int)(200*sin(d2));
    x += 320;
    int    sz = 48;
    //    四角形の頂点の設定
    TLVERTEX2D    pV[4];
    float    ru = g_fTexImageWidth;
    float    bv = g_fTexImageHeight;
    pV[0].x = (float)x;pV[0].y=(float)y;pV[0].z=0.0f;pV[0].rhw=1.0f;
    pV[0].tu = 0.0f;pV[0].tv=0.0f;pV[0].color=D3DCOLOR_XRGB(255,255,255);
    pV[1].x = (float)(x + sz);pV[1].y=(float)y;pV[1].z=0.0f;pV[1].rhw=1.0f;
    pV[1].tu = ru;pV[1].tv=0.0f;pV[1].color=D3DCOLOR_XRGB(255,255,255);
    pV[2].x = (float)(x + sz);pV[2].y=(float)(y + sz);pV[2].z=0.0f;pV[2].rhw=1.0f;
    pV[2].tu = ru;pV[2].tv=bv;pV[2].color=D3DCOLOR_XRGB(255,255,255);
    pV[3].x = (float)x;pV[3].y=(float)(y + sz);pV[3].z=0.0f;pV[3].rhw=1.0f;
    pV[3].tu = 0.0f;pV[3].tv=bv;pV[3].color=D3DCOLOR_XRGB(255,255,255);

    //    描画の実行
    g_lpD3DDEV->SetTexture(0,g_pTexture);
    g_lpD3DDEV->SetVertexShader(FVF_TLVERTEX2D);
    g_lpD3DDEV->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,pV,sizeof(TLVERTEX2D));

    g_lpD3DDEV->EndScene();

    if (FAILED(g_lpD3DDEV->Present(NULL,NULL,NULL,NULL))){
        Resize3DEnvironment();
    }
}
リスト1b

解説
リスト1bの明るい部分の内容を追加記入してください。
ここでは、3Dのレンダリングエンジンを設定し、
続いて、アニメーションの為の座標計算を行っています。
最後に、実際のレンダリング(描画)を行っています。

構造体 TLVERTEX2D および、マクロ定数 FVF_TLVERTEX2D は
d3dmain.h の中で宣言されています。(解説はこちら





【ステップ2 実行】

改造し終えたらF5キーを押して実行してみましょう。
図5 実行画面

これでキャラクタが表示できました。

戻る