電腦遊戲製作開發設計論壇 首頁 電腦遊戲製作開發設計論壇
任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入 

Google
[範例] Direct3D9 - Mesh 動態模型
前往頁面 1, 2  下一頁
 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫
上一篇主題 :: 下一篇主題  
發表人 內容
npcgamer
時常出沒的會員


註冊時間: 2007-11-02
文章: 47

3.00 果凍幣

發表發表於: 2008-3-29, PM 3:28 星期六    文章主題: [範例] Direct3D9 - Mesh 動態模型 引言回覆

【附件】http://blog.yam.com/npcgamer/article/14468811
--------------------------------------------------------------------------------------------------
程式碼是從 DirectX 範例 SkinedMesh 拷貝過來的,並刪掉 Skin Info 的部分,故不能處理有 SkinMesh 的 DirectX X-File。


回頂端
檢視會員個人資料 發送私人訊息
mirror
散播福音的祭司


註冊時間: 2007-07-27
文章: 174

828.60 果凍幣

發表發表於: 2008-3-29, PM 7:42 星期六    文章主題: Re: [範例] Direct3D9 - Mesh 動態模型 引言回覆

其實跟我預期的結果不太一樣
我轉另一組檔案跑出來的結果是一樣的
但預期的要可以跑步
目前我想可能是骨架跟網格未綁定的關係
還在研究要怎麼綁定骨架跟網格
回頂端
檢視會員個人資料 發送私人訊息
npcgamer
時常出沒的會員


註冊時間: 2007-11-02
文章: 47

3.00 果凍幣

發表發表於: 2008-3-30, AM 8:56 星期日    文章主題: 引言回覆

【附件】http://blog.yam.com/npcgamer/article/14480496
---------------------------------------------------------------------------------------------------------
程式碼是從 DirectX 範例 SkinnedMesh 拷貝過來的,使用 Fixed Function non-indexed Skinning 方法處理 Skin。


回頂端
檢視會員個人資料 發送私人訊息
mirror
散播福音的祭司


註冊時間: 2007-07-27
文章: 174

828.60 果凍幣

發表發表於: 2008-3-31, AM 2:56 星期一    文章主題: Re: [範例] Direct3D9 - Mesh 動態模型 引言回覆

