Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

796 lines
22 KiB

  1. //**************************************************************************
  2. //
  3. // Copyright (C) Microsoft Corporation, 1998 - 1999 All Rights Reserved.
  4. //
  5. // File: frmsave.cpp
  6. //
  7. // Description: Save LPDIRECT3DRMFRAME to an x file.
  8. //
  9. // History:
  10. // 011/06/98 CongpaY Created
  11. //
  12. //**************************************************************************
  13. #include <d3drm.h>
  14. #include <dxfile.h>
  15. #include <rmxftmpl.h>
  16. #include <rmxfguid.h>
  17. #include "frmsave.h"
  18. extern HINSTANCE g_hInstD3DXOFDLL;
  19. #define MyD3DRMColorGetAlpha(color) ((float)((color & 0xFF000000)>>24)/(float)255)
  20. #define MyD3DRMColorGetRed(color) ((float)((color & 0x00FF0000)>>16)/(float)255)
  21. #define MyD3DRMColorGetGreen(color) ((float)((color & 0x0000FF00)>>8)/(float)255)
  22. #define MyD3DRMColorGetBlue(color) ((float)((color & 0x000000FF))/(float)255)
  23. HRESULT FrameToXFile(LPDIRECT3DRMFRAME3 pFrame,
  24. LPCSTR filename,
  25. D3DRMXOFFORMAT d3dFormat,
  26. D3DRMSAVEOPTIONS d3dSaveFlags)
  27. {
  28. Saver saver;
  29. saver.Init(filename, d3dFormat, d3dSaveFlags);
  30. saver.SaveHeaderObject();
  31. saver.SaveFrame(pFrame);
  32. return S_OK;
  33. }
  34. Saver::Saver()
  35. {
  36. pXFile=NULL;
  37. pSave=NULL;
  38. }
  39. Saver::~Saver()
  40. {
  41. if (pSave) pSave->Release();
  42. if (pXFile) pXFile->Release();
  43. }
  44. HRESULT Saver::Init(LPCSTR filename,
  45. D3DRMXOFFORMAT d3dFormatArg,
  46. D3DRMSAVEOPTIONS d3dSaveFlagsArg)
  47. {
  48. HRESULT hr;
  49. d3dFormat = d3dFormatArg;
  50. d3dSaveFlags = d3dSaveFlagsArg;
  51. CREATEXFILE pCreateXFile=(CREATEXFILE)GetProcAddress( g_hInstD3DXOFDLL, "DirectXFileCreate" );
  52. if (!pCreateXFile) return E_NOTIMPL;
  53. DXFILEFORMAT xFormat;
  54. if (d3dFormat == D3DRMXOF_BINARY)
  55. xFormat = DXFILEFORMAT_BINARY;
  56. else if (d3dFormat == D3DRMXOF_TEXT)
  57. xFormat = DXFILEFORMAT_TEXT;
  58. else
  59. xFormat = DXFILEFORMAT_COMPRESSED;
  60. //DirectXFileCreate(&pXFile);
  61. pCreateXFile(&pXFile);
  62. if (!pXFile) return E_FAIL;
  63. hr=pXFile->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
  64. if FAILED(hr)
  65. {
  66. pXFile->Release();
  67. pXFile=NULL;
  68. return hr;
  69. }
  70. hr=pXFile->CreateSaveObject(filename, xFormat, &pSave);
  71. if FAILED(hr)
  72. {
  73. pXFile->Release();
  74. pXFile=NULL;
  75. pSave=NULL;
  76. return hr;
  77. }
  78. return S_OK;
  79. }
  80. HRESULT Saver::SaveHeaderObject()
  81. {
  82. LPDIRECTXFILEDATA pHeader=NULL;
  83. Header data;
  84. HRESULT hr;
  85. data.major = 1;
  86. data.minor = 0;
  87. data.flags = (d3dFormat == D3DRMXOF_TEXT)? 1 : 0;
  88. if (!pSave) return E_FAIL;
  89. hr=pSave->CreateDataObject(TID_DXFILEHeader,
  90. NULL,
  91. NULL,
  92. sizeof(Header),
  93. &data,
  94. &pHeader);
  95. if FAILED(hr) return hr;
  96. if (!pHeader) return hr;
  97. hr=pSave->SaveData(pHeader);
  98. pHeader->Release();
  99. return hr;
  100. }
  101. HRESULT Saver::SaveFrame(LPDIRECT3DRMFRAME3 pFrame,
  102. LPDIRECT3DRMFRAME3 pRefFrame,
  103. LPDIRECTXFILEDATA pRefFrameObj)
  104. {
  105. DWORD i;
  106. HRESULT hr;
  107. LPDIRECTXFILEDATA pFrameObj=NULL;
  108. if (!pSave) return E_FAIL;
  109. if (!pFrame) return E_FAIL;
  110. hr=pSave->CreateDataObject(TID_D3DRMFrame,
  111. NULL,
  112. NULL,
  113. 0,
  114. NULL,
  115. &pFrameObj);
  116. if FAILED(hr) return hr;
  117. if (!pFrameObj) return E_FAIL;
  118. hr=SaveFrameTransform(pFrameObj, pFrame, pRefFrame);
  119. if FAILED(hr) {
  120. pFrameObj->Release();
  121. return hr;
  122. }
  123. // Enumerate visuals.
  124. DWORD cVisuals=0;
  125. hr=pFrame->GetVisuals(&cVisuals, NULL);
  126. if FAILED(hr) {
  127. pFrameObj->Release();
  128. return hr;
  129. }
  130. if (cVisuals)
  131. {
  132. LPUNKNOWN *ppUnk = new LPUNKNOWN[cVisuals];
  133. hr=pFrame->GetVisuals(&cVisuals, ppUnk);
  134. if SUCCEEDED(hr)
  135. {
  136. for (i = 0; i < cVisuals; i++)
  137. {
  138. LPDIRECT3DRMFRAME3 pChildFrame;
  139. if (ppUnk[i])
  140. {
  141. hr = ppUnk[i]->QueryInterface(IID_IDirect3DRMFrame3, (LPVOID *)&pChildFrame);
  142. if (SUCCEEDED(hr))
  143. {
  144. SaveFrame(pChildFrame, pFrame, pFrameObj);
  145. pChildFrame->Release();
  146. }
  147. else
  148. {
  149. LPDIRECT3DRMMESHBUILDER3 pMeshBuilder;
  150. hr = ppUnk[i]->QueryInterface(IID_IDirect3DRMMeshBuilder3, (LPVOID *)&pMeshBuilder);
  151. if (SUCCEEDED(hr))
  152. {
  153. SaveMeshBuilder(pFrameObj, pMeshBuilder);
  154. pMeshBuilder->Release();
  155. }
  156. }
  157. ppUnk[i]->Release();
  158. }
  159. }
  160. delete[] ppUnk;
  161. }
  162. } //cVisuals
  163. // Enumerate child frames.
  164. LPDIRECT3DRMFRAMEARRAY pFrameArray=NULL;
  165. hr=pFrame->GetChildren(&pFrameArray);
  166. if SUCCEEDED(hr)
  167. {
  168. for (i = 0; i < pFrameArray->GetSize(); i++)
  169. {
  170. LPDIRECT3DRMFRAME pTmpFrame;
  171. LPDIRECT3DRMFRAME3 pChildFrame;
  172. pFrameArray->GetElement(i, &pTmpFrame);
  173. pTmpFrame->QueryInterface(IID_IDirect3DRMFrame3, (LPVOID *)&pChildFrame);
  174. pTmpFrame->Release();
  175. SaveFrame(pChildFrame, pFrame, pFrameObj);
  176. pChildFrame->Release();
  177. }
  178. pFrameArray->Release();
  179. // Add frame object to the saved list.
  180. if (pRefFrameObj)
  181. pRefFrameObj->AddDataObject(pFrameObj);
  182. else
  183. pSave->SaveData(pFrameObj);
  184. pFrameObj->Release();
  185. }
  186. return hr;
  187. }
  188. HRESULT Saver::SaveFrameTransform(LPDIRECTXFILEDATA pFrameObj,
  189. LPDIRECT3DRMFRAME3 pFrame,
  190. LPDIRECT3DRMFRAME3 pRefFrame)
  191. {
  192. LPDIRECTXFILEDATA pFrameTransformObj=NULL;
  193. D3DRMMATRIX4D rmMatrix;
  194. HRESULT hr;
  195. if (!pFrame) return E_INVALIDARG;
  196. pFrame->GetTransform(pRefFrame, rmMatrix);
  197. hr=pSave->CreateDataObject(TID_D3DRMFrameTransformMatrix,
  198. NULL,
  199. NULL,
  200. sizeof(D3DRMMATRIX4D),
  201. rmMatrix,
  202. &pFrameTransformObj);
  203. if FAILED(hr) return hr;
  204. hr=pFrameObj->AddDataObject(pFrameTransformObj);
  205. pFrameTransformObj->Release();
  206. return hr;
  207. }
  208. HRESULT Saver::SaveMeshBuilder(LPDIRECTXFILEDATA pFrameObj,
  209. LPDIRECT3DRMMESHBUILDER3 pMeshBuilder)
  210. {
  211. LPDIRECTXFILEDATA pMeshObj;
  212. DWORD cVertices, cNormals, cFaces, dwFaceData, *pdwFaceData;
  213. LPDIRECT3DRMFACEARRAY pFaceArray = NULL;
  214. HRESULT hr;
  215. if (!pMeshBuilder) return E_INVALIDARG;
  216. //pFrameObj can be null
  217. hr=pMeshBuilder->GetGeometry(&cVertices, NULL,
  218. &cNormals, NULL,
  219. &dwFaceData, NULL);
  220. if FAILED(hr) return hr;
  221. cFaces = pMeshBuilder->GetFaceCount();
  222. if (!cVertices || !cNormals || !dwFaceData || !cFaces)
  223. return S_OK;
  224. pdwFaceData = new DWORD[dwFaceData];
  225. if FAILED(pdwFaceData) return E_OUTOFMEMORY;
  226. hr=pMeshBuilder->GetGeometry(NULL, NULL,
  227. NULL, NULL,
  228. &dwFaceData, pdwFaceData);
  229. if FAILED(hr) return hr;
  230. hr=CreateMeshObject(cVertices, cFaces, dwFaceData, pdwFaceData,
  231. pMeshBuilder, &pMeshObj);
  232. if FAILED(hr) return hr;
  233. D3DRMCOLORSOURCE clrSrc = pMeshBuilder->GetColorSource();
  234. if (clrSrc == D3DRMCOLOR_FROMVERTEX)
  235. {
  236. CreateVertexColorsObject(pMeshObj, cVertices, pMeshBuilder);
  237. }
  238. if (d3dSaveFlags & D3DRMXOFSAVE_MATERIALS)
  239. {
  240. if (!pFaceArray)
  241. pMeshBuilder->GetFaces(&pFaceArray);
  242. CreateMaterialListObject(pMeshObj, pFaceArray);
  243. }
  244. if (d3dSaveFlags & D3DRMXOFSAVE_NORMALS)
  245. {
  246. CreateNormalsObject(pMeshObj,
  247. cNormals, cFaces, dwFaceData, pdwFaceData,
  248. pMeshBuilder);
  249. }
  250. if (d3dSaveFlags & D3DRMXOFSAVE_TEXTURETOPOLOGY)
  251. {
  252. if (!pFaceArray)
  253. pMeshBuilder->GetFaces(&pFaceArray);
  254. CreateTextureWrapsObject(pMeshObj, pFaceArray);
  255. }
  256. if (d3dSaveFlags & D3DRMXOFSAVE_TEXTURECOORDINATES)
  257. {
  258. CreateTextureCoordsObject(pMeshObj, cVertices, pMeshBuilder);
  259. }
  260. if (pFrameObj)
  261. pFrameObj->AddDataObject(pMeshObj);
  262. else
  263. pSave->SaveData(pMeshObj);
  264. pMeshObj->Release();
  265. delete[] pdwFaceData;
  266. if (pFaceArray)
  267. pFaceArray->Release();
  268. return S_OK;
  269. }
  270. HRESULT Saver::CreateMeshObject(DWORD cVertices,
  271. DWORD cFaces,
  272. DWORD dwFaceData,
  273. LPDWORD pdwFaceData,
  274. LPDIRECT3DRMMESHBUILDER3 pMeshBuilder,
  275. LPDIRECTXFILEDATA *ppMeshObj)
  276. {
  277. // mesh data is vertex_count + vertices + face_count + face_vertex_data;
  278. HRESULT hr;
  279. if (!pMeshBuilder) return E_INVALIDARG;
  280. if (!pSave) return E_INVALIDARG;
  281. DWORD cbSize, *data;
  282. cbSize = cVertices * sizeof(D3DVECTOR) +
  283. (1 + (dwFaceData + cFaces + 1)/2) * sizeof(DWORD);
  284. data = (LPDWORD) new BYTE[cbSize];
  285. if (!data) return E_OUTOFMEMORY;
  286. data[0] = cVertices;
  287. LPD3DVECTOR pVertices = (LPD3DVECTOR)&data[1];
  288. pMeshBuilder->GetGeometry(&cVertices, pVertices,
  289. NULL, NULL,
  290. NULL, NULL);
  291. LPDWORD pdwTmp = (LPDWORD)&pVertices[cVertices];
  292. *pdwTmp++ = cFaces;
  293. while (*pdwFaceData)
  294. {
  295. DWORD cFaceVertices = *pdwFaceData++;
  296. *pdwTmp++ = cFaceVertices;
  297. for (DWORD i = 0; i < cFaceVertices; i++)
  298. {
  299. *pdwTmp++ = *pdwFaceData++;
  300. pdwFaceData++; // skip normal index.
  301. }
  302. }
  303. DWORD dwSize;
  304. pMeshBuilder->GetName(&dwSize, NULL);
  305. LPSTR szName = NULL;
  306. if (dwSize)
  307. {
  308. szName = new char[dwSize];
  309. pMeshBuilder->GetName(&dwSize, szName);
  310. }
  311. hr=pSave->CreateDataObject(TID_D3DRMMesh,
  312. szName,
  313. NULL,
  314. cbSize,
  315. data,
  316. ppMeshObj);
  317. if (szName) lNames.Add(szName);
  318. delete[] data;
  319. return S_OK;
  320. }
  321. HRESULT Saver::CreateNormalsObject(LPDIRECTXFILEDATA pMeshObj,
  322. DWORD cNormals,
  323. DWORD cFaces,
  324. DWORD dwFaceData,
  325. LPDWORD pdwFaceData,
  326. LPDIRECT3DRMMESHBUILDER3 pMeshBuilder)
  327. {
  328. // normals data is normal_count + normals + face_count + face_normal_data;
  329. HRESULT hr;
  330. if (!pMeshObj) return E_INVALIDARG;
  331. DWORD cbSize, *data;
  332. cbSize = cNormals * sizeof(D3DVECTOR) +
  333. (1 + (dwFaceData + cFaces + 1)/2) * sizeof(DWORD);
  334. data = (LPDWORD) new BYTE[cbSize];
  335. if (!data) return E_OUTOFMEMORY;
  336. data[0] = cNormals;
  337. LPD3DVECTOR pNormals = (LPD3DVECTOR)&data[1];
  338. hr=pMeshBuilder->GetGeometry(NULL, NULL,
  339. &cNormals, pNormals,
  340. NULL, NULL);
  341. if FAILED(hr) return hr;
  342. LPDWORD pdwTmp = (LPDWORD)&pNormals[cNormals];
  343. *pdwTmp++ = cFaces;
  344. while (*pdwFaceData)
  345. {
  346. DWORD cFaceVertices = *pdwFaceData++;
  347. *pdwTmp++ = cFaceVertices;
  348. for (DWORD i = 0; i < cFaceVertices; i++)
  349. {
  350. pdwFaceData++; // skip vertex index.
  351. *pdwTmp++ = *pdwFaceData++;
  352. }
  353. }
  354. LPDIRECTXFILEDATA pNormalsObj=NULL;
  355. hr=pSave->CreateDataObject(TID_D3DRMMeshNormals,
  356. NULL,
  357. NULL,
  358. cbSize,
  359. data,
  360. &pNormalsObj);
  361. if FAILED(hr) return hr;
  362. pMeshObj->AddDataObject(pNormalsObj);
  363. pNormalsObj->Release();
  364. delete[] data;
  365. return S_OK;
  366. }
  367. HRESULT Saver::CreateVertexColorsObject(LPDIRECTXFILEDATA pMeshObj,
  368. DWORD cVertices,
  369. LPDIRECT3DRMMESHBUILDER3 pMeshBuilder)
  370. {
  371. DWORD cbSize;
  372. VertexColors *data;
  373. HRESULT hr;
  374. if (!pSave) return E_INVALIDARG;
  375. if (!pMeshBuilder) return E_INVALIDARG;
  376. cbSize = sizeof(DWORD) + cVertices * sizeof(IndexedColor);
  377. data = (VertexColors *) new BYTE[cbSize];
  378. if (!data) return E_OUTOFMEMORY;
  379. data->cVertices = cVertices;
  380. for (DWORD i = 0; i < cVertices; i++)
  381. {
  382. D3DCOLOR color = pMeshBuilder->GetVertexColor(i);
  383. data->vertexColors[i].index = i;
  384. data->vertexColors[i].color.r = MyD3DRMColorGetRed(color);
  385. data->vertexColors[i].color.g = MyD3DRMColorGetGreen(color);
  386. data->vertexColors[i].color.b = MyD3DRMColorGetBlue(color);
  387. data->vertexColors[i].color.a = MyD3DRMColorGetAlpha(color);
  388. }
  389. LPDIRECTXFILEDATA pVertexColorsObj=NULL;
  390. hr=pSave->CreateDataObject(TID_D3DRMMeshVertexColors,
  391. NULL,
  392. NULL,
  393. cbSize,
  394. data,
  395. &pVertexColorsObj);
  396. if FAILED(hr) {
  397. delete[] data;
  398. return hr;
  399. }
  400. pMeshObj->AddDataObject(pVertexColorsObj);
  401. pVertexColorsObj->Release();
  402. delete[] data;
  403. return S_OK;
  404. }
  405. HRESULT Saver::CreateMaterialListObject(LPDIRECTXFILEDATA pMeshObj,
  406. LPDIRECT3DRMFACEARRAY pFaceArray)
  407. {
  408. DWORD cbSize, cFaces;
  409. FaceMaterials *data;
  410. FaceMaterialList lMat;
  411. cFaces = pFaceArray->GetSize();
  412. cbSize = (2 + cFaces) * sizeof(DWORD);
  413. data = (FaceMaterials *) new BYTE[cbSize];
  414. if (!data) return E_OUTOFMEMORY;
  415. data->cFaceIndexes = cFaces;
  416. LPDWORD pdwIndex = data->faceIndexes;
  417. for (DWORD i = 0; i < cFaces; i++, pdwIndex++)
  418. {
  419. LPDIRECT3DRMFACE pFace;
  420. pFaceArray->GetElement(i, &pFace);
  421. D3DCOLOR faceColor;
  422. LPDIRECT3DRMMATERIAL pMaterial;
  423. LPDIRECT3DRMTEXTURE pTexture;
  424. faceColor = pFace->GetColor();
  425. pFace->GetMaterial(&pMaterial);
  426. pFace->GetTexture(&pTexture);
  427. *pdwIndex = lMat.Find(faceColor, pMaterial, pTexture);
  428. pMaterial->Release();
  429. if (pTexture) pTexture->Release();
  430. pFace->Release();
  431. }
  432. data->cMaterials = lMat.Count();
  433. if (data->cMaterials == 1)
  434. {
  435. data->cFaceIndexes = 1;
  436. data->faceIndexes[0] = 0;
  437. cbSize = 3 * sizeof(DWORD);
  438. }
  439. LPDIRECTXFILEDATA pMatListObj;
  440. pSave->CreateDataObject(TID_D3DRMMeshMaterialList,
  441. NULL,
  442. NULL,
  443. cbSize,
  444. data,
  445. &pMatListObj);
  446. FaceMaterial *pMat;
  447. for (pMat = lMat.First(); pMat; pMat = pMat->pNext)
  448. {
  449. CreateMaterialObject(pMatListObj,
  450. pMat);
  451. }
  452. pMeshObj->AddDataObject(pMatListObj);
  453. pMatListObj->Release();
  454. delete[] data;
  455. return S_OK;
  456. }
  457. HRESULT Saver::CreateMaterialObject(LPDIRECTXFILEDATA pMatListObj,
  458. FaceMaterial *pMat)
  459. {
  460. BaseMaterial data;
  461. data.faceColor.r = MyD3DRMColorGetRed(pMat->faceColor);
  462. data.faceColor.g = MyD3DRMColorGetGreen(pMat->faceColor);
  463. data.faceColor.b = MyD3DRMColorGetBlue(pMat->faceColor);
  464. data.faceColor.a = MyD3DRMColorGetAlpha(pMat->faceColor);
  465. data.power = pMat->pMaterial->GetPower();
  466. pMat->pMaterial->GetSpecular(&data.specularColor.r,
  467. &data.specularColor.g,
  468. &data.specularColor.b);
  469. pMat->pMaterial->GetEmissive(&data.emissiveColor.r,
  470. &data.emissiveColor.g,
  471. &data.emissiveColor.b);
  472. LPDIRECTXFILEDATA pMaterialObj;
  473. pSave->CreateDataObject(TID_D3DRMMaterial,
  474. NULL,
  475. NULL,
  476. sizeof(BaseMaterial),
  477. &data,
  478. &pMaterialObj);
  479. if (pMat->pTexture)
  480. {
  481. IDirectXFileData *pTextureObj;
  482. DWORD dwSize;
  483. pMat->pTexture->GetName(&dwSize, NULL);
  484. if (dwSize)
  485. {
  486. LPSTR szName = new char[dwSize];
  487. pMat->pTexture->GetName(&dwSize, szName);
  488. pSave->CreateDataObject(TID_D3DRMTextureFilename,
  489. NULL,
  490. NULL,
  491. sizeof(LPSTR),
  492. &szName,
  493. &pTextureObj);
  494. pMaterialObj->AddDataObject(pTextureObj);
  495. pTextureObj->Release();
  496. lNames.Add(szName);
  497. }
  498. }
  499. pMatListObj->AddDataObject(pMaterialObj);
  500. pMaterialObj->Release();
  501. return S_OK;
  502. }
  503. HRESULT Saver::CreateTextureWrapsObject(LPDIRECTXFILEDATA pMeshObj,
  504. LPDIRECT3DRMFACEARRAY pFaceArray)
  505. {
  506. DWORD cbSize, cFaces;
  507. FaceWraps *data;
  508. cFaces = pFaceArray->GetSize();
  509. cbSize = sizeof(DWORD) + cFaces * sizeof(Boolean2d);
  510. data = (FaceWraps *) new BYTE[cbSize];
  511. if (!data) return E_OUTOFMEMORY;
  512. data->cFaces = cFaces;
  513. Boolean2d *pWrap = data->faceWraps;
  514. for (DWORD i = 0; i < cFaces; i++, pWrap++)
  515. {
  516. LPDIRECT3DRMFACE pFace;
  517. pFaceArray->GetElement(i, &pFace);
  518. pFace->GetTextureTopology(&pWrap->u, &pWrap->v);
  519. pFace->Release();
  520. }
  521. LPDIRECTXFILEDATA pTextureWrapsObj;
  522. pSave->CreateDataObject(TID_D3DRMMeshFaceWraps,
  523. NULL,
  524. NULL,
  525. cbSize,
  526. data,
  527. &pTextureWrapsObj);
  528. pMeshObj->AddDataObject(pTextureWrapsObj);
  529. pTextureWrapsObj->Release();
  530. delete[] data;
  531. return S_OK;
  532. }
  533. HRESULT Saver::CreateTextureCoordsObject(LPDIRECTXFILEDATA pMeshObj,
  534. DWORD cVertices,
  535. LPDIRECT3DRMMESHBUILDER3 pMeshBuilder)
  536. {
  537. DWORD cbSize;
  538. TextureCoords *data;
  539. cbSize = sizeof(DWORD) + cVertices * sizeof(Coords2d);
  540. data = (TextureCoords *) new BYTE[cbSize];
  541. if (!data) return E_OUTOFMEMORY;
  542. data->cVertices = cVertices;
  543. Coords2d *pCoords = data->textureCoords;
  544. for (DWORD i = 0; i < cVertices; i++, pCoords++)
  545. {
  546. pMeshBuilder->GetTextureCoordinates(i, &pCoords->u, &pCoords->v);
  547. }
  548. LPDIRECTXFILEDATA pTexCoordsObj;
  549. pSave->CreateDataObject(TID_D3DRMMeshTextureCoords,
  550. NULL,
  551. NULL,
  552. cbSize,
  553. data,
  554. &pTexCoordsObj);
  555. pMeshObj->AddDataObject(pTexCoordsObj);
  556. pTexCoordsObj->Release();
  557. delete[] data;
  558. return S_OK;
  559. }
  560. FaceMaterialList::FaceMaterialList()
  561. : cElements(0), pFirst(NULL)
  562. {
  563. }
  564. FaceMaterialList::~FaceMaterialList()
  565. {
  566. FaceMaterial *pMat = pFirst;
  567. while (pMat)
  568. {
  569. FaceMaterial *pNext = pMat->pNext;
  570. pMat->pMaterial->Release();
  571. if (pMat->pTexture) pMat->pTexture->Release();
  572. delete pMat;
  573. pMat = pNext;
  574. }
  575. }
  576. DWORD FaceMaterialList::Find(D3DCOLOR faceColor,
  577. LPDIRECT3DRMMATERIAL pMaterial,
  578. LPDIRECT3DRMTEXTURE pTexture)
  579. {
  580. FaceMaterial *pTmp = pFirst;
  581. FaceMaterial **ppNew = &pFirst;
  582. for (DWORD i = 0; pTmp; i++, pTmp = pTmp->pNext)
  583. {
  584. if (pTmp->faceColor == faceColor &&
  585. pTmp->pMaterial == pMaterial &&
  586. pTmp->pTexture == pTexture)
  587. return i;
  588. if (!pTmp->pNext)
  589. ppNew = &pTmp->pNext;
  590. }
  591. FaceMaterial *pNew = new FaceMaterial;
  592. if (!pNew) return 0;
  593. pNew->faceColor = faceColor;
  594. pNew->pMaterial = pMaterial;
  595. pNew->pTexture = pTexture;
  596. pNew->pNext = NULL;
  597. pMaterial->AddRef();
  598. if (pTexture) pTexture->AddRef();
  599. *ppNew = pNew;
  600. cElements++;
  601. return i;
  602. }
  603. NameList::NameList()
  604. : pFirst(NULL),
  605. ppLast(NULL)
  606. {
  607. }
  608. NameList::~NameList()
  609. {
  610. NameEntry *pEntry = pFirst;
  611. while (pEntry)
  612. {
  613. NameEntry *pNext = pEntry->pNext;
  614. delete[] pEntry->pName;
  615. delete pEntry;
  616. pEntry = pNext;
  617. }
  618. }
  619. void NameList::Add(LPSTR pName)
  620. {
  621. NameEntry *pNew = new NameEntry;
  622. if (!pNew) return;
  623. pNew->pName = pName;
  624. pNew->pNext = NULL;
  625. if (ppLast)
  626. *ppLast = pNew;
  627. else
  628. pFirst = pNew;
  629. ppLast = &pNew->pNext;
  630. }