matinfo.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. ** Command & Conquer Renegade(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 RefCountClass
  66. {
  67. public:
  68. MaterialInfoClass();
  69. MaterialInfoClass(const MaterialInfoClass & src);
  70. ~MaterialInfoClass();
  71. MaterialInfoClass * Clone(void) const;
  72. void Reset(void) { Free(); }
  73. int Vertex_Material_Count(void) const { return VertexMaterials.Count(); }
  74. int Texture_Count(void) const { return Textures.Count(); }
  75. int Add_Vertex_Material(VertexMaterialClass * vmat);
  76. int Add_Texture(TextureClass * tex);
  77. int Get_Vertex_Material_Index(const char * name);
  78. int Get_Texture_Index(const char * name);
  79. VertexMaterialClass * Get_Vertex_Material(int index);
  80. VertexMaterialClass * Get_Vertex_Material(const char * name);
  81. VertexMaterialClass * Peek_Vertex_Material(int index);
  82. VertexMaterialClass * Peek_Vertex_Material(const char * name);
  83. void Replace_Material(int index, VertexMaterialClass *newMaterial);
  84. void Reset_Texture_Mappers(void);
  85. void Make_Vertex_Materials_Unique(void);
  86. bool Has_Time_Variant_Texture_Mappers(void);
  87. TextureClass * Get_Texture(int index);
  88. TextureClass * Get_Texture(const char * name);
  89. TextureClass * Peek_Texture(int index);
  90. TextureClass * Peek_Texture(const char * name);
  91. void Replace_Texture(int index, TextureClass *newTexture);
  92. // void Set_Texture_Reduction_Factor(float trf);
  93. // void Process_Texture_Reduction(void);
  94. private:
  95. void Free(void);
  96. DynamicVectorClass<VertexMaterialClass *> VertexMaterials;
  97. DynamicVectorClass<TextureClass *> Textures;
  98. };
  99. /***********************************************************************************************
  100. ** MaterialRemapperClass
  101. ** This class is used when we need to "remap" all of the material pointers in a mesh
  102. ** to a new set of cloned materials. Basically, it assumes that you are going to initialize
  103. ** it with two identical material info objects (src and dest) and then you can give it pointers
  104. ** to materials in the "src" material info and it will give you back pointers to materials
  105. ** in the "dest" material info class.
  106. **
  107. ** This class attempts to take advantage of the fact that meshes should normally be sorted
  108. ** with respect to their materials so we shouldn't really be doing a linear search for
  109. ** each remap...
  110. **
  111. ** Please Note: this class does not hold references to the materials and is meant only to
  112. ** be used in a temporary fashion. Create it, do your conversion, then delete it :-)
  113. ***********************************************************************************************/
  114. class MaterialRemapperClass
  115. {
  116. public:
  117. MaterialRemapperClass(MaterialInfoClass * src,MaterialInfoClass * dest);
  118. ~MaterialRemapperClass(void);
  119. TextureClass * Remap_Texture(TextureClass * src);
  120. VertexMaterialClass * Remap_Vertex_Material(VertexMaterialClass * src);
  121. void Remap_Mesh(const MeshMatDescClass * srcmeshmatdesc, MeshMatDescClass * destmeshmatdesc);
  122. private:
  123. struct VmatRemapStruct
  124. {
  125. VertexMaterialClass * Src;
  126. VertexMaterialClass * Dest;
  127. };
  128. struct TextureRemapStruct
  129. {
  130. TextureClass * Src;
  131. TextureClass * Dest;
  132. };
  133. MaterialInfoClass * SrcMatInfo;
  134. MaterialInfoClass * DestMatInfo;
  135. int TextureCount;
  136. TextureRemapStruct * TextureRemaps;
  137. int VertexMaterialCount;
  138. VmatRemapStruct * VertexMaterialRemaps;
  139. VertexMaterialClass * LastSrcVmat;
  140. VertexMaterialClass * LastDestVmat;
  141. TextureClass * LastSrcTex;
  142. TextureClass * LastDestTex;
  143. };
  144. /***********************************************************************************************
  145. ** MaterialCollectorClass
  146. **
  147. ** This class can be used to collect all of the unique instances of materials from a mesh.
  148. ** Its original motivation is to solve a problem encountered in trying to save a mesh
  149. ** to disk. There are arrays of pointers to vertex materials in the mesh but no record of
  150. ** the set of unique vertex materials (all pointers could point to the same one...) Similar
  151. ** to the remapper, it tries to take advantage of the fact that the materials and textures
  152. ** should be in sorted order to optimize the lookups...
  153. **
  154. ** NOTE: pointer comparisons are used to determine if the objects are unique. I don't
  155. ** check whether the contents of the objects are identical. (Exporter does this, I assume
  156. ** that if there are two separate objects, they are that way for a reason here.)
  157. ***********************************************************************************************/
  158. class MaterialCollectorClass
  159. {
  160. public:
  161. MaterialCollectorClass(void);
  162. ~MaterialCollectorClass(void);
  163. void Reset(void);
  164. void Collect_Materials(MeshModelClass * mesh);
  165. void Add_Texture(TextureClass * tex);
  166. void Add_Shader(ShaderClass shader);
  167. void Add_Vertex_Material(VertexMaterialClass * vmat);
  168. int Get_Shader_Count(void);
  169. int Get_Vertex_Material_Count(void);
  170. int Get_Texture_Count(void);
  171. ShaderClass Peek_Shader(int i);
  172. TextureClass * Peek_Texture(int i);
  173. VertexMaterialClass * Peek_Vertex_Material(int i);
  174. int Find_Shader(const ShaderClass & shader);
  175. int Find_Texture(TextureClass * tex);
  176. int Find_Vertex_Material(VertexMaterialClass * mat);
  177. protected:
  178. DynamicVectorClass<ShaderClass> Shaders;
  179. DynamicVectorClass<VertexMaterialClass *> VertexMaterials;
  180. DynamicVectorClass<TextureClass *> Textures;
  181. ShaderClass LastShader;
  182. VertexMaterialClass * LastMaterial;
  183. TextureClass * LastTexture;
  184. };
  185. inline int MaterialInfoClass::Add_Vertex_Material(VertexMaterialClass * vmat)
  186. {
  187. if (vmat != NULL) {
  188. vmat->Add_Ref();
  189. }
  190. int index = VertexMaterials.Count();
  191. VertexMaterials.Add(vmat);
  192. return index;
  193. }
  194. inline int MaterialInfoClass::Get_Vertex_Material_Index(const char * name)
  195. {
  196. for (int i=0; i<VertexMaterials.Count(); i++) {
  197. if (stricmp(name,VertexMaterials[i]->Get_Name()) == 0) {
  198. return i;
  199. }
  200. }
  201. return -1;
  202. }
  203. inline VertexMaterialClass * MaterialInfoClass::Get_Vertex_Material(int index)
  204. {
  205. WWASSERT(index >= 0);
  206. WWASSERT(index < VertexMaterials.Count());
  207. if (VertexMaterials[index]) {
  208. VertexMaterials[index]->Add_Ref();
  209. }
  210. return VertexMaterials[index];
  211. }
  212. inline VertexMaterialClass * MaterialInfoClass::Get_Vertex_Material(const char * name)
  213. {
  214. int index = Get_Vertex_Material_Index(name);
  215. if (index == -1) {
  216. return NULL;
  217. } else {
  218. return Get_Vertex_Material(index);
  219. }
  220. }
  221. inline VertexMaterialClass * MaterialInfoClass::Peek_Vertex_Material(int index)
  222. {
  223. WWASSERT(index >= 0);
  224. WWASSERT(index < VertexMaterials.Count());
  225. return VertexMaterials[index];
  226. }
  227. inline VertexMaterialClass * MaterialInfoClass::Peek_Vertex_Material(const char * name)
  228. {
  229. int index = Get_Vertex_Material_Index(name);
  230. if (index == -1) {
  231. return NULL;
  232. } else {
  233. return Peek_Vertex_Material(index);
  234. }
  235. }
  236. inline void MaterialInfoClass::Replace_Material(int index, VertexMaterialClass *newMaterial)
  237. {
  238. REF_PTR_SET(VertexMaterials[index],newMaterial);
  239. }
  240. inline void MaterialInfoClass::Reset_Texture_Mappers(void)
  241. {
  242. int vmat_count = VertexMaterials.Count();
  243. for (int i = 0; i < vmat_count; i++) {
  244. VertexMaterials[i]->Reset_Mappers();
  245. }
  246. }
  247. inline bool MaterialInfoClass::Has_Time_Variant_Texture_Mappers(void)
  248. {
  249. int vmat_count = VertexMaterials.Count();
  250. for (int i = 0; i < vmat_count; i++) {
  251. if (VertexMaterials[i]->Are_Mappers_Time_Variant()) return true;
  252. }
  253. return false;
  254. }
  255. inline void MaterialInfoClass::Make_Vertex_Materials_Unique(void)
  256. {
  257. int vmat_count = VertexMaterials.Count();
  258. for (int i = 0; i < vmat_count; i++) {
  259. VertexMaterials[i]->Make_Unique();
  260. }
  261. }
  262. inline TextureClass * MaterialInfoClass::Get_Texture(const char * name)
  263. {
  264. int index = Get_Texture_Index(name);
  265. if (index == -1) {
  266. return NULL;
  267. } else {
  268. return Get_Texture(index);
  269. }
  270. }
  271. inline TextureClass * MaterialInfoClass::Peek_Texture(int index)
  272. {
  273. WWASSERT(index >= 0);
  274. WWASSERT(index < Textures.Count());
  275. return Textures[index];
  276. }
  277. inline void MaterialInfoClass::Replace_Texture(int index, TextureClass *newTexture)
  278. {
  279. REF_PTR_SET(Textures[index],newTexture);
  280. }
  281. #endif // MATINFO_H