3 leaks to get rid of. But I can't find them.
Can anyone who is sensitive enough to find them?
There is one thing remarkable. It should happen only when it is loading skinned meshes.
Thanks
Jack
D3DX: MEMORY LEAKS DETECTED: 3 allocations unfreed (28024 bytes)
D3DX: Set HKLM\Software\Microsoft\Direct3D\D3DXBreakOnAllocId=0x5f5c to debug
The program '[5416] PerfectSim.exe: Native' has exited with code 0 (0x0).
//////////////////////////////////////////////////////////////////////////
// Character Animation with Direct3D //
// Author: C. Granberg //
// 2008 - 2009 //
//////////////////////////////////////////////////////////////////////////
#ifndef SKINNED_MESH
#define SKINNED_MESH
#include <windows.h>
#include <d3dx9.h>
#include <string>
#include <vector>
//using namespace std;
struct D3DXFRAME_DERIVED : public D3DXFRAME
{
D3DXMATRIX CombinedTransformationMatrix;
D3DXFRAME_DERIVED()
{
Name = 0;
pFrameSibling = NULL;
pFrameFirstChild = NULL;
pMeshContainer = NULL;
}
~D3DXFRAME_DERIVED()
{
}
};
struct D3DXMESHCONTAINER_DERIVED : public D3DXMESHCONTAINER
{
LPD3DXMESH OriginalMesh;
std::vector<D3DMATERIAL9> materials;
std::vector<IDirect3DTexture9*> textures;
D3DXMATRIX** boneMatrixPtrs;
D3DXMATRIX* boneOffsetMatrices;
D3DXMATRIX* currentBoneMatrices;
DWORD NumAttributeGroups;
D3DXATTRIBUTERANGE* attributeTable;
D3DXMESHCONTAINER_DERIVED()
{
Name = 0;
pSkinInfo = 0;
boneMatrixPtrs = 0;
boneOffsetMatrices = 0;
currentBoneMatrices = 0;
attributeTable = 0;
OriginalMesh = 0;
pEffects = 0;
pMaterials = 0;
pAdjacency = 0;
NumMaterials = 0;
NumAttributeGroups = 0;
}
~D3DXMESHCONTAINER_DERIVED()
{
int numTextures = (int)textures.size();
for(int i=0;i < numTextures;i++)
{
if( textures != NULL)
{
textures->Release();
textures = NULL;
}
}
if (Name != NULL)
{
delete [] Name;
Name = NULL;
}
if ( MeshData.pMesh != NULL)
{
MeshData.pMesh->Release();
MeshData.pMesh = NULL;
}
if (MeshData.pPatchMesh != NULL)
{
MeshData.pPatchMesh->Release();
MeshData.pPatchMesh = NULL;
}
if (MeshData.pPMesh != NULL)
{
MeshData.pPMesh->Release();
MeshData.pPMesh = NULL;
}
if ( OriginalMesh != NULL)
{
OriginalMesh->Release();
OriginalMesh = NULL;
}
if ( boneMatrixPtrs != NULL)
{
delete [] boneMatrixPtrs;
boneMatrixPtrs = NULL;
}
if ( boneOffsetMatrices != NULL)
{
delete boneOffsetMatrices;
boneOffsetMatrices = NULL;
}
if ( currentBoneMatrices != NULL)
{
delete currentBoneMatrices;
currentBoneMatrices = NULL;
}
if ( attributeTable != NULL)
{
delete attributeTable;
attributeTable = NULL;
}
if ( pSkinInfo != NULL)
{
pSkinInfo->Release();
pSkinInfo = NULL;
}
if ( pAdjacency)
{
delete pAdjacency;
pAdjacency = NULL;
}
if ( pEffects)
{
delete pEffects;
pEffects = NULL;
}
if ( pMaterials)
{
delete pMaterials;
pMaterials = NULL;
}
materials.clear();
textures.clear();
}
};
class CAllocateHierarchy: public ID3DXAllocateHierarchy
{
public:
STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame);
STDMETHOD(CreateMeshContainer)(THIS_ LPCSTR Name, CONST D3DXMESHDATA * pMeshData, CONST D3DXMATERIAL * pMaterials, CONST D3DXEFFECTINSTANCE * pEffectInstances, DWORD NumMaterials, CONST DWORD * pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER * ppNewMeshContainer);
STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree);
STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerBase);
};
class SkinnedMesh
{
public:
SkinnedMesh();
~SkinnedMesh();
bool Load(const std::wstring& filename);
private:
void UpdateMatrices(D3DXFRAME_DERIVED* f, D3DXMATRIX* m);
void Render(D3DXFRAME_DERIVED *f);
void SetupBoneMatrixPointers(D3DXFRAME_DERIVED *f);
public:
void Update(const D3DXMATRIX& mat);
void Draw();
private:
LPD3DXFRAME m_pRoot;
LPD3DXANIMATIONCONTROLLER m_pAnimCtrl;
CAllocateHierarchy Alloc;
};
#endif
#include "skinnedMesh.h"
#pragma warning(disable:4996)
extern IDirect3DDevice9 *g_pDevice;
extern ID3DXEffect *g_pEffect;
extern std::ofstream g_debug;
HRESULT CAllocateHierarchy::CreateFrame(LPCSTR Name, LPD3DXFRAME* ppNewFrame)
{
D3DXFRAME_DERIVED* newFrame = new D3DXFRAME_DERIVED();
//memset (newFrame, 0, sizeof(D3DXFRAME_DERIVED));
if (Name != NULL)
{
newFrame->Name = new char[strlen(Name)+1];
strcpy (newFrame->Name, Name);
}
else
{
newFrame->Name = NULL;
}
D3DXMatrixIdentity(&newFrame->TransformationMatrix);
D3DXMatrixIdentity(&newFrame->CombinedTransformationMatrix);
newFrame->pFrameFirstChild = NULL;
newFrame->pFrameSibling = NULL;
*ppNewFrame = newFrame;
return S_OK;
}
HRESULT CAllocateHierarchy::CreateMeshContainer(LPCSTR Name,
CONST D3DXMESHDATA *pMeshData,
CONST D3DXMATERIAL *pMaterials,
CONST D3DXEFFECTINSTANCE *pEffectInstances,
DWORD NumMaterials,
CONST DWORD *pAdjacency,
LPD3DXSKININFO pSkinInfo,
LPD3DXMESHCONTAINER *ppNewMeshContainer)
{
D3DXMESHCONTAINER_DERIVED *pMeshContainer = new D3DXMESHCONTAINER_DERIVED;
//ZeroMemory(&pMeshContainer, sizeof(D3DXMESHCONTAINER_DERIVED)); // don't do this
if (Name != NULL)
{
pMeshContainer->Name = new char[strlen(Name)+1];
strcpy (pMeshContainer->Name, Name);
}
else
{
Name = NULL;
}
pMeshContainer->MeshData.pMesh = pMeshData->pMesh;
pMeshContainer->MeshData.Type = pMeshData->Type;
pMeshContainer->MeshData.pMesh->AddRef();
pMeshContainer->OriginalMesh = pMeshData->pMesh;
pMeshContainer->OriginalMesh->AddRef();
IDirect3DDevice9 *pDevice = NULL;
pMeshData->pMesh->GetDevice(&pDevice);
for(int i=0;i<(int)NumMaterials;i++)
{
D3DXMATERIAL mtrl;
memcpy(&mtrl, &pMaterials, sizeof(D3DXMATERIAL));
pMeshContainer->materials.push_back(mtrl.MatD3D);
IDirect3DTexture9* newTexture = NULL;
if(mtrl.pTextureFilename != NULL)
{
char textureFname[200];
strcpy(textureFname, "Data/");
strcat(textureFname, mtrl.pTextureFilename);
//Load texture
D3DXCreateTextureFromFileA(g_pDevice, textureFname, &newTexture);
pMeshContainer->textures.push_back(newTexture);
}
else
{
pMeshContainer->textures.push_back(newTexture);
}
}
if(pSkinInfo != NULL)
{
//Get Skin Info
pMeshContainer->pSkinInfo = pSkinInfo;
pSkinInfo->AddRef(); //Add reference so that the SkinInfo isnt deallocated
DWORD maxVertInfluences = 0;
DWORD numBoneComboEntries = 0;
ID3DXBuffer* boneComboTable = 0;
pSkinInfo->ConvertToIndexedBlendedMesh(pMeshData->pMesh,
D3DXMESH_MANAGED | D3DXMESH_WRITEONLY,
30,
0, // ignore adjacency in
0, // ignore adjacency out
0, // ignore face remap
0, // ignore vertex remap
&maxVertInfluences,
&numBoneComboEntries,
&boneComboTable,
&pMeshContainer->MeshData.pMesh);
if(boneComboTable != NULL)
boneComboTable->Release();
//Get Attribute Table
pMeshContainer->MeshData.pMesh->GetAttributeTable(NULL, &pMeshContainer->NumAttributeGroups);
pMeshContainer->attributeTable = new D3DXATTRIBUTERANGE[pMeshContainer->NumAttributeGroups];
pMeshContainer->MeshData.pMesh->GetAttributeTable(pMeshContainer->attributeTable, NULL);
//Create bone offset and current matrices
int NumBones = pSkinInfo->GetNumBones();
pMeshContainer->boneOffsetMatrices = new D3DXMATRIX[NumBones];
pMeshContainer->currentBoneMatrices = new D3DXMATRIX[NumBones];
//Get bone offset matrices
for(int i=0;i < NumBones;i++)
pMeshContainer->boneOffsetMatrices = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i));
}
pMeshContainer->pNextMeshContainer = NULL;
*ppNewMeshContainer = pMeshContainer;
//delete pMeshContainer;
pDevice->Release();
return S_OK;
}
HRESULT CAllocateHierarchy::DestroyFrame(LPD3DXFRAME pFrameToFree)
{
if(pFrameToFree)
{
//Free name
if(pFrameToFree->Name != NULL) {
delete [] pFrameToFree->Name;
pFrameToFree->Name = NULL;
}
/*if (pFrameToFree->pFrameFirstChild != NULL) {
delete pFrameToFree->pFrameFirstChild;
pFrameToFree->pFrameFirstChild = NULL;
}
if (pFrameToFree->pFrameSibling != NULL) {
delete pFrameToFree->pFrameSibling;
pFrameToFree->pFrameSibling = NULL;
}
*/
/*if (pFrameToFree->pMeshContainer != NULL) {
delete pFrameToFree->pMeshContainer;
pFrameToFree->pMeshContainer = NULL;
}
*/
//Free bone
delete pFrameToFree;
}
pFrameToFree = NULL;
return S_OK;
}
HRESULT CAllocateHierarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase)
{
/*
*/
//Release textures
D3DXMESHCONTAINER_DERIVED* pMeshContainer = (D3DXMESHCONTAINER_DERIVED*) pMeshContainerBase;
int numTextures = (int)pMeshContainer->textures.size();
for(int i=0;i < numTextures;i++)
{
if(pMeshContainer->textures != NULL)
{
pMeshContainer->textures->Release();
pMeshContainer->textures = NULL;
}
}
if (pMeshContainer->Name != NULL)
{
delete [] pMeshContainer->Name;
pMeshContainer->Name = NULL;
}
if (pMeshContainer->MeshData.pMesh != NULL)
{
pMeshContainer->MeshData.pMesh->Release();
pMeshContainer->MeshData.pMesh = NULL;
}
if (pMeshContainer->MeshData.pPatchMesh != NULL)
{
pMeshContainer->MeshData.pPatchMesh->Release();
pMeshContainer->MeshData.pPatchMesh = NULL;
}
if (pMeshContainer->MeshData.pPMesh != NULL)
{
pMeshContainer->MeshData.pPMesh->Release();
pMeshContainer->MeshData.pPMesh = NULL;
}
if (pMeshContainer->OriginalMesh != NULL)
{
pMeshContainer->OriginalMesh->Release();
pMeshContainer->OriginalMesh = NULL;
}
if (pMeshContainer->boneMatrixPtrs != NULL)
{
delete [] pMeshContainer->boneMatrixPtrs;
pMeshContainer->boneMatrixPtrs = NULL;
}
if (pMeshContainer->boneOffsetMatrices != NULL)
{
delete pMeshContainer->boneOffsetMatrices;
pMeshContainer->boneOffsetMatrices = NULL;
}
if (pMeshContainer->currentBoneMatrices != NULL)
{
delete pMeshContainer->currentBoneMatrices;
pMeshContainer->currentBoneMatrices = NULL;
}
if (pMeshContainer->attributeTable != NULL)
{
delete pMeshContainer->attributeTable;
pMeshContainer->attributeTable = NULL;
}
if (pMeshContainer->pSkinInfo != NULL)
{
pMeshContainer->pSkinInfo->Release();
pMeshContainer->pSkinInfo = NULL;
}
if (pMeshContainer->pAdjacency)
{
delete pMeshContainer->pAdjacency;
pMeshContainer->pAdjacency = NULL;
}
if (pMeshContainer->pEffects)
{
delete pMeshContainer->pEffects;
pMeshContainer->pEffects = NULL;
}
if (pMeshContainer->pMaterials)
{
delete pMeshContainer->pMaterials;
pMeshContainer->pMaterials = NULL;
}
pMeshContainer->textures.clear();
pMeshContainer->materials.clear();
delete pMeshContainer;
pMeshContainer = NULL;
pMeshContainerBase = NULL;
return S_OK;
}
SkinnedMesh::SkinnedMesh()
: m_pRoot(0), m_pAnimCtrl(0)
{
}
SkinnedMesh::~SkinnedMesh()
{
if (m_pRoot != NULL)
{
//Alloc.DestroyFrame(m_pRoot);
D3DXFrameDestroy(m_pRoot, &Alloc);
m_pRoot = NULL;
}
if (m_pAnimCtrl) { m_pAnimCtrl->Release(); m_pAnimCtrl = NULL; }
}
bool SkinnedMesh::Load(const std::wstring& filename)
{
HRESULT hr = S_OK;
hr = D3DXLoadMeshHierarchyFromXW(filename.c_str(), D3DXMESH_MANAGED,
g_pDevice, &Alloc ,
NULL, &m_pRoot, &m_pAnimCtrl);
/*SetupBoneMatrixPointers((D3DXFRAME_DERIVED*)m_pRoot);*/
//Update all the bones
/*
D3DXMATRIX i;
D3DXMatrixIdentity(&i);
UpdateMatrices((D3DXFRAME_DERIVED*)m_pRoot, &i);
*/
return true;
}
void SkinnedMesh::Update(const D3DXMATRIX& mat)
{
D3DXMATRIX m(mat);
this->UpdateMatrices((D3DXFRAME_DERIVED*)m_pRoot, &m);
}
void SkinnedMesh::Draw()
{
Render(NULL);
}
void SkinnedMesh::UpdateMatrices(D3DXFRAME_DERIVED* f, D3DXMATRIX* parentMatrix)
{
if(f == NULL)return;
D3DXMatrixMultiply(&f->CombinedTransformationMatrix,
&f->TransformationMatrix,
parentMatrix);
if(f->pFrameSibling != NULL)
{
UpdateMatrices((D3DXFRAME_DERIVED*)f->pFrameSibling, parentMatrix);
}
if(f->pFrameFirstChild != NULL)
{
UpdateMatrices((D3DXFRAME_DERIVED*)f->pFrameFirstChild, &f->CombinedTransformationMatrix);
}
}
void SkinnedMesh::SetupBoneMatrixPointers(D3DXFRAME_DERIVED *bone)
{
if(bone->pMeshContainer != NULL)
{
D3DXMESHCONTAINER_DERIVED *boneMesh = (D3DXMESHCONTAINER_DERIVED*)bone->pMeshContainer;
if(boneMesh->pSkinInfo != NULL)
{
int NumBones = boneMesh->pSkinInfo->GetNumBones();
boneMesh->boneMatrixPtrs = new D3DXMATRIX*[NumBones];
for(int i=0;i < NumBones;i++)
{
D3DXFRAME_DERIVED *b = (D3DXFRAME_DERIVED*)D3DXFrameFind(m_pRoot, boneMesh->pSkinInfo->GetBoneName(i));
if(b != NULL)boneMesh->boneMatrixPtrs = &b->CombinedTransformationMatrix;
else boneMesh->boneMatrixPtrs = NULL;
}
}
}
if(bone->pFrameSibling != NULL)SetupBoneMatrixPointers((D3DXFRAME_DERIVED*)bone->pFrameSibling);
if(bone->pFrameFirstChild != NULL)SetupBoneMatrixPointers((D3DXFRAME_DERIVED*)bone->pFrameFirstChild);
}
void SkinnedMesh::Render(D3DXFRAME_DERIVED *f)
{
if(f == NULL)f = (D3DXFRAME_DERIVED*)m_pRoot;
//If there is a mesh to render...
if(f->pMeshContainer != NULL)
{
D3DXMESHCONTAINER_DERIVED *boneMesh = (D3DXMESHCONTAINER_DERIVED*)f->pMeshContainer;
if (boneMesh->pSkinInfo != NULL)
{
/*
// set up bone transforms
int numBones = boneMesh->pSkinInfo->GetNumBones();
for(int i=0;i < numBones;i++)
{
D3DXMatrixMultiply(&boneMesh->currentBoneMatrices,
&boneMesh->boneOffsetMatrices,
boneMesh->boneMatrixPtrs);
}
D3DXMATRIX view, proj, identity;
g_pEffect->SetMatrixArray("FinalTransforms", boneMesh->currentBoneMatrices, boneMesh->pSkinInfo->GetNumBones());
//Render the mesh
for(int i=0;i < (int)boneMesh->NumMaterials; i++)//>NumAttributeGroups;i++)
{
//int mtrlIndex = boneMesh->attributeTable.AttribId;
//g_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));
//g_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);
g_pDevice->SetMaterial(&(boneMesh->materials));
g_pDevice->SetTexture(0, boneMesh->textures);
g_pEffect->SetMatrix("matW", &identity);
g_pEffect->SetVector( "materialColor",
( D3DXVECTOR4* )&(
boneMesh->materials.Diffuse ) );
g_pEffect->SetTexture("texDiffuse", boneMesh->textures);
D3DXHANDLE hTech = g_pEffect->GetTechniqueByName("Skinning");
g_pEffect->SetTechnique(hTech);
g_pEffect->Begin(NULL, NULL);
g_pEffect->BeginPass(0);
boneMesh->MeshData.pMesh->DrawSubset(i);
g_pEffect->EndPass();
g_pEffect->End();
}
*/
}
else
{
try
{
//Normal Static Mesh
g_pEffect->SetMatrix("matW", &f->CombinedTransformationMatrix);
D3DXHANDLE hTech = g_pEffect->GetTechniqueByName("Lighting");
g_pEffect->SetTechnique(hTech);
//Render the mesh
int numMaterials = (int)boneMesh->materials.size();
for(int i=0;i < numMaterials;i++)
{
g_pDevice->SetMaterial(&boneMesh->materials);
g_pEffect->SetVector( "materialColor",
( D3DXVECTOR4* )&(
boneMesh->materials.Diffuse ) );
g_pEffect->SetTexture("texDiffuse", boneMesh->textures);
g_pEffect->Begin(NULL, NULL);
g_pEffect->BeginPass(0);
boneMesh->OriginalMesh->DrawSubset(i);
g_pEffect->EndPass();
g_pEffect->End();
}
}
catch (std::bad_alloc e)
{
OutputDebugStringA(e.what());
}
}
}
if(f->pFrameSibling != NULL)
{
Render((D3DXFRAME_DERIVED*)f->pFrameSibling);
}
if(f->pFrameFirstChild != NULL)
{
Render((D3DXFRAME_DERIVED*)f->pFrameFirstChild);
}
}