these are the functions I am using (from a demo which web address you can find on top-post):
struct D3DXMESHCONTAINER_EXTENDED: public D3DXMESHCONTAINER{/* The base D3DXMESHCONTAINER has a pMaterials member which is a D3DXMATERIAL structure that contains a texture filename and material data. It is easier to ignore this and instead store the data in arrays of textures and materials in this extended structure:*/IDirect3DTexture9** exTextures; // Array of texture pointers D3DMATERIAL9* exMaterials; // Array of materials // Skinned mesh variablesID3DXMesh* exSkinMesh; // The skin meshD3DXMATRIX* exBoneOffsets; // The bone matrix Offsets, one per boneD3DXMATRIX** exFrameCombinedMatrixPointer; // Array of frame matrix pointers};HRESULT CMeshHierarchy::CreateMeshContainer( THIS_ LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances, DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER* ppNewMeshContainer){ // Create a mesh container structure to fill and initilaise to zero values// I use an extended version of the structure (D3DXMESHCONTAINER_EXTENDED)D3DXMESHCONTAINER_EXTENDED *newMeshContainer=new D3DXMESHCONTAINER_EXTENDED;ZeroMemory(newMeshContainer, sizeof(D3DXMESHCONTAINER_EXTENDED));// initialise return pointer before proceeding*ppNewMeshContainer = NULL;// The mesh name (may be null) needs copying overnewMeshContainer->Name=CUtilities::DuplicateCharString(Name);// The mesh type (D3DXMESHTYPE_MESH, D3DXMESHTYPE_PMESH or D3DXMESHTYPE_PATCHMESH) if (pMeshData->Type!=D3DXMESHTYPE_MESH) { // This does not handle mesh types other than the standard DestroyMeshContainer(newMeshContainer); return E_FAIL; }newMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; // Adjacency data - holds information about adjacency, required by ID3DMESH DWORD dwFaces = pMeshData->pMesh->GetNumFaces();newMeshContainer->pAdjacency = new DWORD[dwFaces*3];memcpy(newMeshContainer->pAdjacency, pAdjacency, sizeof(DWORD) * dwFaces*3); // Get the Direct3D device, luckily this is held in the mesh itselfLPDIRECT3DDEVICE9 pd3dDevice = NULL;pMeshData->pMesh->GetDevice(&pd3dDevice);// Make a copy of the mesh data that is passed in to our mesh containerD3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE];if (FAILED(pMeshData->pMesh->GetDeclaration(Declaration))) return E_FAIL;pMeshData->pMesh->CloneMesh(D3DXMESH_MANAGED, Declaration, pd3dDevice, &newMeshContainer->MeshData.pMesh);// Create material and texture arrays. I always want to have at least onenewMeshContainer->NumMaterials= max(NumMaterials,1);newMeshContainer->exMaterials= new D3DMATERIAL9[newMeshContainer->NumMaterials];newMeshContainer->exTextures= new LPDIRECT3DTEXTURE9[newMeshContainer->NumMaterials];ZeroMemory(newMeshContainer->exTextures,sizeof(LPDIRECT3DTEXTURE9)* newMeshContainer->NumMaterials);if (NumMaterials>0){ // Load all the textures and copy the materials over for(DWORD i = 0; i < NumMaterials; ++i) { newMeshContainer->exTextures = NULL; newMeshContainer->exMaterials=pMaterials.MatD3D; if(pMaterials.pTextureFilename) { // Note: the texture filename in the mesh container is an LPSTR (char *) but this // demo uses UNICODE so convert to LPWSTR (WCHAR*) required by D3DXCreateTextureFromFileW WCHAR wszTexName[MAX_PATH]; CUtilities::FillWideStringFromCharString(pMaterials.pTextureFilename,wszTexName,MAX_PATH); // Use the D3DX function to create the texturer if(FAILED(D3DXCreateTextureFromFile(pd3dDevice, wszTexName,&newMeshContainer->exTextures))) { newMeshContainer->exTextures = NULL; } } }}else // make a default material in the case where the mesh did not come with one { ZeroMemory(&newMeshContainer->exMaterials[0], sizeof( D3DMATERIAL9 ) ); newMeshContainer->exMaterials[0].Diffuse.r = 0.5f; newMeshContainer->exMaterials[0].Diffuse.g = 0.5f; newMeshContainer->exMaterials[0].Diffuse.b = 0.5f; newMeshContainer->exMaterials[0].Specular = newMeshContainer->exMaterials[0].Diffuse; newMeshContainer->exTextures[0]=NULL; } // If there is skin data associated with the mesh copy it over if (pSkinInfo) { // save off the SkinInfo newMeshContainer->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); // Need an array of offset matrices to move the vertices from the figure space to the bone's space UINT numBones = pSkinInfo->GetNumBones(); newMeshContainer->exBoneOffsets = new D3DXMATRIX[numBones]; // Create the arrays for the bones and the frame matricesnewMeshContainer->exFrameCombinedMatrixPointer = new D3DXMATRIX*[numBones]; // get each of the bone offset matrices so that we don't need to get them later for (UINT i = 0; i < numBones; i++) newMeshContainer->exBoneOffsets = *(newMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i));/* Note: in the Microsoft samples a GenerateSkinnedMesh function is called here in order to prepare the skinned mesh data for optimial hardware acceleration. As mentioned in the notes this sample does not do hardware skinning but instead uses software skinning*/ } else { // No skin info so null all the pointers newMeshContainer->pSkinInfo = NULL; newMeshContainer->exBoneOffsets = NULL; newMeshContainer->exSkinMesh = NULL; newMeshContainer->exFrameCombinedMatrixPointer = NULL; } // When we got the device we caused an internal reference count to be incremented // So we now need to release it SAFE_RELEASE(pd3dDevice); // The mesh may contain a reference to an effect file if (pEffectInstances) { if (pEffectInstances->pEffectFilename) { OutputDebugString(L"This .x file references an effect file. Effect files are not handled by this demo"); } } // Set the output mesh container to our newly created one *ppNewMeshContainer = newMeshContainer; return S_OK;}HRESULT CMeshHierarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase){// Convert to our extended type. OK as we know for sure it is:D3DXMESHCONTAINER_EXTENDED* pMeshContainer=(D3DXMESHCONTAINER_EXTENDED*)pMeshContainerBase; // name SAFE_DELETE_ARRAY(pMeshContainer->Name) // material array SAFE_DELETE_ARRAY(pMeshContainer->exMaterials) // release the textures before deleting the array if(pMeshContainer->exTextures) { for(UINT i = 0; i < pMeshContainer->NumMaterials; ++i) SAFE_RELEASE(pMeshContainer->exTextures); } // texture array SAFE_DELETE_ARRAY(pMeshContainer->exTextures) // adjacency data SAFE_DELETE_ARRAY(pMeshContainer->pAdjacency) // bone parts SAFE_DELETE_ARRAY(pMeshContainer->exBoneOffsets) // frame matrices SAFE_DELETE_ARRAY(pMeshContainer->exFrameCombinedMatrixPointer) // release skin mesh SAFE_RELEASE(pMeshContainer->exSkinMesh) // release the main mesh SAFE_RELEASE(pMeshContainer->MeshData.pMesh) // release skin information SAFE_RELEASE(pMeshContainer->pSkinInfo) // finally delete the mesh container itself SAFE_DELETE(pMeshContainer); return S_OK;}
If no-one will read all this code... I won't blame them :-)