我把你的程式碼,其中一段改成這樣
(新做的模型)
代碼:

  // 描繪 模型
  {
    static DWORD LastTime = timeGetTime();
    DWORD CurrentTime;
    double Time;

    CurrentTime = timeGetTime();
    Time = double(CurrentTime - LastTime) / 1000;
    LastTime = CurrentTime;

   LPCSTR cString[]={
      "stand",
      "run",
      "ac"
   };
      LPD3DXANIMATIONSET ppAnimSet=NULL;

    if (Mesh.pAnimationContainer != NULL)
    {
      //Mesh.pAnimationContainer->ResetTime();
      
      if(FAILED(Mesh.pAnimationContainer->GetAnimationSetByName(cString[1],&ppAnimSet))) //用名稱決定動畫編號
         return;

     Mesh.pAnimationContainer->SetTrackAnimationSet(0,ppAnimSet);
      Mesh.pAnimationContainer->AdvanceTime(Time, NULL);
    }

    Mesh.Draw();


之後就可以依自己喜好播放動畫了
若你不能下載新做的模型的話
等你上線我再傳給你
回頂端
檢視會員個人資料 發送私人訊息
mirror
散播福音的祭司


註冊時間: 2007-07-27
文章: 174

828.60 果凍幣

發表發表於: 2008-3-31, AM 6:25 星期一    文章主題: Re: [範例] Direct3D9 - Mesh 動態模型 引言回覆

若是使用GetAnimationSet就是直接索引取動畫
就是用1.2.3之類的數字,決定播放的是哪一組動畫
回頂端
檢視會員個人資料 發送私人訊息
Zero
偶而上來逛逛的過客


註冊時間: 2009-01-04
文章: 10

0.00 果凍幣

發表發表於: 2009-1-10, AM 12:37 星期六    文章主題: Re: [範例] Direct3D9 - Mesh 動態模型 引言回覆

mirror 寫到:
我把你的程式碼,其中一段改成這樣
(新做的模型)
代碼:

  // 描繪 模型
  {
    static DWORD LastTime = timeGetTime();
    DWORD CurrentTime;
    double Time;

    CurrentTime = timeGetTime();
    Time = double(CurrentTime - LastTime) / 1000;
    LastTime = CurrentTime;

   LPCSTR cString[]={
      "stand",
      "run",
      "ac"
   };
      LPD3DXANIMATIONSET ppAnimSet=NULL;

    if (Mesh.pAnimationContainer != NULL)
    {
      //Mesh.pAnimationContainer->ResetTime();
      
      if(FAILED(Mesh.pAnimationContainer->GetAnimationSetByName(cString[1],&ppAnimSet))) //用名稱決定動畫編號
         return;

     Mesh.pAnimationContainer->SetTrackAnimationSet(0,ppAnimSet);
      Mesh.pAnimationContainer->AdvanceTime(Time, NULL);
    }

    Mesh.Draw();


之後就可以依自己喜好播放動畫了
若你不能下載新做的模型的話
等你上線我再傳給你





請教各位先進:
小弟使用各位先進所提供的範例,以成功載入了模型,但由於小弟使用不同版本的DirectX的關係,玫於沒有GetAnimationSetByName這個函式可以使用,所以
小弟改用GetAnimationSet這個函式,但索引使用0,人物不會動,使用1人物不見了,
不知道是什麼原因,不知道各位先進可否教小弟,不使用GetAnimationSetByName這個函式,但也能成功的讓人物動作嗎?因為小弟不想更換DirectX的版本

請各位先進,教教小弟,謝謝感激不盡,謝謝
回頂端
檢視會員個人資料 發送私人訊息
Zero
偶而上來逛逛的過客


註冊時間: 2009-01-04
文章: 10

0.00 果凍幣

發表發表於: 2009-1-10, AM 1:04 星期六    文章主題: 引言回覆

請教各位先進:
不好意思各位先進,小弟剛才亂改程式測試,小弟發現,人物好像有在斗動,但是速度很快,小弟不知道是什麼原因,以下是小弟在描繪模型的程式碼?,完全是依造先進所寫的方式,袛有改用GetAnimationSet這個函式,不知道各位先進能不能幫小弟看看是那裡有問題,謝謝,感激不盡,謝謝


代碼:
// 描繪 模型
  {
    static DWORD LastTime = timeGetTime();
    DWORD CurrentTime;
    double Time;

    CurrentTime = timeGetTime();
    Time = double(CurrentTime - LastTime) / 1000;
    LastTime = CurrentTime;

    LPCSTR cString[]={
      "stand",
      "run",
      "ac"
   };

   /*
    if (Mesh.pAnimationContainer != NULL)
    {
      //Mesh.pAnimationContainer->ResetTime();
      //Mesh.pAnimationContainer->AdvanceTime(Time, NULL);
     Mesh.pAnimationContainer->SetTime( Time );
    }
   */

   LPD3DXANIMATIONSET ppAnimSet=NULL;

    if (Mesh.pAnimationContainer != NULL)
    {
      //Mesh.pAnimationContainer->ResetTime();
       
      //if(FAILED(Mesh.pAnimationContainer->GetAnimationSetByName(cString[1],&ppAnimSet))) //用名稱決定動畫編號
      //   return;

     if(FAILED(Mesh.pAnimationContainer->GetAnimationSet(0,&ppAnimSet))) //用名稱決定動畫編號
         return;

     Mesh.pAnimationContainer->SetTrackAnimationSet(0,ppAnimSet);
      Mesh.pAnimationContainer->SetTime(Time);
    }


    Mesh.Draw();
  }
回頂端
檢視會員個人資料 發送私人訊息
mirror
散播福音的祭司


註冊時間: 2007-07-27
文章: 174

828.60 果凍幣

發表發表於: 2009-1-10, PM 5:07 星期六    文章主題: 引言回覆

Zero 寫到:
請教各位先進:
不好意思各位先進,小弟剛才亂改程式測試,小弟發現,人物好像有在斗動,但是速度很快,小弟不知道是什麼原因,以下是小弟在描繪模型的程式碼?,完全是依造先進所寫的方式,袛有改用GetAnimationSet這個函式,不知道各位先進能不能幫小弟看看是那裡有問題,謝謝,感激不盡,謝謝


先看你的模型動畫用了多少格
再用Time去控制
Time是控制整個動畫速度的
回頂端
檢視會員個人資料 發送私人訊息
Zero
偶而上來逛逛的過客


註冊時間: 2009-01-04
文章: 10

0.00 果凍幣

發表發表於: 2009-1-11, PM 2:10 星期日    文章主題: 引言回覆

mirror 寫到:
Zero 寫到:
請教各位先進:
不好意思各位先進,小弟剛才亂改程式測試,小弟發現,人物好像有在斗動,但是速度很快,小弟不知道是什麼原因,以下是小弟在描繪模型的程式碼?,完全是依造先進所寫的方式,袛有改用GetAnimationSet這個函式,不知道各位先進能不能幫小弟看看是那裡有問題,謝謝,感激不盡,謝謝


先看你的模型動畫用了多少格
再用Time去控制
Time是控制整個動畫速度的



感謝mirror這位先進的回覆:
請問先進小弟要如何的得知模型動畫用了多少格呢?小弟是使用開npcgamer先進的人物走動模型來測試的,所以不知要如何得知模型使用了多少畫格

小弟有去修改Time = double(CurrentTime - LastTime) / 1000;這一行程式碼的1000這個值可是不管這麼改,動作就是不會順暢的走動,都是抖動的很利害的動作,完全不會像是使用MeshView去開檔所看到的模型動作,可以請先進告知小弟可以從那方面下去測試呢?

感激不盡,謝謝
回頂端
檢視會員個人資料 發送私人訊息
mirror
散播福音的祭司


註冊時間: 2007-07-27
文章: 174

828.60 果凍幣

發表發表於: 2009-1-12, AM 5:26 星期一    文章主題: 引言回覆

Zero 寫到:
mirror 寫到:
Zero 寫到:
請教各位先進:
不好意思各位先進,小弟剛才亂改程式測試,小弟發現,人物好像有在斗動,但是速度很快,小弟不知道是什麼原因,以下是小弟在描繪模型的程式碼?,完全是依造先進所寫的方式,袛有改用GetAnimationSet這個函式,不知道各位先進能不能幫小弟看看是那裡有問題,謝謝,感激不盡,謝謝


先看你的模型動畫用了多少格
再用Time去控制
Time是控制整個動畫速度的



感謝mirror這位先進的回覆:
請問先進小弟要如何的得知模型動畫用了多少格呢?小弟是使用開npcgamer先進的人物走動模型來測試的,所以不知要如何得知模型使用了多少畫格

小弟有去修改Time = double(CurrentTime - LastTime) / 1000;這一行程式碼的1000這個值可是不管這麼改,動作就是不會順暢的走動,都是抖動的很利害的動作,完全不會像是使用MeshView去開檔所看到的模型動作,可以請先進告知小弟可以從那方面下去測試呢?

感激不盡,謝謝


把 pAnimationContainer->AdvanceTime(Time, NULL);
裡的Time改成 0.01f看看。
你如果是拿Monster的模型那個只有2格動畫
名字的設定是取決於模型
從模型輸出就有設定的,沒有設定的話就沒了
其它等我找到再來補充
回頂端
檢視會員個人資料 發送私人訊息
Zero
偶而上來逛逛的過客


註冊時間: 2009-01-04
文章: 10

0.00 果凍幣

發表發表於: 2009-1-12, PM 11:16 星期一    文章主題: 引言回覆

感謝mirror這位先進的回覆:
小弟有照先進的指示下去做測試,將Mesh.pAnimationContainer->SetTime(Time); 的Time改成0.01f去測試,但模型不會動了,小弟是在想說是否是其它地方有寫錯程式碼,先進方便有範例可PO給小弟參考參考嗎?,謝謝
回頂端
檢視會員個人資料 發送私人訊息
mirror
散播福音的祭司


註冊時間: 2007-07-27
文章: 174

828.60 果凍幣

發表發表於: 2009-1-13, AM 11:28 星期二    文章主題: 引言回覆

Zero 寫到:
感謝mirror這位先進的回覆:
小弟有照先進的指示下去做測試,將Mesh.pAnimationContainer->SetTime(Time); 的Time改成0.01f去測試,但模型不會動了,小弟是在想說是否是其它地方有寫錯程式碼,先進方便有範例可PO給小弟參考參考嗎?,謝謝


你說你的模型動超快
改了Time以後變不會動
我這台電腦測試是沒有問題
改成0.01只是會比較慢而己
還是你要把你的程式丟出來讓人測試..
最近我也有在看這個,只是還沒完全摻透而已
再加上又在忙一堆事...
回頂端
檢視會員個人資料 發送私人訊息
Zero
偶而上來逛逛的過客


註冊時間: 2009-01-04
文章: 10

0.00 果凍幣

發表發表於: 2009-1-13, PM 10:28 星期二    文章主題: 引言回覆

感謝mirror這位先進的回覆:小弟不知如何的上傳檔案,所以直接將整個原始碼貼上
如有危反版規的詁,請版主幫我移除,謝謝

main.cpp 內容

代碼:
#include "stdafx.h"
#include "AnimatedMesh.h"

HWND hWnd;
LPDIRECT3D9         pD3D;
LPDIRECT3DDEVICE9   pDevice;

AnimatedMesh    Mesh;

float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static POINT ptLastMousePosit;
  static POINT ptCurrentMousePosit;
  static bool bMousing = false;

  switch (uMsg)
  {
    case WM_LBUTTONDOWN:
    {
      ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam);
      ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam);
      bMousing = true;
    }
    break;

    case WM_LBUTTONUP:
    {
      bMousing = false;
    }
    break;

    case WM_MOUSEMOVE:
    {
      ptCurrentMousePosit.x = LOWORD (lParam);
      ptCurrentMousePosit.y = HIWORD (lParam);

      if( bMousing )
      {
        g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x);
        g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y);
      }

      ptLastMousePosit.x = ptCurrentMousePosit.x;
      ptLastMousePosit.y = ptCurrentMousePosit.y;
    }
    break;


    case WM_CLOSE:
      DestroyWindow(hWnd);
    break;

    case WM_DESTROY:
      PostQuitMessage(0);
    break;

    default:
      return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
  return 0;
}

