Files
FC1/CryCommon/IShader.h
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

2399 lines
58 KiB
C++

/*=============================================================================
IShader.h : Shaders common interface.
Copyright (c) 2001-2002 Crytek Studios. All Rights Reserved.
Revision history:
* Created by Honich Andrey
=============================================================================*/
#ifndef _ISHADER_H_
#define _ISHADER_H_
#include "TString.h"
#include "TArrays.h"
#include "smartptr.h"
#include "Cry_XOptimise.h"
#ifdef LINUX
# include <platform.h>
#endif
struct IShader;
struct SShader;
class CMaterial;
struct SShaderTexUnit;
struct STexAnim;
struct SShaderPass;
struct CLeafBuffer;
struct SShaderItem;
struct STexPic;
struct SParam;
struct ICryCharInstance;
struct IDeformableRenderMesh;
class CPShader;
template <class T> class list2;
union UCol
{
DWORD dcolor;
bvec4 bcolor;
};
//================================================================
// HW Culling type
enum ECull
{
eCULL_Back = 0,
eCULL_Front,
eCULL_None
};
//=========================================================================
// Array Pointers for HW Shaders
enum ESrcPointer
{
eSrcPointer_Unknown,
eSrcPointer_Vert,
eSrcPointer_Color,
eSrcPointer_SecColor,
eSrcPointer_Tex,
eSrcPointer_TexLM,
eSrcPointer_Normal,
eSrcPointer_Binormal,
eSrcPointer_Tangent,
eSrcPointer_TNormal,
eSrcPointer_LightVector,
eSrcPointer_LightVector_Terrain,
eSrcPointer_NormLightVector,
eSrcPointer_HalfAngleVector,
eSrcPointer_HalfAngleVector_Terrain,
eSrcPointer_Attenuation,
eSrcPointer_LAttenuationSpec0,
eSrcPointer_LAttenuationSpec1,
eSrcPointer_LAttenuationSpec0_Terrain,
eSrcPointer_LAttenuationSpec1_Terrain,
eSrcPointer_Refract,
eSrcPointer_Project,
eSrcPointer_ProjectTexture,
eSrcPointer_ProjectAttenFromCamera,
eSrcPointer_Detail,
eSrcPointer_Max,
};
enum EDstPointer
{
eDstPointer_Unknown,
eDstPointer_Vert,
eDstPointer_Normal,
eDstPointer_Color,
eDstPointer_SecColor,
eDstPointer_FogC,
eDstPointer_Tex0,
eDstPointer_Tex1,
eDstPointer_Tex2,
eDstPointer_Tex3,
eDstPointer_Tex4,
eDstPointer_Tex5,
eDstPointer_Tex6,
eDstPointer_Tex7,
eDstPointer_Max,
};
class COrthoNormalBasis
{
public:
COrthoNormalBasis()
{
m_vForward = Vec3(1,0,0);
m_vUp = Vec3(0,0,1);
m_vRight = Vec3(0,1,0);
}
COrthoNormalBasis(const COrthoNormalBasis& basis)
{
m_vForward = basis.m_vForward;
m_vUp = basis.m_vUp;
m_vRight = basis.m_vRight;
}
COrthoNormalBasis(const Vec3& vForward, const Vec3& vUp, const Vec3& vRight)
{
m_vForward = vForward;
m_vUp = vUp;
m_vRight = vRight;
}
~COrthoNormalBasis()
{
}
COrthoNormalBasis& operator=(const COrthoNormalBasis& basis)
{
m_vForward = basis.m_vForward;
m_vUp = basis.m_vUp;
m_vRight = basis.m_vRight;
return *this;
};
Matrix44 matrixBasisToXYZ() const
{
Matrix44 mat;
mat.SetIdentity();
mat(0,0) = m_vForward.x; mat(0,1) = m_vForward.y; mat(0,2) = m_vForward.z;
mat(1,0) = m_vUp.x; mat(1,1) = m_vUp.y; mat(1,2) = m_vUp.z;
mat(2,0) = m_vRight.x; mat(2,1) = m_vRight.y; mat(2,2) = m_vRight.z;
return mat;
}
Matrix44 matrixXYZToBasis() const
{
Matrix44 mat;
mat.SetIdentity();
mat(0,0) = m_vForward.x; mat(0,1) = m_vUp.x; mat(0,2) = m_vRight.x;
mat(1,0) = m_vForward.y; mat(1,1) = m_vUp.y; mat(1,2) = m_vRight.y;
mat(2,0) = m_vForward.z; mat(2,1) = m_vUp.z; mat(2,2) = m_vRight.z;
return mat;
}
Matrix44 matrixBasisToDestBasis(const COrthoNormalBasis& dest) const
{
return (dest.matrixXYZToBasis() * this->matrixBasisToXYZ());
}
COrthoNormalBasis& rotate(const Vec3& axis, const float degrees)
{
//Vec3 a = axis;
//a.Normalize();
Matrix33 m;
//m = m.GetRotation(a, degrees);
m.SetRotationAA(DEG2RAD(degrees),GetNormalized(axis));
m_vForward = m * m_vForward;
m_vRight = m * m_vRight;
m_vUp = m * m_vUp;
return *this;
};
Vec3 m_vForward; //tangent
Vec3 m_vUp; //binormal
Vec3 m_vRight; //normal
};
//////////////////////////////////////////////////////////////////////
// CCObject::m_ObjFlags: Flags used by shader pipeline
#define FOB_SORTPOLYS 1
#define FOB_SELECTED 2
#define FOB_NEAREST 4
#define FOB_PORTAL 8
#define FOB_CUBE_POSX 0x10
#define FOB_CUBE_NEGX 0x20
#define FOB_CUBE_POSY 0x40
#define FOB_CUBE_NEGY 0x80
#define FOB_CUBE_POSZ 0x100
#define FOB_CUBE_NEGZ 0x200
#define FOB_TEXTURE 0x400
#define FOB_CUBE_MASK 0x7f0
#define FOB_CUBE_SHIFT 4
#define FOB_IGNOREMATERIALAMBIENT 0x800
#define FOB_DRSUN 0x1000
#define FOB_REFRACTED 0x2000
#define FOB_ZPASS 0x4000
#define FOB_LIGHTPASS 0x8000
#define FOB_FOGPASS 0x10000
#define FOB_RENDER_INTO_SHADOWMAP 0x20000
#define FOB_SPECULAR 0x40000
#define FOB_IGNOREREPOINTER 0x80000
#define FOB_ENVLIGHTING 0x100000
#define FOB_BENDED 0x200000
#define FOB_NOBUMP 0x400000
#define FOB_HASALPHA 0x800000
#define FOB_HOTAMBIENT 0x1000000
#define FOB_MASKCONDITIONS (FOB_BENDED | FOB_HASALPHA | FOB_SPECULAR | FOB_NOBUMP | FOB_INSHADOW | FOB_HEATVISION | FOB_HOTAMBIENT | FOB_ENVLIGHTING)
#define FOB_REMOVED 0x2000000
#define FOB_HEATVISION 0x4000000
#define FOB_INSHADOW 0x8000000
#define FOB_TRANS_ROTATE 0x10000000
#define FOB_TRANS_SCALE 0x20000000
#define FOB_TRANS_TRANSLATE 0x40000000
#define FOB_TRANS_MASK (FOB_TRANS_ROTATE | FOB_TRANS_SCALE | FOB_TRANS_TRANSLATE)
#define FOB_NOSCISSOR 0x80000000
struct SWaveForm;
struct SWaveForm2;
typedef TAllocator16<Matrix44> MatrixAllocator16;
typedef TGrowArray<Matrix44, MatrixAllocator16> MatrixArray16;
//=========================================================================
enum EParamType
{
eType_UNKNOWN,
eType_BYTE,
eType_BOOL,
eType_SHORT,
eType_INT,
eType_FLOAT,
eType_STRING,
eType_FCOLOR,
eType_VECTOR
};
union UParamVal
{
byte m_Byte;
bool m_Bool;
short m_Short;
int m_Int;
float m_Float;
char *m_String;
float m_Color[4];
float m_Vector[3];
};
struct SShaderParam
{
// in order to facilitate the memory allocation tracking, we're using here this class;
// if you don't like it, please write a substitute for all string within the project and use them everywhere
char m_Name[32];
EParamType m_Type;
UParamVal m_Value;
int m_nMaterial;
SShaderParam()
{
m_nMaterial = -1;
m_Value.m_Int = 0;
}
size_t Size()
{
size_t nSize = sizeof(*this);
nSize += sizeof(m_Name);
if (m_Type == eType_STRING)
nSize += strlen (m_Value.m_String) + 1;
return nSize;
}
~SShaderParam()
{
if (m_Type == eType_STRING)
delete [] m_Value.m_String;
}
static bool SetParam(const char *name, TArray<SShaderParam> *Params, UParamVal& pr, int nMaterial)
{
int i;
for (i=0; i<Params->Num(); i++)
{
SShaderParam *sp = &Params->Get(i);
if (!sp)
continue;
const char *nm = sp->m_Name;
int n = 0;
char ch = 0;
int ind = -1;
while (true)
{
ch = name[n];
if (!ch)
break;
if (ch == '[')
{
char dig[16];
int m = 0;
n++;
while(true)
{
ch = name[n];
if (!ch)
break;
if (ch == ']')
break;
dig[m++] = ch;
dig[m] = 0;
n++;
}
if (!ch)
break;
ind = atoi(dig);
ch = 0;
break;
}
if (ch != nm[n])
break;
n++;
}
if (!ch)
{
sp->m_nMaterial = nMaterial;
switch (sp->m_Type)
{
case eType_INT:
case eType_FLOAT:
case eType_SHORT:
sp->m_Value.m_Int = pr.m_Int;
break;
case eType_VECTOR:
if (ind >= 0)
sp->m_Value.m_Vector[ind] = pr.m_Vector[ind];
else
{
sp->m_Value.m_Vector[0] = pr.m_Vector[0];
sp->m_Value.m_Vector[1] = pr.m_Vector[1];
sp->m_Value.m_Vector[2] = pr.m_Vector[2];
}
break;
case eType_FCOLOR:
if (ind >= 0)
sp->m_Value.m_Color[ind] = pr.m_Color[ind];
else
{
sp->m_Value.m_Color[0] = pr.m_Color[0];
sp->m_Value.m_Color[1] = pr.m_Color[1];
sp->m_Value.m_Color[2] = pr.m_Color[2];
sp->m_Value.m_Color[3] = pr.m_Color[3];
}
break;
case eType_STRING:
{
char *str = pr.m_String;
size_t len = strlen(str)+1;
sp->m_Value.m_String = new char [len];
strcpy(sp->m_Value.m_String, str);
}
break;
}
break;
}
}
if (i == Params->Num())
return false;
return true;
}
static float GetFloat(const char *name, TArray<SShaderParam> *Params, int nMaterial)
{
int i;
for (i=0; i<Params->Num(); i++)
{
SShaderParam *sp = &Params->Get(i);
if (!sp)
continue;
if (sp->m_nMaterial != nMaterial)
continue;
const char *nm = sp->m_Name;
int n = 0;
char ch = 0;
int ind = -1;
while (true)
{
ch = name[n];
if (!ch)
break;
if (ch == '[')
{
char dig[16];
int m = 0;
n++;
while(true)
{
ch = name[n];
if (!ch)
break;
if (ch == ']')
break;
dig[m++] = ch;
dig[m] = 0;
n++;
}
if (!ch)
break;
ind = atoi(dig);
ch = 0;
break;
}
if (tolower(ch) != nm[n])
break;
n++;
}
if (!ch)
{
switch (sp->m_Type)
{
case eType_INT:
case eType_FLOAT:
case eType_SHORT:
return sp->m_Value.m_Float;
break;
case eType_VECTOR:
if (ind >= 0)
return sp->m_Value.m_Vector[ind];
else
return -9999;
break;
case eType_FCOLOR:
if (ind >= 0)
return sp->m_Value.m_Color[ind];
else
return -9999;
break;
case eType_STRING:
{
return -9999;
}
break;
}
}
}
return -9999;
}
};
//////////////////////////////////////////////////////////////////////
// Objects using in shader pipeline
// Size of CCObject currently is 256 bytes. If you add new members better to ask me before or just
// make sure CCObject is cache line aligned (64 bytes)
class CCObject
{
public:
CCObject()
{
m_ShaderParams = NULL;
m_bShaderParamCreatedInRenderer = false;
m_VPMatrixId = -1;
m_VPMatrixFrame = -1;
}
~CCObject();
short m_Id;
short m_Counter;
short m_VisId;
short m_VPMatrixId;
uint m_ObjFlags;
Matrix44 m_Matrix;
bool m_bShaderParamCreatedInRenderer;
TArray<SShaderParam> *m_ShaderParams;
// Lightmap textures ID's
short m_nLMId;
short m_nLMDirId;
short m_nOcclId;
short m_nHDRLMId;
uint m_Reserved1;
uint m_DynLMMask;
float m_Trans2[3];
float m_Angs2[3];
// Different useful vars (ObjVal component in shaders)
// [0] - used for blending trees sun-rabbits on distance (0-1)
float m_TempVars[5];
float m_fDistanceToCam;
CRendElement *m_RE;
IShader *m_EF;
void *m_CustomData;
uint m_RenderState;
float m_SortId; // Custom sort value
short m_InvMatrixId;
short m_VPMatrixFrame;
short m_NumCM; // Custom Cube/Texture id (indoor engine soft shadows)
union
{
short m_nLod;
short m_NumWFX;
short m_TexId0;
};
union
{
short m_nTemplId;
short m_NumWFY;
short m_TexId1;
};
union
{
short m_FrameLight;
bool m_bVisible;
};
short m_LightStyle;
short m_nScissorX1, m_nScissorY1, m_nScissorX2, m_nScissorY2;
union
{
float m_fRefract;
float m_StartTime;
};
union
{
float m_fBump;
float m_fLightFadeTime;
};
float m_fHeatFactor;
list2<struct ShadowMapLightSourceInstance> * m_pShadowCasters; // list of shadow casters
struct ShadowMapFrustum * m_pShadowFrustum; // will define projection of shadow from this object
Vec3d m_AmbColor;
CFColor m_Color;
IDeformableRenderMesh * m_pCharInstance;
struct CLeafBuffer *m_pLMTCBufferO;
union
{
ITexPic *m_pLightImage;
CDLight *m_pLight;
float m_fBending;
float m_fLastUpdate;
byte m_OcclLights[4];
};
_inline Vec3 GetTranslation() const
{
return m_Matrix.GetTranslationOLD();
}
_inline float GetScaleX() const
{
return cry_sqrtf(m_Matrix(0,0)*m_Matrix(0,0) + m_Matrix(0,1)*m_Matrix(0,1) + m_Matrix(0,2)*m_Matrix(0,2));
}
_inline float GetScaleZ() const
{
return cry_sqrtf(m_Matrix(2,0)*m_Matrix(2,0) + m_Matrix(2,1)*m_Matrix(2,1) + m_Matrix(2,2)*m_Matrix(2,2));
}
_inline bool IsMergable()
{
if (m_Color.a != 1.0f)
return false;
if (m_pShadowCasters)
return false;
if (m_pCharInstance)
return false;
return true;
}
static TArray<SWaveForm2> m_Waves;
static MatrixArray16 m_ObjMatrices;
void Init();
void CloneObject(CCObject *srcObj)
{
int Id = m_Id;
int VisId = m_VisId;
memcpy(this, srcObj, sizeof(*srcObj));
m_Id = Id;
m_VisId = VisId;
}
Matrix44 &GetMatrix()
{
return m_Matrix;
}
Matrix44 &GetInvMatrix();
Matrix44 &GetVPMatrix();
void SetScissor();
void SetAlphaState(CPShader *pPS, int nCurState);
virtual void AddWaves(SWaveForm2 **wf);
virtual void SetShaderFloat(const char *Name, float Val);
virtual void RemovePermanent();
#ifdef _RENDERER
#ifdef DEBUGALLOC
#undef new
#endif
// Sergiy: it's enough to allocate 16 bytes more, even on 64-bit machine
// - and we need to store only the offset, not the actual pointer
void* operator new( size_t Size )
{
byte *ptr = (byte *)malloc(Size+16+4);
memset(ptr, 0, Size+16+4);
byte *bPtrRes = (byte *)((INT_PTR)(ptr+4+16) & ~0xf);
((byte**)bPtrRes)[-1] = ptr;
return bPtrRes;
}
void* operator new[](size_t Size)
{
byte *ptr = (byte *)malloc(Size+16+2*sizeof(INT_PTR));
memset(ptr, 0, Size+16+2*sizeof(INT_PTR));
byte *bPtrRes = (byte *)((INT_PTR)(ptr+16+2*sizeof(INT_PTR)) & ~0xf);
((byte**)bPtrRes)[-2] = ptr;
return bPtrRes-sizeof(INT_PTR);
}
void operator delete( void *Ptr )
{
byte *bActualPtr = ((byte **)Ptr)[-1];
assert (bActualPtr <= (byte*)Ptr && (byte*)Ptr-bActualPtr < 20);
free ((void *)bActualPtr);
}
void operator delete[]( void *Ptr )
{
byte *bActualPtr = ((byte **)Ptr)[-1];
free ((void *)bActualPtr);
}
#ifdef DEBUGALLOC
#define new DEBUG_CLIENTBLOCK
#endif
#endif // _RENDERER
};
//=================================================================================
// Materials
#define LMF_IGNORELIGHTS 1
#define LMF_BUMPMATERIAL 2
#define LMF_NOAMBIENT 4
#define LMF_COLMAT_AMB 8
#define LMF_POLYOFFSET 0x10
#define LMF_NOALPHA 0x20
#define LMF_IGNOREPROJLIGHTS 0x40
#define LMF_NOBUMP 0x80
#define LMF_DISABLE 0x100
#define LMF_NOSPECULAR 0x200
#define LMF_NOADDSPECULAR 0x400
#define LMF_HASPSHADER 0x800
#define LMF_DIVIDEAMB4 0x1000
#define LMF_DIVIDEAMB2 0x2000
#define LMF_DIVIDEDIFF4 0x4000
#define LMF_DIVIDEDIFF2 0x8000
#define LMF_LIGHT0 0x10000
#define LMF_LIGHT1 0x20000
#define LMF_LIGHT2 0x30000
#define LMF_LIGHT3 0x40000
#define LMF_LIGHT4 0x50000
#define LMF_LIGHT5 0x60000
#define LMF_LIGHT6 0x70000
#define LMF_LIGHT7 0x80000
#define LMF_LIGHT_MASK 0xf0000
#define LMF_1SAMPLES 0x100000
#define LMF_2SAMPLES 0x200000
#define LMF_3SAMPLES 0x400000
#define LMF_4SAMPLES 0x800000
#define LMF_SAMPLES 0xf00000
#define LMF_LIGHT_SHIFT 16
#define LMF_ONLYMATERIALAMBIENT 0x1000000
#define LMF_USEOCCLUSIONMAP 0x2000000
#define LMF_HASAMBIENT 0x4000000
#define LMF_HASDOT3LM 0x8000000
struct SSideMaterial
{
SSideMaterial::SSideMaterial()
: m_Ambient(1.0f, 1.0f, 1.0f, 1.0f),
m_Diffuse(1.0f, 1.0f, 1.0f, 1.0f),
m_Specular(1.0f, 1.0f, 1.0, 1.0f),
m_Emission(0.0f, 0.0f, 0.0f, 1.0f),
m_SpecShininess(10.0f) {}
CFColor m_Ambient;
CFColor m_Diffuse;
CFColor m_Specular;
CFColor m_Emission;
float m_SpecShininess;
_inline friend bool operator ==(const SSideMaterial &m1, const SSideMaterial &m2)
{
if (m1.m_Ambient == m2.m_Ambient && m1.m_Diffuse == m2.m_Diffuse && m1.m_Specular == m2.m_Specular && m1.m_Emission == m2.m_Emission && m1.m_SpecShininess == m2.m_SpecShininess)
return true;
return false;
}
};
struct SLightMaterial
{
SLightMaterial()
{
name[0] = 0;
bNeverReplace = false;
m_nRefCounter = 0;
}
int Id;
char name[64];
enum Side {FRONT, BACK, BOTH} side;
int m_nRefCounter;
SSideMaterial Front;
SSideMaterial Back;
bool bNeverReplace;
int Size()
{
int nSize = sizeof(SLightMaterial);
return nSize;
}
void mfApply(int Flags);
void Release();
static SLightMaterial* mfAdd(char *name, SLightMaterial *Compare=NULL);
static SLightMaterial* mfGet(char *name);
static SLightMaterial* current_material;
static int m_ObjFrame;
static TArray<SLightMaterial *> known_materials;
};
//=========================================================================================
// Wave form evaluators
enum EWaveForm
{
eWF_None,
eWF_Sin,
eWF_HalfSin,
eWF_InvHalfSin,
eWF_Square,
eWF_Triangle,
eWF_SawTooth,
eWF_InvSawTooth,
eWF_Hill,
eWF_InvHill,
};
#define WFF_CLAMP 1
#define WFF_LERP 2
// Wave form definition
struct SWaveForm
{
EWaveForm m_eWFType;
byte m_Flags;
float m_Level;
float m_Level1;
float m_Amp;
float m_Amp1;
float m_Phase;
float m_Phase1;
float m_Freq;
float m_Freq1;
int Size()
{
int nSize = sizeof(SWaveForm);
return nSize;
}
SWaveForm()
{
memset(this, 0, sizeof(SWaveForm));
}
bool operator == (SWaveForm wf)
{
if (m_eWFType == wf.m_eWFType && m_Level == wf.m_Level && m_Amp == wf.m_Amp && m_Phase == wf.m_Phase && m_Freq == wf.m_Freq && m_Level1 == wf.m_Level1 && m_Amp1 == wf.m_Amp1 && m_Phase1 == wf.m_Phase1 && m_Freq1 == wf.m_Freq1 && m_Flags == wf.m_Flags)
return true;
return false;
}
SWaveForm& operator += (const SWaveForm& wf )
{
m_Level += wf.m_Level;
m_Level1 += wf.m_Level1;
m_Amp += wf.m_Amp;
m_Amp1 += wf.m_Amp1;
m_Phase += wf.m_Phase;
m_Phase1 += wf.m_Phase1;
m_Freq += wf.m_Freq;
m_Freq1 += wf.m_Freq1;
return *this;
}
};
struct SWaveForm2
{
EWaveForm m_eWFType;
float m_Level;
float m_Amp;
float m_Phase;
float m_Freq;
SWaveForm2()
{
memset(this, 0, sizeof(SWaveForm2));
}
bool operator == (SWaveForm2 wf)
{
if (m_eWFType == wf.m_eWFType && m_Level == wf.m_Level && m_Amp == wf.m_Amp && m_Phase == wf.m_Phase && m_Freq == wf.m_Freq)
return true;
return false;
}
SWaveForm2& operator += (const SWaveForm2& wf )
{
m_Level += wf.m_Level;
m_Amp += wf.m_Amp;
m_Phase += wf.m_Phase;
m_Freq += wf.m_Freq;
return *this;
}
};
//======================================================
// Texture coords generating types
enum EGenTC
{
eGTC_NoFill = 0,
eGTC_None,
eGTC_LightMap,
eGTC_Quad,
eGTC_Base,
eGTC_Projection,
eGTC_Environment,
eGTC_SphereMap,
eGTC_SphereMapEnvironment,
eGTC_ShadowMap,
};
// Color operations
enum EColorOp
{
eCO_NOSET,
eCO_DISABLE,
eCO_REPLACE,
eCO_DECAL,
eCO_ARG2,
eCO_MODULATE,
eCO_MODULATE2X,
eCO_MODULATE4X,
eCO_BLENDDIFFUSEALPHA,
eCO_BLENDTEXTUREALPHA,
eCO_DETAIL,
eCO_ADD,
eCO_ADDSIGNED,
eCO_ADDSIGNED2X,
eCO_MULTIPLYADD,
eCO_BUMPENVMAP,
eCO_BLEND,
eCO_MODULATEALPHA_ADDCOLOR,
eCO_MODULATECOLOR_ADDALPHA,
eCO_MODULATEINVALPHA_ADDCOLOR,
eCO_MODULATEINVCOLOR_ADDALPHA,
eCO_DOTPRODUCT3,
eCO_LERP,
eCO_SUBTRACT,
};
enum EColorArg
{
eCA_Specular,
eCA_Texture,
eCA_Diffuse,
eCA_Previous,
eCA_Constant,
};
#define DEF_TEXARG0 (eCA_Texture|(eCA_Diffuse<<3))
#define DEF_TEXARG1 (eCA_Texture|(eCA_Previous<<3))
// Animating Texture sequence definition
struct STexAnim
{
TArray<STexPic *> m_TexPics;
int m_Rand;
int m_NumAnimTexs;
bool m_bLoop;
float m_Time;
int Size()
{
int nSize = sizeof(STexAnim);
nSize += m_TexPics.GetSize() * sizeof(STexPic *);
return nSize;
}
STexAnim()
{
m_Rand = 0;
m_NumAnimTexs = 0;
m_bLoop = false;
m_Time = 0.0f;
}
~STexAnim()
{
for (int i=0; i<m_TexPics.Num(); i++)
{
ITexPic *pTP = (ITexPic *)m_TexPics[i];
SAFE_RELEASE(pTP);
}
}
STexAnim& operator = (const STexAnim& sl)
{
for (int i=0; i<sl.m_TexPics.Num(); i++)
{
ITexPic *pTP = (ITexPic *)sl.m_TexPics[i];
if (pTP)
pTP->AddRef();
m_TexPics.AddElem(sl.m_TexPics[i]);
}
m_Rand = sl.m_Rand;
m_NumAnimTexs = sl.m_NumAnimTexs;
m_bLoop = sl.m_bLoop;
m_Time = sl.m_Time;
return *this;
}
};
struct SGenTC
{
int m_Mask;
bool m_bDependsOnObject;
virtual ~SGenTC()
{
}
SGenTC()
{
m_Mask = 0x3;
m_bDependsOnObject = false;
}
virtual SGenTC *mfCopy() = 0;
virtual bool mfSet(bool bEnable) = 0;
virtual void mfCompile(char *params, SShader *ef) = 0;
virtual int Size() = 0;
};
// Type of the texture
enum ETexType
{
eTT_Base,
eTT_Cubemap,
eTT_AutoCubemap,
eTT_Bumpmap,
eTT_DSDTBump,
eTT_Rectangle,
eTT_3D
};
#define FFILT_NONE 0
#define FFILT_POINT 1
#define FFILT_LINEAR 2
#define FFILT_ANISOTROPIC 3
#define FTU_OPAQUE 1
#define FTU_CLAMP 2
#define FTU_NOMIPS 4
#define FTU_NOBUMP 8
#define FTU_PROJECTED 0x10
#define FTU_FILTERBILINEAR 0x20
#define FTU_FILTERTRILINEAR 0x40
#define FTU_FILTERNEAREST 0x80
#define FTU_FILTERLINEAR 0x100
#define FTU_BUMPPLANTS 0x1000
#define FTU_NOSCALE 0x2000
// General texture layer
struct SShaderTexUnit
{
SShaderTexUnit()
{
memset(this, 0, sizeof(SShaderTexUnit));
}
void mfFree()
{
SAFE_DELETE(m_GTC);
if (m_AnimInfo)
{
SAFE_DELETE(m_AnimInfo);
}
else
if (m_ITexPic)
m_ITexPic->Release(false);
}
~SShaderTexUnit()
{
mfFree();
}
union
{
STexPic *m_TexPic;
ITexPic *m_ITexPic;
};
STexAnim *m_AnimInfo;
SGenTC *m_GTC;
byte m_eColorOp;
byte m_eAlphaOp;
byte m_eColorArg;
byte m_eAlphaArg;
byte m_eGenTC;
byte m_eTexType;
byte m_eHDRColorOp;
short m_nFlags;
float m_fTexFilterLodBias;
int Size()
{
int nSize = sizeof(SShaderTexUnit);
if (m_AnimInfo)
nSize += m_AnimInfo->Size();
if (m_GTC)
nSize += m_GTC->Size();
return nSize;
}
int GetTexFlags() const
{
int Flags = 0;
if (m_nFlags & FTU_NOMIPS)
Flags |= FT_NOMIPS;
if (m_nFlags & FTU_CLAMP)
Flags |= FT_CLAMP;
if (m_nFlags & FTU_NOSCALE)
Flags |= FT_NORESIZE;
return Flags;
}
int GetTexFlags2() const
{
int Flags = 0;
return Flags;
}
int mfSetTexture(int nt=-1);
void mfUpdate(void);
void mfUpdateAnim(CCObject *obj, int o);
void mfCopy (SShaderTexUnit *dtl) const
{
dtl->mfFree();
memcpy(dtl, this, sizeof(SShaderTexUnit));
if (m_AnimInfo)
{
dtl->m_AnimInfo = new STexAnim;
*dtl->m_AnimInfo = *m_AnimInfo;
}
if (m_GTC)
dtl->m_GTC = m_GTC->mfCopy();
if (m_ITexPic)
m_ITexPic->AddRef();
}
};
enum ETexModRotateType
{
ETMR_NoChange,
ETMR_Fixed,
ETMR_Constant,
ETMR_Oscillated,
};
enum ETexModMoveType
{
ETMM_NoChange,
ETMM_Fixed,
ETMM_Constant,
ETMM_Jitter,
ETMM_Pan,
ETMM_Stretch,
ETMM_StretchRepeat,
};
enum ETexGenType
{
ETG_Stream,
ETG_World,
ETG_Camera,
ETG_WorldEnvMap,
ETG_CameraEnvMap,
ETG_NormalMap,
ETG_SphereMap,
};
#define CASE_TEXMOD(var_name)\
if(!stricmp(#var_name,szParamName))\
{\
var_name = fValue;\
return true;\
}\
#define CASE_TEXMODANGLE(var_name)\
if(!stricmp(#var_name,szParamName))\
{\
var_name = Degr2Word(fValue);\
return true;\
}\
#define CASE_TEXMODBYTE(var_name)\
if(!stricmp(#var_name,szParamName))\
{\
var_name = (byte)fValue;\
return true;\
}\
#define CASE_TEXMODBOOL(var_name)\
if(!stricmp(#var_name,szParamName))\
{\
var_name = (fValue==1.f);\
return true;\
}\
struct SEfTexModificator
{
bool SetMember(const char * szParamName, float fValue)
{
CASE_TEXMODBYTE(m_eTGType);
CASE_TEXMODBYTE(m_eRotType);
CASE_TEXMODBYTE(m_eUMoveType);
CASE_TEXMODBYTE(m_eVMoveType);
CASE_TEXMODBOOL(m_bTexGenProjected);
CASE_TEXMOD(m_Tiling[0]);
CASE_TEXMOD(m_Tiling[1]);
CASE_TEXMOD(m_Tiling[2]);
CASE_TEXMOD(m_Offs[0]);
CASE_TEXMOD(m_Offs[1]);
CASE_TEXMOD(m_Offs[2]);
CASE_TEXMODANGLE(m_Rot[0]);
CASE_TEXMODANGLE(m_Rot[1]);
CASE_TEXMODANGLE(m_Rot[2]);
CASE_TEXMODANGLE(m_RotOscRate[0]);
CASE_TEXMODANGLE(m_RotOscRate[1]);
CASE_TEXMODANGLE(m_RotOscRate[2]);
CASE_TEXMODANGLE(m_RotOscAmplitude[0]);
CASE_TEXMODANGLE(m_RotOscAmplitude[1]);
CASE_TEXMODANGLE(m_RotOscAmplitude[2]);
CASE_TEXMODANGLE(m_RotOscPhase[0]);
CASE_TEXMODANGLE(m_RotOscPhase[1]);
CASE_TEXMODANGLE(m_RotOscPhase[2]);
CASE_TEXMOD(m_RotOscCenter[0]);
CASE_TEXMOD(m_RotOscCenter[1]);
CASE_TEXMOD(m_RotOscCenter[2]);
CASE_TEXMOD(m_UOscRate);
CASE_TEXMOD(m_VOscRate);
CASE_TEXMOD(m_UOscAmplitude);
CASE_TEXMOD(m_VOscAmplitude);
CASE_TEXMOD(m_UOscPhase);
CASE_TEXMOD(m_VOscPhase);
return false;
}
byte m_eTGType;
byte m_eRotType;
byte m_eUMoveType;
byte m_eVMoveType;
bool m_bTexGenProjected;
float m_Tiling[3];
float m_Offs[3];
ushort m_Rot[3];
ushort m_RotOscRate[3];
ushort m_RotOscAmplitude[3];
ushort m_RotOscPhase[3];
float m_RotOscCenter[3];
float m_UOscRate;
float m_VOscRate;
float m_UOscAmplitude;
float m_VOscAmplitude;
float m_UOscPhase;
float m_VOscPhase;
// This members are used only during updating of the matrices
int m_nFrameUpdated;
int m_nLastRecursionLevel;
int m_UpdateFlags;
Matrix44 m_TexMatrix;
Matrix44 m_TexGenMatrix;
float m_LastUTime;
float m_LastVTime;
float m_CurrentUJitter;
float m_CurrentVJitter;
_inline friend bool operator != (const SEfTexModificator &m1, const SEfTexModificator &m2)
{
if (m1.m_eTGType != m2.m_eTGType ||
m1.m_eRotType != m2.m_eRotType ||
m1.m_eUMoveType != m2.m_eUMoveType ||
m1.m_eVMoveType != m2.m_eVMoveType ||
m1.m_bTexGenProjected != m2.m_bTexGenProjected ||
m1.m_UOscRate != m2.m_UOscRate ||
m1.m_VOscRate != m2.m_VOscRate ||
m1.m_UOscAmplitude != m2.m_UOscAmplitude ||
m1.m_VOscAmplitude != m2.m_VOscAmplitude ||
m1.m_UOscPhase != m2.m_UOscPhase ||
m1.m_VOscPhase != m2.m_VOscPhase)
return true;
for (int i=0; i<3; i++)
{
if (m1.m_Tiling[i] != m2.m_Tiling[i] ||
m1.m_Offs[i] != m2.m_Offs[i] ||
m1.m_Rot[i] != m2.m_Rot[i] ||
m1.m_RotOscRate[i] != m2.m_RotOscRate[i] ||
m1.m_RotOscAmplitude[i] != m2.m_RotOscAmplitude[i] ||
m1.m_RotOscPhase[i] != m2.m_RotOscPhase[i] ||
m1.m_RotOscCenter[i] != m2.m_RotOscCenter[i])
return true;
}
return false;
}
};
struct SEfResTexture
{
// in order to facilitate the memory allocation tracking, we're using here this class;
// if you don't like it, please write a substitute for all string within the project and use them everywhere
CryBasicString m_Name;
byte m_TexFlags;
byte m_Amount;
bool m_bUTile;
bool m_bVTile;
SEfTexModificator m_TexModificator;
SShaderTexUnit m_TU;
void Update(int nTU);
_inline friend bool operator != (const SEfResTexture &m1, const SEfResTexture &m2)
{
if (stricmp(m1.m_Name.c_str(), m2.m_Name.c_str()) != 0 ||
m1.m_TexFlags != m2.m_TexFlags ||
m1.m_Amount != m2.m_Amount ||
m1.m_bUTile != m2.m_bUTile ||
m1.m_bVTile != m2.m_bVTile ||
m1.m_TexModificator != m2.m_TexModificator)
return true;
return false;
}
bool IsNeedTexTransform()
{
if (m_TexModificator.m_eRotType != ETMR_NoChange || m_TexModificator.m_eUMoveType != ETMM_NoChange || m_TexModificator.m_eVMoveType != ETMM_NoChange)
return true;
return false;
}
bool IsNeedTexGen()
{
if (m_TexModificator.m_eTGType != ETG_Stream)
return true;
return false;
}
int Size()
{
int nSize = sizeof(SEfResTexture) - sizeof(SShaderTexUnit);
nSize += m_Name.size();
nSize += m_TU.Size();
return nSize;
}
~SEfResTexture()
{
}
void Reset()
{
memset(this, 0, sizeof(*this));
m_bUTile = true;
m_bVTile = true;
m_Amount = 100;
m_TexModificator.m_Tiling[0] = 1.0f;
m_TexModificator.m_Tiling[1] = 1.0f;
m_TexModificator.m_Tiling[2] = 1.0f;
m_TexModificator.m_TexMatrix.SetIdentity();
m_TexModificator.m_nFrameUpdated = -1;
}
SEfResTexture& operator=(const SEfResTexture& src)
{
src.m_TU.mfCopy(&m_TU);
memcpy(&m_TexModificator, &src.m_TexModificator, sizeof(SEfTexModificator));
m_Amount = src.m_Amount;
m_TexFlags = src.m_TexFlags;
m_Name = src.m_Name;
m_bUTile = src.m_bUTile;
m_bVTile = src.m_bVTile;
return *this;
}
SEfResTexture()
{
Reset();
}
};
#define EFTT_DIFFUSE 0
#define EFTT_BUMP 1
#define EFTT_BUMP_DIFFUSE 2
#define EFTT_GLOSS 3
#define EFTT_CUBEMAP 4
#define EFTT_PHONG 5
#define EFTT_BUMP_HEIGHT 6
#define EFTT_ATTENUATION2D 7
#define EFTT_SPECULAR 8
#define EFTT_DETAIL_OVERLAY 9
#define EFTT_REFLECTION 10
#define EFTT_SUBSURFACE 11
#define EFTT_ATTENUATION1D 12
#define EFTT_OPACITY 13
#define EFTT_LIGHTMAP 14
#define EFTT_LIGHTMAP_HDR 15
#define EFTT_LIGHTMAP_DIR 16
#define EFTT_OCCLUSION 17
#define EFTT_DECAL_OVERLAY 18
#define EFTT_NORMALMAP 19
#define EFTT_MAX 20
struct SBaseShaderResources
{
int m_ResFlags;
float m_Opacity;
float m_AlphaRef;
SLightMaterial *m_LMaterial;
TArray<SShaderParam> m_ShaderParams;
// in order to facilitate the memory allocation tracking, we're using here this class;
// if you don't like it, please write a substitute for all string within the project and use them everywhere
CryBasicString m_TexturePath;
int Size()
{
int nSize = sizeof(SBaseShaderResources) + m_ShaderParams.GetMemoryUsage();
return nSize;
}
SBaseShaderResources& operator=(const SBaseShaderResources& src)
{
m_ResFlags = src.m_ResFlags;
m_Opacity = src.m_Opacity;
m_AlphaRef = src.m_AlphaRef;
m_LMaterial = src.m_LMaterial;
m_ShaderParams.Copy(src.m_ShaderParams);
return *this;
}
SBaseShaderResources()
{
m_ResFlags = 0;
m_Opacity = 1.0f;
m_AlphaRef = 0;
m_LMaterial = NULL;
}
~SBaseShaderResources()
{
m_ShaderParams.Free();
}
};
struct SRenderShaderResources : SBaseShaderResources
{
int m_Id;
int m_nRefCounter;
int m_nCheckedTemplates;
bool m_bNeedNormals;
SEfResTexture *m_Textures[EFTT_MAX];
int m_nLastTexture;
int m_nFrameLoad;
float m_fMinDistanceLoad;
void AddTextureMap(int Id)
{
assert (Id >=0 && Id < EFTT_MAX);
m_Textures[Id] = new SEfResTexture;
}
int Size()
{
int nSize = sizeof(SRenderShaderResources);
for (int i=0; i<EFTT_MAX; i++)
{
if (m_Textures[i])
nSize += m_Textures[i]->Size();
}
return nSize;
}
SRenderShaderResources& operator=(const SRenderShaderResources& src)
{
SBaseShaderResources::operator = (src);
int i;
for (i=0; i<EFTT_MAX; i++)
{
if (!src.m_Textures[i])
continue;
AddTextureMap(i);
*src.m_Textures[i] = *m_Textures[i];
}
return *this;
}
SRenderShaderResources(struct SInputShaderResources *pSrc);
void PostLoad()
{
m_bNeedNormals = false;
int i;
m_nLastTexture = 0;
for (i=0; i<EFTT_MAX; i++)
{
if (!m_Textures[i])
continue;
m_nLastTexture = i;
m_Textures[i]->m_TexModificator.m_UpdateFlags = 0;
if (m_Textures[i]->m_TexModificator.m_eTGType == ETG_WorldEnvMap || m_Textures[i]->m_TexModificator.m_eTGType == ETG_CameraEnvMap)
{
m_bNeedNormals = true;
break;
}
}
}
bool IsNeedNormals()
{
return m_bNeedNormals;
}
void Reset()
{
for (int i=0; i<EFTT_MAX; i++)
{
m_Textures[i] = NULL;
}
}
SRenderShaderResources()
{
Reset();
m_Id = 0;
m_nLastTexture = 0;
m_nCheckedTemplates = 0;
m_bNeedNormals = false;
}
~SRenderShaderResources();
virtual void Release()
{
#ifdef NULL_RENDERER
return;
#endif
m_nRefCounter--;
if (!m_nRefCounter)
delete this;
}
void AddRef() { m_nRefCounter++; }
};
struct SInputShaderResources : public SBaseShaderResources
{
SEfResTexture m_Textures[EFTT_MAX];
int Size()
{
int nSize = SBaseShaderResources::Size() - sizeof(SEfResTexture) * EFTT_MAX;
nSize += m_TexturePath.size();
for (int i=0; i<EFTT_MAX; i++)
{
nSize += m_Textures[i].Size();
}
return nSize;
}
SInputShaderResources& operator=(const SInputShaderResources& src)
{
SBaseShaderResources::operator = (src);
m_TexturePath = src.m_TexturePath;
int i;
for (i=0; i<EFTT_MAX; i++)
{
m_Textures[i] = src.m_Textures[i];
}
return *this;
}
SInputShaderResources()
{
for (int i=0; i<EFTT_MAX; i++)
{
m_Textures[i].Reset();
}
}
SInputShaderResources(SRenderShaderResources *pSrc)
{
if (pSrc)
{
m_TexturePath = pSrc->m_TexturePath;
m_ResFlags = pSrc->m_ResFlags;
m_Opacity = pSrc->m_Opacity;
m_AlphaRef = pSrc->m_AlphaRef;
m_LMaterial = pSrc->m_LMaterial;
m_ShaderParams.Copy(pSrc->m_ShaderParams);
}
for (int i=0; i<EFTT_MAX; i++)
{
if (pSrc && pSrc->m_Textures[i])
{
m_Textures[i] = *pSrc->m_Textures[i];
}
else
{
m_Textures[i].Reset();
}
}
}
~SInputShaderResources()
{
}
};
// Texture formats
enum ETEX_Format
{
eTF_Unknown = 0,
eTF_Index,
eTF_HSV,
eTF_0888,
eTF_8888, // Usually BGRA
eTF_RGBA, // Used only in CGLRenderer::DownLoadToVideoMemory
eTF_8000,
eTF_0565,
eTF_0555,
eTF_4444,
eTF_1555,
eTF_DXT1,
eTF_DXT3,
eTF_DXT5,
// Only for normal maps
eTF_SIGNED_HILO16,
eTF_SIGNED_HILO8,
eTF_SIGNED_RGB8,
eTF_RGB8,
// Only for DSDT bump (3 floats)
eTF_DSDT_MAG,
eTF_DSDT,
eTF_V8U8,
eTF_V16U16,
eTF_0088, // Luminance, Alpha
eTF_DEPTH,
};
//===================================================================================
// Shader gen structure (used for automatic shader script generating)
#define SHGF_HIDDEN 1
struct SShaderGenBit
{
SShaderGenBit()
{
m_Mask = 0;
m_Flags = 0;
}
string m_ParamName;
string m_ParamProp;
string m_ParamDesc;
uint64 m_Mask;
uint m_Flags;
};
struct SShaderGen
{
TArray<SShaderGenBit *> m_BitMask;
};
//===========================================================================
//====================================================================
// Template types
#define EFT_DEFAULT 0 // Default shader as it is
#define EFT_DECAL 1 // Only decal without lights
#define EFT_INVLIGHT 3 // Decal with HW lights (DLight should be added)
#define EFT_WHITESHADOW 4 // Depth map
#define EFT_WHITE 7 // Just white texture with Z write
#define EFT_FROMMAX 14 // Max
#define EFT_HEATVISION 19 // Heat vision template
#define EFT_DOF 20 // Depth of field template
#define EFT_USER_FIRST 30 // First user defined template (each user's template must be registered)
//====================================================================================
// Phys. material flags
#define MATF_NOCLIP 1
//====================================================================================
#define EFSLIST_PREPROCESS_ID 2
#define EFSLIST_DISTSORT_ID 1
#define EFSLIST_GENERAL_ID 0
#define EFSLIST_STENCIL_ID 3
#define EFSLIST_LAST_ID 4
#define EFSLIST_UNSORTED_ID 5
#define EFSLIST_MASK (15<<28)
#define EFSLIST_PREPROCESS (EFSLIST_PREPROCESS_ID << 28) // Rendering 1st (preprocess items)
#define EFSLIST_STENCIL (EFSLIST_STENCIL_ID << 28) // Rendering 2nd (opaque surfaces with stencil shadows supporting)
#define EFSLIST_LAST (EFSLIST_LAST_ID << 28) // Rendering last (6th) (sorted list of all fog passes, screen shaders, ...)
#define EFSLIST_GENERAL (EFSLIST_GENERAL_ID << 28) // Rendering 4th (default sorted list for most render items)
#define EFSLIST_DISTSORT (EFSLIST_DISTSORT_ID << 28) // Rendering 5th (blended sorted by distance render items)
#define EFSLIST_UNSORTED (EFSLIST_UNSORTED_ID << 28) // Rendering 3rd (unsorted shadow passes on terrain)
struct SEfTemplates
{
TArray<SShader *> m_TemplShaders; // All templates (Shaders)
int m_nPreferred;
int m_nMaskAuto;
SShader *m_Preferred;
SEfTemplates ()
{
memset(this, 0, sizeof(SEfTemplates));
m_nPreferred = -1;
}
~SEfTemplates()
{
}
void mfFree(SShader *ef);
void mfSetPreferred(SShader *ef);
void mfClear(SShader *ef);
void mfReserve(int Num)
{
if (Num >= m_TemplShaders.Num())
m_TemplShaders.ReserveNew(Num + 1);
}
int Size()
{
int nSize = sizeof(SEfTemplates);
nSize += m_TemplShaders.GetSize() * sizeof(SShader *);
return nSize;
}
};
// Class of the shader
#define MAX_SH_CLASS 16
enum EShClass
{
eSH_Misc,
eSH_World,
eSH_ClientEffect,
eSH_ClientPoly,
eSH_Model,
eSH_Indoor,
eSH_MotModel,
eSH_Screen,
eSH_Temp,
eSH_Tree_Leaves,
eSH_Tree_Branches,
eSH_Max
};
//================================================================
// Sorting type of the Shader
enum EF_Sort
{
eS_Unknown = 0,
eS_PreProcess = 1, // Preprocess shader (draw to texture, visibility check, ...)
eS_Sky = 2, // Sky box shader
eS_ZBuff = 3,
eS_ShadowMap = 4,
eS_Terrain = 5, // Terrain surface
eS_TerrainShadowPass = 6, // Terrain shadow pass
eS_TerrainDetailTextures = 7, // Terrain detail textures
eS_TerrainLightPass = 8, // Terrain light overlay pass
eS_TerrainFogPass = 9, // Terrain fog overlay pass
eS_Stencil = 10, // Stencil buffer pass
eS_Opaque = 11, // General opaque surfaces
eS_Decal = 12, // Decals on surfaces
eS_Trees = 13, // Trees
eS_SeeThrough = 14, // Alphatest shaders (Z-buffer writing is enabled)
eS_Banner = 15, // Blend shaders (Z-buffer writing is disabled)
eS_UnderWater = 16, // Under water objects
eS_Water = 17, // Water surface
eS_WaterBeach = 18, // Water beach
eS_Additive = 19, // Additive blend polygons
eS_Sprites = 20, // Billboards / sprites
eS_TerrainDetailObjects = 21, // Terrain detail grass
eS_Particles = 22, // All terrain particles
eS_OcclusionTest = 23, // Occlusion test geometry
eS_HeatVision = 24,
eS_MuzzleFlash = 25,
eS_Nearest = 26, // Nearest (first person weapon)
eS_FogShader = 27, // Fog polygon
eS_FogShader_Trans = 28, // Fog polygon
eS_Refractive = 29, // Refractive objects
eS_HDR = 30, // HDR post-processing
eS_Glare = 31, // Glare fullscreen polygon
eS_Max = 32
};
// Different preprocess flags for shaders that require preprocessing (like recursive render to texture, screen effects, visibility check, ...)
// SShader->m_nPreprocess flags in priority order
#define SPRID_CORONA 0
#define FSPR_CORONA (1<<SPRID_CORONA)
#define SPRID_NIGHTVIS 1
#define FSPR_NIGHTVIS (1<<SPRID_NIGHTVIS)
#define SPRID_DOFMAP 2
#define FSPR_DOFMAP (1<<SPRID_DOFMAP)
#define SPRID_PORTAL 3
#define FSPR_PORTAL (1<<SPRID_PORTAL)
#define SPRID_SCANCM 4
#define FSPR_SCANCM (1<<SPRID_SCANCM)
#define SPRID_SCANSCR 5
#define FSPR_SCANSCR (1<<SPRID_SCANSCR)
#define SPRID_SCANTEXWATER 6
#define FSPR_SCANTEXWATER (1<<SPRID_SCANTEXWATER)
#define SPRID_SCANTEX 7
#define FSPR_SCANTEX (1<<SPRID_SCANTEX)
#define SPRID_SCANLCM 8
#define FSPR_SCANLCM (1<<SPRID_SCANLCM)
#define SPRID_CUSTOMCM 9
#define FSPR_CUSTOMCM (1<<SPRID_CUSTOMCM)
#define SPRID_CUSTOMTEXTURE 10
#define FSPR_CUSTOMTEXTURE (1<<SPRID_CUSTOMTEXTURE)
#define SPRID_FLASHBANG 11
#define FSPR_FLASHBANG (1<<SPRID_FLASHBANG)
#define SPRID_SHADOWMAPGEN 12
#define FSPR_SHADOWMAPGEN (1<<SPRID_SHADOWMAPGEN)
#define SPRID_RAINOVERLAY 13
#define FSPR_RAINOVERLAY (1<<SPRID_RAINOVERLAY)
#define SPRID_REFRACTED 14
#define FSPR_REFRACTED (1<<SPRID_REFRACTED)
// tiago: added
#define SPRID_HEATVIS 15
#define FSPR_HEATVIS (1<<SPRID_HEATVIS)
#define SPRID_SCREENTEXMAP 16
#define FSPR_SCREENTEXMAP (1<<SPRID_SCREENTEXMAP)
#define FSPR_MAX 0x40000
// SShader::m_Flags
// Different useful flags
#define EF_NEEDTANGENTS 1 // Shader needs tangent vectors array
#define EF_BUMPAUTOPROC 2
#define EF_BUMPAUTOPIC 4
#define EF_HASVSHADER 8
#define EF_HASCULL 0x10
#define EF_NOBREAKABLELIGHT 0x20
#define EF_OVERLAY 0x40
#define EF_ORIENT 0x80
#define EF_MATERIAL 0x100
#define EF_TEMPLNAMES 0x200
#define EF_SKY_HDR 0x400
#define EF_LIGHTSTYLE 0x800
#define EF_SUNFLARES 0x2000
#define EF_NEEDNORMALS 0x4000 // Need normals operations
#define EF_OFFSETBUMP 0x8000
#define EF_NOTFOUND 0x10000
#define EF_DEFAULT 0x20000
#define EF_SKY 0x40000
#define EF_USELIGHTS 0x80000
#define EF_ALLOW3DC 0x100000
#define EF_FOGSHADER 0x200000
#define EF_USEPROJLIGHTS 0x400000
#define EF_POLYGONOFFSET 0x800000
#define EF_NOMIPMAPS 0x1000000
#define EF_COMPILEDLAYERS 0x2000000
#define EF_USEMTLAYERS 0x4000000
#define EF_DIFFUSELIGHT 0x8000000
#define EF_CLIENTEFFECT 0x10000000
#define EF_SYSTEM 0x20000000
#define EF_HASDIFFUSEMAP 0x40000000
#define EF_NOSPOTS 0x80000000
// SShader::Flags2
// Additional Different useful flags
#define EF2_ALLOW_FENCE 0x1
#define EF2_PREPR_OUTSPACE 0x2
#define EF2_NOCASTSHADOWS 0x4
#define EF2_FOGOVERLAY1 0x8
#define EF2_FOGOVERLAY2 0x10
#define EF2_FOGOVERLAY 0x18
#define EF2_TESSSIZE 0x20
#define EF2_HASOPAQUE 0x40
#define EF2_CUSTOMANIMTEX 0x80
#define EF2_DONTSORTBYDIST 0x100
#define EF2_HASSUNFLARE 0x200
#define EF2_OPAQUE 0x400
#define EF2_TEMPLATE 0x800
#define EF2_IGNORERESOURCESTATES 0x1000
#define EF2_USELIGHTMATERIAL 0x2000
#define EF2_REDEPEND 0x4000
#define EF2_DEFAULTVERTEXFORMAT 0x8000
// SShader::Flags3
// Additional Different useful flags
#define EF3_NODRAW 1
#define EF3_NEEDSYSBUF 2
#define EF3_HASLM 4
#define EF3_HASRGBGEN 8
#define EF3_HASALPHAGEN 0x10
#define EF3_CLIPPLANE_BACK 0x20
#define EF3_CLIPPLANE_FRONT 0x40
#define EF3_CLIPPLANE_WATER_FRONT 0x80
#define EF3_CLIPPLANE_WATER_BACK 0x100
#define EF3_CLIPPLANE (EF3_CLIPPLANE_BACK | EF3_CLIPPLANE_FRONT | EF3_CLIPPLANE_WATER_BACK | EF3_CLIPPLANE_WATER_FRONT)
#define EF3_SCREENTEXTURE 0x200
#define EF3_IGNOREDIRECTIONALLIGHT 0x400
#define EF3_HASVCOLORS 0x1000
#define EF3_HASALPHATEST 0x2000
#define EF3_HASALPHABLEND 0x4000
#define EF3_USEPARENTSORT 0x8000
#define EF3_USEPARENTCULL 0x10000
#define EF3_REFLECTION 0x20000
#define EF3_REBUILD 0x40000
#define EF3_NODETAIL 0x80000
#define EF3_DEPTHWRITE 0x100000
#define EF3_NOTEMPLATE 0x200000
#define EF3_HASRCOMBINER 0x400000
#define EF3_HASPSHADER 0x800000
#define EF3_HASAMBPASSES 0x1000000
#define EF3_TESSSIZE 0x2000000
#define EF3_SHAREVERTS 0x4000000
#define EF3_PREPARELV 0x10000000
#define EF3_PREPAREHAV 0x20000000
#define EF3_PREPARELAS0 0x40000000
#define EF3_PREPARELAS1 0x80000000
#define EF3_PREPARE_MASK (EF3_PREPARELV | EF3_PREPAREHAV | EF3_PREPARELAS0 | EF3_PREPARELAS1)
struct IShader
{
public:
virtual int GetID() = 0;
virtual void AddRef() = 0;
virtual void Release(bool bForce=false) = 0;
virtual int GetRefCount() = 0;
virtual const char *GetName() = 0;
virtual EF_Sort GetSort() = 0;
virtual int GetFlags() = 0;
virtual int GetFlags2() = 0;
virtual int GetFlags3() = 0;
virtual int GetRenderFlags() = 0;
virtual void SetRenderFlags(int nFlags) = 0;
virtual int GetLFlags() = 0;
virtual int GetCull() = 0;
virtual uint GetPreprocessFlags() = 0;
virtual void SetFlags3(int Flags) = 0;
virtual bool Reload(int nFlags) = 0;
virtual TArray<CRendElement *> *GetREs () = 0;
virtual bool AddTemplate(SRenderShaderResources *Res, int& TemplId, const char *Name=NULL, bool bSetPreferred=false, uint64 nMaskGen=0) = 0;
virtual void RemoveTemplate(int TemplId) = 0;
virtual IShader *GetTemplate(int num) = 0;
virtual SEfTemplates *GetTemplates() = 0;
virtual TArray<SShaderParam>& GetPublicParams() = 0;
virtual int GetTexId () = 0;
virtual ITexPic *GetBaseTexture(int *nPass, int *nTU) = 0;
virtual unsigned int GetUsedTextureTypes(void) = 0;
virtual int GetVertexFormat(void) = 0;
virtual int Size(int Flags) = 0;
virtual uint64 GetGenerationMask() = 0;
virtual SShaderGen* GetGenerationParams() = 0;
};
struct SShaderItem
{
SShaderItem()
{
m_pShader=0;
m_pShaderResources=0;
}
IShader *m_pShader;
SRenderShaderResources *m_pShaderResources;
int GetSort(IShader *pSh)
{
int nSort = pSh->GetSort();
if (m_pShaderResources && m_pShaderResources->m_Opacity != 1.0f)
{
if (nSort <= eS_Opaque)
nSort = eS_Banner | (nSort & EFSLIST_MASK);
}
return nSort;
}
_inline bool IsTransparent()
{ // note: if you change this function please check bTransparent variable in CLeafBuffer::Render()
IShader *pSH = m_pShader->GetTemplate(-1);
if (!(pSH->GetFlags2() & EF2_OPAQUE) || (m_pShaderResources && m_pShaderResources->m_Opacity != 1.0f))
return true;
return false;
}
};
//////////////////////////////////////////////////////////////////////////
// Used in IMatInfo:Set/GetFlags
//////////////////////////////////////////////////////////////////////////
#define MIF_POLYBUMP 1
#define MIF_INVPOLYBUMP 2
#define MIF_PHYSIC 4
#define MIF_NOCASTSHADOWS 8
#define MIF_COLLIDABLE 16
#define MIF_INVALID 32 // Set when material marked as invalid
#define MIF_WASUSED 64 // Set when material assigned to some object
#define MIF_CHILD 128 // Set if material is parent material
//////////////////////////////////////////////////////////////////////////
// Material class used by renderer and 3D engine.
//////////////////////////////////////////////////////////////////////////
struct IMatInfo
{
virtual ~IMatInfo() {};
//////////////////////////////////////////////////////////////////////////
// Reference counting.
//////////////////////////////////////////////////////////////////////////
virtual void AddRef() = 0;
virtual void Release() = 0;
virtual int GetNumRefs() = 0;
//////////////////////////////////////////////////////////////////////////
// material name
//////////////////////////////////////////////////////////////////////////
//! Set material name, (Do not use this directly, to change material name use I3DEngine::RenameMatInfo method).
virtual void SetName(const char * pName) = 0;
//! Returns material name.
virtual const char *GetName() = 0;
//! Material flags.
//! @see MIF_INVALID
// see MIF_ flags (like MIF_INVALID)
virtual void SetFlags( int flags ) = 0;
virtual int GetFlags() const = 0;
// shader item
virtual void SetShaderItem(SShaderItem & _ShaderItem) = 0;
virtual const SShaderItem & GetShaderItem() = 0;
//! Used by custom material to override shader item.
virtual bool OverrideShaderItem( int subMtlId,SShaderItem &si ) = 0;
// shader params
virtual void SetShaderParams(TArray<SShaderParam> * _pShaderParams) = 0;
virtual const TArray<SShaderParam> * GetShaderParams() = 0;
//////////////////////////////////////////////////////////////////////////
// Sub materials access.
//////////////////////////////////////////////////////////////////////////
//! Returns number of child sub materials holded by this material.
virtual int GetSubMtlCount() = 0;
//! Return sub material at specified index.
virtual IMatInfo* GetSubMtl( int i ) = 0;
//! Adds new sub material to the end of sub materials list.
virtual void AddSubMtl( IMatInfo *pMtl ) = 0;
//! Deletes material from sub material list.
virtual void RemoveSubMtl( IMatInfo *pMtl ) = 0;
//! Remove all child sub materials at once.
virtual void RemoveAllSubMtls() = 0;
};
//////////////////////////////////////////////////////////////////////
struct CMatInfo : public IMatInfo
{
CMatInfo()
{
m_nRefCount = 0;
sScriptMaterial[0]=0;
sMaterialName[0] = 0;
m_Id=0;
m_Flags=0;
nGamePhysMatId=0;
m_dwNumSections=0;
m_pPrimitiveGroups=0;
m_vCenter.Set(0,0,0);
m_fRadius=0;
nFirstIndexId=0;
nNumIndices=0;
nFirstVertId=0;
nNumVerts=0;
pRE=0;
fAlpha=0;
pShaderParams=0;
fAlpha=1;
m_Id = -1;
pMatEnt=0;
pSubMtls = 0;
m_nCGFMaterialID=-1;
}
~CMatInfo()
{
RemoveAllSubMtls();
}
virtual int GetNumRefs() { return m_nRefCount; };
char sScriptMaterial[32];
char sMaterialName[64];
//! Number of references to this material.
int m_nRefCount;
int m_Id;
int m_nCGFMaterialID;
//! Material flags.
//! @see EMatInfoFlags
int m_Flags;
int nGamePhysMatId;
ushort m_dwNumSections;
SPrimitiveGroup *m_pPrimitiveGroups;
Vec3 m_vCenter;
float m_fRadius;
int nFirstIndexId;
int nNumIndices;
int nFirstVertId;
int nNumVerts;
SShaderItem shaderItem;
CREOcLeaf * pRE;
float fAlpha;
struct MAT_ENTITY * pMatEnt; // used by resource compiler
TArray<SShaderParam> *pShaderParams;
//! Array of Sub materials.
typedef TArray<IMatInfo*> SubMtls;
SubMtls *pSubMtls;
//////////////////////////////////////////////////////////////////////////
// IMatInfo implementation
//////////////////////////////////////////////////////////////////////////
// material name
int Size();
CMatInfo& operator=(const CMatInfo& src)
{
memcpy(this, &src, sizeof(CMatInfo));
if (shaderItem.m_pShader)
shaderItem.m_pShader->AddRef();
if (shaderItem.m_pShaderResources)
shaderItem.m_pShaderResources->AddRef();
return *this;
};
virtual void AddRef() { m_nRefCount++; };
virtual void Release()
{
if (--m_nRefCount <= 0)
delete this;
}
virtual void SetName(const char * pName)
{
strncpy( sMaterialName,pName,sizeof(sMaterialName) );
sMaterialName[sizeof(sMaterialName)-1] = 0;
}
virtual const char* GetName() { return sMaterialName; };
virtual void SetFlags( int flags ) { m_Flags = flags; };
virtual int GetFlags() const { return m_Flags; };
// shader item
virtual void SetShaderItem(SShaderItem & _ShaderItem) { shaderItem = _ShaderItem; }
virtual const SShaderItem & GetShaderItem() { return shaderItem; };
// shader params
virtual void SetShaderParams(TArray<SShaderParam> * _pShaderParams) { pShaderParams = _pShaderParams; }
virtual const TArray<SShaderParam> * GetShaderParams() { return pShaderParams; }
//////////////////////////////////////////////////////////////////////////
virtual bool OverrideShaderItem( int subMtlId,SShaderItem &si )
{
// Assume that the root material is the first material, sub materials start from index 1.
if (subMtlId == 0)
{
si = shaderItem;
return true;
}
if (pSubMtls)
{
if (subMtlId-1 < (int)pSubMtls->size())
{
si = (*pSubMtls)[subMtlId-1]->GetShaderItem();;
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
// Sub materials.
//////////////////////////////////////////////////////////////////////////
virtual int GetSubMtlCount()
{
if (pSubMtls)
return pSubMtls->size();
return 0;
}
virtual IMatInfo* GetSubMtl( int i )
{
assert( pSubMtls );
//ASSERT( i >= 0 && i < pSubMtls->size() );
return (*pSubMtls)[i];
}
virtual void AddSubMtl( IMatInfo *pMtl )
{
assert( pMtl );
if (!pSubMtls)
pSubMtls = new SubMtls;
pSubMtls->push_back( pMtl );
pMtl->SetFlags(pMtl->GetFlags() | MIF_CHILD);
}
virtual void RemoveSubMtl( IMatInfo *pMtl )
{
assert( pMtl );
if (pSubMtls)
{
for (unsigned int i = 0; i < pSubMtls->size(); i++)
{
if ((*pSubMtls)[i] == pMtl)
{
pSubMtls->Delete(i);
break;
}
}
}
}
virtual void RemoveAllSubMtls()
{
if (pSubMtls)
delete pSubMtls;
pSubMtls = 0;
}
};
//////////////////////////////////////////////////////////////////////
// DLights
#define DLF_DETAIL 1
#define DLF_DIRECTIONAL 2
#define DLF_DYNAMIC 4 //dynamic lights
#define DLF_ACTIVE 8 //light is active/disactive
#define DLF_CASTSHADOW_MAPS 0x10 //light casting shadows
#define DLF_POINT 0x20
#define DLF_PROJECT 0x40
#define DLF_CASTSHADOW_VOLUME 0x80 //light casting shadows
#define DLF_POSITIONCHANGED 0x100
#define DLF_NOATTENUATION 0x200
#define DLF_UPDATED 0x400
#define DLF_INWORLDSPACE 0x800
#define DLF_TEMP 0x1000
#define DLF_STATIC_ADDED 0x2000 //this static light has been already added to the list
#define DLF_HASAMBIENT 0x4000
#define DLF_HEATSOURCE 0x8000
#define DLF_LIGHTSOURCE 0x10000
#define DLF_FAKE 0x20000 //actually it's not LS, just render elements (Flares, beams, ...)
#define DLF_SUN 0x40000 //only sun may use this flag
#define DLF_COPY 0x80000
#define DLF_LOCAL 0x100000
#define DLF_LM 0x200000
#define DLF_THIS_AREA_ONLY 0x400000 // affects only current area/sector
#define DLF_AMBIENT_LIGHT 0x800000 // only used to add better ambient lighting to polybump characters
#define DLF_IGNORE_OWNER 0x1000000 // do not affect light owner object
#define DLF_IGNORE_TERRAIN 0x2000000 // do not affect heightmap
#define DLF_ONLY_FOR_HIGHSPEC 0x4000000 //!< This light is active as dynamic light only for high spec machines.
#define DLF_SPECULAR_ONLY_FOR_HIGHSPEC 0x8000000 //!< This light have specular component enabled only for high spec machines.
#define DLF_LMDOT3 0x10000000
#define DLF_FAKE_RADIOSITY 0x20000000
#define DLF_LMOCCL 0x40000000
#define DLF_LIGHTTYPE_MASK (DLF_DIRECTIONAL | DLF_POINT | DLF_PROJECT)
struct IEntity;
struct ShadowMapLightSourceInstance;
// Marco's NOTE: Andrey / Vlad please subividide this class
// by putting the members into functions and use the names
// info only if in debug mode, other strcutres can be
// allocated only if needed in the constructor and destroyed in
// the destructor, and you can even define an operator -> to
// access the data into the various structures inside the class
//////////////////////////////////////////////////////////////////////
class CDLight
{
public:
//! constructor
CDLight( void )
{
memset(this, 0, sizeof(CDLight));
m_fLightFrustumAngle = 45.0f;
m_fRadius = 4.0f;
m_fDirectFactor = 1.0f;
m_Flags = DLF_LIGHTSOURCE;
m_Orientation.m_vForward = Vec3(1,0,0);
m_Orientation.m_vUp = Vec3(0,1,0);
m_Orientation.m_vRight = Vec3(0,0,1);
m_NumCM = -1;
m_nEntityLightId = -1;
// m_nStaticLightId = -1;
}
//! destructor
~CDLight()
{
SAFE_RELEASE( m_pShader );
SAFE_RELEASE( m_pLightImage );
}
//!
bool Parse( void )
{
if (!m_Name[0])
return false;
if (strncmp(m_Name, "ls_", 3)==0 || strstr(m_Name, "_ls"))
m_Flags |= DLF_LIGHTSOURCE;
if (strncmp(m_Name, "hs_", 3)==0 || strstr(m_Name, "_hs"))
m_Flags |= DLF_HEATSOURCE;
return true;
}
void MakeBaseParams()
{
m_BaseOrigin = m_Origin;
m_BaseColor = m_Color;
m_BaseSpecColor = m_SpecColor;
m_fBaseRadius = m_fRadius;
m_fBaseLightFrustumAngle = m_fLightFrustumAngle;
m_BaseProjAngles = m_ProjAngles;
}
//! assignment operator
CDLight& operator=( const CDLight& dl )
{
memcpy(this, &dl, sizeof(CDLight));
if (m_pShader)
m_pShader->AddRef();
if (m_pLightImage)
m_pLightImage->AddRef();
m_Flags |= DLF_COPY;
return *this;
}
int m_Id;
Vec3 m_Origin; //world space position
Vec3 m_BaseOrigin; //world space position
CFColor m_Color; //!< clampled diffuse light color
CFColor m_BaseColor; //!< clampled diffuse light color
CFColor m_SpecColor;
CFColor m_BaseSpecColor;
Vec3 m_vObjectSpacePos; //Object space position
float m_fRadius;
float m_fBaseRadius;
float m_fDirectFactor;
float m_fStartRadius;
float m_fEndRadius;
float m_fLastTime;
int m_NumCM;
// Scissor parameters (2d extent)
short m_sX;
short m_sY;
short m_sWidth;
short m_sHeight;
// Far/near planes
float m_fNear;
float m_fFar;
struct IEntityRender * m_pOwner;
// int m_nStaticLightId;
//for static spot light sources casting volumetric shadows
int m_nReserved; // compensates for the vtbl
COrthoNormalBasis m_Orientation;
int m_CustomTextureId;
Matrix44 m_TextureMatrix;
CCObject * m_pObject[4][4]; //!< Object for light coronas and light flares
//the light image
ITexPic* m_pLightImage;
float m_fLightFrustumAngle;
float m_fBaseLightFrustumAngle;
float m_fAnimSpeed;
IShader* m_pShader;
Vec3 m_ProjAngles;
Vec3 m_BaseProjAngles;
uint m_Flags; //!< flags from above (prefix DLF_)
char m_Name[64];
int m_nLightStyle;
float m_fCoronaScale;
float m_fStartTime;
float m_fLifeTime; //!< lsource will be removed after this number of seconds
char m_sDebugName[8]; //!< name of light creator (for debuging, pointer can't be used since entity may be deleted)
ShadowMapLightSourceInstance * m_pShadowMapLightSource; //!<
CLeafBuffer * m_arrLightLeafBuffers[8]; //!< array of leafbuffers used for heightmap lighting pass
int m_nEntityLightId; //!<
int m_nFrameID; //!<
/*
// next change:
inline CFColor GetClampedDiffColor( void )
{
CFColor ret=m_Color; ret.Clamp(); return(ret);
}
private:
CFColor m_Color; //!< non clampled diffuse light color
*/
ICryCharInstance * m_pCharInstance; // pointer to character this source is attached to
};
#include "RendElement.h"
#endif// _ISHADER_H_