Hello,
I'm having a converter for x-meshes - I know, probably not the most modern format, but time to an assignemnt is due, and I don't want ot include and write another importer yet. The x-files serve their purpose under most circumstances - however, a few specific meshes seem to fail. I used all kinds of different meshes - some from the net, some convertes using 3ds-max, so it does not seem to be an issue with the files themselfs - some work, some don't its always the same, but it doesn't matter where they came from.
For example, this recent mesh I'm going to use for an assignment, always crashes after calling the "ID3DXAllocateHierarchy::CreateFrame"-mehod for the 66th time, after creating the final frame (I assume that its the final - its name is the same as the mesh, at least". The crash happens here:
HRESULT STDMETHODCALLTYPE AllocMeshHierarchy::CreateFrame(LPCSTR Name, D3DXFRAME** ppNewFrame)
{
if(ppNewFrame)
{
D3DXFRAME* pFrame = new D3DXFRAME;
ZeroMemory(pFrame, sizeof(D3DXFRAME));
if(Name)
{
const size_t nameLength = strlen(Name)+1;
pFrame->Name = new char[nameLength];
strcpy_s(pFrame->Name, nameLength, Name);
}
else
{
pFrame->Name = new char[1];
pFrame->Name[0] = '\0';
}
*ppNewFrame = pFrame;
}
return D3D_OK;
}
The exact crash line is pointet to the "strcpy_s"-line, but it really happens once this function is done, and after I step out, I get the error. Setting a breakpoint at the beginning doesn't trigger before the crash, so I'm supposing it doesn't really happen here. Without posting the mesh here (I've got to check legals with the creator first), does anybody see something wrong here, or did somebody have an issue along those lines? Here is the full code that loads the mesh:
/****************************************
* Load mesh from file to graphic memory
****************************************/
AllocMeshHierarchy allocHierachy;
LoadUserData userData;
LPD3DXFRAME lpFrame = nullptr;
LPD3DXANIMATIONCONTROLLER lpController = nullptr;
// crash happens inside here
if(D3DXLoadMeshHierarchyFromX(stInName.c_str(), D3DXMESH_MANAGED, m_device.GetDevice(), &allocHierachy, &userData, &lpFrame, &lpController))
throw resourceLoadException(stInName);
Here is the complete alloc-hierachy-class (though the othet three methods are never called before the crash, and so isn't the userData-loader):
HRESULT STDMETHODCALLTYPE AllocMeshHierarchy::CreateFrame(LPCSTR Name, D3DXFRAME** ppNewFrame)
{
if(ppNewFrame)
{
D3DXFRAME* pFrame = new D3DXFRAME;
ZeroMemory(pFrame, sizeof(D3DXFRAME));
if(Name)
{
const size_t nameLength = strlen(Name)+1;
pFrame->Name = new char[nameLength];
strcpy_s(pFrame->Name, nameLength, Name);
}
else
{
pFrame->Name = new char[1];
pFrame->Name[0] = '\0';
}
*ppNewFrame = pFrame;
}
return D3D_OK;
}
HRESULT STDMETHODCALLTYPE AllocMeshHierarchy::CreateMeshContainer(PCSTR Name,
const D3DXMESHDATA* pMeshData,
const D3DXMATERIAL* pMaterials,
const D3DXEFFECTINSTANCE* pEffectInstances,
DWORD NumMaterials,
const DWORD *pAdjacency,
ID3DXSkinInfo* pSkinInfo,
D3DXMESHCONTAINER** ppNewMeshContainer)
{
if(pMeshData->Type != D3DXMESHTYPE_MESH)
return E_FAIL;
D3DXMESHCONTAINER* pMeshContainer = new D3DXMESHCONTAINER;
ZeroMemory(pMeshContainer, sizeof(D3DXMESHCONTAINER));
pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;
const size_t nameLength = strlen(Name)+1;
pMeshContainer->Name = new char[nameLength];
strcpy_s(pMeshContainer->Name, nameLength, Name);
const size_t numVertices = pMeshData->pMesh->GetNumFaces()*3;
pMeshContainer->pAdjacency = new DWORD[numVertices];
memcpy(pMeshContainer->pAdjacency, pAdjacency, sizeof(DWORD)*numVertices);
pMeshContainer->MeshData.pMesh = pMeshData->pMesh;
pMeshContainer->MeshData.pMesh->AddRef();
pMeshContainer->NumMaterials = NumMaterials;
pMeshContainer->pMaterials = new D3DXMATERIAL[NumMaterials];
for(unsigned int i = 0; i < NumMaterials; i++)
{
pMeshContainer->pMaterials[i].MatD3D = pMaterials[i].MatD3D;
if(pMaterials[i].pTextureFilename)
{
const size_t materialLength = strlen(pMaterials[i].pTextureFilename) + 1;
pMeshContainer->pMaterials[i].pTextureFilename = new char[materialLength];
strcpy_s(pMeshContainer->pMaterials[i].pTextureFilename, materialLength, pMaterials[i].pTextureFilename);
}
else
{
pMeshContainer->pMaterials[i].pTextureFilename = new char[1];
pMeshContainer->pMaterials[i].pTextureFilename[0] = '\0';
}
}
if(pSkinInfo)
{
pMeshContainer->pSkinInfo = pSkinInfo;
pSkinInfo->AddRef();
DWORD maxVertices, numCombination;
LPD3DXBUFFER lpBuffer = nullptr;
LPD3DXMESH pMesh = nullptr;
pSkinInfo->ConvertToIndexedBlendedMesh(pMeshContainer->MeshData.pMesh,
D3DXMESH_MANAGED | D3DXMESHOPT_VERTEXCACHE,
pSkinInfo->GetNumBones(),
pMeshContainer->pAdjacency,
nullptr,
nullptr,
nullptr,
&maxVertices,
&numCombination,
&lpBuffer,
&pMesh);
pMeshContainer->MeshData.pMesh->Release();
pMeshContainer->MeshData.pMesh = pMesh;
}
*ppNewMeshContainer = pMeshContainer;
return D3D_OK;
}
HRESULT STDMETHODCALLTYPE AllocMeshHierarchy::DestroyFrame(THIS_ D3DXFRAME* pFrameToFree)
{
delete[] pFrameToFree->Name;
delete pFrameToFree;
return D3D_OK;
}
HRESULT STDMETHODCALLTYPE AllocMeshHierarchy::DestroyMeshContainer(THIS_ D3DXMESHCONTAINER* pMeshContainerBase)
{
pMeshContainerBase->pSkinInfo->Release();
pMeshContainerBase->MeshData.pMesh->Release();
delete[] pMeshContainerBase->Name;
delete[] pMeshContainerBase->pAdjacency;
delete[] pMeshContainerBase->pMaterials;
for(unsigned int i = 0; i < pMeshContainerBase->NumMaterials; i++)
{
delete pMeshContainerBase->pMaterials[i].pTextureFilename;
}
delete pMeshContainerBase;
return D3D_OK;
}
Any ideas? tell me if you'd need the mesh for testing, I'll see what I can do. Thanks in advance!
EDIT: The exact crash message, roughly translated from german:
Exception (first chance) at 0x602A045F (D3DX9_43.dll) in Acclimate Editor.exe: 0xC0000005: Accessviolation reading position 0x00000002
Exception at 0x602A045F (D3DX9_43.dll) in Acclimate Editor.exe: 0xC0000005: Accessviolation reading position 0x00000002