/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** 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 *** *********************************************************************************************** * * * Project Name : WW3D * * * * $Archive:: /VSS_Sync/ww3d2/vertmaterial.h $* * * * Author:: Greg Hjelstrom * * * * $Modtime:: 8/29/01 7:29p $* * * * $Revision:: 26 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(_MSC_VER) #pragma once #endif #ifndef VERTMATERIAL_H #define VERTMATERIAL_H #include "always.h" #include "refcount.h" #include "vector3.h" #include "w3d_file.h" #include "meshbuild.h" #include "w3derr.h" #include "mapper.h" #include "wwstring.h" #include class ChunkLoadClass; class ChunkSaveClass; struct _D3DMATERIAL8; /** ** VertexMaterialClass ** This is simply the typical W3D thin-wrapper around the surrender vertex material. ** The vertex material defines things like the lighting properties of a vertex. */ class VertexMaterialClass : public RefCountClass { friend DX8Wrapper; public: /* ** Similar to the TextureClass, these enumerations are set up to be exactly the same as ** the surrender material enumerations. Nearly all functions in this class are inline ** so that it will go away since the only purpose of Material Class is to protect our ** application code from the ever-changing surrender... */ enum MappingType { MAPPING_NONE = -1, // no mapping needed MAPPING_UV = W3DMAPPING_UV, // default, use the u-v values in the model MAPPING_ENVIRONMENT = W3DMAPPING_ENVIRONMENT, // use the environment mapper }; enum FlagsType { DEPTH_CUE= 0, // enable depth cueing (default = false) DEPTH_CUE_TO_ALPHA, COPY_SPECULAR_TO_DIFFUSE, }; enum ColorSourceType { MATERIAL = 0, // D3DMCS_MATERIAL - the color source should be taken from the material setting COLOR1, // D3DMCS_COLOR1 - the color should be taken from per-vertex color array 1 (aka D3DFVF_DIFFUSE) COLOR2, // D3DMCS_COLOR2 - the color should be taken from per-vertex color array 2 (aka D3DFVF_SPECULAR) }; enum PresetType { PRELIT_DIFFUSE=0, PRELIT_NODIFFUSE, PRESET_COUNT }; VertexMaterialClass(void); VertexMaterialClass(const VertexMaterialClass & src); ~VertexMaterialClass(void); VertexMaterialClass & operator = (const VertexMaterialClass &src); VertexMaterialClass * Clone(void) { VertexMaterialClass * mat = NEW_REF (VertexMaterialClass,()); *mat = *this; return mat;} /* ** Name Access */ void Set_Name(const char * name) { Name = name; } const char * Get_Name(void) const { return Name; } /* ** Control over the material flags */ void Set_Flag(FlagsType flag,bool onoff) { CRCDirty=true; if (onoff) Flags|=(1<>flag) & 0x1; } /* ** Basic material properties */ float Get_Shininess(void) const; void Set_Shininess(float shin); float Get_Opacity(void) const; void Set_Opacity(float o); void Get_Ambient(Vector3 * set_color) const; void Set_Ambient(const Vector3 & color); void Set_Ambient(float r,float g,float b); void Get_Diffuse(Vector3 * set_color) const; void Set_Diffuse(const Vector3 & color); void Set_Diffuse(float r,float g,float b); void Get_Specular(Vector3 * set_color) const; void Set_Specular(const Vector3 & color); void Set_Specular(float r,float g,float b); void Get_Emissive(Vector3 * set_color) const; void Set_Emissive(const Vector3 & color); void Set_Emissive(float r,float g,float b); void Set_Lighting(bool lighting) { CRCDirty=true; UseLighting=lighting; }; bool Get_Lighting() const { return UseLighting; }; /* ** Color source control. Note that if you set one of the sources to be one of ** the arrays, then the setting in the material is ignored. (i.e. if you ** set the diffuse source to array0, then the diffuse color set into the ** vertex material is ignored. */ void Set_Ambient_Color_Source(ColorSourceType src); ColorSourceType Get_Ambient_Color_Source(void); void Set_Emissive_Color_Source(ColorSourceType src); ColorSourceType Get_Emissive_Color_Source(void); void Set_Diffuse_Color_Source(ColorSourceType src); ColorSourceType Get_Diffuse_Color_Source(void); /* ** UV source control. The DX8 FVF can support up to 8 uv-arrays. The vertex ** material can/must be configured to index to the uv-arrays that you want to ** use for the two texture stages. */ void Set_UV_Source(int stage,int array_index); int Get_UV_Source(int stage); /* ** Mapper control. */ inline void Set_Mapper(TextureMapperClass *mapper,int stage=0); inline TextureMapperClass * Get_Mapper(int stage=0); inline TextureMapperClass * Peek_Mapper(int stage=0); inline void Reset_Mappers(void); /* ** Loading and saving to W3D files */ WW3DErrorType Load_W3D(ChunkLoadClass & cload); WW3DErrorType Save_W3D(ChunkSaveClass & csave); void Init_From_Material3(const W3dMaterial3Struct & mat3); /* ** CRC, used by the loading code to build a list of the unique materials */ inline unsigned long Get_CRC(void) const { if (CRCDirty) { CRC=Compute_CRC(); CRCDirty=false; } return CRC; } /* ** Test whether this material is using any mappers which require vertex normals */ bool Do_Mappers_Need_Normals(void) const; /* ** Test whether this material is using any mappers which are time-variant */ bool Are_Mappers_Time_Variant(void) const; // Infrastructure to support presets static void Init(); static void Shutdown(); // TODO: Make Get_Preset const static VertexMaterialClass *Get_Preset(PresetType type); void Make_Unique(); protected: // We're using the pointer instead of the actual structure // so we don't have to include the d3d header - HY _D3DMATERIAL8 * Material; unsigned int Flags; unsigned int AmbientColorSource; unsigned int EmissiveColorSource; unsigned int DiffuseColorSource; StringClass Name; TextureMapperClass * Mapper[MeshBuilderClass::MAX_STAGES]; unsigned int UVSource[MeshBuilderClass::MAX_STAGES]; bool UseLighting; unsigned int UniqueID; mutable unsigned long CRC; mutable bool CRCDirty; private: /* ** Apply the render states to D3D */ void Apply(void) const; /* ** Apply the render states corresponding to a NULL vetex material to D3D */ static void Apply_Null(void); unsigned long VertexMaterialClass::Compute_CRC(void) const; static VertexMaterialClass *Presets[PRESET_COUNT]; }; inline void VertexMaterialClass::Set_Mapper(TextureMapperClass *mapper, int stage) { CRCDirty=true; REF_PTR_SET(Mapper[stage],mapper); } inline TextureMapperClass * VertexMaterialClass::Get_Mapper(int stage) { if (Mapper[stage]) { Mapper[stage]->Add_Ref(); } return Mapper[stage]; } inline TextureMapperClass * VertexMaterialClass::Peek_Mapper(int stage) { return Mapper[stage]; } inline void VertexMaterialClass::Reset_Mappers(void) { for (int stage = 0; stage < MeshBuilderClass::MAX_STAGES; stage++) { if (Mapper[stage]) { Mapper[stage]->Reset(); } } } inline bool VertexMaterialClass::Do_Mappers_Need_Normals(void) const { for (int stage = 0; stage < MeshBuilderClass::MAX_STAGES; stage++) { if (Mapper[stage] && (Mapper[stage]->Needs_Normals())) return true; } return false; } inline bool VertexMaterialClass::Are_Mappers_Time_Variant(void) const { for (int stage = 0; stage < MeshBuilderClass::MAX_STAGES; stage++) { if (Mapper[stage] && (Mapper[stage]->Is_Time_Variant())) return true; } return false; } #endif //VERTMATERIAL_H