X File 解析中遇到的问题和最终解决办法
2011-09-12 10:07
429 查看
一、UNICODE字符串和MBCS字符串的相互转换: 1.从MBCS到UNICODE的转换 BOOL DXUTMByteToWChar( LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize ) { DWORD dwMinSize; dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0); if(dwSize < dwMinSize) { return FALSE; } MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize); return TRUE; } 2.从UNICODE到MBCS的转换 BOOL DXUTWCharToMByte( LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize ) { DWORD dwMinSize; dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE); if(dwSize < dwMinSize) { return FALSE; } WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE); return TRUE; } 二、IDirectXFile系列接口的应用 对于一些需要传递指针的函数(如获取对象名字),在每次调用时候都要手动创建一块内存。为了方便使用可以作一下改进: 1.IDirectXFileObject::GetName的改进(缺点:函数返回的指针不能保存,因为每调用一次都有可能改变静态内存块里面的字符数据) static WCHAR XGetObjName_nameW[1024]; LPCWSTR XGetObjName( IDirectXFileObject* pObj, bool bReturnUniqueName )//must not save the return value for further use! { if(NULL == pObj) return NULL; static char XGetObjName_name[512]; static UINT i = 1;// to identify no name obj ZeroMemory(XGetObjName_name, sizeof(XGetObjName_name)); ZeroMemory(XGetObjName_nameW, sizeof(XGetObjName_nameW)); DWORD len = 0; if (SUCCEEDED( pObj->GetName(NULL, &len) )) { if (len > 0) { pObj->GetName(XGetObjName_name, &len); } else if(bReturnUniqueName) { sprintf_s(XGetObjName_name, "no name: %dth", i++); } } if( DXUTMByteToWChar(XGetObjName_name, XGetObjName_nameW, 1024) ) return XGetObjName_nameW; return NULL; } 2.IDirectXFileData::GetType的改进 const GUID* XGetObjType( IDirectXFileData* pData ) { if(NULL == pData) return NULL; const GUID* pGUID = NULL; if (SUCCEEDED( pData->GetType(&pGUID) ) ) return pGUID; else return NULL; } 3.IDirectXFileData::GetData的改进 void* XGetObjectData(IDirectXFileData *pDataObj, DWORD *pSize) { void *TemplateData = NULL; DWORD TemplateSize = 0; if(pDataObj == NULL) return NULL; HRESULT hr = pDataObj->GetData(NULL,&TemplateSize,(PVOID*)&TemplateData); if (FAILED(hr)) { *pSize = 0; return NULL; } if(pSize != NULL) *pSize = TemplateSize; return TemplateData; } 设计类或函数时 ppUserData / ppUserContext 和 参数默认值 的合理使用 很多情况下我们并不清楚函数调用者的具体应用,这时候用一个指针来传递用户数据是是最好的选择,因为指针一可指向任意的一块数据,调用者在需要的时候可以将这个指转化为适当的数据类型。 1.bool CXFileParserBase::Parse( LPCSTR fileName, void** ppUserData = NULL ); 2.bool CXFileParserBase::ParseObject( IDirectXFileData* pDataObj, IDirectXFileData* pParentDataObj, DWORD depth, bool bRef, void** ppUserData = NULL); 3.bool CXFileParserBase::ParseChildObjects( IDirectXFileData* pDataObj, DWORD depth, bool bRef, void** ppUserData = NULL); 备注:X*类型的地址同样能转化成void**类型! 如: void** ppUserDataTem = (void**)(&m_meshInfo.meshes.back()); return CXFileParserBase::ParseChildObjects(pDataObj, depth, bRef, ppUserDataTem); 递归调用的注意事项 在解析XFile时候用到了大量的递归调用(CXFileParserBase::ParseObject会被多次递归调用),在递归调用时最重要的是要理清思路,把握好递归内部函数的返回时机! 字符串数据的获取方法 DWORD* pData = (DWORD*)XGetObjectData(pDataObj); char* pStr = (char*)(*pData); 在函数内部判断此函数是否被同一个对象调用最好是在内部保存一个静态的对象地址 …… static UINT index = 0; static DWORD* preMtrlIndexG = NULL; XFileMeshData* pMD = (XFileMeshData*)ppUserData; if (preMtrlIndexG != pMD->pMtrlIndexG) { index = 0; preMtrlIndexG = pMD->pMtrlIndexG; } wstring mtrlName = XGetObjName(pDataObj);//get the name of the material that it referenced UINT mtrlIndexG = m_meshInfo.GetMtrlIndex(mtrlName);//get the exact material index pMD->pMtrlIndexG[index++] = mtrlIndexG;// set material global indices …… 如何删除vector中指定元素(符合某种条件的元素) …… //最后删除空mesh vector<XFileMeshData>::iterator iTer = m_meshInfo.meshes.begin(); for ( ; iTer != m_meshInfo.meshes.end() ; ) { if ( iTer->meshName == L"" || NULL == iTer->pMesh || iTer->numSubsets == 0 || 0 == iTer->mtrlIndex.size()) { iTer = m_meshInfo.meshes.erase(iTer); m_meshInfo.numMeshes--; } else { iTer++; } } …… Pandasofts DirectX 导出时注意事项和问题: Optimize mesh: none (adviced option:)如果选择optimezed选项用CXFileMesh类解析时会导致部分法线错误! 待解决问题:如何导出法线贴图 |
相关文章推荐
- VC6.0工程升级到VS2010遇到问题及解决办法 【LNK2019】 无法解析的外部符号 __iob
- IOS json 解析遇到错误问题解决办法
- 百度富文本ueditor和umeditor遇到的问题和解决办法
- 编译器&调试---emulator.exe 遇到问题需要关闭 的解决办法
- 自己搭建MVC时遇到的一些问题及解决办法
- Git 使用过程中遇到的问题以及解决办法
- 自己在使用Android Maps API 开发地图应用程序时遇到的问题,以及解决的办法
- 在access的vba中循环调用带参数查询时遇到的问题及解决办法
- 用Fuel部署OpenStack的时候可能遇到的问题及部分解决办法
- PowerDesigner (12.5) 数据库建模遇到的问题和解决办法
- python 调用pymysql模块遇到\转义问题解决办法
- 开发中遇到的问题及解决办法
- 使用asp.net MVC4中的Bundle遇到的问题及解决办法分享
- android学习——文件下载遇到的问题及解决办法
- 新浪微博爬虫遇到的cookie rejected 问题解决办法
- MySql压缩版遇到的问题和解决办法
- VMware安装Ubuntu(附上所遇到问题解决办法)
- android中画文字的换行 办法(对于遇到canvas.drawText(String s )无法实现换行问题的解决)
- Android studio 安装中遇到一些问题的解决办法,分享一下
- Spark中遇到的一些问题和相应的解决办法