LPDIRECT3DDEVICE9 Direct3DDeviceCreate9(LPDIRECT3D9 pD3D, D3DPRESENT_PARAMETERS* pd3dpp)
{
  LPDIRECT3DDEVICE9  pDevice = NULL;

  if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, pd3dpp, &pDevice) != D3D_OK)
    if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dpp, &pDevice) != D3D_OK)
      if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dpp, &pDevice) != D3D_OK)
      {
        // IDirect3D9::CreateDevice() failed
        return NULL;
      }
  return pDevice;
}

void Render ( )
{
  // 攝影機
  {
    D3DXVECTOR3 CameraEye = D3DXVECTOR3(0.0, 0.0, 200.0);
    D3DXVECTOR3 CameraAt = D3DXVECTOR3(0.0, 0.0, 0.0);
    D3DXVECTOR3 CameraUp = D3DXVECTOR3(0.0, 1.0, 0.0);
    D3DXMATRIX matrix;
    D3DXMatrixLookAtLH(&matrix, &CameraEye, &CameraAt, &CameraUp);
    pDevice->SetTransform(D3DTS_VIEW, &matrix);
  }

  // 攝影機鏡頭
  {
    D3DXMATRIX    matrix;
    D3DVIEWPORT9  Viewport;
    FLOAT         aspect;
    pDevice->GetViewport(&Viewport);
    aspect = (FLOAT) Viewport.Width / Viewport.Height;
    D3DXMatrixPerspectiveFovLH(&matrix, D3DXToRadian(45), aspect, 1.0, 1000.0);
    pDevice->SetTransform(D3DTS_PROJECTION, &matrix);
  }

  // 模型空間
  {
    D3DXMATRIX matrix;
    //D3DXMatrixIdentity(&matrix);
    D3DXMatrixRotationYawPitchRoll(&matrix, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
    pDevice->SetTransform(D3DTS_WORLD, &matrix);
  }

  // 光源
  {
     D3DLIGHT9   Light;
    ZeroMemory( &Light, sizeof(D3DLIGHT9));
    Light.Type      = D3DLIGHT_DIRECTIONAL;
    Light.Diffuse.r = 1.0;
    Light.Diffuse.g = 1.0;
    Light.Diffuse.b = 1.0;
    Light.Diffuse.a = 1.0;
    //Light.Ambient.r = 1.0;
    //Light.Ambient.g = 1.0;
    //Light.Ambient.b = 1.0;
    //Light.Ambient.a = 1.0;

    D3DXVECTOR3      VecDir;
    VecDir = D3DXVECTOR3(0.0, 0.0, -10.0f);
    D3DXVec3Normalize((D3DXVECTOR3*)&Light.Direction, &VecDir);

    pDevice->SetLight(0, &Light);
    pDevice->LightEnable(0, TRUE);
  }

  // Render State
  {
    pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
    pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    pDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
    // 指定兩面描繪的模式
    pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    //pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
    // 比較Z
    pDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    // 混色模式(高品質描繪)
    pDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE);

    //pDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE);

    pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

  }

  // Sampler State
  {
    pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  }

  // 描繪 模型
  {
    static DWORD LastTime = timeGetTime();
    DWORD CurrentTime;
    double Time;

    CurrentTime = timeGetTime();
    Time = double(CurrentTime - LastTime) / 1000;
    LastTime = CurrentTime;

    LPCSTR cString[]={
      "stand",
      "run",
      "ac"
   };

   /*
    if (Mesh.pAnimationContainer != NULL)
    {
      //Mesh.pAnimationContainer->ResetTime();
      //Mesh.pAnimationContainer->AdvanceTime(Time, NULL);
     Mesh.pAnimationContainer->SetTime( Time );
    }
   */

   LPD3DXANIMATIONSET ppAnimSet=NULL;

    if (Mesh.pAnimationContainer != NULL)
    {
      //Mesh.pAnimationContainer->ResetTime();
       
      //if(FAILED(Mesh.pAnimationContainer->GetAnimationSetByName(cString[1],&ppAnimSet))) //用名稱決定動畫編號
      //   return;

     if(FAILED(Mesh.pAnimationContainer->GetAnimationSet(0,&ppAnimSet))) //用名稱決定動畫編號
         return;

     Mesh.pAnimationContainer->SetTrackAnimationSet(0,ppAnimSet);
      Mesh.pAnimationContainer->SetTime(0.1f);
    }


    Mesh.Draw();
  }
}

