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

Google
[範例] Direct3D9 - Mesh 靜態模型

 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫
上一篇主題 :: 下一篇主題  
發表人 內容
npcgamer
時常出沒的會員


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

3.00 果凍幣

發表發表於: 2008-3-23, PM 3:03 星期日    文章主題: [範例] Direct3D9 - Mesh 靜態模型 引言回覆

【附件】http://blog.yam.com/npcgamer/article/14383407

代碼:
#include "stdafx.h"


class StaticMesh
{
  private:
    LPDIRECT3DDEVICE9 pDevice;
    LPD3DXMESH     pMesh;
    DWORD          numMesh;
    LPD3DXBUFFER   pMaterialBuffer;

  public:
    HRESULT LoadMeshFromX (LPCTSTR pFilename, DWORD Options, LPDIRECT3DDEVICE9 pDevice);
    HRESULT DrawSubset ( );
    void Release ( );
};

HRESULT StaticMesh::LoadMeshFromX(LPCTSTR pFilename, DWORD Options, LPDIRECT3DDEVICE9 pDevice)
{
  HRESULT hr;

  hr = D3DXLoadMeshFromX(pFilename, Options, pDevice, NULL, &pMaterialBuffer, NULL, &numMesh, &pMesh);

  if (hr == D3D_OK)
  {
    D3DXMATERIAL        * pMaterial;
    LPDIRECT3DTEXTURE9    pTexture;

    pMaterial= (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();

    for (DWORD i = 0; i < numMesh; i++)
    {
      pTexture = NULL;
      D3DXCreateTextureFromFileA(pDevice, pMaterial[i].pTextureFilename, &pTexture);
      pMaterial[i].pTextureFilename = (LPSTR)pTexture;
    }
    this->pDevice = pDevice;
  }

  return hr;
}

HRESULT StaticMesh::DrawSubset ( )
{
  D3DXMATERIAL        * pMaterial;

  pMaterial= (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();
  for (DWORD i = 0; i < numMesh; i++)
  {
    pDevice->SetMaterial(&pMaterial[i].MatD3D);
    pDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pMaterial[i].pTextureFilename);
    pMesh->DrawSubset(i);
  }

  return D3D_OK;
}

void StaticMesh::Release ( )
{
  {
    D3DXMATERIAL        * pMaterial;
    LPDIRECT3DTEXTURE9    pTexture;

    pMaterial= (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();
    for (DWORD i = 0; i < numMesh; i++)
    {
      pTexture = (LPDIRECT3DTEXTURE9)pMaterial[i].pTextureFilename;
      if (pTexture)
        pTexture->Release();
    }
  }

  if (pMaterialBuffer)
  {
    pMaterialBuffer->Release();
    pMaterialBuffer = NULL;
  }

  if (pMesh)
  {
    pMesh->Release();
    pMesh = NULL;
  }
}

HWND hWnd;
LPDIRECT3D9         pD3D = Direct3DCreate9(D3D_SDK_VERSION);
LPDIRECT3DDEVICE9   pDevice;

StaticMesh  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 RenderScene ( )
{
  // 攝影機
  {
    D3DXVECTOR3 CameraEye = D3DXVECTOR3(0.0, 0.0, 4.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;

    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);
    // 比較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);
  }

  // 描繪 模型
  {
    Mesh.DrawSubset();
  }
}

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

  pDevice->BeginScene();

  RenderScene();

  pDevice->EndScene();

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  // 建立視窗
  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  = L"MyWindowApplication";

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

  HWND hWnd;

  hWnd = CreateWindowEx(0, L"MyWindowApplication", L"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(L"bat01.x", D3DXMESH_SYSTEMMEM, pDevice);
    //Mesh.LoadMeshFromX(L"turtle01.x", D3DXMESH_SYSTEMMEM, pDevice);
    //Mesh.LoadMeshFromX(L"goblin.x", D3DXMESH_SYSTEMMEM, pDevice);
    //Mesh.LoadMeshFromX(L"robo0.x", D3DXMESH_SYSTEMMEM, 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
    {
      Render();
    }
  }

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

  return msg.wParam;
}
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
1頁(共1頁)

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


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