|  | 
 
| 本帖最后由 夜行的猫仔 于 2012-9-16 13:00 编辑 
 FBX环境配置请点击这里
 DirectX SDK的安装与开发环境的配置
 http://forum.exceedu.com/forum/forum.php?mod=viewthread&tid=22539&fromuid=14479
 
 
 同过一天对FBX SDK的了解,基本上了解了FBX的大致调用过程,并通过微软的D3D将FBX数据绘制出来。
 
 1   
 在3DsMax中创建一个单位1的红色Box:
 
 通过FBX_Samples01程序读入FBX到内存,获取FBX模型坐标,填充到D3DXMESH中并画出来~~~
 目前没有实现读取模型颜色,d3d里面的模型颜色是我手动指定的。
 也没有找到Fbx的顶点索引数据,因此我手动指定了索引缓冲取的排列。
 
 以上例题源码下载地址:
 http://kuai.xunlei.com/d/SAIKKXEKUEVO
 
 以下讲解完成fbx文件读写需要的一些步骤。在这里主要讲解读取fbx文件,关于显示使用到的到d3d部分请同学们到论坛的d3d区补充学习。
 
 
 初始化FbxManager和FbxScene:
 在进行使用SDK进行FBX的处理操作之前需要先初始化两个必须的FBX对象:FbxManager和FbxScene
 这里面关键性的变量有两个:m_pFBXSDKManager 和 m_pFBXSDKScene。复制代码bool CFBXLoader::Initialize()
{
        // Create the FBX SDK Manager, destroy the old manager at first 
        if(m_pFBXSDKManager)  
        {  
                m_pFBXSDKManager->Destroy();
        }
        m_pFBXSDKManager = KFbxSdkManager::Create(); 
        if(m_pFBXSDKManager == NULL)  
        {
                return false; 
        }
        // Create an IOSettings object  
        KFbxIOSettings* ios = KFbxIOSettings::Create(m_pFBXSDKManager , IOSROOT);  
        m_pFBXSDKManager->SetIOSettings(ios);  
        //Load plugins from the executable directory (optional)
        FbxString lPath = FbxGetApplicationDirectory();
        m_pFBXSDKManager->LoadPluginsDirectory(lPath.Buffer());
        // Create the entity that hold the whole Scene  
        m_pFBXSDKScene = KFbxScene::Create(m_pFBXSDKManager , "");  
        if(m_pFBXSDKScene == NULL)  
        {
                return false; 
        }
        return true;  
}
 fbx文件数据的加载:
 FBX资源的释放只需要释放FbxManager即可。复制代码bool CFBXLoader::LoadFile(const char* pSeneName)
{
        if(m_pFBXSDKManager == NULL)  
        {  
                return false;  
        }  
        int lFileMajor, lFileMinor, lFileRevision;
        int lSDKMajor,  lSDKMinor,  lSDKRevision;
        int lAnimStackCount;
        //char lPassword[1024];
        // Get the file version number generate by the FBX SDK.  
        KFbxSdkManager::GetFileFormatVersion(lSDKMajor , lSDKMinor , lSDKRevision);  
        // Create an importer.
        int lFileFormat = -1;
        KFbxImporter* pKFBXImporter = KFbxImporter::Create(m_pFBXSDKManager , "");  
        if (!m_pFBXSDKManager->GetIOPluginRegistry()->DetectReaderFileFormat(pSeneName, lFileFormat) )
        {
                // Unrecognizable file format. Try to fall back to FbxImporter::eFBX_BINARY
                lFileFormat = m_pFBXSDKManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary (*.fbx)" );;
        }
        // Initialize the importer by providing a filename  
        bool importStatus = pKFBXImporter->Initialize(pSeneName , -1 , m_pFBXSDKManager->GetIOSettings());  
        pKFBXImporter->GetFileVersion(lFileMajor , lFileMinor , lFileRevision);  
        if(!importStatus)  
        {  
                return false;  
        }  
        FbxTakeInfo* lTakeInfo; 
        if (pKFBXImporter->IsFBX())
        {
                 lAnimStackCount = pKFBXImporter->GetAnimStackCount();
                 for(int i = 0; i < lAnimStackCount; i++)
                 {
                         lTakeInfo = pKFBXImporter->GetTakeInfo(i);
                 }
                 //IOS_REF.SetBoolProp(IMP_FBX_MATERIAL,        true);
                 //IOS_REF.SetBoolProp(IMP_FBX_TEXTURE,         true);
                 //IOS_REF.SetBoolProp(IMP_FBX_LINK,            true);
                 //IOS_REF.SetBoolProp(IMP_FBX_SHAPE,           true);
                 //IOS_REF.SetBoolProp(IMP_FBX_GOBO,            true);
                 //IOS_REF.SetBoolProp(IMP_FBX_ANIMATION,       true);
                 //IOS_REF.SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);
        }
        // Import the scene  
        importStatus = pKFBXImporter->Import(m_pFBXSDKScene);  
        // Destroy the importer.  
        pKFBXImporter->Destroy();  
        return importStatus;  
}
获取Box的顶点数据:复制代码CFBXLoader::~CFBXLoader(void)
{
        //Delete the FBX Manager. All the objects that have been allocated using the FBX Manager and that haven't been explicitly destroyed are also automatically destroyed.
        m_pFBXSDKManager->Destroy();
}
GetMeshInfo函数通过pNode->GetNodeAttribute ()方法获取到当前指向的mesh数据地址。复制代码
void CFBXLoader::GetMeshInfo(FbxNode* pNode)
{
         FbxMesh* lMesh = (FbxMesh*) pNode->GetNodeAttribute ();
         GetControlsPoints(lMesh);
}
void CFBXLoader::GetControlsPoints(FbxMesh* pMesh)
{
        int i, lControlPointsCount = pMesh->GetControlPointsCount();
        FbxVector4* lControlPoints = pMesh->GetControlPoints();        
        FbxVector4  temp;
        for (i = 0; i < lControlPointsCount; i++)
        {
                temp = lControlPoints[i];
                vBuffer[i].x = temp.mData[0];
                vBuffer[i].y = temp.mData[1];
                vBuffer[i].z = temp.mData[2];
                vBuffer[i].color = 0xffFF0000;
        }
}
然后通过pMesh->GetControlPointsCount();获取模型定点个数, 通过pMesh->GetControlPoints();函数获取顶点数据首地址。
 指针lControlPoints 内保存的就是顶点数据,数量个数为lControlPointsCount 个。lControlPoints是一个FbxVector4四维向量,其中数据排列的顺序是x,y,z,w。不懂齐次坐标w的此处可以忽略,以为作为顶点数据这里都是0。
 下面通过一个循环从内存中逐个将数据取出存放在缓存vBuffer中。
 为了方便测试看到赋值情况,我中间临时增加了一个temp变量,仅作测试时使用。复制代码        FbxVector4  temp;
        for (i = 0; i < lControlPointsCount; i++)
        {
                temp = lControlPoints[i];
                vBuffer[i].x = temp.mData[0];
                vBuffer[i].y = temp.mData[1];
                vBuffer[i].z = temp.mData[2];
        }
 | 
 |