matinfo.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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 : WW3D *
  23. * *
  24. * $Archive:: /VSS_Sync/ww3d2/matinfo.h $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 8/29/01 7:29p $*
  29. * *
  30. * $Revision:: 11 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef MATINFO_H
  39. #define MATINFO_H
  40. #include "always.h"
  41. #include "wwdebug.h"
  42. #include "vector.h"
  43. #include "vertmaterial.h"
  44. #include "texture.h"
  45. #include "shader.h"
  46. #ifdef _UNIX
  47. #include "osdep.h"
  48. #endif
  49. class MeshModelClass;
  50. class MeshMatDescClass;
  51. /***********************************************************************************************
  52. ** MaterialInfoClass
  53. **
  54. ** This class gives an interface to the "changeable" material parameters inside a
  55. ** W3D render object. Typically, this will include things like the following:
  56. ** - one or more textures,
  57. ** - the vertex material used by the mesh (defines lighting properties, etc)
  58. **
  59. ** Another purpose of this class is to actually hold onto a ref for each material
  60. ** object that a mesh uses. The "per-triangle" pointer arrays are not ref counted
  61. ** so the material info serves as a place to hold a reference to each material object
  62. ** that the mesh is using.
  63. **
  64. ***********************************************************************************************/
  65. class MaterialInfoClass : public W3DMPO, public RefCountClass
  66. {
  67. W3DMPO_GLUE(MaterialInfoClass)
  68. public:
  69. MaterialInfoClass();
  70. MaterialInfoClass(const MaterialInfoClass & src);
  71. ~MaterialInfoClass();
  72. MaterialInfoClass * Clone(void) const;
  73. void Reset(void) { Free(); }
  74. int Vertex_Material_Count(void) const { return VertexMaterials.Count(); }
  75. int Texture_Count(void) const { return Textures.Count(); }
  76. int Add_Vertex_Material(VertexMaterialClass * vmat);
  77. int Add_Texture(TextureClass * tex);
  78. int Get_Vertex_Material_Index(const char * name);
  79. int Get_Texture_Index(const char * name);
  80. VertexMaterialClass * Get_Vertex_Material(int index);
  81. VertexMaterialClass * Get_Vertex_Material(const char * name);
  82. VertexMaterialClass * Peek_Vertex_Material(int index);
  83. VertexMaterialClass * Peek_Vertex_Material(const char * name);
  84. void Replace_Material(int index, VertexMaterialClass *newMaterial);
  85. void Reset_Texture_Mappers(void);
  86. void Make_Vertex_Materials_Unique(void);
  87. bool Has_Time_Variant_Texture_Mappers(void);
  88. TextureClass * Get_Texture(int index);
  89. TextureClass * Get_Texture(const char * name);
  90. TextureClass * Peek_Texture(int index);
  91. TextureClass * Peek_Texture(const char * name);
  92. void Replace_Texture(int index, TextureClass *newTexture);
  93. // void Set_Texture_Reduction_Factor(float trf);
  94. // void Process_Texture_Reduction(void);
  95. private:
  96. void Free(void);
  97. DynamicVectorClass<VertexMaterialClass *> VertexMaterials;
  98. DynamicVectorClass<TextureClass *> Textures;
  99. };
  100. /***********************************************************************************************
  101. ** MaterialRemapperClass
  102. ** This class is used when we need to "remap" all of the material pointers in a mesh
  103. ** to a new set of cloned materials. Basically, it assumes that you are going to initialize
  104. ** it with two identical material info objects (src and dest) and then you can give it pointers
  105. ** to materials in the "src" material info and it will give you back pointers to materials
  106. ** in the "dest" material info class.
  107. **
  108. ** This class attempts to take advantage of the fact that meshes should normally be sorted
  109. ** with respect to their materials so we shouldn't really be doing a linear search for
  110. ** each remap...
  111. **
  112. ** Please Note: this class does not hold references to the materials and is meant only to
  113. ** be used in a temporary fashion. Create it, do your conversion, then delete it :-)
  114. ***********************************************************************************************/
  115. class MaterialRemapperClass
  116. {
  117. public:
  118. MaterialRemapperClass(MaterialInfoClass * src,MaterialInfoClass * dest);
  119. ~MaterialRemapperClass(void);
  120. TextureClass * Remap_Texture(TextureClass * src);
  121. VertexMaterialClass * Remap_Vertex_Material(VertexMaterialClass * src);
  122. void Remap_Mesh(const MeshMatDescClass * srcmeshmatdesc, MeshMatDescClass * destmeshmatdesc);
  123. private:
  124. struct VmatRemapStruct
  125. {
  126. VertexMaterialClass * Src;
  127. VertexMaterialClass * Dest;
  128. };
  129. struct TextureRemapStruct
  130. {
  131. TextureClass * Src;
  132. TextureClass * Dest;
  133. };
  134. MaterialInfoClass * SrcMatInfo;
  135. MaterialInfoClass * DestMatInfo;
  136. int TextureCount;
  137. TextureRemapStruct * TextureRemaps;
  138. int VertexMaterialCount;
  139. VmatRemapStruct * VertexMaterialRemaps;
  140. VertexMaterialClass * LastSrcVmat;
  141. VertexMaterialClass * LastDestVmat;
  142. TextureClass * LastSrcTex;
  143. TextureClass * LastDestTex;
  144. };
  145. /***********************************************************************************************
  146. ** MaterialCollectorClass
  147. **
  148. ** This class can be used to collect all of the unique instances of materials from a mesh.
  149. ** Its original motivation is to solve a problem encountered in trying to save a mesh
  150. ** to disk. There are arrays of pointers to vertex materials in the mesh but no record of
  151. ** the set of unique vertex materials (all pointers could point to the same one...) Similar
  152. ** to the remapper, it tries to take advantage of the fact that the materials and textures
  153. ** should be in sorted order to optimize the lookups...
  154. **
  155. ** NOTE: pointer comparisons are used to determine if the objects are unique. I don't
  156. ** check whether the contents of the objects are identical. (Exporter does this, I assume
  157. ** that if there are two separate objects, they are that way for a reason here.)
  158. ***********************************************************************************************/
  159. class MaterialCollectorClass
  160. {
  161. public:
  162. MaterialCollectorClass(void);
  163. ~MaterialCollectorClass(void);
  164. void Reset(void);
  165. void Collect_Materials(MeshModelClass * mesh);
  166. void Add_Texture(TextureClass * tex);
  167. void Add_Shader(ShaderClass shader);
  168. void Add_Vertex_Material(VertexMaterialClass * vmat);
  169. int Get_Shader_Count(void);
  170. int Get_Vertex_Material_Count(void);
  171. int Get_Texture_Count(void);
  172. ShaderClass Peek_Shader(int i);
  173. TextureClass * Peek_Texture(int i);
  174. VertexMaterialClass * Peek_Vertex_Material(int i);
  175. int Find_Shader(const ShaderClass & shader);
  176. int Find_Texture(TextureClass * tex);
  177. int Find_Vertex_Material(VertexMaterialClass * mat);
  178. protected:
  179. DynamicVectorClass<ShaderClass> Shaders;
  180. DynamicVectorClass<VertexMaterialClass *> VertexMaterials;
  181. DynamicVectorClass<TextureClass *> Textures;
  182. ShaderClass LastShader;
  183. VertexMaterialClass * LastMaterial;
  184. TextureClass * LastTexture;
  185. };
  186. inline int MaterialInfoClass::Add_Vertex_Material(VertexMaterialClass * vmat)
  187. {
  188. if (vmat != NULL) {
  189. vmat->Add_Ref();
  190. }
  191. int index = VertexMaterials.Count();
  192. VertexMaterials.Add(vmat);
  193. return index;
  194. }
  195. inline int MaterialInfoClass::Get_Vertex_Material_Index(const char * name)
  196. {
  197. for (int i=0; i<VertexMaterials.Count(); i++) {
  198. if (stricmp(name,VertexMaterials[i]->Get_Name()) == 0) {
  199. return i;
  200. }
  201. }
  202. return -1;
  203. }
  204. inline VertexMaterialClass * MaterialInfoClass::Get_Vertex_Material(int index)
  205. {
  206. WWASSERT(index >= 0);
  207. WWASSERT(index < VertexMaterials.Count());
  208. if (VertexMaterials[index]) {
  209. VertexMaterials[index]->Add_Ref();
  210. }
  211. return VertexMaterials[index];
  212. }
  213. inline VertexMaterialClass * MaterialInfoClass::Get_Vertex_Material(const char * name)
  214. {
  215. int index = Get_Vertex_Material_Index(name);
  216. if (index == -1) {
  217. return NULL;
  218. } else {
  219. return Get_Vertex_Material(index);
  220. }
  221. }
  222. inline VertexMaterialClass * MaterialInfoClass::Peek_Vertex_Material(int index)
  223. {
  224. WWASSERT(index >= 0);
  225. WWASSERT(index < VertexMaterials.Count());
  226. return VertexMaterials[index];
  227. }
  228. inline VertexMaterialClass * MaterialInfoClass::Peek_Vertex_Material(const char * name)
  229. {
  230. int index = Get_Vertex_Material_Index(name);
  231. if (index == -1) {
  232. return NULL;
  233. } else {
  234. return Peek_Vertex_Material(index);
  235. }
  236. }
  237. inline void MaterialInfoClass::Replace_Material(int index, VertexMaterialClass *newMaterial)
  238. {
  239. REF_PTR_SET(VertexMaterials[index],newMaterial);
  240. }
  241. inline void MaterialInfoClass::Reset_Texture_Mappers(void)
  242. {
  243. int vmat_count = VertexMaterials.Count();
  244. for (int i = 0; i < vmat_count; i++) {
  245. VertexMaterials[i]->Reset_Mappers();
  246. }
  247. }
  248. inline bool MaterialInfoClass::Has_Time_Variant_Texture_Mappers(void)
  249. {
  250. int vmat_count = VertexMaterials.Count();
  251. for (int i = 0; i < vmat_count; i++) {
  252. if (VertexMaterials[i]->Are_Mappers_Time_Variant()) return true;
  253. }
  254. return false;
  255. }
  256. inline void MaterialInfoClass::Make_Vertex_Materials_Unique(void)
  257. {
  258. int vmat_count = VertexMaterials.Count();
  259. for (int i = 0; i < vmat_count; i++) {
  260. VertexMaterials[i]->Make_Unique();
  261. }
  262. }
  263. inline TextureClass * MaterialInfoClass::Get_Texture(const char * name)
  264. {
  265. int index = Get_Texture_Index(name);
  266. if (index == -1) {
  267. return NULL;
  268. } else {
  269. return Get_Texture(index);
  270. }
  271. }
  272. inline TextureClass * MaterialInfoClass::Peek_Texture(int index)
  273. {
  274. WWASSERT(index >= 0);
  275. WWASSERT(index < Textures.Count());
  276. return Textures[index];
  277. }
  278. inline void MaterialInfoClass::Replace_Texture(int index, TextureClass *newTexture)
  279. {
  280. REF_PTR_SET(Textures[index],newTexture);
  281. }
  282. #endif // MATINFO_H