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.练习多了就会越来越熟练。
D3D Mesh 例子程序
时间: 2024-10-13 05:23:29