| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- /*
- ** Command & Conquer Generals Zero Hour(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 <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** 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 : MatInfo.h *
- * *
- * $Archive:: /Commando/Code/ww3d2/matinfo.cpp $*
- * *
- * Author:: Greg Hjelstrom *
- * *
- * $Modtime:: 6/15/01 5:50p $*
- * *
- * $Revision:: 10 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "matinfo.h"
- #include "wwdebug.h"
- #include "meshmdl.h"
- #include "texture.h"
- MaterialInfoClass::MaterialInfoClass(void)
- {
- }
- MaterialInfoClass::MaterialInfoClass(const MaterialInfoClass & src)
- {
- for (int mi=0; mi<src.VertexMaterials.Count(); mi++) {
- VertexMaterialClass * vmat;
- vmat = src.VertexMaterials[mi]->Clone();
- VertexMaterials.Add(vmat);
- }
-
- for (int ti=0; ti<src.Textures.Count(); ti++) {
- TextureClass * tex = src.Textures[ti];
- tex->Add_Ref();
- Textures.Add(tex);
- }
- }
- MaterialInfoClass::~MaterialInfoClass(void)
- {
- Free();
- }
- MaterialInfoClass * MaterialInfoClass::Clone(void) const
- {
- return W3DNEW MaterialInfoClass(*this);
- }
- int MaterialInfoClass::Add_Texture(TextureClass * tex)
- {
- WWASSERT(tex != NULL);
- tex->Add_Ref();
- int index = Textures.Count();
- Textures.Add(tex);
- return index;
- }
- int MaterialInfoClass::Get_Texture_Index(const char * name)
- {
- for (int i=0; i<Textures.Count(); i++) {
- if (stricmp(name,Textures[i]->Get_Texture_Name()) == 0) {
- return i;
- }
- }
- return -1;
- }
- TextureClass * MaterialInfoClass::Get_Texture(int index)
- {
- WWASSERT(index >= 0);
- WWASSERT(index < Textures.Count());
- Textures[index]->Add_Ref();
- return Textures[index];
- }
- /*
- void MaterialInfoClass::Set_Texture_Reduction_Factor(float trf)
- {
- for (int i = 0; i < Textures.Count(); i++) {
- Textures[i]->Set_Reduction_Factor(trf);
- }
- }
- void MaterialInfoClass::Process_Texture_Reduction(void)
- {
- for (int i = 0; i < Textures.Count(); i++) {
- Textures[i]->Process_Reduction();
- }
- }
- */
- void MaterialInfoClass::Free(void)
- {
- int i;
-
- for (i=0; i<VertexMaterials.Count(); i++) {
- REF_PTR_RELEASE(VertexMaterials[i]);
- }
- VertexMaterials.Delete_All();
- for (i=0; i<Textures.Count(); i++) {
- REF_PTR_RELEASE(Textures[i]);
- }
- Textures.Delete_All();
- }
- MaterialRemapperClass::MaterialRemapperClass(MaterialInfoClass * src,MaterialInfoClass * dest) :
- TextureCount(0),
- TextureRemaps(NULL),
- VertexMaterialCount(0),
- VertexMaterialRemaps(NULL),
- LastSrcVmat(NULL),
- LastDestVmat(NULL),
- LastSrcTex(NULL),
- LastDestTex(NULL)
- {
- WWASSERT(src);
- WWASSERT(dest);
- WWASSERT(src->Texture_Count() == dest->Texture_Count());
- WWASSERT(src->Vertex_Material_Count() == dest->Vertex_Material_Count());
- SrcMatInfo = src;
- SrcMatInfo->Add_Ref();
- DestMatInfo = dest;
- DestMatInfo->Add_Ref();
- if (src->Vertex_Material_Count() > 0) {
- VertexMaterialCount = src->Vertex_Material_Count();
- VertexMaterialRemaps = W3DNEWARRAY VmatRemapStruct[VertexMaterialCount];
- for (int i=0; i<src->Vertex_Material_Count(); i++) {
- VertexMaterialRemaps[i].Src = src->Peek_Vertex_Material(i);
- VertexMaterialRemaps[i].Dest = dest->Peek_Vertex_Material(i);
- }
- }
- if (src->Texture_Count() > 0) {
- TextureCount = src->Texture_Count();
- TextureRemaps = W3DNEWARRAY TextureRemapStruct[TextureCount];
- for (int i=0; i<src->Texture_Count(); i++) {
- TextureRemaps[i].Src = src->Peek_Texture(i);
- TextureRemaps[i].Dest = dest->Peek_Texture(i);
- }
- }
- }
- MaterialRemapperClass::~MaterialRemapperClass(void)
- {
- SrcMatInfo->Release_Ref();
- DestMatInfo->Release_Ref();
- if (TextureRemaps) {
- delete[] TextureRemaps;
- }
- if (VertexMaterialRemaps) {
- delete[] VertexMaterialRemaps;
- }
- }
- TextureClass * MaterialRemapperClass::Remap_Texture(TextureClass * src)
- {
- if (src == NULL) return src;
- if (src == LastSrcTex) return LastDestTex;
- for (int i=0; i<TextureCount; i++) {
- if (TextureRemaps[i].Src == src) {
- LastSrcTex = src;
- LastDestTex = TextureRemaps[i].Dest;
- return TextureRemaps[i].Dest;
- }
- }
- WWASSERT(0); // uh-oh didn't find the texture, what happend???
- return NULL;
- }
- VertexMaterialClass * MaterialRemapperClass::Remap_Vertex_Material(VertexMaterialClass * src)
- {
- if (src == NULL) return src;
- if (src == LastSrcVmat) return LastDestVmat;
- for (int i=0; i<VertexMaterialCount; i++) {
- if (VertexMaterialRemaps[i].Src == src) {
- LastSrcVmat = src;
- LastDestVmat = VertexMaterialRemaps[i].Dest;
- return VertexMaterialRemaps[i].Dest;
- }
- }
- WWASSERT(0); // uh-oh didn't find the material, what happend???
- return NULL;
- }
- void MaterialRemapperClass::Remap_Mesh(const MeshMatDescClass * srcmeshmatdesc, MeshMatDescClass * destmeshmatdesc)
- {
- /*
- ** Remap the vertex materials if there is at least one of them
- */
- if (SrcMatInfo->Vertex_Material_Count() >= 1) {
-
- for (int pass = 0;pass < srcmeshmatdesc->Get_Pass_Count(); pass++) {
- if (srcmeshmatdesc->Has_Material_Array(pass)) {
-
- for (int vert_index = 0; vert_index < srcmeshmatdesc->Get_Vertex_Count(); vert_index++) {
- VertexMaterialClass * src = srcmeshmatdesc->Peek_Material(vert_index, pass);
- destmeshmatdesc->Set_Material(vert_index, Remap_Vertex_Material(src),pass);
- }
- } else {
-
- VertexMaterialClass * src = srcmeshmatdesc->Peek_Single_Material(pass);
- destmeshmatdesc->Set_Single_Material(Remap_Vertex_Material(src), pass);
-
- }
- }
- }
-
- /*
- ** Remap the textures if there is at least one of them
- */
- if (SrcMatInfo->Texture_Count() >= 1) {
-
- for (int pass = 0;pass < srcmeshmatdesc->Get_Pass_Count(); pass++) {
- for (int stage = 0; stage < MeshMatDescClass::MAX_TEX_STAGES; stage++) {
-
- if (srcmeshmatdesc->Has_Texture_Array(pass, stage)) {
-
- for (int poly_index = 0; poly_index < srcmeshmatdesc->Get_Polygon_Count(); poly_index++) {
- TextureClass * src = srcmeshmatdesc->Peek_Texture(poly_index, pass, stage);
- destmeshmatdesc->Set_Texture(poly_index, Remap_Texture(src), pass, stage);
- }
- } else {
-
- TextureClass * src = srcmeshmatdesc->Peek_Single_Texture(pass, stage);
- destmeshmatdesc->Set_Single_Texture(Remap_Texture(src), pass, stage);
- }
- }
- }
- }
- }
- MaterialCollectorClass::MaterialCollectorClass(void)
- {
- LastShader = ShaderClass(0xFFFFFFFF);
- LastMaterial = NULL;
- LastTexture = NULL;
- }
- MaterialCollectorClass::~MaterialCollectorClass(void)
- {
- Reset();
- }
- void MaterialCollectorClass::Collect_Materials(MeshModelClass * mesh)
- {
- for (int pass = 0;pass < mesh->Get_Pass_Count(); pass++) {
- // Vertex materials (either single or per vertex)
- if (mesh->Has_Material_Array(pass)) {
-
- for (int vert_index = 0;vert_index < mesh->Get_Vertex_Count(); vert_index++) {
- VertexMaterialClass * mat = mesh->Peek_Material(vert_index,pass);
- Add_Vertex_Material(mat);
- }
- } else {
- VertexMaterialClass * mat = mesh->Get_Single_Material(pass);
- Add_Vertex_Material(mat);
- REF_PTR_RELEASE(mat);
- }
-
- // Shaders (single or per poly...)
- if (mesh->Has_Shader_Array(pass)) {
- for (int poly_index=0; poly_index < mesh->Get_Polygon_Count(); poly_index++) {
- Add_Shader(mesh->Get_Shader(poly_index,pass));
- }
- } else {
- ShaderClass sh = mesh->Get_Single_Shader(pass);
- Add_Shader(sh);
- }
-
-
- // Textures per pass, per stage (either array or single...)
- for (int stage = 0; stage < MeshMatDescClass::MAX_TEX_STAGES; stage++) {
- if (mesh->Has_Texture_Array(pass,stage)) {
-
- for (int poly_index = 0;poly_index < mesh->Get_Polygon_Count(); poly_index++) {
- TextureClass * tex = mesh->Peek_Texture(poly_index,pass,stage);
- Add_Texture(tex);
- }
- } else {
-
- TextureClass * tex = mesh->Peek_Single_Texture(pass,stage);
- Add_Texture(tex);
- }
- }
- }
- }
- void MaterialCollectorClass::Reset(void)
- {
- for (int ti=0; ti<Textures.Count(); ti++) {
- REF_PTR_RELEASE(Textures[ti]);
- }
- for (int vi=0; vi<VertexMaterials.Count(); vi++) {
- REF_PTR_RELEASE(VertexMaterials[vi]);
- }
- Textures.Clear();
- VertexMaterials.Clear();
- Shaders.Clear();
- }
- void MaterialCollectorClass::Add_Texture(TextureClass * tex)
- {
- if (tex == NULL) return;
- if (tex == LastTexture) return;
- if (Find_Texture(tex) != -1) return;
- Textures.Add(tex);
- tex->Add_Ref();
- LastTexture = tex;
- }
- void MaterialCollectorClass::Add_Shader(ShaderClass shader)
- {
- if (shader == LastShader) return;
- if (Find_Shader(shader) != -1) return;
- Shaders.Add(shader);
- LastShader = shader;
- }
- void MaterialCollectorClass::Add_Vertex_Material(VertexMaterialClass * vmat)
- {
- if (vmat == NULL) return;
- if (vmat == LastMaterial) return;
- if (Find_Vertex_Material(vmat) != -1) return;
- VertexMaterials.Add(vmat);
- vmat->Add_Ref();
- LastMaterial = vmat;
- }
- int MaterialCollectorClass::Get_Shader_Count(void)
- {
- return Shaders.Count();
- }
- int MaterialCollectorClass::Get_Vertex_Material_Count(void)
- {
- return VertexMaterials.Count();
- }
- int MaterialCollectorClass::Get_Texture_Count(void)
- {
- return Textures.Count();
- }
-
- ShaderClass MaterialCollectorClass::Peek_Shader(int i)
- {
- return Shaders[i];
- }
- TextureClass * MaterialCollectorClass::Peek_Texture(int i)
- {
- return Textures[i];
- }
- VertexMaterialClass * MaterialCollectorClass::Peek_Vertex_Material(int i)
- {
- return VertexMaterials[i];
- }
- int MaterialCollectorClass::Find_Shader(const ShaderClass & shader)
- {
- for (int si=0; si<Shaders.Count(); si++) {
- if (Shaders[si] == shader) {
- return si;
- }
- }
- return -1;
- }
- int MaterialCollectorClass::Find_Texture(TextureClass * tex)
- {
- for (int ti=0; ti<Textures.Count(); ti++) {
- if (Textures[ti] == tex) {
- return ti;
- }
- }
- return -1;
- }
- int MaterialCollectorClass::Find_Vertex_Material(VertexMaterialClass * mat)
- {
- for (int vi=0; vi<VertexMaterials.Count(); vi++) {
- if (VertexMaterials[vi] == mat) {
- return vi;
- }
- }
- return -1;
- }
|