D3D Mesh 例子程序
程序目的
加载简单的 .x资源文件 ,显示mesh 模型。
程序实现
#pragma once
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#include<d3d9.h>
#include<d3dx9.h>
LRESULT CALLBACK MsgProc(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);
HRESULT Init(HWND hWnd);
HRESULT InitD3D(HWND hWnd);
void InitMatrices();
HRESULT InitGeometry();
void SetUpMatrices();
void Render();
void CleanUp();
LPDIRECT3D9 g_pd3d9=NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice9=NULL;
D3DXMATRIXA16 worldMatrix;
D3DXMATRIXA16 viewMatrix;
D3DXMATRIXA16 projectionMatrix;
LPD3DXMESH g_pd3dMesh=NULL;
D3DMATERIAL9* g_pd3dMeshMaterial=NULL;
LPDIRECT3DTEXTURE9* g_pd3dMeshTexture=NULL;
DWORD g_dwNumMaterials=0;
INT WINAPI wWinMain(
HINSTANCE,
HINSTANCE,
LPWSTR,
INT)
{
WNDCLASSEX wcex;
ZeroMemory(&wcex,sizeof(wcex));
wcex.cbSize=sizeof(wcex);
wcex.hInstance=GetModuleHandle(NULL);
wcex.lpfnWndProc=MsgProc;
wcex.lpszClassName=L"DXMeshes";
wcex.style=CS_CLASSDC;
RegisterClassEx(&wcex);
HWND hWnd=CreateWindowEx(
WS_EX_OVERLAPPEDWINDOW,
L"DXMeshes",
L"DXMeshes Window",
WS_OVERLAPPEDWINDOW,
100,
100,
300,
300,
NULL,
NULL,
wcex.hInstance,
NULL);
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
if(FAILED(Init(hWnd)))
{
return -1;
}
MSG msg;
ZeroMemory(&msg,sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render();
}
}
UnregisterClass(L"DXMeshes",wcex.hInstance);
return 0;
}
LRESULT CALLBACK MsgProc(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
CleanUp();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
HRESULT Init(HWND hWnd)
{
if(FAILED(InitD3D(hWnd)))
{
return E_FAIL;
}
InitMatrices();
if(FAILED(InitGeometry()))
{
return E_FAIL;
}
return S_OK;
}
HRESULT InitD3D(HWND hWnd)
{
g_pd3d9=Direct3DCreate9(D3D_SDK_VERSION);
if(g_pd3d9 == NULL)
{
return E_FAIL;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil=TRUE;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
if(FAILED(g_pd3d9->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&g_pd3dDevice9)))
{
return E_FAIL;
}
return S_OK;
}
void Render()
{
g_pd3dDevice9->Clear(
0,
NULL,
D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,255),
1.0f,
0);
if(SUCCEEDED(g_pd3dDevice9->BeginScene()))
{
SetUpMatrices();
for(DWORD i=0;i<g_dwNumMaterials;i++)
{
g_pd3dDevice9->SetMaterial(&g_pd3dMeshMaterial[i]);
g_pd3dDevice9->SetTexture(0,g_pd3dMeshTexture[i]);
g_pd3dMesh->DrawSubset(i);
}
g_pd3dDevice9->EndScene();
}
g_pd3dDevice9->Present(NULL,NULL,NULL,NULL);
}
void CleanUp()
{
if(g_pd3dMeshMaterial != NULL)
{
delete[] g_pd3dMeshMaterial;
g_pd3dMeshMaterial=NULL;
}
if(g_pd3dMeshTexture != NULL)
{
for(DWORD i=0;i<g_dwNumMaterials;i++)
{
if(g_pd3dMeshTexture[i] != NULL)
{
g_pd3dMeshTexture[i]->Release();
g_pd3dMeshTexture[i]=NULL;
}
}
delete[] g_pd3dMeshTexture;
g_pd3dMeshTexture=NULL;
}
if(g_pd3dMesh != NULL)
{
g_pd3dMesh->Release();
g_pd3dMesh=NULL;
}
if(g_pd3dDevice9 != NULL)
{
g_pd3dDevice9->Release();
g_pd3dDevice9=NULL;
}
if(g_pd3d9 != NULL)
{
g_pd3d9->Release();
g_pd3d9=NULL;
}
}
void InitMatrices()
{
//world matrix.
D3DXMatrixIdentity(&worldMatrix);
g_pd3dDevice9->SetTransform(D3DTS_WORLD,&worldMatrix);
//view matrix.
D3DXVECTOR3 vEye(0.0f,3.0f,-5.0f);
D3DXVECTOR3 vLookAt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vUp(0.0f,1.0f,0.0f);
D3DXMatrixLookAtLH(&viewMatrix,&vEye,&vLookAt,&vUp);
g_pd3dDevice9->SetTransform(D3DTS_VIEW,&viewMatrix);
//projection matrix.
D3DXMatrixPerspectiveFovLH(&projectionMatrix,D3DX_PI/4,1.0f,1.0f,1000.0f);
g_pd3dDevice9->SetTransform(D3DTS_PROJECTION,&projectionMatrix);
}
void SetUpMatrices()
{
D3DXMatrixRotationY(&worldMatrix,timeGetTime()/1000.0f);
g_pd3dDevice9->SetTransform(D3DTS_WORLD,&worldMatrix);
}
HRESULT InitGeometry()
{
LPD3DXBUFFER pd3dxMtrlBuffer;
if(FAILED(D3DXLoadMeshFromX(
L"Tiger.x",
D3DXMESH_SYSTEMMEM,
g_pd3dDevice9,
NULL,
&pd3dxMtrlBuffer,
NULL,
&g_dwNumMaterials,
&g_pd3dMesh)))
{
return E_FAIL;
}
D3DXMATERIAL* d3dxMaterials=(D3DXMATERIAL*)pd3dxMtrlBuffer->GetBufferPointer();
g_pd3dMeshMaterial=new D3DMATERIAL9[g_dwNumMaterials];
if(g_pd3dMeshMaterial == NULL)
{
return E_OUTOFMEMORY;
}
g_pd3dMeshTexture=new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
if(g_pd3dMeshTexture == NULL)
{
return E_OUTOFMEMORY;
}
for(DWORD i=0;i<g_dwNumMaterials;i++)
{
g_pd3dMeshMaterial[i]=d3dxMaterials[i].MatD3D;
g_pd3dMeshMaterial[i].Ambient=g_pd3dMeshMaterial[i].Diffuse;
if(d3dxMaterials[i].pTextureFilename != NULL&&
lstrlenA(d3dxMaterials[i].pTextureFilename) > 0)
{
if(FAILED(D3DXCreateTextureFromFileA(
g_pd3dDevice9,
d3dxMaterials[i].pTextureFilename,
&g_pd3dMeshTexture[i])))
{
return E_FAIL;
}
}
}
pd3dxMtrlBuffer->Release();
g_pd3dDevice9->SetRenderState(D3DRS_ZENABLE,TRUE);
g_pd3dDevice9->SetRenderState(D3DRS_AMBIENT,0xffffffff);
return S_OK;
}
运行结果
总结
1.这个倒不是很难,加载上.x文件以后,从加载的对象里面获取各种数据,最后在渲染得时候依次显示就可以了。
2.练习多了就会越来越熟练。