This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/ww3d2/matinfo.h

334 lines
11 KiB
C++

/*
** 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 <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 : WW3D *
* *
* $Archive:: /VSS_Sync/ww3d2/matinfo.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 8/29/01 7:29p $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef MATINFO_H
#define MATINFO_H
#include "always.h"
#include "wwdebug.h"
#include "vector.h"
#include "vertmaterial.h"
#include "texture.h"
#include "shader.h"
#ifdef _UNIX
#include "osdep.h"
#endif
class MeshModelClass;
class MeshMatDescClass;
/***********************************************************************************************
** MaterialInfoClass
**
** This class gives an interface to the "changeable" material parameters inside a
** W3D render object. Typically, this will include things like the following:
** - one or more textures,
** - the vertex material used by the mesh (defines lighting properties, etc)
**
** Another purpose of this class is to actually hold onto a ref for each material
** object that a mesh uses. The "per-triangle" pointer arrays are not ref counted
** so the material info serves as a place to hold a reference to each material object
** that the mesh is using.
**
***********************************************************************************************/
class MaterialInfoClass : public RefCountClass
{
public:
MaterialInfoClass();
MaterialInfoClass(const MaterialInfoClass & src);
~MaterialInfoClass();
MaterialInfoClass * Clone(void) const;
void Reset(void) { Free(); }
int Vertex_Material_Count(void) const { return VertexMaterials.Count(); }
int Texture_Count(void) const { return Textures.Count(); }
int Add_Vertex_Material(VertexMaterialClass * vmat);
int Add_Texture(TextureClass * tex);
int Get_Vertex_Material_Index(const char * name);
int Get_Texture_Index(const char * name);
VertexMaterialClass * Get_Vertex_Material(int index);
VertexMaterialClass * Get_Vertex_Material(const char * name);
VertexMaterialClass * Peek_Vertex_Material(int index);
VertexMaterialClass * Peek_Vertex_Material(const char * name);
void Replace_Material(int index, VertexMaterialClass *newMaterial);
void Reset_Texture_Mappers(void);
void Make_Vertex_Materials_Unique(void);
bool Has_Time_Variant_Texture_Mappers(void);
TextureClass * Get_Texture(int index);
TextureClass * Get_Texture(const char * name);
TextureClass * Peek_Texture(int index);
TextureClass * Peek_Texture(const char * name);
void Replace_Texture(int index, TextureClass *newTexture);
// void Set_Texture_Reduction_Factor(float trf);
// void Process_Texture_Reduction(void);
private:
void Free(void);
DynamicVectorClass<VertexMaterialClass *> VertexMaterials;
DynamicVectorClass<TextureClass *> Textures;
};
/***********************************************************************************************
** MaterialRemapperClass
** This class is used when we need to "remap" all of the material pointers in a mesh
** to a new set of cloned materials. Basically, it assumes that you are going to initialize
** it with two identical material info objects (src and dest) and then you can give it pointers
** to materials in the "src" material info and it will give you back pointers to materials
** in the "dest" material info class.
**
** This class attempts to take advantage of the fact that meshes should normally be sorted
** with respect to their materials so we shouldn't really be doing a linear search for
** each remap...
**
** Please Note: this class does not hold references to the materials and is meant only to
** be used in a temporary fashion. Create it, do your conversion, then delete it :-)
***********************************************************************************************/
class MaterialRemapperClass
{
public:
MaterialRemapperClass(MaterialInfoClass * src,MaterialInfoClass * dest);
~MaterialRemapperClass(void);
TextureClass * Remap_Texture(TextureClass * src);
VertexMaterialClass * Remap_Vertex_Material(VertexMaterialClass * src);
void Remap_Mesh(const MeshMatDescClass * srcmeshmatdesc, MeshMatDescClass * destmeshmatdesc);
private:
struct VmatRemapStruct
{
VertexMaterialClass * Src;
VertexMaterialClass * Dest;
};
struct TextureRemapStruct
{
TextureClass * Src;
TextureClass * Dest;
};
MaterialInfoClass * SrcMatInfo;
MaterialInfoClass * DestMatInfo;
int TextureCount;
TextureRemapStruct * TextureRemaps;
int VertexMaterialCount;
VmatRemapStruct * VertexMaterialRemaps;
VertexMaterialClass * LastSrcVmat;
VertexMaterialClass * LastDestVmat;
TextureClass * LastSrcTex;
TextureClass * LastDestTex;
};
/***********************************************************************************************
** MaterialCollectorClass
**
** This class can be used to collect all of the unique instances of materials from a mesh.
** Its original motivation is to solve a problem encountered in trying to save a mesh
** to disk. There are arrays of pointers to vertex materials in the mesh but no record of
** the set of unique vertex materials (all pointers could point to the same one...) Similar
** to the remapper, it tries to take advantage of the fact that the materials and textures
** should be in sorted order to optimize the lookups...
**
** NOTE: pointer comparisons are used to determine if the objects are unique. I don't
** check whether the contents of the objects are identical. (Exporter does this, I assume
** that if there are two separate objects, they are that way for a reason here.)
***********************************************************************************************/
class MaterialCollectorClass
{
public:
MaterialCollectorClass(void);
~MaterialCollectorClass(void);
void Reset(void);
void Collect_Materials(MeshModelClass * mesh);
void Add_Texture(TextureClass * tex);
void Add_Shader(ShaderClass shader);
void Add_Vertex_Material(VertexMaterialClass * vmat);
int Get_Shader_Count(void);
int Get_Vertex_Material_Count(void);
int Get_Texture_Count(void);
ShaderClass Peek_Shader(int i);
TextureClass * Peek_Texture(int i);
VertexMaterialClass * Peek_Vertex_Material(int i);
int Find_Shader(const ShaderClass & shader);
int Find_Texture(TextureClass * tex);
int Find_Vertex_Material(VertexMaterialClass * mat);
protected:
DynamicVectorClass<ShaderClass> Shaders;
DynamicVectorClass<VertexMaterialClass *> VertexMaterials;
DynamicVectorClass<TextureClass *> Textures;
ShaderClass LastShader;
VertexMaterialClass * LastMaterial;
TextureClass * LastTexture;
};
inline int MaterialInfoClass::Add_Vertex_Material(VertexMaterialClass * vmat)
{
if (vmat != NULL) {
vmat->Add_Ref();
}
int index = VertexMaterials.Count();
VertexMaterials.Add(vmat);
return index;
}
inline int MaterialInfoClass::Get_Vertex_Material_Index(const char * name)
{
for (int i=0; i<VertexMaterials.Count(); i++) {
if (stricmp(name,VertexMaterials[i]->Get_Name()) == 0) {
return i;
}
}
return -1;
}
inline VertexMaterialClass * MaterialInfoClass::Get_Vertex_Material(int index)
{
WWASSERT(index >= 0);
WWASSERT(index < VertexMaterials.Count());
if (VertexMaterials[index]) {
VertexMaterials[index]->Add_Ref();
}
return VertexMaterials[index];
}
inline VertexMaterialClass * MaterialInfoClass::Get_Vertex_Material(const char * name)
{
int index = Get_Vertex_Material_Index(name);
if (index == -1) {
return NULL;
} else {
return Get_Vertex_Material(index);
}
}
inline VertexMaterialClass * MaterialInfoClass::Peek_Vertex_Material(int index)
{
WWASSERT(index >= 0);
WWASSERT(index < VertexMaterials.Count());
return VertexMaterials[index];
}
inline VertexMaterialClass * MaterialInfoClass::Peek_Vertex_Material(const char * name)
{
int index = Get_Vertex_Material_Index(name);
if (index == -1) {
return NULL;
} else {
return Peek_Vertex_Material(index);
}
}
inline void MaterialInfoClass::Replace_Material(int index, VertexMaterialClass *newMaterial)
{
REF_PTR_SET(VertexMaterials[index],newMaterial);
}
inline void MaterialInfoClass::Reset_Texture_Mappers(void)
{
int vmat_count = VertexMaterials.Count();
for (int i = 0; i < vmat_count; i++) {
VertexMaterials[i]->Reset_Mappers();
}
}
inline bool MaterialInfoClass::Has_Time_Variant_Texture_Mappers(void)
{
int vmat_count = VertexMaterials.Count();
for (int i = 0; i < vmat_count; i++) {
if (VertexMaterials[i]->Are_Mappers_Time_Variant()) return true;
}
return false;
}
inline void MaterialInfoClass::Make_Vertex_Materials_Unique(void)
{
int vmat_count = VertexMaterials.Count();
for (int i = 0; i < vmat_count; i++) {
VertexMaterials[i]->Make_Unique();
}
}
inline TextureClass * MaterialInfoClass::Get_Texture(const char * name)
{
int index = Get_Texture_Index(name);
if (index == -1) {
return NULL;
} else {
return Get_Texture(index);
}
}
inline TextureClass * MaterialInfoClass::Peek_Texture(int index)
{
WWASSERT(index >= 0);
WWASSERT(index < Textures.Count());
return Textures[index];
}
inline void MaterialInfoClass::Replace_Texture(int index, TextureClass *newTexture)
{
REF_PTR_SET(Textures[index],newTexture);
}
#endif // MATINFO_H