Well, 我們的Exporter還沒做完。
我們在MyExporter1::DoExport設定中斷點,會發現,這個函式會在我們選定了輸出檔,按下存檔之後才被呼叫。這時候,就開始了輸出工作。
首先會看到一個對話盒。
DoExport的程式碼裡,也就呼叫這個對話盒而已,實際輸出工作的呼叫,還是得要我們自己來。
這個對話盒是project wizard幫我們建立的,專案裡面有一個rc檔,我們可以打開來自己改。
例如,改成這樣,
我們可以將輸出時候需要的設定與選項,放在這對話盒裡頭,使用者按下了OK,實際的輸出工作就會開始進行了。
接下來,我們真的要開始從Max抓資料了。
Max有SDK,SDK也有Help文件。但是我們看習慣了MSDN, DirectX SDK文件之後,會發現Max SDK的文件真的是弄得很糟糕。但是我們還是得看。
有總比沒有好。
為了讓程式碼結構清晰些,我們建立一個ExporterPipeline物件來做這一堆苦工。
class CExporterPipeline
{
public:
CExporterPipeline();
~CExporterPipeline();
HRESULT Create(const char* model_name,const ExporterParameters& param);
void SyncData();
HRESULT Destroy();
private:
void BeginSync();
void EndSync();
void SyncScene();
void SyncGameNodeTree(int level,IGameNode* node,IGameNode* parent_node);
void SyncGameNode(int level, IGameNode* node,IGameNode* parent_node);
void SyncGameNodeGameObject(IGameNode* node, IGameObject* go);
void SyncGameNodeMesh(IGameNode* node, IGameMesh* gm);
void SyncGameNodeMaterial(IGameNode* node);
void SyncGeometryData(IGameNode* node,IGameMesh* gm);
void SyncMaterial(IGameNode* node, int matid, Mtl* mtl);
void UpdateMeshSkinVertex(IGameNode* node,IGameMesh* gm);
void UpdateNodeFrameAnimation(IGameNode* node);
private:
Interface* m_MaxCore;
IGameScene* m_Scene;
IGameConversionManager* m_ConversionMgr;
FILE* m_fpExportFile;
ExporterParameters m_ExportParameters;
int m_nTotalNodeCount;
int m_nProgressNodeCount;
std::vector<int> m_GameNodeIDArray;
};
extern CExporterPipeline g_ExporterPipeline;
ExporterPipeline只有幾個public函式: Create, SyncData, Destroy。其餘的苦工全部寫在private函式裡。
我們在MyExporter1::DoExport裡面這樣呼叫 :
int MyExporter1::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)
{
#pragma message(TODO("Implement the actual file Export here and"))
if(!suppressPrompts)
DialogBoxParam(hInstance,
MAKEINTRESOURCE(IDD_PANEL),
GetActiveWindow(),
MyExporter1OptionsDlgProc, (LPARAM)this);
ExporterParameters params;
g_ExporterPipeline.Create(name,params);
g_ExporterPipeline.SyncData();
g_ExporterPipeline.Destroy();
#pragma message(TODO("return TRUE If the file is exported properly"))
return FALSE;
}
Create建立需要的物件與檔案,SyncData處理資料輸出,Destroy清除物件以及關閉檔案。
大致上外部的步驟就這樣。細節都藏在Exporter Pipeline裡,下回再繼續吧...