Sign in to follow this  
lucky6969b

Can you guess what is leaking?

Recommended Posts

I've got a puzzle for you.

First it is unallocated 6 times.

it is uniform, everyone of them is 144 bytes long

I am using win32, Direct3D 9

If I don't load a skinned mesh, there are no leaks at all. If I do, there are.

Each floating point number is 32-bit, 4 bytes long, so 16x4=64 bytes.

Which doesn't seem like it.

144 bytes used to be a familiar magic number but I can't really remember.

#include "skinnedMesh.h"

#include <fstream>



#pragma warning(disable:4996)



extern IDirect3DDevice9 *g_pDevice;

extern ID3DXEffect *g_pEffect;

extern std::ofstream g_debug;



class BoneHierarchyLoader: 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);

};



HRESULT BoneHierarchyLoader::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 BoneHierarchyLoader::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

    boneMesh->OriginalMesh->AddRef();

    boneMesh->MeshData.pMesh->AddRef();



    

    IDirect3DDevice9 *pDevice = NULL;    

    pMeshData->pMesh->GetDevice(&pDevice);    //Get g_pDevice ptr from mesh



    //Copy materials and load textures (just like with a static mesh)

    

    for(int i=0;i<(int)NumMaterials;i++)

    {

        D3DXMATERIAL mtrl;

        memcpy(&mtrl, &pMaterials[i], sizeof(D3DXMATERIAL));

        boneMesh->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);

        }



        boneMesh->textures.push_back(newTexture);



        /*if (newTexture != NULL)

        {

            newTexture->Release();

            newTexture = NULL;

        }*/

    }

    



    if(pSkinInfo != NULL)

    {

        //Get Skin Info

        boneMesh->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,

                                                &boneMesh->MeshData.pMesh);



        if(boneComboTable != NULL)

            boneComboTable->Release();



        //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[i] = *(boneMesh->pSkinInfo->GetBoneOffsetMatrix(i));

    }



    //Set ppNewMeshContainer to the newly created boneMesh container

    *ppNewMeshContainer = boneMesh;



    return S_OK;

}



HRESULT BoneHierarchyLoader::DestroyFrame(LPD3DXFRAME pFrameToFree)

{

    

    if(pFrameToFree)

    {

        //Free name

        if(pFrameToFree->Name != NULL) {

            delete [] pFrameToFree->Name;

            pFrameToFree = NULL;

        }



        //Free bone

        delete pFrameToFree;

    }

    pFrameToFree = NULL;

    

 

    return S_OK;

}



HRESULT BoneHierarchyLoader::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase)

{

    BoneMesh *boneMesh = (BoneMesh*)pMeshContainerBase;



    



    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;

}



SkinnedMesh::~SkinnedMesh()

{

    //BoneHierarchyLoader boneHierarchy;

    //boneHierarchy.DestroyFrame(m_pRootBone);

    BoneHierarchyLoader alloc;

    D3DXFrameDestroy(m_pRootBone, &alloc);

    if(m_pAnimControl)m_pAnimControl->Release();

}



void SkinnedMesh::Load(const std::wstring& fileName)

{

    HRESULT hr = S_OK;

    BoneHierarchyLoader boneHierarchy;



    

    

    hr = D3DXLoadMeshHierarchyFromXW(fileName.c_str(), D3DXMESH_MANAGED,

                               g_pDevice, &boneHierarchy,

                               NULL, &m_pRootBone, &m_pAnimControl);



    if (FAILED(hr))

    {

        MessageBox(NULL, L"Error Loading Mesh", L"Error", NULL);

        PostQuitMessage(0);

    }



    SetupBoneMatrixPointers((Bone*)m_pRootBone);



    //Update all the bones

    D3DXMATRIX i;

    D3DXMatrixIdentity(&i);

    UpdateMatrices((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::Render(Bone *bone)

{

    

    if(bone == NULL)bone = (Bone*)m_pRootBone;



    //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[i],

                                   &boneMesh->boneOffsetMatrices[i],

                                   boneMesh->boneMatrixPtrs[i]);

            }



            D3DXMATRIX view, proj, identity;                

            g_pEffect->SetMatrixArray("FinalTransforms", boneMesh->currentBoneMatrices, boneMesh->pSkinInfo->GetNumBones());

            D3DXMatrixIdentity(&identity);



            //Render the mesh

            for(int i=0;i < (int)boneMesh->NumAttributeGroups;i++)

            {

                int mtrlIndex = boneMesh->attributeTable[i].AttribId;

                g_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));

                g_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);

                g_pEffect->SetMatrix("matW", &identity);



                g_pEffect->SetTexture("texDiffuse", boneMesh->textures[mtrlIndex]);

                D3DXHANDLE hTech = g_pEffect->GetTechniqueByName("Skinning");

                g_pEffect->SetTechnique(hTech);

                g_pEffect->Begin(NULL, NULL);

                g_pEffect->BeginPass(0);



                boneMesh->MeshData.pMesh->DrawSubset(mtrlIndex);



                g_pEffect->EndPass();

                g_pEffect->End();

            }

        }

        else

        {

            //Normal Static Mesh

            g_pEffect->SetMatrix("matW", &bone->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[i]);

                g_pEffect->SetVector( "materialColor",

                                         ( D3DXVECTOR4* )&(

                                         boneMesh->materials[i].Diffuse ) );

                g_pEffect->SetTexture("texDiffuse", boneMesh->textures[i]);



                g_pEffect->Begin(NULL, NULL);

                g_pEffect->BeginPass(0);



                boneMesh->OriginalMesh->DrawSubset(i);



                g_pEffect->EndPass();

                g_pEffect->End();

            }

        }

    }

    

    if(bone->pFrameSibling != NULL)Render((Bone*)bone->pFrameSibling);

    if(bone->pFrameFirstChild != NULL)Render((Bone*)bone->pFrameFirstChild);

}



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[i] = &b->CombinedTransformationMatrix;

                else boneMesh->boneMatrixPtrs[i] = NULL;

            }

        }

        

    }



    if(bone->pFrameSibling != NULL)SetupBoneMatrixPointers((Bone*)bone->pFrameSibling);

    if(bone->pFrameFirstChild != NULL)SetupBoneMatrixPointers((Bone*)bone->pFrameFirstChild);

}



