以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- DXUT源码分析 ---- 类CDXUTMeshFile (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=70889) |
-- 作者:卷积内核 -- 发布时间:12/26/2008 10:52:00 AM -- DXUT源码分析 ---- 类CDXUTMeshFile 类CDXUTMeshFile位于DXUTMesh.h和DXUTMesh.cpp中,继承自类CDXUTMeshFrame,其实类CDXUTMeshFrame本身只完成一些基础操作,不是最终使用的一个类,CDXUTMeshFile在CDXUTMeshFrame的基础上将各种操作进一步封装。 在.x网格模型中使用框架的主要目的是实现模型自身包含的动画,而CDXUTMeshFile和CDXUTMeshFrame虽然考虑了网格模型的层次框架,可是并没有实现对网格模型动画的播放,所以通常不直接使用这两个类,因为对于不包含动画信息的静态网格模型CDXUTMesh类就已经足够了。当然也完全可以像使用CDXUTMesh类一样使用CDXUTMeshFile类来操作不包含动画信息的网格模型。 来看看CDXUTMeshFile的定义: //----------------------------------------------------------------------------- public: // For pure devices, specify the world transform. CDXUTMeshFile() : CDXUTMeshFrame( L"CDXUTMeshFile_Root" ) {} // Get the mesh name CHAR strAnsiName[512] = {0}; if( FAILED( hr = pFileData->GetName(strAnsiName, &dwNameLength) ) ) MultiByteToWideChar(CP_ACP, 0, strAnsiName, -1, strName, 512); // Create the mesh pParentFrame->m_pMesh = new CDXUTMesh(strName); if( pParentFrame->m_pMesh == NULL ) pParentFrame->m_pMesh->Create( pd3dDevice, pFileData ); return S_OK; LoadFrame()用于从ID3DXFileData中加载一个框架: HRESULT CDXUTMeshFile::LoadFrame(LPDIRECT3DDEVICE9 pd3dDevice, LPD3DXFILEDATA pFileData, CDXUTMeshFrame* pParentFrame) // Get the type of the object if(Guid == TID_D3DRMMesh) if( FAILED(hr) ) if( FAILED(hr) ) // Update the parent's matrix with the new one if( FAILED( hr = pFileData->GetName(strAnsiName, &dwNameLength) ) ) MultiByteToWideChar(CP_ACP, 0, strAnsiName, -1, strName, 512); // Create the frame pCurrentFrame->m_pNext = pParentFrame->m_pChild; // Enumerate child objects pFileData->GetChildren(&cChildren); for (UINT iChild = 0; iChild < cChildren; iChild++) if( SUCCEEDED(hr) ) if( FAILED(hr) ) return S_OK; if( FAILED( hr = pFileData->GetName(strAnsiName, &dwNameLength) ) ) return hr; // Create the frame pCurrentFrame = new CDXUTMeshFrame(strName); if(pCurrentFrame == NULL) return E_OUTOFMEMORY; // Enumerate child objects 第一个Create()函数负责从模型文件加载网格模型: HRESULT CDXUTMeshFile::Create(LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename) // Create a x file object // Register templates for d3drm and patch extensions. // Find the path to the file, and convert it to ANSI (for the D3DXOF API) WCHAR strPath[MAX_PATH]; if( FAILED(hr) ) // Enumerate top level objects (which are always frames) for (UINT iChild = 0; iChild < cChildren; iChild++) hr = LoadFrame(pd3dDevice, pFileData, this); if( FAILED(hr) ) SAFE_RELEASE(pFileData); return S_OK; // Find the path to the file, and convert it to ANSI (for the D3DXOF API) // Create enum object hr = pDXFile->CreateEnumObject((void*) strPathANSI, D3DXF_FILELOAD_FROMFILE, &pEnumObj); Creates an enumerator object that will read a .x file. HRESULT CreateEnumObject( LPCVOID pvSource, D3DXF_FILELOADOPTIONS loadflags, ID3DXFileEnumObject ** ppEnumObj); Remarks 再接下来通过ID3DXFileEnumObjec枚举对象读取数据并调用LoadFrame()加载框架: // Enumerate top level objects (which are always frames) pEnumObj->GetChildren(&cChildren); SAFE_RELEASE(pFileData); SAFE_RELEASE(pEnumObj); SAFE_RELEASE(pDXFile); 第二个Create()函数与第一个非常类似,只是该函数负责从资源加载网格模型: HRESULT CDXUTMeshFile::CreateFromResource(LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strResource, LPCWSTR strType) // Create a x file object // Register templates for d3drm and patch extensions. WideCharToMultiByte(CP_ACP, 0, strType, -1, strTypeAnsi, MAX_PATH, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, strResource, -1, strResourceAnsi, MAX_PATH, NULL, NULL); D3DXF_FILELOADRESOURCE dxlr; dxlr.hModule = NULL; // Create enum object if( FAILED(hr) ) // Enumerate top level objects (which are always frames) pEnumObj->GetChildren(&cChildren); for (UINT iChild = 0; iChild < cChildren; iChild++) hr = LoadFrame(pd3dDevice, pFileData, this); if( FAILED(hr) ) SAFE_RELEASE(pFileData); return S_OK; 唯一需要解释的代码是: D3DXF_FILELOADRESOURCE dxlr; |
-- 作者:卷积内核 -- 发布时间:12/26/2008 10:53:00 AM -- 该代码片段负责从指定的资源中加载网格模型,D3DXF_FILELOADRESOURCE的声明如下: Identifies resource data. typedef struct D3DXF_FILELOADRESOURCE { HMODULE hModule; LPCSTR lpName; LPCSTR lpType;} D3DXF_FILELOADRESOURCE, *LPD3DXF_FILELOADRESOURCE;
Render()函数负责网格模型的渲染,它允许用户在调用时设置一个世界坐标矩阵: HRESULT CDXUTMeshFile::Render(LPDIRECT3DDEVICE9 pd3dDevice, D3DXMATRIX* pmatWorldMatrix) // Set up the world transformation if (NULL == pmatWorldMatrix) D3DXMatrixMultiply(&matWorld, &matSavedWorld, &m_mat); // Render opaque subsets in the meshes // Enable alpha blending // Render alpha subsets in the meshes // Restore state return S_OK; 也就是说在创建该类对象时默认创建了一个CDXUTMeshFrame对象,这也意味着在加载网格模型时所有后续的CDXUTMeshFrame对象都是该对象的子对象,所以下面的代码是合法的: // Render opaque subsets in the meshes if(m_pChild) m_pChild->Render(pd3dDevice, TRUE, FALSE, &matWorld);
|
-- 作者:秋十三 -- 发布时间:1/2/2009 8:32:00 PM -- 好 我顶啊!!! |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
3,091.797ms |