📄 winmain.cpp
字号:
}
// Display the scene
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
return TRUE;
}
sFrame *LoadFile(char *Filename)
{
return ParseXFile(Filename);
}
sFrame *ParseXFile(char *Filename)
{
IDirectXFile *pDXFile = NULL;
IDirectXFileEnumObject *pDXEnum = NULL;
IDirectXFileData *pDXData = NULL;
sFrame *Frame;
// Create the file object
if(FAILED(DirectXFileCreate(&pDXFile)))
return FALSE;
// Register the templates
if(FAILED(pDXFile->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES))) {
pDXFile->Release();
return FALSE;
}
// Create an enumeration object
if(FAILED(pDXFile->CreateEnumObject((LPVOID)Filename, DXFILELOAD_FROMFILE, &pDXEnum))) {
pDXFile->Release();
return FALSE;
}
// Allocate a frame that becomes root
Frame = new sFrame();
// Loop through all objects looking for the frames and meshes
while(SUCCEEDED(pDXEnum->GetNextDataObject(&pDXData))) {
ParseXFileData(pDXData, Frame);
ReleaseCOM(pDXData);
}
// Release used COM objects
ReleaseCOM(pDXEnum);
ReleaseCOM(pDXFile);
// Return root frame
return Frame;
}
void ParseXFileData(IDirectXFileData *pDataObj, sFrame *ParentFrame)
{
IDirectXFileObject *pSubObj = NULL;
IDirectXFileData *pSubData = NULL;
IDirectXFileDataReference *pDataRef = NULL;
const GUID *Type = NULL;
char *Name = NULL;
DWORD Size;
sFrame *Frame = NULL;
sFrame *SubFrame = NULL;
sMesh *Mesh = NULL;
ID3DXBuffer *MaterialBuffer = NULL;
D3DXMATERIAL *Materials = NULL;
ID3DXBuffer *Adjacency = NULL;
DWORD *AdjacencyIn = NULL;
DWORD *AdjacencyOut = NULL;
DWORD i;
// Get the template type
if(FAILED(pDataObj->GetType(&Type)))
return;
// Get the template name (if any)
if(FAILED(pDataObj->GetName(NULL, &Size)))
return;
if(Size) {
if((Name = new char[Size]) != NULL)
pDataObj->GetName(Name, &Size);
}
// Give template a default name if none found
if(Name == NULL) {
if((Name = new char[9]) == NULL)
return;
strcpy(Name, "Template");
}
// Set sub frame
SubFrame = ParentFrame;
// Process the templates
// Frame
if(*Type == TID_D3DRMFrame) {
// Create a new frame structure
Frame = new sFrame();
// Store the name
Frame->m_Name = Name;
Name = NULL;
// Add to parent frame
Frame->m_Sibling = ParentFrame->m_Child;
ParentFrame->m_Child = Frame;
// Set sub frame parent
SubFrame = Frame;
}
// Load a mesh
if(*Type == TID_D3DRMMesh) {
// Create a new mesh structure
Mesh = new sMesh();
// Store the name
Mesh->m_Name = Name;
Name = NULL;
// Load mesh data (as a skinned mesh)
if(FAILED(D3DXLoadSkinMeshFromXof(pDataObj, 0,
g_pD3DDevice,
&Adjacency,
&MaterialBuffer, &Mesh->m_NumMaterials,
&Mesh->m_BoneNames, &Mesh->m_BoneTransforms,
&Mesh->m_SkinMesh))) {
delete Mesh;
return;
}
// Convert to regular mesh if no bones
if(!(Mesh->m_NumBones = Mesh->m_SkinMesh->GetNumBones())) {
// Convert to a regular mesh
Mesh->m_SkinMesh->GetOriginalMesh(&Mesh->m_Mesh);
ReleaseCOM(Mesh->m_SkinMesh);
} else {
// Get a pointer to bone matrices
Mesh->m_BoneMatrices = (D3DXMATRIX*)Mesh->m_BoneTransforms->GetBufferPointer();
// Allocate buffers for adjacency info
AdjacencyIn = (DWORD*)Adjacency->GetBufferPointer();
AdjacencyOut = new DWORD[Mesh->m_SkinMesh->GetNumFaces() * 3];
// Generate the skin mesh object
if(FAILED(Mesh->m_SkinMesh->GenerateSkinnedMesh(
D3DXMESH_WRITEONLY, 0.0f,
AdjacencyIn, AdjacencyOut,
&Mesh->m_Mesh))) {
// Convert to a regular mesh if error
Mesh->m_SkinMesh->GetOriginalMesh(&Mesh->m_Mesh);
ReleaseCOM(Mesh->m_SkinMesh);
Mesh->m_NumBones = 0;
}
delete [] AdjacencyOut;
ReleaseCOM(Adjacency);
}
// Load materials or create a default one if none
if(!Mesh->m_NumMaterials) {
// Create a default one
Mesh->m_Materials = new D3DMATERIAL8[1];
Mesh->m_Textures = new LPDIRECT3DTEXTURE8[1];
ZeroMemory(Mesh->m_Materials, sizeof(D3DMATERIAL8));
Mesh->m_Materials[0].Diffuse.r = 1.0f;
Mesh->m_Materials[0].Diffuse.g = 1.0f;
Mesh->m_Materials[0].Diffuse.b = 1.0f;
Mesh->m_Materials[0].Diffuse.a = 1.0f;
Mesh->m_Materials[0].Ambient = Mesh->m_Materials[0].Diffuse;
Mesh->m_Materials[0].Specular = Mesh->m_Materials[0].Diffuse;
Mesh->m_Textures[0] = NULL;
Mesh->m_NumMaterials = 1;
} else {
// Load the materials
Materials = (D3DXMATERIAL*)MaterialBuffer->GetBufferPointer();
Mesh->m_Materials = new D3DMATERIAL8[Mesh->m_NumMaterials];
Mesh->m_Textures = new LPDIRECT3DTEXTURE8[Mesh->m_NumMaterials];
for(i=0;i<Mesh->m_NumMaterials;i++) {
Mesh->m_Materials[i] = Materials[i].MatD3D;
Mesh->m_Materials[i].Ambient = Mesh->m_Materials[i].Diffuse;
// Build a texture path and load it
if(FAILED(D3DXCreateTextureFromFile(g_pD3DDevice,
Materials[i].pTextureFilename,
&Mesh->m_Textures[i]))) {
Mesh->m_Textures[i] = NULL;
}
}
}
ReleaseCOM(MaterialBuffer);
// Link in mesh
Mesh->m_Next = ParentFrame->m_Mesh;
ParentFrame->m_Mesh = Mesh;
}
// Skip animation sets and animations
if(*Type == TID_D3DRMAnimationSet || *Type == TID_D3DRMAnimation || *Type == TID_D3DRMAnimationKey) {
delete [] Name;
return;
}
// Release name buffer
delete [] Name;
// Scan for embedded templates
while(SUCCEEDED(pDataObj->GetNextObject(&pSubObj))) {
// Process embedded references
if(SUCCEEDED(pSubObj->QueryInterface(IID_IDirectXFileDataReference, (void**)&pDataRef))) {
if(SUCCEEDED(pDataRef->Resolve(&pSubData))) {
ParseXFileData(pSubData, SubFrame);
ReleaseCOM(pSubData);
}
ReleaseCOM(pDataRef);
}
// Process non-referenced embedded templates
if(SUCCEEDED(pSubObj->QueryInterface(IID_IDirectXFileData, (void**)&pSubData))) {
ParseXFileData(pSubData, SubFrame);
ReleaseCOM(pSubData);
}
ReleaseCOM(pSubObj);
}
return;
}
void DrawFrame(sFrame *Frame)
{
sMesh *Mesh;
D3DXMATRIX *Matrices;
DWORD i;
// Return if no frame
if(Frame == NULL)
return;
// Draw meshes if any in frame
if((Mesh = Frame->m_Mesh) != NULL) {
// Generate mesh from skinned mesh to draw with
if(Mesh->m_SkinMesh != NULL) {
// Allocate an array of matrices to orient bones
Matrices = new D3DXMATRIX[Mesh->m_NumBones];
// Set all bones orientation to identity
for(i=0;i<Mesh->m_NumBones;i++)
D3DXMatrixIdentity(&Matrices[i]);
// Update skinned mesh
Mesh->m_SkinMesh->UpdateSkinnedMesh(Matrices, Mesh->m_Mesh);
// Render the mesh
for(i=0;i<Mesh->m_NumMaterials;i++) {
g_pD3DDevice->SetMaterial(&Mesh->m_Materials[i]);
g_pD3DDevice->SetTexture(0, Mesh->m_Textures[i]);
Mesh->m_Mesh->DrawSubset(i);
}
// Free array of matrices
delete [] Matrices;
}
// Go to next mesh
Mesh = Mesh->m_Next;
}
// Draw child frames
DrawFrame(Frame->m_Child);
// Draw sibling frames
DrawFrame(Frame->m_Sibling);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -