SKINNEDMESH::~SKINNEDMESH(){ BONE_HIERARCHY boneHierarchy; boneHierarchy.DestroyFrame(m_pRootBone); if(m_pAnimControl)m_pAnimControl->Release();}
Memory Leaks
I can not find where the memory leak is happening in my class (SkinnedMesh), I am releasing this:
If you're sure the leak is due to the creation of a SKINNEDMESH instance, then either or both:
1. DestroyFrame is not deleting and releasing all objects that it should.
2. You create or new other objects in your SKINNEDMESH instance that aren't deleted or released in DestroyFrame (mesh, skininfo, textures, etc.).
1. DestroyFrame is not deleting and releasing all objects that it should.
2. You create or new other objects in your SKINNEDMESH instance that aren't deleted or released in DestroyFrame (mesh, skininfo, textures, etc.).
Quote:Original post by Buckeye
If you're sure the leak is due to the creation of a SKINNEDMESH instance, then either or both:
1. DestroyFrame is not deleting and releasing all objects that it should.
2. You create or new other objects in your SKINNEDMESH instance that aren't deleted or released in DestroyFrame (mesh, skininfo, textures, etc.).
Yes, I did the tests and the leak is in SkinnedMesh
I would ask for your help, because I have tried several ways and found where the leak is (something is going unnoticed by me)
my class:
#ifndef SKINNED_MESH#define SKINNED_MESH#include <windows.h>#include <d3dx9.h>#include <string>#include <vector>struct BONE: public D3DXFRAME{ D3DXMATRIX CombinedTransformationMatrix;};struct BONEMESH: public D3DXMESHCONTAINER{ ID3DXMesh* OriginalMesh; std::vector<D3DMATERIAL9> materials; std::vector<IDirect3DTexture9*> textures; DWORD NumAttributeGroups; D3DXATTRIBUTERANGE* attributeTable; D3DXMATRIX** boneMatrixPtrs; D3DXMATRIX* boneOffsetMatrices; D3DXMATRIX* currentBoneMatrices;};class SKINNEDMESH{public: SKINNEDMESH(); ~SKINNEDMESH(); void Load(char *fileName, IDirect3DDevice9 *Dev); void Render(BONE *bone, float scale); void UpdateAnim(bool bones, D3DXMATRIX world, ID3DXAnimationController* animControl, float time); void SetAnimation(char name[]); void SetPosition(D3DXVECTOR3 pos); void SetRotation(D3DXVECTOR3 angle); std::vector<std::string> GetAnimations(); BONE* FindBone(char name[]); //Controller of Bones void mouselocal(D3DXVECTOR3 pos, int Width, D3DXMATRIX pm, D3DXMATRIX vm, D3DVIEWPORT9 vp); //Testesprivate: void UpdateMatrices(bool bones, BONE* bone, D3DXMATRIX *parentMatrix); void SetupBoneMatrixPointers(BONE *bone); IDirect3DDevice9 *m_pDevice; D3DXFRAME *m_pRootBone; ID3DXAnimationController *m_pAnimControl; D3DXVECTOR3 vPos; D3DXVECTOR3 rotation; float scale; //Controller of Bones D3DXVECTOR3 mouseLocation; int m_Width; D3DXMATRIX m_pm; // projection matrix D3DXMATRIX m_vm; // view matrix D3DVIEWPORT9 m_vp; // viewport};#endif
#include "skinnedMesh.h"class BONE_HIERARCHY: public ID3DXAllocateHierarchy{ public: STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame); STDMETHOD(CreateMeshContainer)(THIS_ LPCTSTR 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);};HRESULT BONE_HIERARCHY::CreateFrame(LPCSTR Name, LPD3DXFRAME *ppNewFrame){ BONE *newBone = new BONE; memset(newBone, 0, sizeof(BONE)); //Copy name if(Name != NULL) { newBone->Name = new char[strlen(Name)+1]; strcpy(newBone->Name, Name); } //Set the transformation matrices D3DXMatrixIdentity(&newBone->TransformationMatrix); D3DXMatrixIdentity(&newBone->CombinedTransformationMatrix); //Return the new bone... *ppNewFrame = (D3DXFRAME*)newBone; return S_OK;}HRESULT BONE_HIERARCHY::CreateMeshContainer(LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances, DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer){ //Create new Bone Mesh BONEMESH *boneMesh = new BONEMESH; memset(boneMesh, 0, sizeof(BONEMESH)); //Get mesh data boneMesh->OriginalMesh = pMeshData->pMesh; boneMesh->MeshData.pMesh = pMeshData->pMesh; boneMesh->MeshData.Type = pMeshData->Type; pMeshData->pMesh->AddRef(); //Add Reference so that the mesh isnt deallocated IDirect3DDevice9 *m_pDevice = NULL; pMeshData->pMesh->GetDevice(&m_pDevice); //Get m_pDevice ptr from mesh //Copy materials and load textures (just like with a static mesh) for(int i = 0; i < NumMaterials; i++) { D3DXMATERIAL mtrl; memcpy(&mtrl, &pMaterials, sizeof(D3DXMATERIAL)); boneMesh->materials.push_back(mtrl.MatD3D); char textureFname[200]; //strcpy(textureFname, "mesh/"); strcat(textureFname, mtrl.pTextureFilename); //Load texture IDirect3DTexture9* newTexture = NULL; D3DXCreateTextureFromFile(m_pDevice, pMaterials.pTextureFilename, &newTexture); boneMesh->textures.push_back(newTexture); } if(pSkinInfo != NULL) { //Get Skin Info boneMesh->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); //Add reference so that the SkinInfo isnt deallocated //Clone mesh and store in boneMesh->MeshData.pMesh pMeshData->pMesh->CloneMeshFVF(D3DXMESH_MANAGED, pMeshData->pMesh->GetFVF(), m_pDevice, &boneMesh->MeshData.pMesh); //Get Attribute Table boneMesh->MeshData.pMesh->GetAttributeTable(NULL, &boneMesh->NumAttributeGroups); boneMesh->attributeTable = new D3DXATTRIBUTERANGE[boneMesh->NumAttributeGroups]; boneMesh->MeshData.pMesh->GetAttributeTable(boneMesh->attributeTable, NULL); //Create bone offset and current matrices int NumBones = pSkinInfo->GetNumBones(); boneMesh->boneOffsetMatrices = new D3DXMATRIX[NumBones]; boneMesh->currentBoneMatrices = new D3DXMATRIX[NumBones]; //Get bone offset matrices for(int i=0;i < NumBones;i++) boneMesh->boneOffsetMatrices = *(boneMesh->pSkinInfo->GetBoneOffsetMatrix(i)); } //Set ppNewMeshContainer to the newly created boneMesh container *ppNewMeshContainer = boneMesh; return S_OK;}HRESULT BONE_HIERARCHY::DestroyFrame(LPD3DXFRAME pFrameToFree) { if(pFrameToFree) { //Free name if(pFrameToFree->Name != NULL) delete [] pFrameToFree->Name; //Free bone delete pFrameToFree; } pFrameToFree = NULL; return S_OK; }HRESULT BONE_HIERARCHY::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase){ BONEMESH *boneMesh = (BONEMESH*)pMeshContainerBase; //Release textures for(int i=0;i < boneMesh->textures.size();i++) if(boneMesh->textures != NULL) boneMesh->textures->Release(); //Release mesh data if(boneMesh->MeshData.pMesh)boneMesh->MeshData.pMesh->Release(); if(boneMesh->pSkinInfo)boneMesh->pSkinInfo->Release(); if(boneMesh->OriginalMesh)boneMesh->OriginalMesh->Release(); delete boneMesh; return S_OK;}//////////////////////////////////////////////////////////////////////////////////////////////////// SKINNED MESH ////////////////////////////////////////////////////////////////////////////////////////////////////struct VERTEX{ VERTEX(); VERTEX(D3DXVECTOR3 pos, D3DCOLOR col){position = pos; color = col;} D3DXVECTOR3 position; D3DCOLOR color; static const DWORD FVF;};const DWORD VERTEX::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;SKINNEDMESH::SKINNEDMESH(){ m_pRootBone = NULL; m_pAnimControl = NULL; vPos=D3DXVECTOR3(0.0f,0.0f,0.0f); rotation=D3DXVECTOR3(0.0f,0.0f,0.0f); scale = 1;}SKINNEDMESH::~SKINNEDMESH(){ BONE_HIERARCHY boneHierarchy; boneHierarchy.DestroyFrame(m_pRootBone); if(m_pAnimControl)m_pAnimControl->Release();}void SKINNEDMESH::Load(char *fileName, IDirect3DDevice9 *Dev){ m_pDevice = Dev; BONE_HIERARCHY boneHierarchy; D3DXLoadMeshHierarchyFromX(fileName, D3DXMESH_MANAGED, m_pDevice, &boneHierarchy, NULL, &m_pRootBone, &m_pAnimControl); SetupBoneMatrixPointers((BONE*)m_pRootBone); //Update all the bones D3DXMATRIX i; D3DXMatrixIdentity(&i); UpdateMatrices(false, (BONE*)m_pRootBone, &i);}/*void SKINNEDMESH::UpdateMatrices(BONE* bone, D3DXMATRIX *parentMatrix){ if(bone == NULL)return; D3DXMatrixMultiply(&bone->CombinedTransformationMatrix, &bone->TransformationMatrix, parentMatrix); if(bone->pFrameSibling)UpdateMatrices((BONE*)bone->pFrameSibling, parentMatrix); if(bone->pFrameFirstChild)UpdateMatrices((BONE*)bone->pFrameFirstChild, &bone->CombinedTransformationMatrix);}*/void SKINNEDMESH::UpdateMatrices(bool bones, BONE* bone, D3DXMATRIX *parentMatrix){ if(bones) { if(parentMatrix != NULL) { if(bone->Name != NULL && strcmp(bone->Name,"Bip01_L_UpperArm")==0) //|| strcmp(bone->Name,"Bip01_R_UpperArm")==0) { D3DXMATRIX ident; D3DXMatrixIdentity(&ident); D3DXMATRIX final = bone->TransformationMatrix*(*parentMatrix); D3DXVECTOR3 boneLocation(final._41,final._42,final._43); D3DXVec3Project(&boneLocation,&boneLocation,&m_vp,&m_pm,&m_vm,&ident); // use YOUR viewport, projection and view matrices in this call D3DXVECTOR3 dir = mouseLocation - boneLocation; if(mouseLocation.x > m_Width/2) { float offset = D3DX_PI/2.0f; float angle = offset - atan2(dir.y,dir.x); // change this when you rotate the model D3DXMATRIX rot; D3DXMatrixRotationY(&rot,angle); bone->CombinedTransformationMatrix = rot*final; } else { float offset = -D3DX_PI/2.0f; float angle = offset + atan2(dir.y,dir.x); // change this when you rotate the model D3DXMATRIX rot; D3DXMatrixRotationY(&rot,angle); bone->CombinedTransformationMatrix = rot*final; } } else D3DXMatrixMultiply(&bone->CombinedTransformationMatrix, &bone->TransformationMatrix, parentMatrix); } else bone->CombinedTransformationMatrix = bone->TransformationMatrix; if(bone->pFrameSibling) { UpdateMatrices(bones, (BONE*)bone->pFrameSibling, parentMatrix); } if(bone->pFrameFirstChild) { UpdateMatrices(bones, (BONE*)bone->pFrameFirstChild, &bone->CombinedTransformationMatrix); } } else { if(bone != NULL) D3DXMatrixMultiply(&bone->CombinedTransformationMatrix, &bone->TransformationMatrix, parentMatrix); else bone->CombinedTransformationMatrix = bone->TransformationMatrix; if(bone->pFrameSibling) UpdateMatrices(bones, (BONE*)bone->pFrameSibling, parentMatrix); if(bone->pFrameFirstChild) UpdateMatrices(bones, (BONE*)bone->pFrameFirstChild, &bone->CombinedTransformationMatrix); }}void SKINNEDMESH::Render(BONE *bone, float scale){ if(bone == NULL)bone = (BONE*)m_pRootBone; // Setup world matrix D3DXMATRIXA16 matWorld,matWorld2; // set the rotation matrix D3DXMatrixRotationYawPitchRoll(&matWorld2,rotation.x,rotation.y,rotation.z); D3DXMatrixScaling(&matWorld,scale,scale,scale); D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2); D3DXMatrixTranslation( &matWorld2, vPos.x, vPos.y,vPos.z ); D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2); m_pDevice->SetTransform( D3DTS_WORLD, &matWorld ); //If there is a mesh to render... if(bone->pMeshContainer != NULL) { BONEMESH *boneMesh = (BONEMESH*)bone->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); //Update the skinned mesh BYTE *src = NULL, *dest = NULL; boneMesh->OriginalMesh->LockVertexBuffer(D3DLOCK_READONLY, (VOID**)&src); boneMesh->MeshData.pMesh->LockVertexBuffer(0, (VOID**)&dest); boneMesh->pSkinInfo->UpdateSkinnedMesh(boneMesh->currentBoneMatrices, NULL, src, dest); boneMesh->MeshData.pMesh->UnlockVertexBuffer(); boneMesh->OriginalMesh->UnlockVertexBuffer(); //Render the mesh for(int i=0;i < boneMesh->NumAttributeGroups;i++) { int mtrlIndex = boneMesh->attributeTable.AttribId; m_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex])); m_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]); boneMesh->MeshData.pMesh->DrawSubset(mtrlIndex); } } } if(bone->pFrameSibling != NULL)Render((BONE*)bone->pFrameSibling, scale); if(bone->pFrameFirstChild != NULL)Render((BONE*)bone->pFrameFirstChild, scale);}void SKINNEDMESH::SetupBoneMatrixPointers(BONE *bone){ if(bone->pMeshContainer != NULL) { BONEMESH *boneMesh = (BONEMESH*)bone->pMeshContainer; if(boneMesh->pSkinInfo != NULL) { int NumBones = boneMesh->pSkinInfo->GetNumBones(); boneMesh->boneMatrixPtrs = new D3DXMATRIX*[NumBones]; for(int i=0;i < NumBones;i++) { BONE *b = (BONE*)D3DXFrameFind(m_pRootBone, boneMesh->pSkinInfo->GetBoneName(i)); if(b != NULL)boneMesh->boneMatrixPtrs = &b->CombinedTransformationMatrix; else boneMesh->boneMatrixPtrs = NULL; } } } if(bone->pFrameSibling != NULL)SetupBoneMatrixPointers((BONE*)bone->pFrameSibling); if(bone->pFrameFirstChild != NULL)SetupBoneMatrixPointers((BONE*)bone->pFrameFirstChild);}BONE* SKINNEDMESH::FindBone(char name[]){ return (BONE*) D3DXFrameFind(m_pRootBone, name);}void SKINNEDMESH::UpdateAnim(bool bones, D3DXMATRIX world, ID3DXAnimationController* animControl, float time){ if(animControl != NULL) animControl->AdvanceTime(time, NULL); else m_pAnimControl->AdvanceTime(time, NULL); UpdateMatrices(bones, (BONE*)m_pRootBone, &world);}void SKINNEDMESH::SetAnimation(char name[]){ ID3DXAnimationSet *anim = NULL; for(int i=0;i<m_pAnimControl->GetMaxNumAnimationSets();i++) { anim = NULL; m_pAnimControl->GetAnimationSet(i, &anim); if(anim != NULL) { if(strcmp(name, anim->GetName()) == 0) m_pAnimControl->SetTrackAnimationSet(0, anim); anim->Release(); } }}std::vector<std::string> SKINNEDMESH::GetAnimations(){ ID3DXAnimationSet *anim = NULL; std::vector<std::string> animations; for(int i=0;i<m_pAnimControl->GetMaxNumAnimationSets();i++) { anim = NULL; m_pAnimControl->GetAnimationSet(i, &anim); if(anim != NULL) { animations.push_back(anim->GetName()); anim->Release(); } } return animations;}void SKINNEDMESH::SetPosition(D3DXVECTOR3 pos){ vPos = pos;}void SKINNEDMESH::SetRotation(D3DXVECTOR3 angle){ rotation = angle;}void SKINNEDMESH::mouselocal(D3DXVECTOR3 pos, int Width, D3DXMATRIX pm, D3DXMATRIX vm, D3DVIEWPORT9 vp){ mouseLocation = pos; m_Width = Width; m_pm = pm; m_vm = vm; m_vp = vp;}
Thank you
As mentioned above, DestroyFrame doesn't delete or release all the objects that were created. During the process of loading the mesh hierarchy, many objects (frames, meshes, materials, etc.) are created, and several DirectX objects are created that need to be released. Take a look at CreateFrame to see all the possibilities.
Your DestroyFrame(m_pRootBone) call merely deletes the memory allocated for the m_pRootBone frame, without deleting or releasing any of the objects that were created during the loading process.
You might try looking at the docs for D3DXFrameDestroy(..).
You can also google around for an example of using the AllocateHierchy implementation.
Your DestroyFrame(m_pRootBone) call merely deletes the memory allocated for the m_pRootBone frame, without deleting or releasing any of the objects that were created during the loading process.
You might try looking at the docs for D3DXFrameDestroy(..).
You can also google around for an example of using the AllocateHierchy implementation.
I tried something like this:
and
but when I close the game (which is the time that he tries to release the skinned mesh) compiler (debug) indicates a number of crashes and errors on the line D3DXFrameDestroy (m_pRootBone, & boneHierarchy)
class BONE_HIERARCHY: public ID3DXAllocateHierarchy{ public: STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame); STDMETHOD(CreateMeshContainer)(THIS_ LPCTSTR 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); BONE_HIERARCHY(SKINNEDMESH *pSkinMesh) : m_pSkinMesh(pSkinMesh) {} //here!this line is new!!public: SKINNEDMESH* m_pSkinMesh; //my class of SkinnedMesh};
and
SKINNEDMESH::~SKINNEDMESH(){ BONE_HIERARCHY boneHierarchy(this); boneHierarchy.DestroyFrame(m_pRootBone); D3DXFrameDestroy(m_pRootBone, &boneHierarchy); if(m_pAnimControl) m_pAnimControl->Release();}
but when I close the game (which is the time that he tries to release the skinned mesh) compiler (debug) indicates a number of crashes and errors on the line D3DXFrameDestroy (m_pRootBone, & boneHierarchy)
Quote: (debug) indicates a number of crashes and errors on the line D3DXFrameDestroy (m_pRootBone, & boneHierarchy)
I would certainly expect that, since you destroy the root frame before you destroy the rest of the frames.
boneHierarchy.DestroyFrame(m_pRootBone); // destroy the root frame D3DXFrameDestroy(m_pRootBone, &boneHierarchy); // destroy a frame which has already been destroyed
I would strongly suggest you take a good look at your code and get a good understanding of what each piece does.
My previous post:
Quote:You can also google around for an example of using the AllocateHierchy implementation.
You really should do that.
I apologize, I need to deliver this work in college tomorrow, I will read more calmly on google :)
Thanks
Thanks
I tried some examples and articles about D3DXFrameDestroy and followed them, the problem is that when he will release to this line:
SKINNEDMESH::~SKINNEDMESH(){ BONE_HIERARCHY boneHierarchy(this); D3DXFrameDestroy(m_pRootBone, &boneHierarchy); if(m_pAnimControl) m_pAnimControl->Release();}
HRESULT BONE_HIERARCHY::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase){ UINT iMaterial; BONEMESH *pMeshContainer = (BONEMESH*)pMeshContainerBase; SAFE_DELETE_ARRAY( pMeshContainer->Name ); SAFE_DELETE_ARRAY( pMeshContainer->pAdjacency ); SAFE_DELETE_ARRAY( pMeshContainer->pMaterials ); SAFE_DELETE_ARRAY( pMeshContainer->boneOffsetMatrices ); // release all the allocated textures for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++) { SAFE_RELEASE( pMeshContainer->textures[iMaterial] ); } SAFE_DELETE_ARRAY( pMeshContainer->boneMatrixPtrs ); SAFE_RELEASE( pMeshContainer->MeshData.pMesh ); SAFE_RELEASE( pMeshContainer->pSkinInfo ); SAFE_RELEASE( pMeshContainer->OriginalMesh ); SAFE_DELETE( pMeshContainer );}HRESULT BONE_HIERARCHY::DestroyFrame(LPD3DXFRAME pFrameToFree) { SAFE_DELETE_ARRAY( pFrameToFree->Name ); SAFE_DELETE( pFrameToFree ); return S_OK; }
Quote:the problem is that when he will release to this line
What's the problem?
Just a guess, but if it's a memory access violation, it may be that you don't initialize all the variables to 0 or NULL.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement