vertmaterial.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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:: /Commando/Code/ww3d2/vertmaterial.h $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 4/27/01 2:22p $*
  29. * *
  30. * $Revision:: 25 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef VERTMATERIAL_H
  39. #define VERTMATERIAL_H
  40. #include "always.h"
  41. #include "refcount.h"
  42. #include "vector3.h"
  43. #include "w3d_file.h"
  44. #include "meshbuild.h"
  45. #include "w3derr.h"
  46. #include "mapper.h"
  47. #include "wwstring.h"
  48. #include <string.h>
  49. class ChunkLoadClass;
  50. class ChunkSaveClass;
  51. #define DYN_MAT8
  52. #ifdef DYN_MAT8
  53. class DynD3DMATERIAL8;
  54. #else
  55. struct _D3DMATERIAL8;
  56. #endif
  57. /**
  58. ** VertexMaterialClass
  59. ** This is simply the typical W3D thin-wrapper around the surrender vertex material.
  60. ** The vertex material defines things like the lighting properties of a vertex.
  61. */
  62. class VertexMaterialClass : public W3DMPO, public RefCountClass
  63. {
  64. W3DMPO_GLUE(VertexMaterialClass)
  65. friend DX8Wrapper;
  66. public:
  67. /*
  68. ** Similar to the TextureClass, these enumerations are set up to be exactly the same as
  69. ** the surrender material enumerations. Nearly all functions in this class are inline
  70. ** so that it will go away since the only purpose of Material Class is to protect our
  71. ** application code from the ever-changing surrender...
  72. */
  73. enum MappingType {
  74. MAPPING_NONE = -1, // no mapping needed
  75. MAPPING_UV = W3DMAPPING_UV, // default, use the u-v values in the model
  76. MAPPING_ENVIRONMENT = W3DMAPPING_ENVIRONMENT, // use the environment mapper
  77. };
  78. enum FlagsType {
  79. DEPTH_CUE= 0, // enable depth cueing (default = false)
  80. DEPTH_CUE_TO_ALPHA,
  81. COPY_SPECULAR_TO_DIFFUSE,
  82. };
  83. enum ColorSourceType {
  84. MATERIAL = 0, // D3DMCS_MATERIAL - the color source should be taken from the material setting
  85. COLOR1, // D3DMCS_COLOR1 - the color should be taken from per-vertex color array 1 (aka D3DFVF_DIFFUSE)
  86. COLOR2, // D3DMCS_COLOR2 - the color should be taken from per-vertex color array 2 (aka D3DFVF_SPECULAR)
  87. };
  88. enum PresetType
  89. {
  90. PRELIT_DIFFUSE=0,
  91. PRELIT_NODIFFUSE,
  92. PRESET_COUNT
  93. };
  94. VertexMaterialClass(void);
  95. VertexMaterialClass(const VertexMaterialClass & src);
  96. ~VertexMaterialClass(void);
  97. VertexMaterialClass & operator = (const VertexMaterialClass &src);
  98. VertexMaterialClass * Clone(void) { VertexMaterialClass * mat = NEW_REF (VertexMaterialClass,()); *mat = *this; return mat;}
  99. /*
  100. ** Name Access
  101. */
  102. void Set_Name(const char * name)
  103. {
  104. Name = name;
  105. }
  106. const char * Get_Name(void) const
  107. {
  108. return Name;
  109. }
  110. /*
  111. ** Control over the material flags
  112. */
  113. void Set_Flag(FlagsType flag,bool onoff)
  114. {
  115. CRCDirty=true;
  116. if (onoff)
  117. Flags|=(1<<flag);
  118. else
  119. Flags&=~(1<<flag);
  120. }
  121. int Get_Flag(FlagsType flag)
  122. { return (Flags>>flag) & 0x1; }
  123. /*
  124. ** Basic material properties
  125. */
  126. float Get_Shininess(void) const;
  127. void Set_Shininess(float shin);
  128. float Get_Opacity(void) const;
  129. void Set_Opacity(float o);
  130. void Get_Ambient(Vector3 * set_color) const;
  131. void Set_Ambient(const Vector3 & color);
  132. void Set_Ambient(float r,float g,float b);
  133. void Get_Diffuse(Vector3 * set_color) const;
  134. void Set_Diffuse(const Vector3 & color);
  135. void Set_Diffuse(float r,float g,float b);
  136. void Get_Specular(Vector3 * set_color) const;
  137. void Set_Specular(const Vector3 & color);
  138. void Set_Specular(float r,float g,float b);
  139. void Get_Emissive(Vector3 * set_color) const;
  140. void Set_Emissive(const Vector3 & color);
  141. void Set_Emissive(float r,float g,float b);
  142. void Set_Lighting(bool lighting) { CRCDirty=true; UseLighting=lighting; };
  143. bool Get_Lighting() const { return UseLighting; };
  144. /*
  145. ** Color source control. Note that if you set one of the sources to be one of
  146. ** the arrays, then the setting in the material is ignored. (i.e. if you
  147. ** set the diffuse source to array0, then the diffuse color set into the
  148. ** vertex material is ignored.
  149. */
  150. void Set_Ambient_Color_Source(ColorSourceType src);
  151. ColorSourceType Get_Ambient_Color_Source(void);
  152. void Set_Emissive_Color_Source(ColorSourceType src);
  153. ColorSourceType Get_Emissive_Color_Source(void);
  154. void Set_Diffuse_Color_Source(ColorSourceType src);
  155. ColorSourceType Get_Diffuse_Color_Source(void);
  156. /*
  157. ** UV source control. The DX8 FVF can support up to 8 uv-arrays. The vertex
  158. ** material can/must be configured to index to the uv-arrays that you want to
  159. ** use for the two texture stages.
  160. */
  161. void Set_UV_Source(int stage,int array_index);
  162. int Get_UV_Source(int stage);
  163. /*
  164. ** Mapper control.
  165. */
  166. inline void Set_Mapper(TextureMapperClass *mapper,int stage=0);
  167. inline TextureMapperClass * Get_Mapper(int stage=0);
  168. inline TextureMapperClass * Peek_Mapper(int stage=0);
  169. inline void Reset_Mappers(void);
  170. /*
  171. ** Loading and saving to W3D files
  172. */
  173. WW3DErrorType Load_W3D(ChunkLoadClass & cload);
  174. WW3DErrorType Save_W3D(ChunkSaveClass & csave);
  175. void Parse_W3dVertexMaterialStruct(const W3dVertexMaterialStruct & vmat);
  176. void Parse_Mapping_Args(const W3dVertexMaterialStruct & vmat,char * mapping0_arg_buffer,char * mapping1_arg_buffer);
  177. void Init_From_Material3(const W3dMaterial3Struct & mat3);
  178. /*
  179. ** CRC, used by the loading code to build a list of the unique materials
  180. */
  181. inline unsigned long Get_CRC(void) const
  182. {
  183. if (CRCDirty) {
  184. CRC=Compute_CRC();
  185. CRCDirty=false;
  186. }
  187. return CRC;
  188. }
  189. /*
  190. ** Test whether this material is using any mappers which require vertex normals
  191. */
  192. bool Do_Mappers_Need_Normals(void) const;
  193. /*
  194. ** Test whether this material is using any mappers which are time-variant
  195. */
  196. bool Are_Mappers_Time_Variant(void) const;
  197. // Infrastructure to support presets
  198. static void Init();
  199. static void Shutdown();
  200. // TODO: Make Get_Preset const
  201. static VertexMaterialClass *Get_Preset(PresetType type);
  202. void Make_Unique();
  203. private:
  204. // We're using the pointer instead of the actual structure
  205. // so we don't have to include the d3d header - HY
  206. #ifdef DYN_MAT8
  207. DynD3DMATERIAL8 * MaterialDyn;
  208. #else
  209. _D3DMATERIAL8 * MaterialOld;
  210. #endif
  211. unsigned int Flags;
  212. unsigned int AmbientColorSource;
  213. unsigned int EmissiveColorSource;
  214. unsigned int DiffuseColorSource;
  215. StringClass Name;
  216. TextureMapperClass * Mapper[MeshBuilderClass::MAX_STAGES];
  217. unsigned int UVSource[MeshBuilderClass::MAX_STAGES];
  218. unsigned int UniqueID;
  219. mutable unsigned long CRC;
  220. mutable bool CRCDirty;
  221. bool UseLighting;
  222. private:
  223. /*
  224. ** Apply the render states to D3D
  225. */
  226. void Apply(void) const;
  227. /*
  228. ** Apply the render states corresponding to a NULL vetex material to D3D
  229. */
  230. static void Apply_Null(void);
  231. unsigned long VertexMaterialClass::Compute_CRC(void) const;
  232. static VertexMaterialClass *Presets[PRESET_COUNT];
  233. };
  234. inline void VertexMaterialClass::Set_Mapper(TextureMapperClass *mapper, int stage)
  235. {
  236. CRCDirty=true;
  237. REF_PTR_SET(Mapper[stage],mapper);
  238. }
  239. inline TextureMapperClass * VertexMaterialClass::Get_Mapper(int stage)
  240. {
  241. if (Mapper[stage]) {
  242. Mapper[stage]->Add_Ref();
  243. }
  244. return Mapper[stage];
  245. }
  246. inline TextureMapperClass * VertexMaterialClass::Peek_Mapper(int stage)
  247. {
  248. return Mapper[stage];
  249. }
  250. inline void VertexMaterialClass::Reset_Mappers(void)
  251. {
  252. for (int stage = 0; stage < MeshBuilderClass::MAX_STAGES; stage++) {
  253. if (Mapper[stage]) {
  254. Mapper[stage]->Reset();
  255. }
  256. }
  257. }
  258. inline bool VertexMaterialClass::Do_Mappers_Need_Normals(void) const
  259. {
  260. for (int stage = 0; stage < MeshBuilderClass::MAX_STAGES; stage++) {
  261. if (Mapper[stage] && (Mapper[stage]->Needs_Normals())) return true;
  262. }
  263. return false;
  264. }
  265. inline bool VertexMaterialClass::Are_Mappers_Time_Variant(void) const
  266. {
  267. for (int stage = 0; stage < MeshBuilderClass::MAX_STAGES; stage++) {
  268. if (Mapper[stage] && (Mapper[stage]->Is_Time_Variant())) return true;
  269. }
  270. return false;
  271. }
  272. #endif //VERTMATERIAL_H