void OnRender ( )
{
  pDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,192,0), 1.0, 0);

  pDevice->BeginScene();

  Render();

  pDevice->EndScene();

  pDevice->Present(NULL, NULL, NULL, NULL);
}



int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   // 建立主視窗
   
   static TCHAR szAppName[] = TEXT ( "Skinned" );


  WNDCLASSEX wcex;

  wcex.cbSize         = sizeof(WNDCLASSEX);
  wcex.cbClsExtra     = 0;
  wcex.cbWndExtra       = 0;
  wcex.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  wcex.lpfnWndProc    = WindowProc;
  wcex.hInstance      = hInstance;
  wcex.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
  wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  wcex.hIconSm        = wcex.hIcon;
  wcex.hbrBackground  = CreateSolidBrush(RGB(0, 0, 0));
  wcex.lpszMenuName   = NULL;
  wcex.lpszClassName  = szAppName;

  if (!RegisterClassEx(&wcex))
  {
    return 0;
  }

  HWND hWnd;

  hWnd = CreateWindow( szAppName, TEXT ( "MyWindowApplication DirectX 應用程式" ),
                        WS_OVERLAPPEDWINDOW,
                   CW_USEDEFAULT,
                   CW_USEDEFAULT,
                   800,
                   600,
                   NULL,
                   NULL,
                   hInstance,
                   NULL );

  if (!hWnd)
  {
    return 0;
  }

  // 初始化 Direct3D
  pD3D = Direct3DCreate9(D3D_SDK_VERSION);

  // 設定 D3DPRESENT_PARAMETERS 繪圖參數
  D3DDISPLAYMODE        d3ddm;
  D3DPRESENT_PARAMETERS d3dpp;

  pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
  ZeroMemory(&d3dpp, sizeof(d3dpp));

  d3dpp.hDeviceWindow = hWnd;
  d3dpp.BackBufferWidth = 0;
  d3dpp.BackBufferHeight = 0;
  d3dpp.BackBufferCount = 1;
  d3dpp.BackBufferFormat = d3ddm.Format;
  d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  d3dpp.EnableAutoDepthStencil = true;
  d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
  d3dpp.Windowed = true;
  // d3dpp.FullScreen_RefreshRateInHz = d3ddm.RefreshRate;
  // d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

  // 建立繪圖裝置
  pDevice = Direct3DDeviceCreate9(pD3D, &d3dpp);

  // 載入模型
  Mesh.LoadMeshFromX( TEXT ( "mos01.x" ), 0, pDevice);


  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  // 視窗訊息迴路
  MSG msg = {0};
  while (msg.message != WM_QUIT)
  {
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    else
    {
      OnRender();
    }
  }

  // 釋放資源
  Mesh.Release();
  if (pDevice) pDevice->Release();
  if (pD3D) pD3D->Release();

  return msg.wParam;
}
回頂端
檢視會員個人資料 發送私人訊息
Zero
偶而上來逛逛的過客


註冊時間: 2009-01-04
文章: 10

0.00 果凍幣

發表發表於: 2009-1-13, PM 10:30 星期二    文章主題: 引言回覆

AnimatedMesh.cpp內容


代碼:
#include "AnimatedMesh.h"

CHAR* AnimatedMesh::CAllocateHierarchy::AllocName (CHAR* Name)
{
  DWORD dwLen = (DWORD) strlen(Name) + 1;
  CHAR * NewName = new CHAR[ dwLen ];
  if (NewName)
    StringCchCopyA(NewName, dwLen, Name);
  return NewName;
}

