void CreateGeometry(const char* sourceFile) { cout << endl << "Reading " << sourceFile << endl; wstring wideSourceFile(sourceFile, sourceFile + strlen(sourceFile)); // Load the mesh from the specified file LPD3DXBUFFER pD3DXMtrlBuffer; LPD3DXBUFFER pD3DXEffectInstances; HRESULT hr = D3DXLoadMeshFromX( wideSourceFile.c_str(), D3DXMESH_SYSTEMMEM, g_pd3dDevice, 0, &pD3DXMtrlBuffer, &pD3DXEffectInstances, &g_dwNumMaterials, &g_pMesh); if (FAILED(hr)) { MessageBox(0, (L"Could not find " + wideSourceFile).c_str(), L"X2CTM", MB_OK); exit(1); } DWORD* adjacencyIn = new DWORD[3 * g_pMesh->GetNumFaces()]; g_pMesh->GenerateAdjacency(0.0001f, adjacencyIn); DWORD* adjacencyOut = new DWORD[3 * g_pMesh->GetNumFaces()]; LPD3DXMESH newMesh = 0; //hr = g_pMesh->Optimize(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT, adjacencyIn, adjacencyOut, 0, 0, &newMesh); //hr = g_pMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, adjacencyIn, adjacencyOut, 0, 0); if (FAILED(hr)) { MessageBox(0, L"Unable to build attribute table", L"Whatever", MB_OK); exit(1); } //g_pMesh = newMesh; if (WeldVertices) { DWORD beforeVertCount = g_pMesh->GetNumVertices(); DWORD beforeFaceCount = g_pMesh->GetNumFaces(); hr = D3DXWeldVertices(g_pMesh, D3DXWELDEPSILONS_WELDALL, 0, 0, 0, 0, 0); DWORD afterVertCount = g_pMesh->GetNumVertices(); DWORD afterFaceCount = g_pMesh->GetNumFaces(); } D3DXATTRIBUTERANGE table[256]; DWORD tableSize = sizeof(table) / sizeof(table[0]); g_pMesh->GetAttributeTable(&table[0], &tableSize); D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*) pD3DXMtrlBuffer->GetBufferPointer(); D3DXEFFECTINSTANCE* d3dxEffects = (D3DXEFFECTINSTANCE*) pD3DXEffectInstances->GetBufferPointer(); g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials]; g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials]; for (DWORD i = 0; i < g_dwNumMaterials; i++) { g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D; g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse; g_pMeshTextures[i] = 0; if (d3dxMaterials[i].pTextureFilename && lstrlenA(d3dxMaterials[i].pTextureFilename) > 0) { D3DXCreateTextureFromFileA(g_pd3dDevice, d3dxMaterials[i].pTextureFilename, &g_pMeshTextures[i]); } } /* for (DWORD attrib = 0; attrib < tableSize; ++attrib) { // I'm not so sure about material-to-attribute correlation // if (attrib < g_dwNumMaterials) // { LPSTR pTexture = d3dxMaterials[attrib].pTextureFilename; LPSTR pSlash = strchr(pTexture, '\\'); if (pSlash) { pTexture = ++pSlash; } cout << "{Texture='" << pTexture << "',"; // } string subMeshFilename = string("X_") + string("Armature.ctm"); // string(pTexture).substr(0, strlen(pTexture) - 4) + ".ctm"; subMeshFilename[0] = attrib + 'A'; ExportRangeCTM(table[attrib], g_pMesh, subMeshFilename.c_str()); cout //<< table[attrib].AttribId << ' ' << "FaceStart=" << table[attrib].FaceStart << ',' << "FaceCount=" << table[attrib].FaceCount << ',' << "VertexStart=" << table[attrib].VertexStart << ',' << "VertexCount=" << table[attrib].VertexCount << '}' << endl; } */ pD3DXMtrlBuffer->Release(); // Convert the filename from .X to .CTM while preserving the full path. char destFile[_MAX_PATH]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath_s(sourceFile, drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME, ext, _MAX_EXT); _makepath_s(destFile, _MAX_PATH, drive, dir, fname, "ctm"); ExportCTM(g_pMesh, destFile); cout << "Exported " << destFile << endl; /* const WORD MISSING_ATTRIBUTE = 0xffff; WORD positionsOffset = MISSING_ATTRIBUTE; WORD normalsOffset = MISSING_ATTRIBUTE; WORD texCoordsOffset = MISSING_ATTRIBUTE; D3DVERTEXELEMENT9 vertexLayout[MAX_FVF_DECL_SIZE]; D3DVERTEXELEMENT9 endMarker = D3DDECL_END(); g_pMesh->GetDeclaration(vertexLayout); D3DVERTEXELEMENT9* pVertexLayout = &vertexLayout[0]; for (int attrib = 0; attrib < MAX_FVF_DECL_SIZE; ++attrib, pVertexLayout++) { if (0 == memcmp(&vertexLayout[attrib], &endMarker, sizeof(endMarker))) { break; } if (pVertexLayout->Stream != 0) { cout << "Nonzero stream: " << pVertexLayout->Stream << endl; continue; } if (pVertexLayout->Usage == D3DDECLUSAGE_POSITION && pVertexLayout->Type == D3DDECLTYPE_FLOAT3) { cout << "Contains positions " << (int) pVertexLayout->UsageIndex << endl; positionsOffset = pVertexLayout->Offset; } else if (pVertexLayout->Usage == D3DDECLUSAGE_NORMAL && pVertexLayout->Type == D3DDECLTYPE_FLOAT3) { cout << "Contains normals " << (int) pVertexLayout->UsageIndex << endl; normalsOffset = pVertexLayout->Offset; } else if (pVertexLayout->Usage == D3DDECLUSAGE_TEXCOORD && pVertexLayout->Type == D3DDECLTYPE_FLOAT2) { cout << "Contains texture coordinates " << (int) pVertexLayout->UsageIndex << endl; texCoordsOffset = pVertexLayout->Offset; } else { cout << "Mysterious attribute" << endl; } } // Check that we support the format of the data. if (positionsOffset == MISSING_ATTRIBUTE) { exit(1); } // Obtain vertex & index counts from the D3D mesh; allocate memory for the CTM mesh. DWORD dwVertexCount = g_pMesh->GetNumVertices(); DWORD dwTriangleCount = g_pMesh->GetNumFaces(); DWORD dwIndexCount = dwTriangleCount * 3; // Lock down the verts and pluck out the positions and normals. { void* pData = 0; if (S_OK != g_pMesh->LockVertexBuffer(0, &pData)) { exit(1); } if (positionsOffset != MISSING_ATTRIBUTE) { unsigned char* pSource = ((unsigned char*) pData) + positionsOffset; DWORD dwSourceStride = g_pMesh->GetNumBytesPerVertex(); DWORD dwDestStride = sizeof(CTMfloat) * 3; for (DWORD dwVertex = 0; dwVertex < dwVertexCount; ++dwVertex) { float* pFloat = (float*) pSource; *pFloat = -*pFloat; //*pFloat = -*pFloat; pSource += dwSourceStride; } } g_pMesh->UnlockVertexBuffer(); } // Lock down the indices and convert them to unsigned 32-bit integers. { void* pData = 0; g_pMesh->LockIndexBuffer(0, &pData); DWORD dwOptions = g_pMesh->GetOptions(); DWORD dwSourceStride = (dwOptions & D3DXMESH_32BIT) ? 4 : 2; unsigned char* pSource = (unsigned char*) pData; for (DWORD dwIndex = 0; dwIndex < dwIndexCount / 3; ++dwIndex) { unsigned short* inds = (unsigned short*) pSource; std::swap(inds[0], inds[1]); pSource += dwSourceStride * 3; } g_pMesh->UnlockIndexBuffer(); } D3DXSaveMeshToX(L"new.x", g_pMesh, 0, d3dxMaterials, d3dxEffects, g_dwNumMaterials, D3DXF_FILEFORMAT_BINARY | D3DXF_FILEFORMAT_COMPRESSED); cout << "Saved." << endl; */ }