Я пытаюсь проанализировать файл .x для использования с DirectX. Я написал класс парсера .x, теперь я пытаюсь переопределить функцию ParseObject класса парсера, чтобы я мог загрузить файл сетки (.x). Когда я использую функцию D3DXLoadMeshFromXof, программа выдает исключение и вылетает. Кроме того, я использую tiger.x из DirectX June 2010 SDK! Я пытался открыть другие файлы ... некоторые открываются правильно, другие вызывают сбой в функции CreateEnumObject ... При попытке открыть файл tiger.x программа выдает исключение после того, как я пытаюсь скопировать материалы из материала. буфер в cXMeshParser.cpp:
LPD3DXMATERIAL pMat = (LPD3DXMATERIAL)pMaterials->GetBufferPointer();
Есть идеи?
Вот класс анализатора (CXParser.h):
#pragma once
#include "d3d9.h"
#include "d3dx9.h"
#include "dxfile.h"
#include "initGuid.h"
#include "rmxfguid.h"
class CXParser
{
public:
// Function to start parsing an .X File
BOOL Parse(char *filename, void** data = NULL);
// Functions to retrieve data object information
const GUID *GetObjectGUID(LPD3DXFILEDATA pDataObj);
char *GetObjectName(LPD3DXFILEDATA pDataObj);
//void *GetObjectData(LPD3DXFILEDATA pDataObj, DWORD *dwSize);
protected:
// Functions called when parsing begins and ends
virtual BOOL BeginParse(void **data) {return true;}
virtual BOOL EndParse(void **data) {return true;}
virtual BOOL ParseObject(LPD3DXFILEDATA pDataObj, DWORD Depth, void **data) {return ParseChildObjects(pDataObj, Depth, data);}
BOOL ParseChildObjects(LPD3DXFILEDATA pDataObj, DWORD Depth, void **data);
};
вот исходный файл (CXParser.cpp):
#include "CXParser.h"
#include "d3dx9xof.h"
BOOL CXParser::Parse(char *filename, void** data)
{
LPD3DXFILE pDXFile = NULL;
LPD3DXFILEENUMOBJECT pEnum = NULL;
LPD3DXFILEDATA pDataObj = NULL;
SIZE_T nChildren = NULL;
DWORD Depth = 0;
BeginParse(data);
if(FAILED(D3DXFileCreate(&pDXFile)))
{
MessageBox(NULL, L"Could not Create DX File Interface Object", L"ERROR", MB_OK);
return false;
}
if(FAILED(pDXFile->CreateEnumObject((LPVOID)filename, DXFILELOAD_FROMFILE, &pEnum)))
{
MessageBox(NULL, L"Could not Create DX Enumeration Object", L"ERROR", MB_OK);
pDXFile->Release();
return false;
}
if(FAILED(pEnum->GetChildren(&nChildren)))
{
MessageBox(NULL, L"Could not Enumerate .X File", L"ERROR", MB_OK);
return false;
}
for(SIZE_T index = 0; index < nChildren; index++)
{
if(SUCCEEDED(pEnum->GetChild(index, &pDataObj)))
{
if(!pDataObj->IsReference())
{
GetObjectName(pDataObj);
ParseObject(pDataObj, Depth, NULL);
pDataObj->Release();
}
}
}
EndParse(data);
pEnum->Release();
pDXFile->Release();
return TRUE;
}
BOOL CXParser::ParseChildObjects(LPD3DXFILEDATA pDataObj, DWORD Depth, void **Data)
{
LPD3DXFILEDATA pSubData = NULL;
SIZE_T nChildren = NULL;
Depth++;
if(FAILED(pDataObj->GetChildren(&nChildren)))
{
MessageBox(NULL, L"Could not Enumerate .X File", L"ERROR", MB_OK);
return false;
}
for(SIZE_T index = 0; index < nChildren; index++)
{
if(SUCCEEDED(pDataObj->GetChild(index, &pSubData)))
{
if(!pSubData->IsReference())
{
GetObjectName(pSubData);
ParseChildObjects(pSubData, Depth, NULL);
pSubData->Release();
}
}
}
return true;
}
const GUID *CXParser::GetObjectGUID(LPD3DXFILEDATA pDataObj)
{
// Retrieve the GUID of the Object's Template
GUID *pTemplateGUID = NULL;
if(FAILED(pDataObj->GetType(pTemplateGUID)))
return NULL;
return pTemplateGUID;
}
char *CXParser::GetObjectName(LPD3DXFILEDATA pDataObj)
{
char *Name = NULL;
DWORD dwSize;
// Retrieve the Name of the Object's Template
if(FAILED(pDataObj->GetName(NULL, &dwSize)))
return NULL;
if(dwSize>1){
if((Name = new char[dwSize]) != NULL)
pDataObj->GetName(Name, &dwSize);
}
// Give template a default name if none found
if(!dwSize) {
Name = new char[8];
strcpy_s(Name, sizeof(char)*8, "Unknown");
}
MessageBoxA(NULL, (LPCSTR)Name, "Data Object Found", MB_OK);
return Name;
}
вот класс производного синтаксического анализатора сетки (cXMeshParser.h):
#include "CXParser.h"
class cXMeshParser : public CXParser
{
public:
LPD3DXMESH m_mesh;
public:
cXMeshParser() {m_mesh = NULL;}
~cXMeshParser() {if(m_mesh) m_mesh->Release();}
BOOL ParseObject(LPD3DXFILEDATA pDataObj, DWORD Depth, void **Data);
};
вот исходный файл (cXMeshParser.cpp):
#include "cXMeshParser.h"
#include "dxManager.h"
#include "d3dx9xof.h"
/* Get a reference to the DirectX Manager */
static dxManager& dxMgr = dxManager::getInstance();
BOOL cXMeshParser::ParseObject(LPD3DXFILEDATA pDataObj, DWORD Depth, void **data)
{
if(pDataObj->IsReference())
return true;
LPD3DXBUFFER pMaterials = NULL;
D3DMATERIAL9 *Materials = NULL;
LPDIRECT3DTEXTURE9 *Textures = NULL;
DWORD numMaterials=0;
D3DXLoadMeshFromXof(pDataObj, D3DXMESH_MANAGED, dxMgr.getD3DDevice(), NULL, &pMaterials, NULL, &numMaterials, &m_mesh);
LPD3DXMATERIAL pMat = (LPD3DXMATERIAL)pMaterials->GetBufferPointer();
MessageBox(NULL, L"Made It", L"ALERT", MB_OK);
if(numMaterials)
{
Materials = new D3DMATERIAL9[numMaterials];
Textures = new LPDIRECT3DTEXTURE9[numMaterials];
for(DWORD i = 0; i < numMaterials; i++)
{
Materials[i] = pMat[i].MatD3D;
Materials[i].Ambient = Materials[i].Diffuse;
Textures[i] = NULL;
if(pMat[i].pTextureFilename)
{
D3DXCreateTextureFromFileA(dxMgr.getD3DDevice(), pMat[i].pTextureFilename, &Textures[i]);
}
}
}else
{
// Create a default material if none were loaded
Materials = new D3DMATERIAL9[1];
Textures = new LPDIRECT3DTEXTURE9[1];
Textures[0] = NULL;
ZeroMemory(&Materials[0], sizeof(D3DMATERIAL9));
Materials[0].Diffuse.r = Materials[0].Ambient.r = 1.0f;
Materials[0].Diffuse.g = Materials[0].Ambient.g = 1.0f;
Materials[0].Diffuse.b = Materials[0].Ambient.b = 1.0f;
Materials[0].Diffuse.a = Materials[0].Ambient.a = 1.0f;
}
pMaterials->Release();
return ParseChildObjects(pDataObj, Depth, data);
}
Любые идеи относительно того, почему это исключение, будут приветствоваться! Заранее благодарим за любую помощь, которую вы можете оказать!