//--------------------------------------------------------------------------------------
// Called either by CreateMeshContainer when loading a skin mesh, or when
// changing methods.  This function uses the pSkinInfo of the mesh
// container to generate the desired drawable mesh and bone combination
// table.
//--------------------------------------------------------------------------------------
HRESULT AnimatedMesh::CAllocateHierarchy::GenerateSkinnedMesh (IDirect3DDevice9 *pDevice, D3DXMESHCONTAINER_DERIVED *pMeshContainer)
{
  HRESULT hr;
  D3DCAPS9 d3dCaps;
  pDevice->GetDeviceCaps( &d3dCaps );

  if( pMeshContainer->pSkinInfo == NULL )
    return D3D_OK;

  if (pMeshContainer->MeshData.pMesh)
  {
    pMeshContainer->MeshData.pMesh->Release();
    pMeshContainer->MeshData.pMesh = 0;
  }

  if (pMeshContainer->pBoneCombinationBuf)
  {
    pMeshContainer->pBoneCombinationBuf->Release();
    pMeshContainer->pBoneCombinationBuf = 0;
  }

  // non-indexed skinning mode selected, use ConvertToBlendedMesh to generate drawable mesh
  {
    hr = pMeshContainer->pSkinInfo->ConvertToBlendedMesh(pMeshContainer->pOrigMesh, D3DXMESH_MANAGED|D3DXMESHOPT_VERTEXCACHE, pMeshContainer->pAdjacency, NULL, NULL, NULL, &pMeshContainer->NumInfl, &pMeshContainer->NumAttributeGroups, &pMeshContainer->pBoneCombinationBuf, &pMeshContainer->MeshData.pMesh);
    if (hr != D3D_OK)
      return hr;

    // If the device can only do 2 matrix blends, ConvertToBlendedMesh cannot approximate all meshes to it
    // Thus we split the mesh in two parts: The part that uses at most 2 matrices and the rest. The first is
    // drawn using the device's HW vertex processing and the rest is drawn using SW vertex processing.
    LPD3DXBONECOMBINATION rgBoneCombinations  = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer());

    // look for any set of bone combinations that do not fit the caps
    for (pMeshContainer->iAttributeSW = 0; pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups; pMeshContainer->iAttributeSW++)
    {
      DWORD cInfl   = 0;

      for (DWORD iInfl = 0; iInfl < pMeshContainer->NumInfl; iInfl++)
      {
        if (rgBoneCombinations[pMeshContainer->iAttributeSW].BoneId[iInfl] != UINT_MAX)
        {
          ++cInfl;
        }
      }

      if (cInfl > d3dCaps.MaxVertexBlendMatrices)
      {
        break;
      }
    }

    // if there is both HW and SW, add the Software Processing flag
    if (pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups)
    {
      LPD3DXMESH pMeshTmp;

      hr = pMeshContainer->MeshData.pMesh->CloneMeshFVF(D3DXMESH_SOFTWAREPROCESSING|pMeshContainer->MeshData.pMesh->GetOptions(), pMeshContainer->MeshData.pMesh->GetFVF(), pDevice, &pMeshTmp);
      if (hr != D3D_OK)
      {
        return hr;
      }

      pMeshContainer->MeshData.pMesh->Release();
      pMeshContainer->MeshData.pMesh = pMeshTmp;
      pMeshTmp = NULL;
    }
  }

  return D3D_OK;
}

HRESULT AnimatedMesh::CAllocateHierarchy::CreateFrame (LPCSTR Name, LPD3DXFRAME *ppNewFrame)
{
   D3DXFRAME_DERIVED *pFrame;

   *ppNewFrame = NULL;

   pFrame = new D3DXFRAME_DERIVED;
   if ( pFrame == NULL )
   {
      return E_OUTOFMEMORY;
   }

   // 初始化成員資料
   D3DXMatrixIdentity(&pFrame->TransformationMatrix);
   D3DXMatrixIdentity(&pFrame->CombinedTransformationMatrix);

   pFrame->pMeshContainer = NULL;
   pFrame->pFrameSibling = NULL;
   pFrame->pFrameFirstChild = NULL;

   if ( Name )
   {
      pFrame->Name = AllocName((CHAR*)Name);
      if ( pFrame->Name == NULL )
     {
         delete pFrame;
         return E_OUTOFMEMORY;
     }
   }
   else
   {
      pFrame->Name = NULL;
   }

   *ppNewFrame = pFrame;

   return D3D_OK;
}

