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;
} |
|
|