void SkinnedMesh::Update(const D3DXMATRIX& mat)

{

    D3DXMATRIX m(mat);

    this->UpdateMatrices((Bone*)m_pRootBone, &m);

}



void SkinnedMesh::Draw()

{

    Render(NULL);

}



void SkinnedMesh::SetPose(D3DXMATRIX world)

{

    UpdateMatrices((Bone*)m_pRootBone, &world);

}



void SkinnedMesh::GetAnimations(std::vector<std::string> &animations)

{

    ID3DXAnimationSet *anim = NULL;



    for(int i=0;i<(int)m_pAnimControl->GetMaxNumAnimationSets();i++)

    {

        anim = NULL;

        m_pAnimControl->GetAnimationSet(i, &anim);



        if(anim != NULL)

        {

            animations.push_back(anim->GetName());

            anim->Release();

        }

    }

}



ID3DXAnimationController* SkinnedMesh::GetController()

{

    ID3DXAnimationController* newAnimController = NULL;



    if(m_pAnimControl != NULL)

    {

        m_pAnimControl->CloneAnimationController(m_pAnimControl->GetMaxNumAnimationOutputs(),

                                                 m_pAnimControl->GetMaxNumAnimationSets(),

                                                 m_pAnimControl->GetMaxNumTracks(),

                                                 m_pAnimControl->GetMaxNumEvents(),

                                                 &newAnimController);

    }



    return newAnimController;

}

I am using a destructor for my hierarchy.

Any fair guesses?

Thanks

Jack

 

Share this post


Link to post
Share on other sites

he3117,

oops, forgot to show you the destructors

struct Bone: public D3DXFRAME
{
    D3DXMATRIX CombinedTransformationMatrix;

    Bone()
    {
        Name = NULL;
        ZeroMemory(&pMeshContainer, sizeof(D3DXMESHCONTAINER));
        
    }

    ~Bone()
    {
        delete pMeshContainer;
        if(Name != NULL) { delete []Name;  Name = NULL; }
        //delete this;
    }
};

struct BoneMesh : public D3DXMESHCONTAINER
{
    ID3DXMesh* OriginalMesh;
    std::vector<D3DMATERIAL9> materials;
    std::vector<IDirect3DTexture9*> textures;

    DWORD NumAttributeGroups;
    D3DXATTRIBUTERANGE* attributeTable;
    D3DXMATRIX** boneMatrixPtrs;
    D3DXMATRIX* boneOffsetMatrices;
    D3DXMATRIX* currentBoneMatrices;

    BoneMesh()
    {
        Name = NULL;
        OriginalMesh = NULL;
        pAdjacency = NULL;
        pEffects = NULL;
        pMaterials = NULL;
        pSkinInfo = NULL;
        materials.clear();
        textures.clear();

    
        NumAttributeGroups = 0;
        attributeTable = NULL;
        boneMatrixPtrs = NULL;
        boneOffsetMatrices = NULL;
        currentBoneMatrices = NULL;
    }

    ~BoneMesh()
    {
    
        //Release textures
        int numTextures = (int)textures.size();

        for(int i=0;i < numTextures;i++)
        {
            if(textures[i] != NULL)
            {
            
                textures[i]->Release();
                textures[i] = NULL;
            }
        }

        //Release mesh data
        if(MeshData.pMesh != NULL) { MeshData.pMesh->Release(); MeshData.pMesh = NULL; }
        if(pSkinInfo != NULL ) { pSkinInfo->Release(); pSkinInfo = NULL; }
        if(OriginalMesh != NULL) { OriginalMesh->Release(); OriginalMesh = NULL; }
        if(attributeTable != NULL) { delete attributeTable; attributeTable = NULL; }
        if(boneMatrixPtrs != NULL) { delete [] boneMatrixPtrs; boneMatrixPtrs = NULL; }
        if(boneOffsetMatrices != NULL) { delete boneOffsetMatrices; boneOffsetMatrices = NULL; }
        if(currentBoneMatrices != NULL) { delete currentBoneMatrices; currentBoneMatrices = NULL; }
        if(Name != NULL) { delete []Name;  Name = NULL; }
        if(pAdjacency != NULL) { delete []pAdjacency; pAdjacency = NULL; }
        if(pEffects != NULL) { delete pEffects; pEffects = NULL; }
        if(pMaterials != NULL) { delete [] pMaterials; pMaterials = NULL; }
 
        materials.clear();
        textures.clear();
        //delete this;
    }
};

Share this post


Link to post
Share on other sites
#include <crtdbg.h>
 
First line of your main:
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
 
That should give you the allocation ID.
 
To set a breakpoint on the allocation ID either set a breakpoint on {,,msvcr100d.dll}_crtBreakAlloc   (the dll name here will change depending on your visual studio/etc)
The alternative is to call _CrtSetBreakAlloc(n); in your code.
 
 
If you want to go all the way and get file:line numbers on the leak, try:
#define new new( _NORMAL_BLOCK, __FILE__, __LINE__) 

 

 

 

Good luck! smile.png
(And if you happen to not be using MSVC, the leaks is the least of your problems)

 

[b]Edit:[/b] Hint hint hint: Notice how your deconstructor is not virtual. Look it up! ;)

Edited by marius1930

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this