• Advertisement

Archived

This topic is now archived and is closed to further replies.

Access Violation in XFile Loader

This topic is 5500 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello All, I''ve written an XFile loader based off of a Flipcode tutorial (which was just creating a wrapper class for the SDK skinned mesh code). I''m recieving an access violation in the CAllocateHierarchy::CreateMeshContainer function. It is breaking on this line: memcpy(MeshContainer->TextureArray, 0, sizeof(LPDIRECT3DTEXTURE9) * MeshContainer->NumMaterials); Here is the complete function:
  
HRESULT CAllocateHierarchy::CreateMeshContainer(LPCTSTR Name, LPD3DXMESHDATA MeshData, LPD3DXMATERIAL Materials, LPD3DXEFFECTINSTANCE EffectInstances, DWORD MaterialCount, DWORD * Adjacency, LPD3DXSKININFO SkinInfo, LPD3DXMESHCONTAINER * NewMeshContainer){

	D3DXMESHCONTAINER_DERIVED * MeshContainer = NULL;
	UINT FaceCount;
	UINT Material;
	UINT Bone, Bones;
	LPD3DXMESH Mesh = NULL;
	LPDIRECT3DDEVICE9 Device = NULL;
	*NewMeshContainer = NULL;

	if(MeshData->Type != D3DXMESHTYPE_MESH){
		RCOM(Device);
		DestroyMeshContainer(MeshContainer);
		return E_FAIL;
	}

	Mesh = MeshData->pMesh;

	if(Mesh->GetFVF() == NULL){
		RCOM(Device);
		DestroyMeshContainer(MeshContainer);
		return E_FAIL;
	}

	MeshContainer = new D3DXMESHCONTAINER_DERIVED;
	if(MeshContainer == NULL){
		RCOM(Device);
		DestroyMeshContainer(MeshContainer);
		return E_OUTOFMEMORY;
	}
	memset(MeshContainer, 0, sizeof(D3DXMESHCONTAINER_DERIVED));

	if(!AllocateName(Name, &MeshContainer->Name)){
		RCOM(Device);
		DestroyMeshContainer(MeshContainer);
		return E_FAIL;
	}

	Mesh->GetDevice(&Device);
	FaceCount = Mesh->GetNumFaces();

	// if no normals are in the mesh, add them

	if(!(Mesh->GetFVF() & D3DFVF_NORMAL)){

		MeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;

		if(FAILED(Mesh->CloneMeshFVF(Mesh->GetOptions(), Mesh->GetFVF() | D3DFVF_NORMAL, Device, &MeshContainer->MeshData.pMesh))){
			RCOM(Device);
			DestroyMeshContainer(MeshContainer);
			return E_FAIL;
		}

		Mesh = MeshContainer->MeshData.pMesh;
		D3DXComputeNormals(Mesh, NULL);

	}else{
		MeshContainer->MeshData.pMesh = Mesh;
		MeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;

		Mesh->AddRef();
	}

	// Allocate memory to contain the material information.

	MeshContainer->NumMaterials = max(1, MaterialCount);
	MeshContainer->pMaterials = new D3DXMATERIAL[MeshContainer->NumMaterials];
	MeshContainer->TextureArray = new LPDIRECT3DTEXTURE9[MeshContainer->NumMaterials];
	MeshContainer->pAdjacency = new DWORD[FaceCount * 3];

	if((MeshContainer->pAdjacency == NULL) || (MeshContainer->pMaterials == NULL)){
		RCOM(Device);
		DestroyMeshContainer(MeshContainer);
		return E_FAIL;
	}

	memcpy(MeshContainer->pAdjacency, Adjacency, sizeof(DWORD) * FaceCount * 3);
	memcpy(MeshContainer->TextureArray, 0, sizeof(LPDIRECT3DTEXTURE9) * MeshContainer->NumMaterials);

	// Copy materials if they are present

	if(MaterialCount > 0){

		memcpy(MeshContainer->pMaterials, Materials, sizeof(D3DXMATERIAL) * MaterialCount);

		for(Material = 0; Material < MaterialCount; Material++){
			if(MeshContainer->pMaterials[Material].pTextureFilename != NULL){
				TCHAR TexturePath[MAX_PATH] = _T("");
				DXUtil_FindMediaFileCb(TexturePath, sizeof(TexturePath), MeshContainer->pMaterials[Material].pTextureFilename);

				if(FAILED(D3DXCreateTextureFromFile(Device, TexturePath, &MeshContainer->TextureArray[Material])))
					MeshContainer->TextureArray[Material] = NULL;

				// Don''t remember a pointer into dynamic memory, just forget the name after loading

				MeshContainer->pMaterials[Material].pTextureFilename = NULL;
			}
		}
	}else{

		// No materials provided, use a default white one instead

		MeshContainer->pMaterials[0].pTextureFilename = NULL;
		memset(&MeshContainer->pMaterials[0].MatD3D, 0, sizeof(D3DMATERIAL9));
		MeshContainer->pMaterials[0].MatD3D.Diffuse.r = 0.5f;
		MeshContainer->pMaterials[0].MatD3D.Diffuse.g = 0.5f;
		MeshContainer->pMaterials[0].MatD3D.Diffuse.b = 0.5f;
		MeshContainer->pMaterials[0].MatD3D.Specular = MeshContainer->pMaterials[0].MatD3D.Diffuse;
	}

	// If there is skinning information, save it and setup for HW skinning

	if(SkinInfo != NULL){

		// First save SkinInfo and original mesh data

		MeshContainer->pSkinInfo = SkinInfo;
		SkinInfo->AddRef();

		MeshContainer->OriginalMesh = Mesh;
		Mesh->AddRef();

		// We will need an array of offset matrices to move the vertices from the figure space to the bone''s space

		Bones = SkinInfo->GetNumBones();
		MeshContainer->BoneOffsetMatrices = new D3DXMATRIX[Bones];
		if(MeshContainer->BoneOffsetMatrices == NULL){
			RCOM(Device);
			DestroyMeshContainer(MeshContainer);
			return E_FAIL;
		}

		// Get each one of the bone offset matrices so that we don''t need to get them later

		for(Bone = 0; Bone < Bones; Bone++)
			MeshContainer->BoneOffsetMatrices[Bone] = *(MeshContainer->pSkinInfo->GetBoneOffsetMatrix(Bone));
	
		// GenerateSkinMesh will take the general skinning information and transform it into a HW friendly version

		if(FAILED(m_XFile->GenerateSkinnedMesh(MeshContainer, m_XFile->GetSkinningMethod()))){
			RCOM(Device);
			DestroyMeshContainer(MeshContainer);
			return E_FAIL;
		}
	}

    *NewMeshContainer = MeshContainer;
	MeshContainer = NULL;

	return S_OK;
}  
Here are the derived classes and structures:
  
struct D3DXFRAME_DERIVED : public D3DXFRAME{

	D3DXMATRIX	CombinedTransformationMatrix;
};

struct D3DXMESHCONTAINER_DERIVED : public D3DXMESHCONTAINER{

	LPDIRECT3DTEXTURE9	 *	TextureArray;
	LPD3DXMESH			 	OriginalMesh;
	LPD3DXATTRIBUTERANGE	AttributeTable;
	DWORD					AttributeGroupCount;
	DWORD					InflCount;
	LPD3DXBUFFER			BoneCombinationBuffer;
	D3DXMATRIX			**	BoneMatrixPointers;
	D3DXMATRIX			 *	BoneOffsetMatrices;
	DWORD					PaletteEntryCount;
	BOOL					UseSoftwareVP;
	DWORD					AttributeSW;			// used for non-indexed skinning

};

class CAllocateHierarchy : public ID3DXAllocateHierarchy{

public:
	STDMETHOD(CreateFrame)(THIS_ LPCTSTR Name, LPD3DXFRAME * NewFrame);
	STDMETHOD(CreateMeshContainer)(THIS_ LPCTSTR Name, LPD3DXMESHDATA MeshData, LPD3DXMATERIAL Materials, 
		LPD3DXEFFECTINSTANCE EffectInstances, DWORD MaterialCount, DWORD * Adjacency, LPD3DXSKININFO SkinInfo, 
		LPD3DXMESHCONTAINER * NewMeshContainer);
	STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME FrameToFree);
	STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER MeshContainerBase);
	CAllocateHierarchy(CXFile * XFile, D3DCAPS9 D3DCaps) : m_XFile(XFile), m_D3DCaps(D3DCaps){}

	CXFile * m_XFile;
	D3DCAPS9 m_D3DCaps;
};  
I''m not sure what''s wrong. When I plug MeshContainer or MeshContainer->TextureArray into the watch window I get nothing (it says that MeshContainer cannot be found). I''ve also checked the passed parameters in the function. LPCTSTR Name is a bad pointer, and LPD3DXEFFECTINSTANCE EffectInstance''s pEffectFilename is also a bad pointer. I''m not really sure what to do, I''ll admit I''m a bit lazy at the moment and I don''t want to go through line by line. Perhaps tomorrow I will if I can''t figure it out by then. If you have any information that would help me, please post! I greatly appreciate it! Thanks in advance. Fuzztrek ¬_¬

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Hi

Good chance I''m missing something here - but you asking it to copy from a NULL pointer (ie the second param in your call to memcpy - the source - is 0). So memcpy is going to fail when it tries to dereference it.

Phill

Share this post


Link to post
Share on other sites
Ah yeah. Ahha. I was using memcpy when I should have been using memset. Thanks!

¬_¬

Share this post


Link to post
Share on other sites

  • Advertisement