DirectX - анализ файла .X: D3DXLoadMeshFromXof Crash - PullRequest
1 голос
/ 30 января 2012

Я пытаюсь проанализировать файл .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);
}

Любые идеи относительно того, почему это исключение, будут приветствоваться! Заранее благодарим за любую помощь, которую вы можете оказать!

...