赞
踩
//----------------------------------------------------------------------------- // 文件: D3DMesh.h // // 描述: D3DMesh类的头文件,定义变量,函数。 // // 更新: 2009-03-19 by Ninsun //----------------------------------------------------------------------------- #pragma once #include <d3dx9.h> #pragma comment (lib, "d3d9.lib") #pragma comment (lib, "d3dx9.lib") enum RENDERTYPE { RT_INDEX = 0, RT_ANIME = 1, }; class D3DMesh { public: D3DMesh(LPDIRECT3DDEVICE9 _pd3dDevice); public: ~D3DMesh(void); public: HRESULT loadMesh(LPCTSTR _pSrcFile); VOID drawMesh(INT _mode, INT _parameter); VOID setPosition(INT _index, FLOAT _x, FLOAT _y, FLOAT _z); VOID setZoom(INT _index, FLOAT _zoomX, FLOAT _zoomY, FLOAT _zoomZ); VOID setRotation(INT _index, FLOAT _rotationX, FLOAT _rotationY, FLOAT _rotationZ); VOID move(INT _index, FLOAT _x, FLOAT _y, FLOAT _z); private: VOID removePathFromFileName(LPSTR fullPath, LPWSTR fileName); VOID autoExpand(); VOID drawIndex(INT _parameter); VOID drawAnime(INT _parameter); VOID setTransForm(INT _mode); public: private: LPDIRECT3DDEVICE9 m_pd3dDevice; // D3D设备 struct MESH { LPD3DXMESH pMesh; // 网格模型对象 D3DMATERIAL9* pMeshMaterials; // 网格模型材质 LPDIRECT3DTEXTURE9* pMeshTextures; // 网格模型纹理 DWORD dwNumMaterials; // 网格模型材质数量 D3DXVECTOR3 vCenter; // 网格模型中心点 FLOAT fX; // 网格模型坐标 FLOAT fY; // 网格模型坐标 FLOAT fZ; // 网格模型坐标 FLOAT fZoomX; // 网格模型X轴方向缩放比率 FLOAT fZoomY; // 网格模型Y轴方向缩放比率 FLOAT fZoomZ; // 网格模型Z轴方向缩放比率 FLOAT fRotationX; // 网格模型X轴旋转角度 FLOAT fRotationY; // 网格模型Y轴旋转角度 FLOAT fRotationZ; // 网格模型Z轴旋转角度 D3DXMATRIX matTranslate; // 平移变换矩阵 D3DXMATRIX matScaling; // 缩放变换矩阵 D3DXMATRIX matRotationZ; // Z轴旋转变换矩阵 D3DXMATRIX matRotationX; // X轴旋转变换矩阵 D3DXMATRIX matRotationY; // Y轴旋转变换矩阵 }; MESH * m_mesh; // 模型数组 MESH * m_meshTemp; // 模型临时数组 INT m_iMaxIndex; // 最大帧数 INT m_iCurrentIndex; // 当前帧数 INT m_iDelay; // 延迟变量 #define ZOOM (1.0f/100.0f) }; //----------------------------------------------------------------------------- // 文件: D3DMesh.cpp // // 描述: D3DMesh类,用于载入X文件,渲染模型。可以实现移动、缩放、旋转模型,可实现基本动画 // // 更新: 2009-03-19 by Ninsun //----------------------------------------------------------------------------- #include "D3DMesh.h" //----------------------------------------------------------------------------- // 名称: D3DMesh() // 描述: 自定义构造函数 //----------------------------------------------------------------------------- D3DMesh::D3DMesh(LPDIRECT3DDEVICE9 _pd3dDevice) { m_pd3dDevice = _pd3dDevice; m_iMaxIndex = 0; m_iCurrentIndex = 0; m_iDelay = 0; m_mesh = new MESH[m_iMaxIndex+1]; ZeroMemory(m_mesh,(m_iMaxIndex+1)*sizeof(MESH)); m_mesh[0].fZoomX = 1.0f; m_mesh[0].fZoomY = 1.0f; m_mesh[0].fZoomZ = 1.0f; // 初始化变换矩阵 D3DXMatrixTranslation(&m_mesh[0].matTranslate, 0, 0, 0); D3DXMatrixScaling(&m_mesh[0].matScaling, 1.0f,1.0f, 1.0f); D3DXMatrixRotationZ(&m_mesh[0].matRotationZ, 0); D3DXMatrixRotationX(&m_mesh[0].matRotationX, 0); D3DXMatrixRotationY(&m_mesh[0].matRotationY, 0); } D3DMesh::~D3DMesh(void) { } //----------------------------------------------------------------------------- // 名称: autoExpand() // 描述: 自动扩展MESH数组 //----------------------------------------------------------------------------- VOID D3DMesh::autoExpand() { m_meshTemp = new MESH[m_iMaxIndex+2]; ZeroMemory(m_meshTemp,(m_iMaxIndex+2)*sizeof(MESH)); m_meshTemp[m_iMaxIndex+1].fZoomX = 1.0f; m_meshTemp[m_iMaxIndex+1].fZoomY = 1.0f; m_meshTemp[m_iMaxIndex+1].fZoomZ = 1.0f; // 初始化变换矩阵 D3DXMatrixTranslation(&m_meshTemp[m_iMaxIndex+1].matTranslate, 0, 0, 0); D3DXMatrixScaling(&m_meshTemp[m_iMaxIndex+1].matScaling, 1.0f,1.0f, 1.0f); D3DXMatrixRotationZ(&m_meshTemp[m_iMaxIndex+1].matRotationZ, 0); D3DXMatrixRotationX(&m_meshTemp[m_iMaxIndex+1].matRotationX, 0); D3DXMatrixRotationY(&m_meshTemp[m_iMaxIndex+1].matRotationY, 0); memcpy(m_meshTemp,m_mesh, (m_iMaxIndex+1)*sizeof(MESH)); delete m_mesh; m_mesh = m_meshTemp; m_meshTemp = NULL; } //----------------------------------------------------------------------------- // 名称: loadMesh() // 描述: 载入模型 //----------------------------------------------------------------------------- HRESULT D3DMesh::loadMesh(LPCTSTR _pSrcFile) { // 自动扩展MESH数组 autoExpand(); // 存储网格模型材质的缓冲区对象 LPD3DXBUFFER pD3DXMtrlBuffer; // 从磁盘文件加载网格模型 if( FAILED( D3DXLoadMeshFromX( _pSrcFile, D3DXMESH_MANAGED, m_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &m_mesh[m_iMaxIndex].dwNumMaterials, &m_mesh[m_iMaxIndex].pMesh ) ) ) { MessageBox(NULL, _pSrcFile, TEXT("以下模型加载失败"), MB_OK); return E_FAIL; } //从网格模型中提取材质属性和纹理文件名 D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); m_mesh[m_iMaxIndex].pMeshMaterials = new D3DMATERIAL9[m_mesh[m_iMaxIndex].dwNumMaterials]; if( m_mesh[m_iMaxIndex].pMeshMaterials == NULL ) return E_FAIL; m_mesh[m_iMaxIndex].pMeshTextures = new LPDIRECT3DTEXTURE9[m_mesh[m_iMaxIndex].dwNumMaterials]; if( m_mesh[m_iMaxIndex].pMeshTextures == NULL ) return E_FAIL; //逐块提取网格模型材质属性和纹理文件名 for( DWORD i=0; i<m_mesh[m_iMaxIndex].dwNumMaterials; i++ ) { //材料属性 m_mesh[m_iMaxIndex].pMeshMaterials[i] = d3dxMaterials[i].MatD3D; //设置模型材料的环境光反射系数, 因为模型材料本身没有设置环境光反射系数 m_mesh[m_iMaxIndex].pMeshMaterials[i].Ambient = m_mesh[m_iMaxIndex].pMeshMaterials[i].Diffuse; m_mesh[m_iMaxIndex].pMeshTextures[i] = NULL; if( d3dxMaterials[i].pTextureFilename != NULL && strlen(d3dxMaterials[i].pTextureFilename) > 0 ) { //获取纹理文件名 WCHAR filename[256]; removePathFromFileName(d3dxMaterials[i].pTextureFilename, filename); if( FAILED( D3DXCreateTextureFromFile( m_pd3dDevice, filename, &m_mesh[m_iMaxIndex].pMeshTextures[i] ) ) ) { MessageBox(NULL, TEXT("纹理加载失败"), TEXT("失败"), MB_OK); } } } //释放在加载模型文件时创建的保存模型材质和纹理数据的缓冲区对象 pD3DXMtrlBuffer->Release(); m_iMaxIndex++; return S_OK; } //----------------------------------------------------------------------------- // 名称: RemovePathFromFileName() // 描述: 从绝对路径中提取文件名 //----------------------------------------------------------------------------- VOID D3DMesh::removePathFromFileName(LPSTR fullPath, LPWSTR fileName) { //先将fullPath的类型变换为LPWSTR WCHAR wszBuf[MAX_PATH]; MultiByteToWideChar( CP_ACP, 0, fullPath, -1, wszBuf, MAX_PATH ); wszBuf[MAX_PATH-1] = L'/0'; WCHAR* wszFullPath = wszBuf; //从绝对路径中提取文件名 LPCTSTR pch = wcsrchr(wszBuf,'//'); if (pch) { lstrcpy(fileName, TEXT("Mesh//")); lstrcat(fileName, ++pch); } else { lstrcpy(fileName, TEXT("Mesh//")); lstrcat(fileName, wszFullPath); } } //----------------------------------------------------------------------------- // 名称: setPosition() // 描述: 设置模型位置 //----------------------------------------------------------------------------- VOID D3DMesh::setPosition(INT _index, FLOAT _x, FLOAT _y, FLOAT _z) { m_mesh[_index].fX = _x; m_mesh[_index].fY = _y; m_mesh[_index].fZ = _z; D3DXMatrixTranslation(&m_mesh[_index].matTranslate, m_mesh[_index].fX, m_mesh[_index].fY, m_mesh[_index].fZ); } //----------------------------------------------------------------------------- // 名称: move() // 描述: 移动模型位置 //----------------------------------------------------------------------------- VOID D3DMesh::move(INT _index, FLOAT _x, FLOAT _y, FLOAT _z) { m_mesh[_index].fX += _x; m_mesh[_index].fY += _y; m_mesh[_index].fZ += _z; D3DXMatrixTranslation(&m_mesh[_index].matTranslate, m_mesh[_index].fX, m_mesh[_index].fY, m_mesh[_index].fZ); } //----------------------------------------------------------------------------- // 名称: setZoom() // 描述: 设置模型缩放 //----------------------------------------------------------------------------- VOID D3DMesh::setZoom(INT _index, FLOAT _zoomX, FLOAT _zoomY, FLOAT _zoomZ) { m_mesh[_index].fZoomX = _zoomX; m_mesh[_index].fZoomY = _zoomY; m_mesh[_index].fZoomZ = _zoomZ; D3DXMatrixScaling(&m_mesh[_index].matScaling, m_mesh[_index].fZoomX, m_mesh[_index].fZoomY, m_mesh[_index].fZoomZ); } //----------------------------------------------------------------------------- // 名称: setRotation() // 描述: 设置图片旋转 //----------------------------------------------------------------------------- VOID D3DMesh::setRotation(INT _index, FLOAT _rotationX, FLOAT _rotationY, FLOAT _rotationZ) { m_mesh[_index].fRotationX = _rotationX; m_mesh[_index].fRotationY = _rotationY; m_mesh[_index].fRotationZ = _rotationZ; _rotationX = _rotationX * D3DX_PI /180.0f; _rotationY = _rotationY * D3DX_PI /180.0f; _rotationZ = _rotationZ * D3DX_PI /180.0f; D3DXMatrixRotationX(&m_mesh[_index].matRotationX, _rotationX); D3DXMatrixRotationY(&m_mesh[_index].matRotationY, _rotationY); D3DXMatrixRotationZ(&m_mesh[_index].matRotationZ, _rotationZ); } //----------------------------------------------------------------------------- // 名称: setTransForm() // 描述: 设置变换 //----------------------------------------------------------------------------- VOID D3DMesh::setTransForm(INT _mode) { D3DXMATRIX matWorld; if( _mode < 0 ) { D3DXMATRIX matTranslate; D3DXMATRIX matScla; D3DXMATRIX matRotationZ; D3DXMATRIX matRotationX; D3DXMATRIX matRotationY; D3DXMatrixScaling(&matScla, ZOOM, ZOOM, ZOOM); D3DXMatrixTranslation(&matTranslate, 0, 0, 0); D3DXMatrixRotationZ(&matRotationZ, 0); D3DXMatrixRotationX(&matRotationX, 0); D3DXMatrixRotationY(&matRotationY, 0); D3DXMatrixMultiply(&matWorld, &matScla, &matRotationZ); D3DXMatrixMultiply(&matWorld, &matWorld, &matRotationX); D3DXMatrixMultiply(&matWorld, &matWorld, &matRotationY); D3DXMatrixMultiply(&matWorld, &matWorld, &matTranslate); } else { D3DXMATRIX matScla; D3DXMatrixScaling(&matScla, ZOOM, ZOOM, ZOOM); D3DXMatrixMultiply(&matWorld, &m_mesh[_mode].matScaling, &m_mesh[_mode].matRotationX); D3DXMatrixMultiply(&matWorld, &matWorld, &m_mesh[_mode].matRotationY); D3DXMatrixMultiply(&matWorld, &matWorld, &m_mesh[_mode].matRotationZ); D3DXMatrixMultiply(&matWorld, &matWorld, &m_mesh[_mode].matTranslate); D3DXMatrixMultiply(&matWorld, &matWorld, &matScla); } m_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld); } //----------------------------------------------------------------------------- // 名称: drawMesh() // 描述: 绘制模型 //----------------------------------------------------------------------------- VOID D3DMesh::drawMesh(INT _mode, INT _parameter) { switch(_mode) { case RT_INDEX: drawIndex(_parameter); break; case RT_ANIME: drawAnime(_parameter); break; } } //----------------------------------------------------------------------------- // 名称: drawIndex() // 描述: 绘制单帧模型 //----------------------------------------------------------------------------- VOID D3DMesh::drawIndex(INT _index) { for( DWORD i=0; i<m_mesh[_index].dwNumMaterials; i++ ) { //设置材料和纹理 m_pd3dDevice->SetMaterial( &m_mesh[_index].pMeshMaterials[i] ); m_pd3dDevice->SetTexture( 0, m_mesh[_index].pMeshTextures[i] ); //渲染模型 setTransForm(_index); m_mesh[_index].pMesh->DrawSubset( i ); } } //----------------------------------------------------------------------------- // 名称: drawAnime() // 描述: 绘制切帧模型 //----------------------------------------------------------------------------- VOID D3DMesh::drawAnime(INT _delay) { if (m_iDelay < _delay) m_iDelay++; else { if (m_iCurrentIndex < m_iMaxIndex-1) { m_iCurrentIndex++; } else { m_iCurrentIndex = 0; } m_iDelay = 0; } for( DWORD i=0; i<m_mesh[m_iCurrentIndex].dwNumMaterials; i++ ) { //设置材料和纹理 m_pd3dDevice->SetMaterial( &m_mesh[m_iCurrentIndex].pMeshMaterials[i] ); m_pd3dDevice->SetTexture( 0, m_mesh[m_iCurrentIndex].pMeshTextures[i] ); //渲染模型 setTransForm(m_iCurrentIndex); m_mesh[m_iCurrentIndex].pMesh->DrawSubset( i ); } }