HRESULT AnimatedMesh::CAllocateHierarchy::CreateMeshContainer (LPCSTR Name, LPD3DXMESHDATA pMeshData,
                 LPD3DXMATERIAL pMaterials, LPD3DXEFFECTINSTANCE pEffectInstances, DWORD NumMaterials,
                 DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer)
{

   *ppNewMeshContainer = NULL;

   // 配置 Mesh Container 記憶體空間
   D3DXMESHCONTAINER_DERIVED *  pMeshContainer = NULL;
   pMeshContainer = new D3DXMESHCONTAINER_DERIVED;
   if (pMeshContainer == NULL)
   {
      return E_OUTOFMEMORY;
   }

   //ZeroMemory(pMeshContainer, sizeof(D3DXMESHCONTAINER_DERIVED));
   memset(pMeshContainer, 0, sizeof(D3DXMESHCONTAINER_DERIVED));

   // Name
   {
      if (Name)
      {
         pMeshContainer->Name = AllocName((CHAR*)Name);
      }
      else
      {
         pMeshContainer->Name = AllocName("<no_name>");
      }
   }

   // Mesh Data
   {
      HRESULT hr;
       LPD3DXMESH pMesh;

      if (pMeshData->Type != D3DXMESHTYPE_MESH)
     {
         DestroyMeshContainer(pMeshContainer);
         return E_FAIL;
     }

     // get the pMesh interface pointer out of the mesh data structure
      pMesh = pMeshData->pMesh;

     // this sample does not FVF compatible meshes, so fail when one is found
      if (pMesh->GetFVF() == 0)
     {
         DestroyMeshContainer(pMeshContainer);
         return E_FAIL;
     }

      LPDIRECT3DDEVICE9 pDevice;

      pMesh->GetDevice(&pDevice);

      // if no normals are in the mesh, add them
      if (!(pMesh->GetFVF() & D3DFVF_NORMAL))
     {
         pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;

         // clone the mesh to make room for the normals
         hr = pMesh->CloneMeshFVF(pMeshData->pMesh->GetOptions(), pMesh->GetFVF() | D3DFVF_NORMAL, pDevice, &pMeshContainer->MeshData.pMesh);
         if (hr != D3D_OK)
           return hr;

         // get the new pMesh pointer back out of the mesh container to use
         // NOTE: we do not release pMesh because we do not have a reference to it yet
         pMesh = pMeshContainer->MeshData.pMesh;

         // now generate the normals for the pmesh
         D3DXComputeNormals(pMesh, NULL);
     }
      else  // if no normals, just add a reference to the mesh for the mesh container
     {
         pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;
         pMeshContainer->MeshData.pMesh = pMesh;
         pMeshContainer->MeshData.pMesh->AddRef();
     }
   }

   // Adjacency
   {
      DWORD NumFaces = pMeshData->pMesh->GetNumFaces();

      pMeshContainer->pAdjacency = new DWORD [NumFaces*3];
      if (pMeshContainer->pAdjacency == NULL)
     {
         DestroyMeshContainer(pMeshContainer);;
         return E_OUTOFMEMORY;
     }
      else
     {
         CopyMemory(pMeshContainer->pAdjacency, pAdjacency, 3 * sizeof(DWORD) * NumFaces);
     }
   }

   // Effect Instance
   {
      pMeshContainer->pEffects = NULL;
   }

   // Material
   {
      pMeshContainer->NumMaterials = NumMaterials ? NumMaterials : 1;

      pMeshContainer->pMaterials = new D3DXMATERIAL [pMeshContainer->NumMaterials];
      if (pMeshContainer->pMaterials == NULL)
     {
         DestroyMeshContainer(pMeshContainer);
        return E_OUTOFMEMORY;
     }

      pMeshContainer->ppTextures = new LPDIRECT3DTEXTURE9 [pMeshContainer->NumMaterials];
      if (pMeshContainer->ppTextures == NULL)
     {
         DestroyMeshContainer(pMeshContainer);
         return E_OUTOFMEMORY;
     }

      if (NumMaterials)
     {
         LPDIRECT3DDEVICE9   pDevice;
         pMeshData->pMesh->GetDevice(&pDevice);

         CopyMemory(pMeshContainer->pMaterials, pMaterials, NumMaterials * sizeof(D3DXMATERIAL));

         for (DWORD i = 0; i < NumMaterials; i++)
       {
           pMeshContainer->ppTextures[i] = NULL;
           D3DXCreateTextureFromFileA(pDevice,  pMeshContainer->pMaterials[i].pTextureFilename, &pMeshContainer->ppTextures[i]);
       }

         pDevice->Release();
     }
      else
     {
         ZeroMemory(pMeshContainer->pMaterials, sizeof(D3DXMATERIAL));

         pMeshContainer->pMaterials[0].MatD3D.Diffuse.r = 1.0;
         pMeshContainer->pMaterials[0].MatD3D.Diffuse.g = 1.0;
         pMeshContainer->pMaterials[0].MatD3D.Diffuse.b = 1.0;
         pMeshContainer->pMaterials[0].MatD3D.Diffuse.a = 1.0;
         pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse;
         pMeshContainer->pMaterials[0].pTextureFilename = NULL;
         pMeshContainer->ppTextures[0] = NULL;
     }
   }

   // Skin Info
  if (pSkinInfo)
  {
    HRESULT hr;
    UINT iBone, cBones;

    // first save off the SkinInfo and original mesh data
    pMeshContainer->pSkinInfo = pSkinInfo;
    pSkinInfo->AddRef();

    pMeshContainer->pOrigMesh = pMeshContainer->MeshData.pMesh;
    pMeshContainer->MeshData.pMesh->AddRef();

    // Will need an array of offset matrices to move the vertices from the figure space to the bone's space
    cBones = pSkinInfo->GetNumBones();
    pMeshContainer->pBoneOffsetMatrices = new D3DXMATRIX[cBones];
    if (pMeshContainer->pBoneOffsetMatrices == NULL)
    {
      return E_OUTOFMEMORY;
    }

    // get each of the bone offset matrices so that we don't need to get them later
    for (iBone = 0; iBone < cBones; iBone++)
    {
        pMeshContainer->pBoneOffsetMatrices[iBone] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(iBone));
    }

    // GenerateSkinnedMesh will take the general skinning information and transform it to a HW friendly version

    LPDIRECT3DDEVICE9   pDevice;
    pMeshData->pMesh->GetDevice(&pDevice);

    hr = GenerateSkinnedMesh( pDevice, pMeshContainer );
    pDevice->Release();

    if (hr != D3D_OK)
      return hr;
  }

   // 設定輸出參考
   * ppNewMeshContainer = pMeshContainer;

   return D3D_OK;
}

HRESULT AnimatedMesh::CAllocateHierarchy::DestroyFrame (LPD3DXFRAME pFrameToFree)
{
  if (pFrameToFree->Name)
  {
    delete[] pFrameToFree->Name;
    pFrameToFree->Name = NULL;
  }

  if (pFrameToFree)
  {
    delete pFrameToFree;
    pFrameToFree = NULL;
  }

  return D3D_OK;
}

