cone.x のモデルを回転しながら描画する

August2007 DirectX9 で cone.x のモデルを回転しながら描画します。

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

プロジェクトの作成

  1. Template のプロジェクトをコピーして、フォルダーの名前を Cone に変更して下さい。
    プロジェクトのフォルダーに Cone.x を格納して下さい。
    Cone.x は「directx10/X-FILE(Cone.x) を参照して頂点データを定義する」から取得することが出来ます。
  2. g_pMesh は Cone.x のメッシュを格納する領域です。
    g_pMeshMaterials はメッシュのマテリアルを設定する領域です。
    g_pMeshTextures はメッシュのテクスチャを設定する領域です。
    material は描画環境のマテリアルを設定する領域です。
    light はメッシュを照らすライトを設定する領域です。
    LPD3DXMESH              g_pMesh          = NULL; // Our mesh object in sysmem
    D3DMATERIAL9*           g_pMeshMaterials = NULL; // Materials for our mesh
    LPDIRECT3DTEXTURE9*     g_pMeshTextures  = NULL; // Textures for our mesh
    DWORD                   g_dwNumMaterials = 0L;   // Number of mesh materials
    D3DMATERIAL9            material;
    D3DLIGHT9               light;
    
  3. OnD3D9CreateDevice() で Cone.x を入力して g_pMesh に格納します。
    Cone.x のモデルにはページ先頭の画像のように、ポリゴンに色が設定されています。
    HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
    {   LPD3DXBUFFER pD3DXMtrlBuffer;
        WCHAR *wszName;
        WCHAR wszBuf[MAX_PATH];
        wszName = wszBuf;
    
        if (FAILED(D3DXLoadMeshFromX(L"Cone.x",D3DXMESH_SYSTEMMEM,pd3dDevice,NULL,
                                    &pD3DXMtrlBuffer,NULL,&g_dwNumMaterials,&g_pMesh)))
        {   MessageBox(NULL,L"Could not find Cone.x",L"Meshes.exe",MB_OK);
            return E_FAIL;
        }
        D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
        g_pMeshMaterials= new D3DMATERIAL9[g_dwNumMaterials];
        if(g_pMeshMaterials==NULL)  return E_OUTOFMEMORY;
        g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
        if(g_pMeshTextures==NULL)   return E_OUTOFMEMORY;
        for(DWORD i=0; i<g_dwNumMaterials; i++)
        {   g_pMeshMaterials[i]= d3dxMaterials[i].MatD3D;
            g_pMeshTextures[i] = NULL;
            if (d3dxMaterials[i].pTextureFilename!=NULL)
            {   MultiByteToWideChar( CP_ACP, 0, d3dxMaterials[i].pTextureFilename, -1, wszBuf, MAX_PATH );
                if (wszBuf[0]!=NULL)
                {   if(FAILED(D3DXCreateTextureFromFile(pd3dDevice,wszName,&g_pMeshTextures[i])))
                        MessageBox(NULL,L"Could not find texture map",L"Meshes.exe",MB_OK);
                }
            }
        }
        pD3DXMtrlBuffer->Release();
        //初期マテリアルの設定
        material.Diffuse.r= material.Diffuse.g= material.Diffuse.b= 1.0f;
        material.Ambient.r= material.Ambient.g= material.Ambient.b= 0.5f;
        material.Specular.r= material.Specular.g= material.Specular.b= 0.0f;
        material.Emissive.r= material.Emissive.g= material.Emissive.b= 0.0f;
        material.Power= 0;
        //光源の作成
        ZeroMemory(&light,sizeof(D3DLIGHT9));
        light.Type = D3DLIGHT_DIRECTIONAL;
        light.Diffuse.r= light.Diffuse.g= light.Diffuse.b= 1.0f;
        light.Specular.r= light.Specular.g= light.Specular.b= 0.2f;
        light.Ambient.r= light.Ambient.g= light.Ambient.b= 0.5f;
        light.Direction = D3DXVECTOR3(10,-20,10);
        return S_OK;
    }
    
  4. OnD3D9FrameRender() でメッシュを描画します。
    メッシュの回転とマテリアルと光源の設定は SetupMatrices() 関数で行います。
    void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
    {
        HRESULT hr;
    
        // Clear the render target and the zbuffer 
        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 150, 200, 200), 1.0f, 0) );
    
        // Render the scene
        if( SUCCEEDED( pd3dDevice->BeginScene() ) )
        {   SetupMatrices(pd3dDevice);
            for(DWORD i=0; i<g_dwNumMaterials; i++)
            {   pd3dDevice->SetMaterial(&g_pMeshMaterials[i]);
                pd3dDevice->SetTexture(0,g_pMeshTextures[i]);
                g_pMesh->DrawSubset(i);
            }
            pd3dDevice->EndScene();
        }
        pd3dDevice->Present(NULL,NULL,NULL,NULL);
    }
    
  5. メッシュの回転とマテリアルと光源の設定を行う SetupMatrices() 関数です。
    回転の速度は timeGetTime()/1000.0f で調整して下さい。
    VOID SetupMatrices( IDirect3DDevice9* pd3dDevice )
    {
        D3DXMATRIXA16 matWorld;
        D3DXMatrixRotationY(&matWorld,timeGetTime()/1000.0f);
        pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);
        D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
        D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
        D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
        D3DXMATRIXA16 matView;
        D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);
        pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
        D3DXMATRIXA16 matProj;
        D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
        pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
    
        pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);     //カリングを行う
        pd3dDevice->SetRenderState(D3DRS_LIGHTING,TRUE);            //ライティングする
    
        pd3dDevice->SetLight(0,&light);
        pd3dDevice->LightEnable(0,TRUE);
        pd3dDevice->SetMaterial(&material);
    }
    
  6. OnD3D9DestroyDevice() でメッシュを開放します。
    void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
    {
        if(g_pMeshMaterials!=NULL)  delete[] g_pMeshMaterials;
        if(g_pMeshTextures)
        {   for( DWORD i=0; i<g_dwNumMaterials; i++)
            {   if(g_pMeshTextures[i])  g_pMeshTextures[i]->Release();
            }
            delete[] g_pMeshTextures;
        }
        if(g_pMesh!=NULL)       g_pMesh->Release();
    }
    
  7. あとは Template で作成したソースコードのままです。

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

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

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