CreateMeshX.cpp
资源名称:Direct3D.rar [点击查看]
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:10k
源码类别:
DirextX编程
开发平台:
Visual C++
- #include "zfxd3dUtility.h"
- #include <stdio.h>
- // D3D对象接口
- IDirect3D9* g_pd3d;
- // D3D设备接口
- IDirect3DDevice9* g_pd3dDevice;
- // D3D模型接口
- ID3DXMesh* g_pMesh = NULL;
- IDirect3DTexture9** g_ppTex;
- D3DMATERIAL9* g_pMtrl;
- DWORD g_numXMtrl;
- // 顶点结构体
- typedef struct tagCUSTOMVERTEX{
- D3DXVECTOR3 position; // The position of the vertex.
- D3DXVECTOR3 normal; // The nomal Vector.
- FLOAT tu, tv; // The texture coordinates
- static const DWORD D3D_FVF;
- }CUSTOMVERTEX;
- const DWORD CUSTOMVERTEX::D3D_FVF = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1;
- // 字体
- ID3DXFont* g_pFont = NULL;
- bool Setup()
- {
- // 创建模型
- HRESULT hr = 0;
- hr = D3DXCreateMeshFVF(
- 196, // NumFaces
- 202, // NumVertices
- D3DXMESH_MANAGED,
- CUSTOMVERTEX::D3D_FVF,
- g_pd3dDevice,
- &g_pMesh);
- if(FAILED(hr))
- {
- ::MessageBox(0, L"D3DXCreateMeshFVF() - FAILED", 0, 0);
- return false;
- }
- //*******************************填充顶点数据**********************************************************************//
- CUSTOMVERTEX *vertices;
- g_pMesh->LockVertexBuffer(0, (void**)&vertices);
- // 侧面,100个顶点
- for(int i=0;i<50;i++)
- {
- FLOAT alpha = (2*D3DX_PI*i)/49;
- vertices[2*i].position = D3DXVECTOR3( sinf(alpha), 1.0f, cosf(alpha));
- vertices[2*i].normal = D3DXVECTOR3( sinf(alpha), 0.0f, cosf(alpha));
- vertices[2*i].tu = (FLOAT)i/49;
- vertices[2*i].tv = 1.0f;
- vertices[2*i+1].position = D3DXVECTOR3( sinf(alpha),-1.0f, cosf(alpha));
- vertices[2*i+1].normal = D3DXVECTOR3( sinf(alpha), 0.0f, cosf(alpha));
- vertices[2*i+1].tu = (FLOAT)i/49;
- vertices[2*i+1].tv = 0.0f;
- }
- // 顶部,51个顶点
- vertices[100].position = D3DXVECTOR3( 0.0f, 1.0f, 0.0f);
- vertices[100].normal = D3DXVECTOR3( 0.0f, 1.0f, 0.0f);
- vertices[100].tu = 0.5f;
- vertices[100].tv = 0.5f;
- for(int i=101;i<151;i++)
- {
- FLOAT alpha = (2*D3DX_PI*i)/49;
- vertices[i].position = D3DXVECTOR3( sinf(alpha), 1.0f, cosf(alpha));
- vertices[i].normal = D3DXVECTOR3( 0.0f, 1.0f, 0.0f);
- vertices[i].tu = (sinf(alpha)+1)/2;
- vertices[i].tv = (cosf(alpha)+1)/2;
- }
- // 低部,51个顶点
- vertices[151].position = D3DXVECTOR3( 0.0f, -1.0f, 0.0f);
- vertices[151].normal = D3DXVECTOR3( 0.0f, -1.0f, 0.0f);
- vertices[151].tu = 0.5f;
- vertices[151].tv = 0.5f;
- for(int i=152;i<202;i++)
- {
- FLOAT alpha = (2*D3DX_PI*i)/49;
- vertices[i].position = D3DXVECTOR3( sinf(alpha), -1.0f, cosf(alpha));
- vertices[i].normal = D3DXVECTOR3( 0.0f, -1.0f, 0.0f);
- vertices[i].tu = (sinf(alpha)+1)/2;
- vertices[i].tv = (cosf(alpha)+1)/2;
- }
- g_pMesh->UnlockVertexBuffer();
- //*******************************填充顶点数据**********************************************************************//
- //*******************************填充索引数据**********************************************************************//
- WORD* indices = 0;
- g_pMesh->LockIndexBuffer(0, (void**)&indices);
- // 侧面,98个三角形,填写索引顺序时一定要保证顶点顺序都是按照顺时针排列的
- for(int i=0;i<98;i++)
- {
- if(!(i%2))
- {
- indices[3*i] = i;
- indices[3*i+1] = i+1;
- indices[3*i+2] = i+2;
- }
- else
- {
- indices[3*i] = i+1;
- indices[3*i+1] = i;
- indices[3*i+2] = i+2;
- }
- }
- // 顶部,49个三角形
- for(int i=98;i<147;i++)
- {
- indices[3*i] = 100;
- indices[3*i+1] = i+3;
- indices[3*i+2] = i+4;
- }
- // 低部,49个三角形
- for(int i=147;i<196;i++)
- {
- indices[3*i] = 151;
- indices[3*i+1] = i+6;
- indices[3*i+2] = i+5;
- }
- g_pMesh->UnlockIndexBuffer();
- //*******************************填充索引数据**********************************************************************//
- //*******************************填充属性数据**********************************************************************//
- // 填充属性数据,分为3个子集
- DWORD* attributeBuffer = 0;
- g_pMesh->LockAttributeBuffer(0, &attributeBuffer);
- for(int i=0;i<98;i++)
- attributeBuffer[i] = 0;
- for(int i=98;i<147;i++)
- attributeBuffer[i] = 1;
- for(int i=147;i<196;i++)
- attributeBuffer[i] = 2;
- g_pMesh->UnlockAttributeBuffer();
- //*******************************填充属性数据**********************************************************************//
- // 产生邻接数据
- DWORD* pAdjacency = new DWORD[g_pMesh->GetNumFaces()*3];;
- g_pMesh->GenerateAdjacency(0.01f, pAdjacency);
- // 设置材质和纹理
- D3DXMATERIAL xMtrl[3];
- xMtrl[0].MatD3D = RED_MTRL;
- xMtrl[0].pTextureFilename = "sidetex.jpg";
- xMtrl[1].MatD3D = YELLOW_MTRL;
- xMtrl[1].pTextureFilename = "toptex.jpg";
- xMtrl[2].MatD3D = YELLOW_MTRL;
- xMtrl[2].pTextureFilename = "bottomtex.jpg";
- // 保存模型到文件中
- D3DXSaveMeshToX(L"cylinder.x", g_pMesh, pAdjacency, xMtrl, NULL, 3, D3DXF_FILEFORMAT_TEXT);
- delete [] pAdjacency;
- // 保存后释放g_pMesh对象
- SAFE_RELEASE(g_pMesh);
- //*******************************载入已存储的.X模型**********************************************************************//
- // 从.X文件中导入模型到g_pMesh对象中
- ID3DXBuffer* pMtrlBuffer;// 定义缓冲,记得一定要释放
- hr = D3DXLoadMeshFromX(L"cylinder.x", D3DXMESH_MANAGED, g_pd3dDevice, NULL, &pMtrlBuffer, NULL, &g_numXMtrl, &g_pMesh);
- if(FAILED(hr))
- {
- MessageBox(0, L"load mesh failed", 0, 0);
- return false;
- }
- D3DXMATERIAL* pMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
- g_pMtrl = new D3DMATERIAL9[g_numXMtrl];
- g_ppTex = new IDirect3DTexture9*[g_numXMtrl];
- for(DWORD i=0;i<g_numXMtrl;i++)
- {
- g_pMtrl[i] = pMtrls[i].MatD3D;
- g_pMtrl[i].Ambient = g_pMtrl[i].Diffuse;
- g_ppTex[i] = 0;
- hr = D3DXCreateTextureFromFileA(g_pd3dDevice, pMtrls[i].pTextureFilename, &g_ppTex[i]);
- if(FAILED(hr))
- g_ppTex[i] = 0;
- }
- // 释放缓冲区
- SAFE_RELEASE(pMtrlBuffer);
- //*******************************载入已存储的.X模型,完毕****************************************************************//
- // 设定渲染状态
- g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0xff444444);
- g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
- g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- // 设置投影矩阵
- D3DXMATRIX proj;
- D3DXMatrixPerspectiveFovLH(
- &proj,
- D3DX_PI * 0.25f, // 45 - degree
- 1,
- 1.0f,
- 100.0f);
- g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);
- return true;
- }
- bool DrawTextX()
- {
- //用于渲染侦FPS
- static int tmLastTime = GetTickCount();
- int tmNow = GetTickCount();
- //用于计算渲染FPS
- static int nFrameCount = 0;
- static int nFPS = 0;
- if(tmNow - tmLastTime > 1000)
- {
- //计算FPS
- tmLastTime = tmNow;
- nFPS = nFrameCount;
- nFrameCount = 0;
- }
- nFrameCount ++;
- char str[500];
- RECT rect;
- rect.left = rect.top = 10;
- rect.bottom = rect.top + 30;
- rect.right = rect.left + 260;
- sprintf_s(str, 500, "Current FPS:%d, please press Q to toggle WireFrame mode", nFPS);
- g_pFont->DrawTextA(NULL, str, (int)strlen(str), &rect, DT_LEFT|DT_NOCLIP|DT_WORDBREAK, 0xffffff00);
- return true;
- }
- bool Display()
- {
- // 获取两次进入函数入口的时间间隔
- static float lastTime = (float)timeGetTime();
- float curTime = (float)timeGetTime();
- float timeDelta = (curTime - lastTime)*0.001f;
- lastTime = curTime;
- // 设定视口矩阵,你可以通过按下上下左右键改变视角
- static float angle = (3.0f * D3DX_PI) / 2.0f;
- static float height = 5.0f;
- if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
- angle -= 0.5f * timeDelta;
- if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
- angle += 0.5f * timeDelta;
- if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
- height += 1.5f * timeDelta;
- if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
- height -= 1.5f * timeDelta;
- D3DXVECTOR3 eyept( cosf(angle) * 10.0f, height, sinf(angle) * 10.0f );
- D3DXVECTOR3 lookAt(0.0f, 0.0f, 0.0f);
- D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
- D3DXMATRIX view_mat;
- D3DXMatrixLookAtLH(&view_mat, &eyept, &lookAt, &up);
- g_pd3dDevice->SetTransform(D3DTS_VIEW, &view_mat);
- // 绘制场景
- g_pd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
- g_pd3dDevice->BeginScene();
- for(DWORD i=0; i<g_numXMtrl; i++)
- {
- // 设置相关的材质和世界矩阵,然后绘制物体
- g_pd3dDevice->SetMaterial(&g_pMtrl[i]);
- g_pd3dDevice->SetTexture(0, g_ppTex[i]);
- g_pMesh->DrawSubset(i);
- }
- // 在屏幕上写字
- if(g_pFont)
- DrawTextX();
- g_pd3dDevice->EndScene();
- g_pd3dDevice->Present(0, 0, 0, 0);
- return true;
- }
- bool CleanUp()
- {
- SAFE_RELEASE(g_pd3dDevice);
- SAFE_RELEASE(g_pd3d);
- SAFE_RELEASE(g_pMesh);
- SAFE_DELETE_ARRAY(g_pMtrl);
- for(DWORD i=0; i<g_numXMtrl; i++)
- {
- SAFE_RELEASE(g_ppTex[i]);
- }
- return true;
- }
- int WINAPI WinMain(HINSTANCE hInstance,
- HINSTANCE prevInstance,
- PSTR cmdLine,
- int showCmd)
- {
- // 应用程序初始化
- if(!InitD3DApp(hInstance, false/*true代表窗口模式*/,
- D3DDEVTYPE_HAL, &g_pd3d, &g_pd3dDevice, L"CreateMeshX"/*窗口标题*/, 1024, 768))
- {
- MessageBoxW(0, L"应用程序初始化失败", 0, 0);
- return 0;
- }
- // 创建字体
- if(!InitDXFont(g_pd3dDevice, &g_pFont, L"Times New Roman"))
- g_pFont = NULL;
- Setup();
- // 进入消息循环
- MSG msg;
- ZeroMemory(&msg, sizeof(msg));
- while(msg.message != WM_QUIT)
- {
- if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- Display();
- }
- }
- CleanUp();
- return 0;
- }
- // 消息循环函数
- LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- static bool bWireFrame = false;
- switch( msg )
- {
- case WM_DESTROY:
- ::PostQuitMessage(0);
- break;
- case WM_KEYDOWN:
- if( wParam == VK_ESCAPE )
- ::DestroyWindow(hwnd);
- break;
- case WM_CHAR:
- if(wParam == 'q')
- bWireFrame = !bWireFrame;
- if(bWireFrame)
- g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
- else
- g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
- break;
- }
- return ::DefWindowProc(hwnd, msg, wParam, lParam);
- }