虎のモデルを表示

DirectX の D3DXLoadMeshFromX でサンプルモデルとして格納されている虎のメッシュ(X-FILE)を表示します。
Xファイルを確認するには、次のプログラムを起動して下さい。
DirectX の Version によって格納されているフォルダーが異なりますが名前は同じです。
C:\DX90SDK\Utilities\mview.exe
C:\DXSDK\Bin\DXUtils\mview.exe
2011年11月ごろから X-FILE のダブルクリックで Mview.exe が起動出来なくなりました。
仕方が無いので自前で Mview を作成する を開発しました。

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

プログラムの説明

  1. プライベートライブラリを使わないで DirectX9 の標準ライブラリだけで作成します。
    プロジェクトを作成して、次のファイルをフォルダーに格納して下さい。
    Tiger.x と Tiger.bmp は DirectX のサンプルデータとして添付されています。
    ファイル名 ファイルの説明
    Tiger.cpp 説明を参考にして作成して下さい
    Tiger.x 虎のモデルのXファイル
    Tiger.bmp 虎のテクスチャファイル
    見つからないときは下記のページからダウンロードして下さい。
    こちらは Tiger.bmp に代えて、Tiger.jpg を使っています。
    X-FILE Loader_3
  2. 必要なライブラリは #pragma でリンクしています。
    g_pMesh は tiger.x の Mesh のオブジェクトです。
    g_pMeshMaterials は tiger.x の Materials です。
    g_pMeshTextures は tiger.x の Textures です。
    g_dwNumMaterials は X-File に格納されている「属性テーブル」のエントリ数?が格納されます。
        #include <Windows.h>
        #include <mmsystem.h>
        #include <d3dx9.h>
        #include <strsafe.h>
    
        #pragma comment(lib,"d3dxof.lib")
        #pragma comment(lib,"dxguid.lib")
        #pragma comment(lib,"d3dx9d.lib")
        #pragma comment(lib,"d3d9.lib")
        #pragma comment(lib,"winmm.lib")
    
        // Global variables
        LPDIRECT3D9             g_pD3D           = NULL; // Used to create the D3DDevice
        LPDIRECT3DDEVICE9       g_pd3dDevice     = NULL; // Our rendering device
    
        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
        
  3. WinMain() ではウインドウを生成して、InitD3D() で DirectX3D を初期化します。
    次に InitGeometry() で tiger.x を入力して、描画環境の初期化を行います。
    初期化が終われば、メッセージループの中から Render() でモデルを描画します。
        HWND hWnd = CreateWindow("D3D Tutorial","D3D Tutorial 06: Meshes", 
                                  WS_OVERLAPPEDWINDOW,100,100,800,800,
                                  GetDesktopWindow(),NULL,wc.hInstance,NULL);
        if(SUCCEEDED(InitD3D(hWnd)))
        {   if(SUCCEEDED(InitGeometry()))
            {   ShowWindow(hWnd,SW_SHOWDEFAULT);
                UpdateWindow(hWnd);
                MSG msg;
                ZeroMemory(&msg,sizeof(msg));
                while(msg.message!=WM_QUIT)
                {   if(PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
                    {   TranslateMessage(&msg);
                        DispatchMessage(&msg);
                    }
                    else    Render();
                }
            }
        }
        
  4. DirectX3D を初期化する関数は、何時もと同じです。
    デバイスが取得できたら D3DRS_CULLMODE を D3DCULL_NONE に、D3DRS_LIGHTING を FALSE に設定して下さい。
    Tiger.x には法線ベクトルが設定されていないようで、ライトを設定すると真っ黒になります。
        HRESULT InitD3D( HWND hWnd )
        {       :
            g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
            g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
            return S_OK;
        }
        
  5. 描画環境の初期化を行う関数です。
    D3DXLoadMeshFromX() で Tiger.x を入力して Mesh の Object を生成します。
    次に Tiger.x の Materials と Textures を生成して描画の準備を整えます。
        HRESULT InitGeometry()
        {   LPD3DXBUFFER pD3DXMtrlBuffer;
    
            if(FAILED(D3DXLoadMeshFromX("Tiger.x",D3DXMESH_SYSTEMMEM,g_pd3dDevice,NULL,
                                         &pD3DXMtrlBuffer,NULL,&g_dwNumMaterials,&g_pMesh)))
            {   MessageBox(NULL,"Could not find tiger.x","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 && 
                   lstrlen(d3dxMaterials[i].pTextureFilename)>0)
                {   if(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,
                              d3dxMaterials[i].pTextureFilename,&g_pMeshTextures[i])))
                        MessageBox(NULL,"Could not find texture map","Meshes.exe",MB_OK);
                }
            }
            pD3DXMtrlBuffer->Release();
            return S_OK;
        }
        
  6. メッシュ(Tiger.x) を描画する関数です。
    SetupMatrices() で描画環境を設定します。
    Material と Texture を設定して DrawSubset() で虎のメッシュを描画します。
        VOID Render()
        {
            g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 
                                D3DCOLOR_XRGB(0,0,255),1.0f,0);
            if(SUCCEEDED(g_pd3dDevice->BeginScene()))
            {   SetupMatrices();
                for(DWORD i=0; i<g_dwNumMaterials; i++)
                {   g_pd3dDevice->SetMaterial(&g_pMeshMaterials[i]);
                    g_pd3dDevice->SetTexture(0,g_pMeshTextures[i]);
                    g_pMesh->DrawSubset(i);
                }
                g_pd3dDevice->EndScene();
            }
            g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
        }
        
  7. 描画環境を設定する関数です。
    D3DXMatrixRotationY() でY軸を中心に座標を回転しています。
    D3DXMatrixLookAtLH() で View 座標を設定します。
    D3DXMatrixPerspectiveFovLH() で透視変換の設定をします。
    D3DRS_LIGHTING を FALSE に設定しているので、マテリアルの設定は行いません。
        VOID SetupMatrices()
        {
            D3DXMATRIXA16 matWorld;
            D3DXMatrixRotationY(&matWorld,timeGetTime()/1000.0f);
            g_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);
            g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
            D3DXMATRIXA16 matProj;
            D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
            g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
        }
        
  8. オブジェクトを開放する関数です。
    取得したオブジェクトは必ず開放して下さい。
        VOID Cleanup()
        {
            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();
            if(g_pd3dDevice!=NULL)  g_pd3dDevice->Release();
            if(g_pD3D!=NULL)        g_pD3D->Release();
        }
        

【課題】

ライトとマテリアルを設定して虎のメッシュを描画して下さい。
Tiger.x には法線ベクトルが設定されていないらしく、そのままでは真っ黒になります。
ライトで照らして立体的に描画するには、法線ベクトルを設定しなければなりません。

超初心者の方のために全ソースコードを掲載します。 (^_^;)
こちらは MyD3D Object Class を使っています。
全ソースコード

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

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

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