mirror of
https://github.com/dhewm/dhewm3.git
synced 2024-12-12 22:02:06 +00:00
736ec20d4d
Don't include the lazy precompiled.h everywhere, only what's required for the compilation unit. platform.h needs to be included instead to provide all essential defines and types. All includes use the relative path to the neo or the game specific root. Move all idlib related includes from idlib/Lib.h to precompiled.h. precompiled.h still exists for the MFC stuff in tools/. Add some missing header guards.
695 lines
25 KiB
C++
695 lines
25 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
|
|
|
Doom 3 Source Code 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.
|
|
|
|
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#ifndef __MATERIAL_H__
|
|
#define __MATERIAL_H__
|
|
|
|
#include "idlib/containers/List.h"
|
|
#include "idlib/Lexer.h"
|
|
#include "framework/DeclManager.h"
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
Material
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
class idImage;
|
|
class idCinematic;
|
|
class idUserInterface;
|
|
class idMegaTexture;
|
|
|
|
// moved from image.h for default parm
|
|
typedef enum {
|
|
TF_LINEAR,
|
|
TF_NEAREST,
|
|
TF_DEFAULT // use the user-specified r_textureFilter
|
|
} textureFilter_t;
|
|
|
|
typedef enum {
|
|
TR_REPEAT,
|
|
TR_CLAMP,
|
|
TR_CLAMP_TO_BORDER, // this should replace TR_CLAMP_TO_ZERO and TR_CLAMP_TO_ZERO_ALPHA,
|
|
// but I don't want to risk changing it right now
|
|
TR_CLAMP_TO_ZERO, // guarantee 0,0,0,255 edge for projected textures,
|
|
// set AFTER image format selection
|
|
TR_CLAMP_TO_ZERO_ALPHA // guarantee 0 alpha edge for projected textures,
|
|
// set AFTER image format selection
|
|
} textureRepeat_t;
|
|
|
|
typedef struct {
|
|
int stayTime; // msec for no change
|
|
int fadeTime; // msec to fade vertex colors over
|
|
float start[4]; // vertex color at spawn (possibly out of 0.0 - 1.0 range, will clamp after calc)
|
|
float end[4]; // vertex color at fade-out (possibly out of 0.0 - 1.0 range, will clamp after calc)
|
|
} decalInfo_t;
|
|
|
|
typedef enum {
|
|
DFRM_NONE,
|
|
DFRM_SPRITE,
|
|
DFRM_TUBE,
|
|
DFRM_FLARE,
|
|
DFRM_EXPAND,
|
|
DFRM_MOVE,
|
|
DFRM_EYEBALL,
|
|
DFRM_PARTICLE,
|
|
DFRM_PARTICLE2,
|
|
DFRM_TURB
|
|
} deform_t;
|
|
|
|
typedef enum {
|
|
DI_STATIC,
|
|
DI_SCRATCH, // video, screen wipe, etc
|
|
DI_CUBE_RENDER,
|
|
DI_MIRROR_RENDER,
|
|
DI_XRAY_RENDER,
|
|
DI_REMOTE_RENDER
|
|
} dynamicidImage_t;
|
|
|
|
// note: keep opNames[] in sync with changes
|
|
typedef enum {
|
|
OP_TYPE_ADD,
|
|
OP_TYPE_SUBTRACT,
|
|
OP_TYPE_MULTIPLY,
|
|
OP_TYPE_DIVIDE,
|
|
OP_TYPE_MOD,
|
|
OP_TYPE_TABLE,
|
|
OP_TYPE_GT,
|
|
OP_TYPE_GE,
|
|
OP_TYPE_LT,
|
|
OP_TYPE_LE,
|
|
OP_TYPE_EQ,
|
|
OP_TYPE_NE,
|
|
OP_TYPE_AND,
|
|
OP_TYPE_OR,
|
|
OP_TYPE_SOUND
|
|
} expOpType_t;
|
|
|
|
typedef enum {
|
|
EXP_REG_TIME,
|
|
|
|
EXP_REG_PARM0,
|
|
EXP_REG_PARM1,
|
|
EXP_REG_PARM2,
|
|
EXP_REG_PARM3,
|
|
EXP_REG_PARM4,
|
|
EXP_REG_PARM5,
|
|
EXP_REG_PARM6,
|
|
EXP_REG_PARM7,
|
|
EXP_REG_PARM8,
|
|
EXP_REG_PARM9,
|
|
EXP_REG_PARM10,
|
|
EXP_REG_PARM11,
|
|
|
|
EXP_REG_GLOBAL0,
|
|
EXP_REG_GLOBAL1,
|
|
EXP_REG_GLOBAL2,
|
|
EXP_REG_GLOBAL3,
|
|
EXP_REG_GLOBAL4,
|
|
EXP_REG_GLOBAL5,
|
|
EXP_REG_GLOBAL6,
|
|
EXP_REG_GLOBAL7,
|
|
|
|
EXP_REG_NUM_PREDEFINED
|
|
} expRegister_t;
|
|
|
|
typedef struct {
|
|
expOpType_t opType;
|
|
int a, b, c;
|
|
} expOp_t;
|
|
|
|
typedef struct {
|
|
int registers[4];
|
|
} colorStage_t;
|
|
|
|
typedef enum {
|
|
TG_EXPLICIT,
|
|
TG_DIFFUSE_CUBE,
|
|
TG_REFLECT_CUBE,
|
|
TG_SKYBOX_CUBE,
|
|
TG_WOBBLESKY_CUBE,
|
|
TG_SCREEN, // screen aligned, for mirrorRenders and screen space temporaries
|
|
TG_SCREEN2,
|
|
TG_GLASSWARP
|
|
} texgen_t;
|
|
|
|
typedef struct {
|
|
idCinematic * cinematic;
|
|
idImage * image;
|
|
texgen_t texgen;
|
|
bool hasMatrix;
|
|
int matrix[2][3]; // we only allow a subset of the full projection matrix
|
|
|
|
// dynamic image variables
|
|
dynamicidImage_t dynamic;
|
|
int width, height;
|
|
int dynamicFrameCount;
|
|
} textureStage_t;
|
|
|
|
// the order BUMP / DIFFUSE / SPECULAR is necessary for interactions to draw correctly on low end cards
|
|
typedef enum {
|
|
SL_AMBIENT, // execute after lighting
|
|
SL_BUMP,
|
|
SL_DIFFUSE,
|
|
SL_SPECULAR
|
|
} stageLighting_t;
|
|
|
|
// cross-blended terrain textures need to modulate the color by
|
|
// the vertex color to smoothly blend between two textures
|
|
typedef enum {
|
|
SVC_IGNORE,
|
|
SVC_MODULATE,
|
|
SVC_INVERSE_MODULATE
|
|
} stageVertexColor_t;
|
|
|
|
static const int MAX_FRAGMENT_IMAGES = 8;
|
|
static const int MAX_VERTEX_PARMS = 4;
|
|
|
|
typedef struct {
|
|
int vertexProgram;
|
|
int numVertexParms;
|
|
int vertexParms[MAX_VERTEX_PARMS][4]; // evaluated register indexes
|
|
|
|
int fragmentProgram;
|
|
int numFragmentProgramImages;
|
|
idImage * fragmentProgramImages[MAX_FRAGMENT_IMAGES];
|
|
|
|
idMegaTexture *megaTexture; // handles all the binding and parameter setting
|
|
} newShaderStage_t;
|
|
|
|
typedef struct {
|
|
int conditionRegister; // if registers[conditionRegister] == 0, skip stage
|
|
stageLighting_t lighting; // determines which passes interact with lights
|
|
int drawStateBits;
|
|
colorStage_t color;
|
|
bool hasAlphaTest;
|
|
int alphaTestRegister;
|
|
textureStage_t texture;
|
|
stageVertexColor_t vertexColor;
|
|
bool ignoreAlphaTest; // this stage should act as translucent, even
|
|
// if the surface is alpha tested
|
|
float privatePolygonOffset; // a per-stage polygon offset
|
|
|
|
newShaderStage_t *newStage; // vertex / fragment program based stage
|
|
} shaderStage_t;
|
|
|
|
typedef enum {
|
|
MC_BAD,
|
|
MC_OPAQUE, // completely fills the triangle, will have black drawn on fillDepthBuffer
|
|
MC_PERFORATED, // may have alpha tested holes
|
|
MC_TRANSLUCENT // blended with background
|
|
} materialCoverage_t;
|
|
|
|
typedef enum {
|
|
SS_SUBVIEW = -3, // mirrors, viewscreens, etc
|
|
SS_GUI = -2, // guis
|
|
SS_BAD = -1,
|
|
SS_OPAQUE, // opaque
|
|
|
|
SS_PORTAL_SKY,
|
|
|
|
SS_DECAL, // scorch marks, etc.
|
|
|
|
SS_FAR,
|
|
SS_MEDIUM, // normal translucent
|
|
SS_CLOSE,
|
|
|
|
SS_ALMOST_NEAREST, // gun smoke puffs
|
|
|
|
SS_NEAREST, // screen blood blobs
|
|
|
|
SS_POST_PROCESS = 100 // after a screen copy to texture
|
|
} materialSort_t;
|
|
|
|
typedef enum {
|
|
CT_FRONT_SIDED,
|
|
CT_BACK_SIDED,
|
|
CT_TWO_SIDED
|
|
} cullType_t;
|
|
|
|
// these don't effect per-material storage, so they can be very large
|
|
const int MAX_SHADER_STAGES = 256;
|
|
|
|
const int MAX_TEXGEN_REGISTERS = 4;
|
|
|
|
const int MAX_ENTITY_SHADER_PARMS = 12;
|
|
|
|
// material flags
|
|
typedef enum {
|
|
MF_DEFAULTED = BIT(0),
|
|
MF_POLYGONOFFSET = BIT(1),
|
|
MF_NOSHADOWS = BIT(2),
|
|
MF_FORCESHADOWS = BIT(3),
|
|
MF_NOSELFSHADOW = BIT(4),
|
|
MF_NOPORTALFOG = BIT(5), // this fog volume won't ever consider a portal fogged out
|
|
MF_EDITOR_VISIBLE = BIT(6) // in use (visible) per editor
|
|
} materialFlags_t;
|
|
|
|
// contents flags, NOTE: make sure to keep the defines in doom_defs.script up to date with these!
|
|
typedef enum {
|
|
CONTENTS_SOLID = BIT(0), // an eye is never valid in a solid
|
|
CONTENTS_OPAQUE = BIT(1), // blocks visibility (for ai)
|
|
CONTENTS_WATER = BIT(2), // used for water
|
|
CONTENTS_PLAYERCLIP = BIT(3), // solid to players
|
|
CONTENTS_MONSTERCLIP = BIT(4), // solid to monsters
|
|
CONTENTS_MOVEABLECLIP = BIT(5), // solid to moveable entities
|
|
CONTENTS_IKCLIP = BIT(6), // solid to IK
|
|
CONTENTS_BLOOD = BIT(7), // used to detect blood decals
|
|
CONTENTS_BODY = BIT(8), // used for actors
|
|
CONTENTS_PROJECTILE = BIT(9), // used for projectiles
|
|
CONTENTS_CORPSE = BIT(10), // used for dead bodies
|
|
CONTENTS_RENDERMODEL = BIT(11), // used for render models for collision detection
|
|
CONTENTS_TRIGGER = BIT(12), // used for triggers
|
|
CONTENTS_AAS_SOLID = BIT(13), // solid for AAS
|
|
CONTENTS_AAS_OBSTACLE = BIT(14), // used to compile an obstacle into AAS that can be enabled/disabled
|
|
CONTENTS_FLASHLIGHT_TRIGGER = BIT(15), // used for triggers that are activated by the flashlight
|
|
|
|
// contents used by utils
|
|
CONTENTS_AREAPORTAL = BIT(20), // portal separating renderer areas
|
|
CONTENTS_NOCSG = BIT(21), // don't cut this brush with CSG operations in the editor
|
|
|
|
CONTENTS_REMOVE_UTIL = ~(CONTENTS_AREAPORTAL|CONTENTS_NOCSG)
|
|
} contentsFlags_t;
|
|
|
|
// surface types
|
|
const int NUM_SURFACE_BITS = 4;
|
|
const int MAX_SURFACE_TYPES = 1 << NUM_SURFACE_BITS;
|
|
|
|
typedef enum {
|
|
SURFTYPE_NONE, // default type
|
|
SURFTYPE_METAL,
|
|
SURFTYPE_STONE,
|
|
SURFTYPE_FLESH,
|
|
SURFTYPE_WOOD,
|
|
SURFTYPE_CARDBOARD,
|
|
SURFTYPE_LIQUID,
|
|
SURFTYPE_GLASS,
|
|
SURFTYPE_PLASTIC,
|
|
SURFTYPE_RICOCHET,
|
|
SURFTYPE_10,
|
|
SURFTYPE_11,
|
|
SURFTYPE_12,
|
|
SURFTYPE_13,
|
|
SURFTYPE_14,
|
|
SURFTYPE_15
|
|
} surfTypes_t;
|
|
|
|
// surface flags
|
|
typedef enum {
|
|
SURF_TYPE_BIT0 = BIT(0), // encodes the material type (metal, flesh, concrete, etc.)
|
|
SURF_TYPE_BIT1 = BIT(1), // "
|
|
SURF_TYPE_BIT2 = BIT(2), // "
|
|
SURF_TYPE_BIT3 = BIT(3), // "
|
|
SURF_TYPE_MASK = ( 1 << NUM_SURFACE_BITS ) - 1,
|
|
|
|
SURF_NODAMAGE = BIT(4), // never give falling damage
|
|
SURF_SLICK = BIT(5), // effects game physics
|
|
SURF_COLLISION = BIT(6), // collision surface
|
|
SURF_LADDER = BIT(7), // player can climb up this surface
|
|
SURF_NOIMPACT = BIT(8), // don't make missile explosions
|
|
SURF_NOSTEPS = BIT(9), // no footstep sounds
|
|
SURF_DISCRETE = BIT(10), // not clipped or merged by utilities
|
|
SURF_NOFRAGMENT = BIT(11), // dmap won't cut surface at each bsp boundary
|
|
SURF_NULLNORMAL = BIT(12) // renderbump will draw this surface as 0x80 0x80 0x80, which
|
|
// won't collect light from any angle
|
|
} surfaceFlags_t;
|
|
|
|
class idSoundEmitter;
|
|
|
|
class idMaterial : public idDecl {
|
|
public:
|
|
idMaterial();
|
|
virtual ~idMaterial();
|
|
|
|
virtual size_t Size( void ) const;
|
|
virtual bool SetDefaultText( void );
|
|
virtual const char *DefaultDefinition( void ) const;
|
|
virtual bool Parse( const char *text, const int textLength );
|
|
virtual void FreeData( void );
|
|
virtual void Print( void ) const;
|
|
|
|
//BSM Nerve: Added for material editor
|
|
bool Save( const char *fileName = NULL );
|
|
|
|
// returns the internal image name for stage 0, which can be used
|
|
// for the renderer CaptureRenderToImage() call
|
|
// I'm not really sure why this needs to be virtual...
|
|
virtual const char *ImageName( void ) const;
|
|
|
|
void ReloadImages( bool force ) const;
|
|
|
|
// returns number of stages this material contains
|
|
const int GetNumStages( void ) const { return numStages; }
|
|
|
|
// get a specific stage
|
|
const shaderStage_t *GetStage( const int index ) const { assert(index >= 0 && index < numStages); return &stages[index]; }
|
|
|
|
// get the first bump map stage, or NULL if not present.
|
|
// used for bumpy-specular
|
|
const shaderStage_t *GetBumpStage( void ) const;
|
|
|
|
// returns true if the material will draw anything at all. Triggers, portals,
|
|
// etc, will not have anything to draw. A not drawn surface can still castShadow,
|
|
// which can be used to make a simplified shadow hull for a complex object set
|
|
// as noShadow
|
|
bool IsDrawn( void ) const { return ( numStages > 0 || entityGui != 0 || gui != NULL ); }
|
|
|
|
// returns true if the material will draw any non light interaction stages
|
|
bool HasAmbient( void ) const { return ( numAmbientStages > 0 ); }
|
|
|
|
// returns true if material has a gui
|
|
bool HasGui( void ) const { return ( entityGui != 0 || gui != NULL ); }
|
|
|
|
// returns true if the material will generate another view, either as
|
|
// a mirror or dynamic rendered image
|
|
bool HasSubview( void ) const { return hasSubview; }
|
|
|
|
// returns true if the material will generate shadows, not making a
|
|
// distinction between global and no-self shadows
|
|
bool SurfaceCastsShadow( void ) const { return TestMaterialFlag( MF_FORCESHADOWS ) || !TestMaterialFlag( MF_NOSHADOWS ); }
|
|
|
|
// returns true if the material will generate interactions with fog/blend lights
|
|
// All non-translucent surfaces receive fog unless they are explicitly noFog
|
|
bool ReceivesFog( void ) const { return ( IsDrawn() && !noFog && coverage != MC_TRANSLUCENT ); }
|
|
|
|
// returns true if the material will generate interactions with normal lights
|
|
// Many special effect surfaces don't have any bump/diffuse/specular
|
|
// stages, and don't interact with lights at all
|
|
bool ReceivesLighting( void ) const { return numAmbientStages != numStages; }
|
|
|
|
// returns true if the material should generate interactions on sides facing away
|
|
// from light centers, as with noshadow and noselfshadow options
|
|
bool ReceivesLightingOnBackSides( void ) const { return ( materialFlags & (MF_NOSELFSHADOW|MF_NOSHADOWS) ) != 0; }
|
|
|
|
// Standard two-sided triangle rendering won't work with bump map lighting, because
|
|
// the normal and tangent vectors won't be correct for the back sides. When two
|
|
// sided lighting is desired. typically for alpha tested surfaces, this is
|
|
// addressed by having CleanupModelSurfaces() create duplicates of all the triangles
|
|
// with apropriate order reversal.
|
|
bool ShouldCreateBackSides( void ) const { return shouldCreateBackSides; }
|
|
|
|
// characters and models that are created by a complete renderbump can use a faster
|
|
// method of tangent and normal vector generation than surfaces which have a flat
|
|
// renderbump wrapped over them.
|
|
bool UseUnsmoothedTangents( void ) const { return unsmoothedTangents; }
|
|
|
|
// by default, monsters can have blood overlays placed on them, but this can
|
|
// be overrided on a per-material basis with the "noOverlays" material command.
|
|
// This will always return false for translucent surfaces
|
|
bool AllowOverlays( void ) const { return allowOverlays; }
|
|
|
|
// MC_OPAQUE, MC_PERFORATED, or MC_TRANSLUCENT, for interaction list linking and
|
|
// dmap flood filling
|
|
// The depth buffer will not be filled for MC_TRANSLUCENT surfaces
|
|
// FIXME: what do nodraw surfaces return?
|
|
materialCoverage_t Coverage( void ) const { return coverage; }
|
|
|
|
// returns true if this material takes precedence over other in coplanar cases
|
|
bool HasHigherDmapPriority( const idMaterial &other ) const { return ( IsDrawn() && !other.IsDrawn() ) ||
|
|
( Coverage() < other.Coverage() ); }
|
|
|
|
// returns a idUserInterface if it has a global gui, or NULL if no gui
|
|
idUserInterface * GlobalGui( void ) const { return gui; }
|
|
|
|
// a discrete surface will never be merged with other surfaces by dmap, which is
|
|
// necessary to prevent mutliple gui surfaces, mirrors, autosprites, and some other
|
|
// special effects from being combined into a single surface
|
|
// guis, merging sprites or other effects, mirrors and remote views are always discrete
|
|
bool IsDiscrete( void ) const { return ( entityGui || gui || deform != DFRM_NONE || sort == SS_SUBVIEW ||
|
|
( surfaceFlags & SURF_DISCRETE ) != 0 ); }
|
|
|
|
// Normally, dmap chops each surface by every BSP boundary, then reoptimizes.
|
|
// For gigantic polygons like sky boxes, this can cause a huge number of planar
|
|
// triangles that make the optimizer take forever to turn back into a single
|
|
// triangle. The "noFragment" option causes dmap to only break the polygons at
|
|
// area boundaries, instead of every BSP boundary. This has the negative effect
|
|
// of not automatically fixing up interpenetrations, so when this is used, you
|
|
// should manually make the edges of your sky box exactly meet, instead of poking
|
|
// into each other.
|
|
bool NoFragment( void ) const { return ( surfaceFlags & SURF_NOFRAGMENT ) != 0; }
|
|
|
|
//------------------------------------------------------------------
|
|
// light shader specific functions, only called for light entities
|
|
|
|
// lightshader option to fill with fog from viewer instead of light from center
|
|
bool IsFogLight() const { return fogLight; }
|
|
|
|
// perform simple blending of the projection, instead of interacting with bumps and textures
|
|
bool IsBlendLight() const { return blendLight; }
|
|
|
|
// an ambient light has non-directional bump mapping and no specular
|
|
bool IsAmbientLight() const { return ambientLight; }
|
|
|
|
// implicitly no-shadows lights (ambients, fogs, etc) will never cast shadows
|
|
// but individual light entities can also override this value
|
|
bool LightCastsShadows() const { return TestMaterialFlag( MF_FORCESHADOWS ) ||
|
|
( !fogLight && !ambientLight && !blendLight && !TestMaterialFlag( MF_NOSHADOWS ) ); }
|
|
|
|
// fog lights, blend lights, ambient lights, etc will all have to have interaction
|
|
// triangles generated for sides facing away from the light as well as those
|
|
// facing towards the light. It is debatable if noshadow lights should effect back
|
|
// sides, making everything "noSelfShadow", but that would make noshadow lights
|
|
// potentially slower than normal lights, which detracts from their optimization
|
|
// ability, so they currently do not.
|
|
bool LightEffectsBackSides() const { return fogLight || ambientLight || blendLight; }
|
|
|
|
// NULL unless an image is explicitly specified in the shader with "lightFalloffShader <image>"
|
|
idImage * LightFalloffImage() const { return lightFalloffImage; }
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// returns the renderbump command line for this shader, or an empty string if not present
|
|
const char * GetRenderBump() const { return renderBump; };
|
|
|
|
// set specific material flag(s)
|
|
void SetMaterialFlag( const int flag ) const { materialFlags |= flag; }
|
|
|
|
// clear specific material flag(s)
|
|
void ClearMaterialFlag( const int flag ) const { materialFlags &= ~flag; }
|
|
|
|
// test for existance of specific material flag(s)
|
|
bool TestMaterialFlag( const int flag ) const { return ( materialFlags & flag ) != 0; }
|
|
|
|
// get content flags
|
|
const int GetContentFlags( void ) const { return contentFlags; }
|
|
|
|
// get surface flags
|
|
const int GetSurfaceFlags( void ) const { return surfaceFlags; }
|
|
|
|
// gets name for surface type (stone, metal, flesh, etc.)
|
|
const surfTypes_t GetSurfaceType( void ) const { return static_cast<surfTypes_t>( surfaceFlags & SURF_TYPE_MASK ); }
|
|
|
|
// get material description
|
|
const char * GetDescription( void ) const { return desc; }
|
|
|
|
// get sort order
|
|
const float GetSort( void ) const { return sort; }
|
|
// this is only used by the gui system to force sorting order
|
|
// on images referenced from tga's instead of materials.
|
|
// this is done this way as there are 2000 tgas the guis use
|
|
void SetSort( float s ) const { sort = s; };
|
|
|
|
// DFRM_NONE, DFRM_SPRITE, etc
|
|
deform_t Deform( void ) const { return deform; }
|
|
|
|
// flare size, expansion size, etc
|
|
const int GetDeformRegister( int index ) const { return deformRegisters[index]; }
|
|
|
|
// particle system to emit from surface and table for turbulent
|
|
const idDecl *GetDeformDecl( void ) const { return deformDecl; }
|
|
|
|
// currently a surface can only have one unique texgen for all the stages
|
|
texgen_t Texgen() const;
|
|
|
|
// wobble sky parms
|
|
const int * GetTexGenRegisters( void ) const { return texGenRegisters; }
|
|
|
|
// get cull type
|
|
const cullType_t GetCullType( void ) const { return cullType; }
|
|
|
|
float GetEditorAlpha( void ) const { return editorAlpha; }
|
|
|
|
int GetEntityGui( void ) const { return entityGui; }
|
|
|
|
decalInfo_t GetDecalInfo( void ) const { return decalInfo; }
|
|
|
|
// spectrums are used for "invisible writing" that can only be
|
|
// illuminated by a light of matching spectrum
|
|
int Spectrum( void ) const { return spectrum; }
|
|
|
|
float GetPolygonOffset( void ) const { return polygonOffset; }
|
|
|
|
float GetSurfaceArea( void ) const { return surfaceArea; }
|
|
void AddToSurfaceArea( float area ) { surfaceArea += area; }
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// returns the length, in milliseconds, of the videoMap on this material,
|
|
// or zero if it doesn't have one
|
|
int CinematicLength( void ) const;
|
|
|
|
void CloseCinematic( void ) const;
|
|
|
|
void ResetCinematicTime( int time ) const;
|
|
|
|
void UpdateCinematic( int time ) const;
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// gets an image for the editor to use
|
|
idImage * GetEditorImage( void ) const;
|
|
int GetImageWidth( void ) const;
|
|
int GetImageHeight( void ) const;
|
|
|
|
void SetGui( const char *_gui ) const;
|
|
|
|
// just for resource tracking
|
|
void SetImageClassifications( int tag ) const;
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// returns number of registers this material contains
|
|
const int GetNumRegisters() const { return numRegisters; }
|
|
|
|
// regs should point to a float array large enough to hold GetNumRegisters() floats
|
|
void EvaluateRegisters( float *regs, const float entityParms[MAX_ENTITY_SHADER_PARMS],
|
|
const struct viewDef_s *view, idSoundEmitter *soundEmitter = NULL ) const;
|
|
|
|
// if a material only uses constants (no entityParm or globalparm references), this
|
|
// will return a pointer to an internal table, and EvaluateRegisters will not need
|
|
// to be called. If NULL is returned, EvaluateRegisters must be used.
|
|
const float * ConstantRegisters() const;
|
|
|
|
bool SuppressInSubview() const { return suppressInSubview; };
|
|
bool IsPortalSky() const { return portalSky; };
|
|
void AddReference();
|
|
|
|
private:
|
|
// parse the entire material
|
|
void CommonInit();
|
|
void ParseMaterial( idLexer &src );
|
|
bool MatchToken( idLexer &src, const char *match );
|
|
void ParseSort( idLexer &src );
|
|
void ParseBlend( idLexer &src, shaderStage_t *stage );
|
|
void ParseVertexParm( idLexer &src, newShaderStage_t *newStage );
|
|
void ParseFragmentMap( idLexer &src, newShaderStage_t *newStage );
|
|
void ParseStage( idLexer &src, const textureRepeat_t trpDefault = TR_REPEAT );
|
|
void ParseDeform( idLexer &src );
|
|
void ParseDecalInfo( idLexer &src );
|
|
bool CheckSurfaceParm( idToken *token );
|
|
int GetExpressionConstant( float f );
|
|
int GetExpressionTemporary( void );
|
|
expOp_t * GetExpressionOp( void );
|
|
int EmitOp( int a, int b, expOpType_t opType );
|
|
int ParseEmitOp( idLexer &src, int a, expOpType_t opType, int priority );
|
|
int ParseTerm( idLexer &src );
|
|
int ParseExpressionPriority( idLexer &src, int priority );
|
|
int ParseExpression( idLexer &src );
|
|
void ClearStage( shaderStage_t *ss );
|
|
int NameToSrcBlendMode( const idStr &name );
|
|
int NameToDstBlendMode( const idStr &name );
|
|
void MultiplyTextureMatrix( textureStage_t *ts, int registers[2][3] ); // FIXME: for some reason the const is bad for gcc and Mac
|
|
void SortInteractionStages();
|
|
void AddImplicitStages( const textureRepeat_t trpDefault = TR_REPEAT );
|
|
void CheckForConstantRegisters();
|
|
|
|
private:
|
|
idStr desc; // description
|
|
idStr renderBump; // renderbump command options, without the "renderbump" at the start
|
|
|
|
idImage * lightFalloffImage;
|
|
|
|
int entityGui; // draw a gui with the idUserInterface from the renderEntity_t
|
|
// non zero will draw gui, gui2, or gui3 from renderEnitty_t
|
|
mutable idUserInterface *gui; // non-custom guis are shared by all users of a material
|
|
|
|
bool noFog; // surface does not create fog interactions
|
|
|
|
int spectrum; // for invisible writing, used for both lights and surfaces
|
|
|
|
float polygonOffset;
|
|
|
|
int contentFlags; // content flags
|
|
int surfaceFlags; // surface flags
|
|
mutable int materialFlags; // material flags
|
|
|
|
decalInfo_t decalInfo;
|
|
|
|
|
|
mutable float sort; // lower numbered shaders draw before higher numbered
|
|
deform_t deform;
|
|
int deformRegisters[4]; // numeric parameter for deforms
|
|
const idDecl *deformDecl; // for surface emitted particle deforms and tables
|
|
|
|
int texGenRegisters[MAX_TEXGEN_REGISTERS]; // for wobbleSky
|
|
|
|
materialCoverage_t coverage;
|
|
cullType_t cullType; // CT_FRONT_SIDED, CT_BACK_SIDED, or CT_TWO_SIDED
|
|
bool shouldCreateBackSides;
|
|
|
|
bool fogLight;
|
|
bool blendLight;
|
|
bool ambientLight;
|
|
bool unsmoothedTangents;
|
|
bool hasSubview; // mirror, remote render, etc
|
|
bool allowOverlays;
|
|
|
|
int numOps;
|
|
expOp_t * ops; // evaluate to make expressionRegisters
|
|
|
|
int numRegisters; //
|
|
float * expressionRegisters;
|
|
|
|
float * constantRegisters; // NULL if ops ever reference globalParms or entityParms
|
|
|
|
int numStages;
|
|
int numAmbientStages;
|
|
|
|
shaderStage_t * stages;
|
|
|
|
struct mtrParsingData_s *pd; // only used during parsing
|
|
|
|
float surfaceArea; // only for listSurfaceAreas
|
|
|
|
// we defer loading of the editor image until it is asked for, so the game doesn't load up
|
|
// all the invisible and uncompressed images.
|
|
// If editorImage is NULL, it will atempt to load editorImageName, and set editorImage to that or defaultImage
|
|
idStr editorImageName;
|
|
mutable idImage * editorImage; // image used for non-shaded preview
|
|
float editorAlpha;
|
|
|
|
bool suppressInSubview;
|
|
bool portalSky;
|
|
int refCount;
|
|
};
|
|
|
|
typedef idList<const idMaterial *> idMatList;
|
|
|
|
#endif /* !__MATERIAL_H__ */
|