HRESULT AnimatedMesh::CAllocateHierarchy::DestroyMeshContainer (LPD3DXMESHCONTAINER pMeshContainerBase)
{
  D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;

  if (pMeshContainer->Name)
  {
    delete[] pMeshContainer->Name;
    pMeshContainer->Name = 0;
  }

  if (pMeshContainer->pAdjacency)
  {
    delete[] pMeshContainer->pAdjacency;
    pMeshContainer->pAdjacency = 0;
  }

  if (pMeshContainer->pMaterials)
  {
    delete[] pMeshContainer->pMaterials;
    pMeshContainer->pMaterials = 0;
  }

  // release all the allocated textures
  if (pMeshContainer->ppTextures != NULL)
  {
    for (DWORD iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
    {
      if (pMeshContainer->ppTextures[iMaterial])
      {
        pMeshContainer->ppTextures[iMaterial]->Release();
        pMeshContainer->ppTextures[iMaterial] = 0;
      }
    }
  }

  if (pMeshContainer->pBoneOffsetMatrices)
 {
    delete[] pMeshContainer->pBoneOffsetMatrices;
    pMeshContainer->pBoneOffsetMatrices = 0;
 }

  if (pMeshContainer->ppBoneMatrixPtrs)
 {
    delete[] pMeshContainer->ppBoneMatrixPtrs;
    pMeshContainer->ppBoneMatrixPtrs = 0;
 }

  if (pMeshContainer->pBoneCombinationBuf)
 {
    pMeshContainer->pBoneCombinationBuf->Release();
    pMeshContainer->pBoneCombinationBuf = 0;
 }

  if (pMeshContainer->MeshData.pMesh)
  {
    pMeshContainer->MeshData.pMesh->Release();
    pMeshContainer->MeshData.pMesh = 0;
  }

  if (pMeshContainer->pSkinInfo)
  {
    pMeshContainer->pSkinInfo->Release();
    pMeshContainer->pSkinInfo = 0;
  }

   if (pMeshContainer->pOrigMesh)
 {
    pMeshContainer->pOrigMesh->Release();
    pMeshContainer->pOrigMesh = 0;
 }


  if (pMeshContainer)
  {
    delete pMeshContainer;
    pMeshContainer = 0;
  }

  return D3D_OK;
}

//--------------------------------------------------------------------------------------
// Called to setup the pointers for a given bone to its transformation matrix
//--------------------------------------------------------------------------------------
HRESULT AnimatedMesh::SetupBoneMatrixPointersOnMesh (LPD3DXMESHCONTAINER pMeshContainerBase)
{
    D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;

    // if there is a skinmesh, then setup the bone matrices
    if (pMeshContainer->pSkinInfo != NULL)
    {
      UINT iBone, cBones;
        D3DXFRAME_DERIVED *pFrame;

        cBones = pMeshContainer->pSkinInfo->GetNumBones();

        pMeshContainer->ppBoneMatrixPtrs = new D3DXMATRIX*[cBones];
        if (pMeshContainer->ppBoneMatrixPtrs == NULL)
            return E_OUTOFMEMORY;

        for (iBone = 0; iBone < cBones; iBone++)
        {
            pFrame = (D3DXFRAME_DERIVED*)D3DXFrameFind( pFrameRoot, pMeshContainer->pSkinInfo->GetBoneName(iBone) );
            if (pFrame == NULL)
                return E_FAIL;

            pMeshContainer->ppBoneMatrixPtrs[iBone] = &pFrame->CombinedTransformationMatrix;
        }
    }

    return D3D_OK;
}

//--------------------------------------------------------------------------------------
// Called to setup the pointers for a given bone to its transformation matrix
//--------------------------------------------------------------------------------------
HRESULT AnimatedMesh::SetupBoneMatrixPointers (LPD3DXFRAME pFrame)
{
  HRESULT hr;

  if (pFrame->pMeshContainer != NULL)
  {
    hr = SetupBoneMatrixPointersOnMesh(pFrame->pMeshContainer);
    if (hr != D3D_OK)
      return hr;
  }

  if (pFrame->pFrameSibling != NULL)
  {
    hr = SetupBoneMatrixPointers(pFrame->pFrameSibling);
    if (hr != D3D_OK)
      return hr;
  }

  if (pFrame->pFrameFirstChild != NULL)
  {
    hr = SetupBoneMatrixPointers(pFrame->pFrameFirstChild);
    if (hr != D3D_OK)
      return hr;
  }

  return D3D_OK;
}

void AnimatedMesh::UpdateFrameMatrix (LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix)
{
  D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;

  if (pParentMatrix != NULL)
    D3DXMatrixMultiply(&pFrame->CombinedTransformationMatrix, &pFrame->TransformationMatrix, pParentMatrix);
  else
    pFrame->CombinedTransformationMatrix = pFrame->TransformationMatrix;

  if (pFrame->pFrameSibling != NULL)
  {
    UpdateFrameMatrix(pFrame->pFrameSibling, pParentMatrix);
  }

  if (pFrame->pFrameFirstChild != NULL)
  {
    UpdateFrameMatrix(pFrame->pFrameFirstChild, &pFrame->CombinedTransformationMatrix);
  }
}

void AnimatedMesh::DrawFrame (IDirect3DDevice9 *pd3dDevice, LPD3DXFRAME pFrame)
{
  LPD3DXMESHCONTAINER pMeshContainer;

  pMeshContainer = pFrame->pMeshContainer;
  while (pMeshContainer != NULL)
  {
    DrawMeshContainer(pd3dDevice, pMeshContainer, pFrame);

    pMeshContainer = pMeshContainer->pNextMeshContainer;
  }

  if (pFrame->pFrameSibling != NULL)
  {
    DrawFrame(pd3dDevice, pFrame->pFrameSibling);
  }

  if (pFrame->pFrameFirstChild != NULL)
  {
    DrawFrame(pd3dDevice, pFrame->pFrameFirstChild);
  }
}

void AnimatedMesh::DrawMeshContainer(IDirect3DDevice9 *pd3dDevice, LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase)
{
  //HRESULT hr;
  D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;

  // first check for skinning
  if (pMeshContainer->pSkinInfo != NULL)
  {
     UINT    iAttrib;
     UINT    NumBlend;
     UINT    iMatrixIndex;
     DWORD     AttribIdPrev;
     D3DCAPS9      d3dCaps;
     D3DXMATRIXA16 matTemp;
     LPD3DXBONECOMBINATION pBoneComb;

     pd3dDevice->GetDeviceCaps(&d3dCaps);

    // Fixed Function non-indexed Skinning
    {
      AttribIdPrev = UNUSED32;
      pBoneComb = (LPD3DXBONECOMBINATION)pMeshContainer->pBoneCombinationBuf->GetBufferPointer();
      //pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer());

      // Draw using default vtx processing of the device (typically HW)
      for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++)
      {
        NumBlend = 0;
        for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i)
        {
          if (pBoneComb[iAttrib].BoneId[i] != UINT_MAX)
          {
            NumBlend = i;
          }
        }

        if (d3dCaps.MaxVertexBlendMatrices >= NumBlend + 1)
        {
          // first calculate the world matrices for the current set of blend weights and get the accurate count of the number of blends
          for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i)
          {
            iMatrixIndex = pBoneComb[iAttrib].BoneId[i];
            if (iMatrixIndex != UINT_MAX)
            {
              D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] );
              pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(i), &matTemp);
            }
          }

          pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend);

          // lookup the material used for this subset of faces
          if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32))
          {
            pd3dDevice->SetMaterial(&pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D);
            pd3dDevice->SetTexture(0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId]);
            AttribIdPrev = pBoneComb[iAttrib].AttribId;
          }

          // draw the subset now that the correct material and matrices are loaded
          pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib);
        }
      }

      // If necessary, draw parts that HW could not handle using SW
      if (pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups)
      {
        AttribIdPrev = UNUSED32;
        pd3dDevice->SetSoftwareVertexProcessing(TRUE);
        for (iAttrib = pMeshContainer->iAttributeSW; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++)
        {
          NumBlend = 0;
          for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i)
          {
            if (pBoneComb[iAttrib].BoneId[i] != UINT_MAX)
            {
              NumBlend = i;
            }
          }

          if (d3dCaps.MaxVertexBlendMatrices < NumBlend + 1)
          {
            // first calculate the world matrices for the current set of blend weights and get the accurate count of the number of blends
            for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i)
            {
              iMatrixIndex = pBoneComb[iAttrib].BoneId[i];
              if (iMatrixIndex != UINT_MAX)
              {
                D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] );
                pd3dDevice->SetTransform( D3DTS_WORLDMATRIX(i), &matTemp);
              }
            }

            pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend);

            // lookup the material used for this subset of faces
            if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32))
            {
              pd3dDevice->SetMaterial(&pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D);
              pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId]);
              AttribIdPrev = pBoneComb[iAttrib].AttribId;
            }

            // draw the subset now that the correct material and matrices are loaded
            pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib);
          }
        }
        pd3dDevice->SetSoftwareVertexProcessing(FALSE);
      }

      pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
    }
  }
  else  // standard mesh, just draw it after setting material properties
  {
     UINT iMaterial;
      D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;

      pd3dDevice->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix);

    for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
    {
      pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[iMaterial].MatD3D);
      pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[iMaterial]);
      pMeshContainer->MeshData.pMesh->DrawSubset(iMaterial);
    }
  }
}
//載入模型
HRESULT AnimatedMesh::LoadMeshFromX (LPTSTR Filename, DWORD MeshOptions, LPDIRECT3DDEVICE9 pDevice)
{
  HRESULT hr;
  CAllocateHierarchy  ah;

  hr = D3DXLoadMeshHierarchyFromX(Filename, MeshOptions, pDevice, &ah, NULL, (LPD3DXFRAME *) &pFrameRoot, &pAnimationContainer);

  if (hr == D3D_OK)
  {
    SetupBoneMatrixPointers(pFrameRoot);
    //D3DXFrameCalculateBoundingSphere(g_pFrameRoot, &g_vObjectCenter, &g_fObjectRadius);
    this->pDevice = pDevice;
  }

  return hr;
}

