matinfo.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : MatInfo.h *
  23. * *
  24. * $Archive:: /Commando/Code/ww3d2/matinfo.cpp $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 6/15/01 5:50p $*
  29. * *
  30. * $Revision:: 10 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "matinfo.h"
  36. #include "wwdebug.h"
  37. #include "meshmdl.h"
  38. #include "texture.h"
  39. MaterialInfoClass::MaterialInfoClass(void)
  40. {
  41. }
  42. MaterialInfoClass::MaterialInfoClass(const MaterialInfoClass & src)
  43. {
  44. for (int mi=0; mi<src.VertexMaterials.Count(); mi++) {
  45. VertexMaterialClass * vmat;
  46. vmat = src.VertexMaterials[mi]->Clone();
  47. VertexMaterials.Add(vmat);
  48. }
  49. for (int ti=0; ti<src.Textures.Count(); ti++) {
  50. TextureClass * tex = src.Textures[ti];
  51. tex->Add_Ref();
  52. Textures.Add(tex);
  53. }
  54. }
  55. MaterialInfoClass::~MaterialInfoClass(void)
  56. {
  57. Free();
  58. }
  59. MaterialInfoClass * MaterialInfoClass::Clone(void) const
  60. {
  61. return W3DNEW MaterialInfoClass(*this);
  62. }
  63. int MaterialInfoClass::Add_Texture(TextureClass * tex)
  64. {
  65. WWASSERT(tex != NULL);
  66. tex->Add_Ref();
  67. int index = Textures.Count();
  68. Textures.Add(tex);
  69. return index;
  70. }
  71. int MaterialInfoClass::Get_Texture_Index(const char * name)
  72. {
  73. for (int i=0; i<Textures.Count(); i++) {
  74. if (stricmp(name,Textures[i]->Get_Texture_Name()) == 0) {
  75. return i;
  76. }
  77. }
  78. return -1;
  79. }
  80. TextureClass * MaterialInfoClass::Get_Texture(int index)
  81. {
  82. WWASSERT(index >= 0);
  83. WWASSERT(index < Textures.Count());
  84. Textures[index]->Add_Ref();
  85. return Textures[index];
  86. }
  87. /*
  88. void MaterialInfoClass::Set_Texture_Reduction_Factor(float trf)
  89. {
  90. for (int i = 0; i < Textures.Count(); i++) {
  91. Textures[i]->Set_Reduction_Factor(trf);
  92. }
  93. }
  94. void MaterialInfoClass::Process_Texture_Reduction(void)
  95. {
  96. for (int i = 0; i < Textures.Count(); i++) {
  97. Textures[i]->Process_Reduction();
  98. }
  99. }
  100. */
  101. void MaterialInfoClass::Free(void)
  102. {
  103. int i;
  104. for (i=0; i<VertexMaterials.Count(); i++) {
  105. REF_PTR_RELEASE(VertexMaterials[i]);
  106. }
  107. VertexMaterials.Delete_All();
  108. for (i=0; i<Textures.Count(); i++) {
  109. REF_PTR_RELEASE(Textures[i]);
  110. }
  111. Textures.Delete_All();
  112. }
  113. MaterialRemapperClass::MaterialRemapperClass(MaterialInfoClass * src,MaterialInfoClass * dest) :
  114. TextureCount(0),
  115. TextureRemaps(NULL),
  116. VertexMaterialCount(0),
  117. VertexMaterialRemaps(NULL),
  118. LastSrcVmat(NULL),
  119. LastDestVmat(NULL),
  120. LastSrcTex(NULL),
  121. LastDestTex(NULL)
  122. {
  123. WWASSERT(src);
  124. WWASSERT(dest);
  125. WWASSERT(src->Texture_Count() == dest->Texture_Count());
  126. WWASSERT(src->Vertex_Material_Count() == dest->Vertex_Material_Count());
  127. SrcMatInfo = src;
  128. SrcMatInfo->Add_Ref();
  129. DestMatInfo = dest;
  130. DestMatInfo->Add_Ref();
  131. if (src->Vertex_Material_Count() > 0) {
  132. VertexMaterialCount = src->Vertex_Material_Count();
  133. VertexMaterialRemaps = W3DNEWARRAY VmatRemapStruct[VertexMaterialCount];
  134. for (int i=0; i<src->Vertex_Material_Count(); i++) {
  135. VertexMaterialRemaps[i].Src = src->Peek_Vertex_Material(i);
  136. VertexMaterialRemaps[i].Dest = dest->Peek_Vertex_Material(i);
  137. }
  138. }
  139. if (src->Texture_Count() > 0) {
  140. TextureCount = src->Texture_Count();
  141. TextureRemaps = W3DNEWARRAY TextureRemapStruct[TextureCount];
  142. for (int i=0; i<src->Texture_Count(); i++) {
  143. TextureRemaps[i].Src = src->Peek_Texture(i);
  144. TextureRemaps[i].Dest = dest->Peek_Texture(i);
  145. }
  146. }
  147. }
  148. MaterialRemapperClass::~MaterialRemapperClass(void)
  149. {
  150. SrcMatInfo->Release_Ref();
  151. DestMatInfo->Release_Ref();
  152. if (TextureRemaps) {
  153. delete[] TextureRemaps;
  154. }
  155. if (VertexMaterialRemaps) {
  156. delete[] VertexMaterialRemaps;
  157. }
  158. }
  159. TextureClass * MaterialRemapperClass::Remap_Texture(TextureClass * src)
  160. {
  161. if (src == NULL) return src;
  162. if (src == LastSrcTex) return LastDestTex;
  163. for (int i=0; i<TextureCount; i++) {
  164. if (TextureRemaps[i].Src == src) {
  165. LastSrcTex = src;
  166. LastDestTex = TextureRemaps[i].Dest;
  167. return TextureRemaps[i].Dest;
  168. }
  169. }
  170. WWASSERT(0); // uh-oh didn't find the texture, what happend???
  171. return NULL;
  172. }
  173. VertexMaterialClass * MaterialRemapperClass::Remap_Vertex_Material(VertexMaterialClass * src)
  174. {
  175. if (src == NULL) return src;
  176. if (src == LastSrcVmat) return LastDestVmat;
  177. for (int i=0; i<VertexMaterialCount; i++) {
  178. if (VertexMaterialRemaps[i].Src == src) {
  179. LastSrcVmat = src;
  180. LastDestVmat = VertexMaterialRemaps[i].Dest;
  181. return VertexMaterialRemaps[i].Dest;
  182. }
  183. }
  184. WWASSERT(0); // uh-oh didn't find the material, what happend???
  185. return NULL;
  186. }
  187. void MaterialRemapperClass::Remap_Mesh(const MeshMatDescClass * srcmeshmatdesc, MeshMatDescClass * destmeshmatdesc)
  188. {
  189. /*
  190. ** Remap the vertex materials if there is at least one of them
  191. */
  192. if (SrcMatInfo->Vertex_Material_Count() >= 1) {
  193. for (int pass = 0;pass < srcmeshmatdesc->Get_Pass_Count(); pass++) {
  194. if (srcmeshmatdesc->Has_Material_Array(pass)) {
  195. for (int vert_index = 0; vert_index < srcmeshmatdesc->Get_Vertex_Count(); vert_index++) {
  196. VertexMaterialClass * src = srcmeshmatdesc->Peek_Material(vert_index, pass);
  197. destmeshmatdesc->Set_Material(vert_index, Remap_Vertex_Material(src),pass);
  198. }
  199. } else {
  200. VertexMaterialClass * src = srcmeshmatdesc->Peek_Single_Material(pass);
  201. destmeshmatdesc->Set_Single_Material(Remap_Vertex_Material(src), pass);
  202. }
  203. }
  204. }
  205. /*
  206. ** Remap the textures if there is at least one of them
  207. */
  208. if (SrcMatInfo->Texture_Count() >= 1) {
  209. for (int pass = 0;pass < srcmeshmatdesc->Get_Pass_Count(); pass++) {
  210. for (int stage = 0; stage < MeshMatDescClass::MAX_TEX_STAGES; stage++) {
  211. if (srcmeshmatdesc->Has_Texture_Array(pass, stage)) {
  212. for (int poly_index = 0; poly_index < srcmeshmatdesc->Get_Polygon_Count(); poly_index++) {
  213. TextureClass * src = srcmeshmatdesc->Peek_Texture(poly_index, pass, stage);
  214. destmeshmatdesc->Set_Texture(poly_index, Remap_Texture(src), pass, stage);
  215. }
  216. } else {
  217. TextureClass * src = srcmeshmatdesc->Peek_Single_Texture(pass, stage);
  218. destmeshmatdesc->Set_Single_Texture(Remap_Texture(src), pass, stage);
  219. }
  220. }
  221. }
  222. }
  223. }
  224. MaterialCollectorClass::MaterialCollectorClass(void)
  225. {
  226. LastShader = ShaderClass(0xFFFFFFFF);
  227. LastMaterial = NULL;
  228. LastTexture = NULL;
  229. }
  230. MaterialCollectorClass::~MaterialCollectorClass(void)
  231. {
  232. Reset();
  233. }
  234. void MaterialCollectorClass::Collect_Materials(MeshModelClass * mesh)
  235. {
  236. for (int pass = 0;pass < mesh->Get_Pass_Count(); pass++) {
  237. // Vertex materials (either single or per vertex)
  238. if (mesh->Has_Material_Array(pass)) {
  239. for (int vert_index = 0;vert_index < mesh->Get_Vertex_Count(); vert_index++) {
  240. VertexMaterialClass * mat = mesh->Peek_Material(vert_index,pass);
  241. Add_Vertex_Material(mat);
  242. }
  243. } else {
  244. VertexMaterialClass * mat = mesh->Get_Single_Material(pass);
  245. Add_Vertex_Material(mat);
  246. REF_PTR_RELEASE(mat);
  247. }
  248. // Shaders (single or per poly...)
  249. if (mesh->Has_Shader_Array(pass)) {
  250. for (int poly_index=0; poly_index < mesh->Get_Polygon_Count(); poly_index++) {
  251. Add_Shader(mesh->Get_Shader(poly_index,pass));
  252. }
  253. } else {
  254. ShaderClass sh = mesh->Get_Single_Shader(pass);
  255. Add_Shader(sh);
  256. }
  257. // Textures per pass, per stage (either array or single...)
  258. for (int stage = 0; stage < MeshMatDescClass::MAX_TEX_STAGES; stage++) {
  259. if (mesh->Has_Texture_Array(pass,stage)) {
  260. for (int poly_index = 0;poly_index < mesh->Get_Polygon_Count(); poly_index++) {
  261. TextureClass * tex = mesh->Peek_Texture(poly_index,pass,stage);
  262. Add_Texture(tex);
  263. }
  264. } else {
  265. TextureClass * tex = mesh->Peek_Single_Texture(pass,stage);
  266. Add_Texture(tex);
  267. }
  268. }
  269. }
  270. }
  271. void MaterialCollectorClass::Reset(void)
  272. {
  273. for (int ti=0; ti<Textures.Count(); ti++) {
  274. REF_PTR_RELEASE(Textures[ti]);
  275. }
  276. for (int vi=0; vi<VertexMaterials.Count(); vi++) {
  277. REF_PTR_RELEASE(VertexMaterials[vi]);
  278. }
  279. Textures.Clear();
  280. VertexMaterials.Clear();
  281. Shaders.Clear();
  282. }
  283. void MaterialCollectorClass::Add_Texture(TextureClass * tex)
  284. {
  285. if (tex == NULL) return;
  286. if (tex == LastTexture) return;
  287. if (Find_Texture(tex) != -1) return;
  288. Textures.Add(tex);
  289. tex->Add_Ref();
  290. LastTexture = tex;
  291. }
  292. void MaterialCollectorClass::Add_Shader(ShaderClass shader)
  293. {
  294. if (shader == LastShader) return;
  295. if (Find_Shader(shader) != -1) return;
  296. Shaders.Add(shader);
  297. LastShader = shader;
  298. }
  299. void MaterialCollectorClass::Add_Vertex_Material(VertexMaterialClass * vmat)
  300. {
  301. if (vmat == NULL) return;
  302. if (vmat == LastMaterial) return;
  303. if (Find_Vertex_Material(vmat) != -1) return;
  304. VertexMaterials.Add(vmat);
  305. vmat->Add_Ref();
  306. LastMaterial = vmat;
  307. }
  308. int MaterialCollectorClass::Get_Shader_Count(void)
  309. {
  310. return Shaders.Count();
  311. }
  312. int MaterialCollectorClass::Get_Vertex_Material_Count(void)
  313. {
  314. return VertexMaterials.Count();
  315. }
  316. int MaterialCollectorClass::Get_Texture_Count(void)
  317. {
  318. return Textures.Count();
  319. }
  320. ShaderClass MaterialCollectorClass::Peek_Shader(int i)
  321. {
  322. return Shaders[i];
  323. }
  324. TextureClass * MaterialCollectorClass::Peek_Texture(int i)
  325. {
  326. return Textures[i];
  327. }
  328. VertexMaterialClass * MaterialCollectorClass::Peek_Vertex_Material(int i)
  329. {
  330. return VertexMaterials[i];
  331. }
  332. int MaterialCollectorClass::Find_Shader(const ShaderClass & shader)
  333. {
  334. for (int si=0; si<Shaders.Count(); si++) {
  335. if (Shaders[si] == shader) {
  336. return si;
  337. }
  338. }
  339. return -1;
  340. }
  341. int MaterialCollectorClass::Find_Texture(TextureClass * tex)
  342. {
  343. for (int ti=0; ti<Textures.Count(); ti++) {
  344. if (Textures[ti] == tex) {
  345. return ti;
  346. }
  347. }
  348. return -1;
  349. }
  350. int MaterialCollectorClass::Find_Vertex_Material(VertexMaterialClass * mat)
  351. {
  352. for (int vi=0; vi<VertexMaterials.Count(); vi++) {
  353. if (VertexMaterials[vi] == mat) {
  354. return vi;
  355. }
  356. }
  357. return -1;
  358. }