void AnimatedMesh::Draw ( )
{
  D3DXMATRIX  WorldMatrix;
  pDevice->GetTransform(D3DTS_WORLD, &WorldMatrix);

  UpdateFrameMatrix(pFrameRoot, &WorldMatrix);
  DrawFrame(pDevice, pFrameRoot);
}

void AnimatedMesh::Release ( )
{
  if (pAnimationContainer)
  {
    pAnimationContainer->Release();
    pAnimationContainer = 0;
  }
}
回頂端
檢視會員個人資料 發送私人訊息
Zero
偶而上來逛逛的過客


註冊時間: 2009-01-04
文章: 10

0.00 果凍幣

發表發表於: 2009-1-13, PM 10:31 星期二    文章主題: 引言回覆

AnimatedMesh.h內容

代碼:
#pragma once

#include "stdafx.h"

class AnimatedMesh
{
   // Frame
   struct D3DXFRAME_DERIVED: public D3DXFRAME
   {
      D3DXMATRIXA16     CombinedTransformationMatrix;
   };

   // Mesh Container
   struct D3DXMESHCONTAINER_DERIVED: public D3DXMESHCONTAINER
   {
      LPDIRECT3DTEXTURE9    * ppTextures;

     // SkinMesh info             
      LPD3DXMESH              pOrigMesh;
      LPD3DXATTRIBUTERANGE    pAttributeTable;
      DWORD                   NumAttributeGroups;
      DWORD                   NumInfl;
      LPD3DXBUFFER            pBoneCombinationBuf;
      D3DXMATRIX**            ppBoneMatrixPtrs;
      D3DXMATRIX*             pBoneOffsetMatrices;
      DWORD                   NumPaletteEntries;
      bool                    UseSoftwareVP;
      DWORD                   iAttributeSW;     // used to denote the split between SW and HW if necessary for non-indexed skinning
   };

   // Allocate Hierarchy
   class CAllocateHierarchy : public ID3DXAllocateHierarchy
   {
   public:
      STDMETHOD (CreateFrame) (LPCSTR Name, LPD3DXFRAME *ppNewFrame);
      STDMETHOD (CreateMeshContainer) (LPCSTR Name, LPD3DXMESHDATA pMeshData,
                        LPD3DXMATERIAL pMaterials, LPD3DXEFFECTINSTANCE pEffectInstances, DWORD NumMaterials,
                    DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo,
                    LPD3DXMESHCONTAINER *ppNewMeshContainer);
      STDMETHOD (DestroyFrame) (LPD3DXFRAME pFrameToFree);
      STDMETHOD (DestroyMeshContainer) (LPD3DXMESHCONTAINER pMeshContainerBase);
      CHAR* AllocName (CHAR* Name);

     HRESULT GenerateSkinnedMesh (IDirect3DDevice9 *pDevice, D3DXMESHCONTAINER_DERIVED *pMeshContainer);
   };

   HRESULT SetupBoneMatrixPointersOnMesh (LPD3DXMESHCONTAINER pMeshContainerBase);
   HRESULT SetupBoneMatrixPointers (LPD3DXFRAME pFrame);
   void UpdateFrameMatrix (LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix);
   void DrawFrame (IDirect3DDevice9 *pd3dDevice, LPD3DXFRAME pFrame);
   void DrawMeshContainer(IDirect3DDevice9 *pd3dDevice, LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase);

 
   private:
      LPDIRECT3DDEVICE9             pDevice;

   public:
      D3DXFRAME_DERIVED           * pFrameRoot;
      LPD3DXANIMATIONCONTROLLER     pAnimationContainer;

      //D3DXVECTOR3       vObjectCenter;        // Center of bounding sphere of object
      //FLOAT             fObjectRadius;        // Radius of bounding sphere of object

   public:
      HRESULT LoadMeshFromX (LPTSTR Filename, DWORD MeshOptions, LPDIRECT3DDEVICE9 pDevice);
      void Draw ( );
      void Release ( );
};
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
前往頁面 1, 2  下一頁
1頁(共2頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
可以 在這個版面附加檔案
可以 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作