DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

Material.h (26253B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition 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 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 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.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #ifndef __MATERIAL_H__
     30 #define __MATERIAL_H__
     31 
     32 /*
     33 ===============================================================================
     34 
     35 	Material
     36 
     37 ===============================================================================
     38 */
     39 
     40 class idImage;
     41 class idCinematic;
     42 class idUserInterface;
     43 
     44 // moved from image.h for default parm
     45 typedef enum {
     46 	TF_LINEAR,
     47 	TF_NEAREST,
     48 	TF_DEFAULT				// use the user-specified r_textureFilter
     49 } textureFilter_t;
     50 
     51 typedef enum {
     52 	TR_REPEAT,
     53 	TR_CLAMP,
     54 	TR_CLAMP_TO_ZERO,		// guarantee 0,0,0,255 edge for projected textures
     55 	TR_CLAMP_TO_ZERO_ALPHA	// guarantee 0 alpha edge for projected textures
     56 } textureRepeat_t;
     57 
     58 typedef struct {
     59 	int		stayTime;		// msec for no change
     60 	int		fadeTime;		// msec to fade vertex colors over
     61 	float	start[4];		// vertex color at spawn (possibly out of 0.0 - 1.0 range, will clamp after calc)
     62 	float	end[4];			// vertex color at fade-out (possibly out of 0.0 - 1.0 range, will clamp after calc)
     63 } decalInfo_t;
     64 
     65 typedef enum {
     66 	DFRM_NONE,
     67 	DFRM_SPRITE,
     68 	DFRM_TUBE,
     69 	DFRM_FLARE,
     70 	DFRM_EXPAND,
     71 	DFRM_MOVE,
     72 	DFRM_EYEBALL,
     73 	DFRM_PARTICLE,
     74 	DFRM_PARTICLE2,
     75 	DFRM_TURB
     76 } deform_t;
     77 
     78 typedef enum {
     79 	DI_STATIC,
     80 	DI_SCRATCH,		// video, screen wipe, etc
     81 	DI_CUBE_RENDER,
     82 	DI_MIRROR_RENDER,
     83 	DI_XRAY_RENDER,
     84 	DI_REMOTE_RENDER
     85 } dynamicidImage_t;
     86 
     87 // note: keep opNames[] in sync with changes
     88 typedef enum {
     89 	OP_TYPE_ADD,
     90 	OP_TYPE_SUBTRACT,
     91 	OP_TYPE_MULTIPLY,
     92 	OP_TYPE_DIVIDE,
     93 	OP_TYPE_MOD,
     94 	OP_TYPE_TABLE,
     95 	OP_TYPE_GT,
     96 	OP_TYPE_GE,
     97 	OP_TYPE_LT,
     98 	OP_TYPE_LE,
     99 	OP_TYPE_EQ,
    100 	OP_TYPE_NE,
    101 	OP_TYPE_AND,
    102 	OP_TYPE_OR,
    103 	OP_TYPE_SOUND
    104 } expOpType_t;
    105 
    106 typedef enum {
    107 	EXP_REG_TIME,
    108 
    109 	EXP_REG_PARM0,
    110 	EXP_REG_PARM1,
    111 	EXP_REG_PARM2,
    112 	EXP_REG_PARM3,
    113 	EXP_REG_PARM4,
    114 	EXP_REG_PARM5,
    115 	EXP_REG_PARM6,
    116 	EXP_REG_PARM7,
    117 	EXP_REG_PARM8,
    118 	EXP_REG_PARM9,
    119 	EXP_REG_PARM10,
    120 	EXP_REG_PARM11,
    121 
    122 	EXP_REG_GLOBAL0,
    123 	EXP_REG_GLOBAL1,
    124 	EXP_REG_GLOBAL2,
    125 	EXP_REG_GLOBAL3,
    126 	EXP_REG_GLOBAL4,
    127 	EXP_REG_GLOBAL5,
    128 	EXP_REG_GLOBAL6,
    129 	EXP_REG_GLOBAL7,
    130 
    131 	EXP_REG_NUM_PREDEFINED
    132 } expRegister_t;
    133 
    134 typedef struct {
    135 	expOpType_t		opType;	
    136 	int				a, b, c;
    137 } expOp_t;
    138 
    139 typedef struct {
    140 	int				registers[4];
    141 } colorStage_t;
    142 
    143 typedef enum {
    144 	TG_EXPLICIT,
    145 	TG_DIFFUSE_CUBE,
    146 	TG_REFLECT_CUBE,
    147 	TG_SKYBOX_CUBE,
    148 	TG_WOBBLESKY_CUBE,
    149 	TG_SCREEN,			// screen aligned, for mirrorRenders and screen space temporaries
    150 	TG_SCREEN2,
    151 	TG_GLASSWARP
    152 } texgen_t;
    153 
    154 typedef struct {
    155 	idCinematic *		cinematic;
    156 	idImage *			image;
    157 	texgen_t			texgen;
    158 	bool				hasMatrix;
    159 	int					matrix[2][3];	// we only allow a subset of the full projection matrix
    160 
    161 	// dynamic image variables
    162 	dynamicidImage_t	dynamic;
    163 	int					width, height;
    164 	int					dynamicFrameCount;
    165 } textureStage_t;
    166 
    167 // the order BUMP / DIFFUSE / SPECULAR is necessary for interactions to draw correctly on low end cards
    168 typedef enum {
    169 	SL_AMBIENT,						// execute after lighting
    170 	SL_BUMP,
    171 	SL_DIFFUSE,
    172 	SL_SPECULAR,
    173 	SL_COVERAGE,
    174 } stageLighting_t;
    175 
    176 // cross-blended terrain textures need to modulate the color by
    177 // the vertex color to smoothly blend between two textures
    178 typedef enum {
    179 	SVC_IGNORE,
    180 	SVC_MODULATE,
    181 	SVC_INVERSE_MODULATE
    182 } stageVertexColor_t;
    183 
    184 static const int	MAX_FRAGMENT_IMAGES = 8;
    185 static const int	MAX_VERTEX_PARMS = 4;
    186 
    187 typedef struct {
    188 	int					vertexProgram;
    189 	int					numVertexParms;
    190 	int					vertexParms[MAX_VERTEX_PARMS][4];	// evaluated register indexes
    191 
    192 	int					fragmentProgram;
    193 	int					glslProgram;
    194 	int					numFragmentProgramImages;
    195 	idImage *			fragmentProgramImages[MAX_FRAGMENT_IMAGES];
    196 } newShaderStage_t;
    197 
    198 typedef struct {
    199 	int					conditionRegister;	// if registers[conditionRegister] == 0, skip stage
    200 	stageLighting_t		lighting;			// determines which passes interact with lights
    201 	uint64				drawStateBits;
    202 	colorStage_t		color;
    203 	bool				hasAlphaTest;
    204 	int					alphaTestRegister;
    205 	textureStage_t		texture;
    206 	stageVertexColor_t	vertexColor;
    207 	bool				ignoreAlphaTest;	// this stage should act as translucent, even
    208 											// if the surface is alpha tested
    209 	float				privatePolygonOffset;	// a per-stage polygon offset
    210 
    211 	newShaderStage_t	*newStage;			// vertex / fragment program based stage
    212 } shaderStage_t;
    213 
    214 typedef enum {
    215 	MC_BAD,
    216 	MC_OPAQUE,			// completely fills the triangle, will have black drawn on fillDepthBuffer
    217 	MC_PERFORATED,		// may have alpha tested holes
    218 	MC_TRANSLUCENT		// blended with background
    219 } materialCoverage_t;
    220 
    221 typedef enum {
    222 	SS_SUBVIEW = -3,	// mirrors, viewscreens, etc
    223 	SS_GUI = -2,		// guis
    224 	SS_BAD = -1,
    225 	SS_OPAQUE,			// opaque
    226 
    227 	SS_PORTAL_SKY,
    228 
    229 	SS_DECAL,			// scorch marks, etc.
    230 
    231 	SS_FAR,
    232 	SS_MEDIUM,			// normal translucent
    233 	SS_CLOSE,
    234 
    235 	SS_ALMOST_NEAREST,	// gun smoke puffs
    236 
    237 	SS_NEAREST,			// screen blood blobs
    238 
    239 	SS_POST_PROCESS = 100	// after a screen copy to texture
    240 } materialSort_t;
    241 
    242 typedef enum {
    243 	CT_FRONT_SIDED,
    244 	CT_BACK_SIDED,
    245 	CT_TWO_SIDED
    246 } cullType_t;
    247 
    248 // these don't effect per-material storage, so they can be very large
    249 const int MAX_SHADER_STAGES			= 256;
    250 
    251 const int MAX_TEXGEN_REGISTERS		= 4;
    252 
    253 const int MAX_ENTITY_SHADER_PARMS	= 12;
    254 const int MAX_GLOBAL_SHADER_PARMS	= 12;	// ? this looks like it should only be 8
    255 
    256 // material flags
    257 typedef enum {
    258 	MF_DEFAULTED				= BIT(0),
    259 	MF_POLYGONOFFSET			= BIT(1),
    260 	MF_NOSHADOWS				= BIT(2),
    261 	MF_FORCESHADOWS				= BIT(3),
    262 	MF_NOSELFSHADOW				= BIT(4),
    263 	MF_NOPORTALFOG				= BIT(5),	// this fog volume won't ever consider a portal fogged out
    264 	MF_EDITOR_VISIBLE			= BIT(6)	// in use (visible) per editor
    265 } materialFlags_t;
    266 
    267 // contents flags, NOTE: make sure to keep the defines in doom_defs.script up to date with these!
    268 typedef enum {
    269 	CONTENTS_SOLID				= BIT(0),	// an eye is never valid in a solid
    270 	CONTENTS_OPAQUE				= BIT(1),	// blocks visibility (for ai)
    271 	CONTENTS_WATER				= BIT(2),	// used for water
    272 	CONTENTS_PLAYERCLIP			= BIT(3),	// solid to players
    273 	CONTENTS_MONSTERCLIP		= BIT(4),	// solid to monsters
    274 	CONTENTS_MOVEABLECLIP		= BIT(5),	// solid to moveable entities
    275 	CONTENTS_IKCLIP				= BIT(6),	// solid to IK
    276 	CONTENTS_BLOOD				= BIT(7),	// used to detect blood decals
    277 	CONTENTS_BODY				= BIT(8),	// used for actors
    278 	CONTENTS_PROJECTILE			= BIT(9),	// used for projectiles
    279 	CONTENTS_CORPSE				= BIT(10),	// used for dead bodies
    280 	CONTENTS_RENDERMODEL		= BIT(11),	// used for render models for collision detection
    281 	CONTENTS_TRIGGER			= BIT(12),	// used for triggers
    282 	CONTENTS_AAS_SOLID			= BIT(13),	// solid for AAS
    283 	CONTENTS_AAS_OBSTACLE		= BIT(14),	// used to compile an obstacle into AAS that can be enabled/disabled
    284 	CONTENTS_FLASHLIGHT_TRIGGER	= BIT(15),	// used for triggers that are activated by the flashlight
    285 
    286 	// contents used by utils
    287 	CONTENTS_AREAPORTAL			= BIT(20),	// portal separating renderer areas
    288 	CONTENTS_NOCSG				= BIT(21),	// don't cut this brush with CSG operations in the editor
    289 
    290 	CONTENTS_REMOVE_UTIL		= ~(CONTENTS_AREAPORTAL|CONTENTS_NOCSG)
    291 } contentsFlags_t;
    292 
    293 // surface types
    294 const int NUM_SURFACE_BITS		= 4;
    295 const int MAX_SURFACE_TYPES		= 1 << NUM_SURFACE_BITS;
    296 
    297 typedef enum {
    298 	SURFTYPE_NONE,					// default type
    299     SURFTYPE_METAL,
    300 	SURFTYPE_STONE,
    301 	SURFTYPE_FLESH,
    302 	SURFTYPE_WOOD,
    303 	SURFTYPE_CARDBOARD,
    304 	SURFTYPE_LIQUID,
    305 	SURFTYPE_GLASS,
    306 	SURFTYPE_PLASTIC,
    307 	SURFTYPE_RICOCHET,
    308 	SURFTYPE_10,
    309 	SURFTYPE_11,
    310 	SURFTYPE_12,
    311 	SURFTYPE_13,
    312 	SURFTYPE_14,
    313 	SURFTYPE_15
    314 } surfTypes_t;
    315 
    316 // surface flags
    317 typedef enum {
    318 	SURF_TYPE_BIT0				= BIT(0),	// encodes the material type (metal, flesh, concrete, etc.)
    319 	SURF_TYPE_BIT1				= BIT(1),	// "
    320 	SURF_TYPE_BIT2				= BIT(2),	// "
    321 	SURF_TYPE_BIT3				= BIT(3),	// "
    322 	SURF_TYPE_MASK				= ( 1 << NUM_SURFACE_BITS ) - 1,
    323 
    324 	SURF_NODAMAGE				= BIT(4),	// never give falling damage
    325 	SURF_SLICK					= BIT(5),	// effects game physics
    326 	SURF_COLLISION				= BIT(6),	// collision surface
    327 	SURF_LADDER					= BIT(7),	// player can climb up this surface
    328 	SURF_NOIMPACT				= BIT(8),	// don't make missile explosions
    329 	SURF_NOSTEPS				= BIT(9),	// no footstep sounds
    330 	SURF_DISCRETE				= BIT(10),	// not clipped or merged by utilities
    331 	SURF_NOFRAGMENT				= BIT(11),	// dmap won't cut surface at each bsp boundary
    332 	SURF_NULLNORMAL				= BIT(12)	// renderbump will draw this surface as 0x80 0x80 0x80, which
    333 											// won't collect light from any angle
    334 } surfaceFlags_t;
    335 
    336 class idSoundEmitter;
    337 
    338 class idMaterial : public idDecl {
    339 public:
    340 						idMaterial();
    341 	virtual				~idMaterial();
    342 
    343 	virtual size_t		Size() const;
    344 	virtual bool		SetDefaultText();
    345 	virtual const char *DefaultDefinition() const;
    346 	virtual bool		Parse( const char *text, const int textLength, bool allowBinaryVersion );
    347 	virtual void		FreeData();
    348 	virtual void		Print() const;
    349 
    350 	//BSM Nerve: Added for material editor
    351 	bool				Save( const char *fileName = NULL );
    352 
    353 						// returns the internal image name for stage 0, which can be used
    354 						// for the renderer CaptureRenderToImage() call
    355 						// I'm not really sure why this needs to be virtual...
    356 	virtual const char	*ImageName() const;
    357 
    358 	void				ReloadImages( bool force ) const;
    359 
    360 						// returns number of stages this material contains
    361 	const int			GetNumStages() const { return numStages; }
    362 
    363 						// if the material is simple, all that needs to be known are
    364 						// the images for drawing.
    365 						// These will either all return valid images, or all return NULL
    366 	idImage *			GetFastPathBumpImage() const { return fastPathBumpImage; };
    367 	idImage *			GetFastPathDiffuseImage() const { return fastPathDiffuseImage; };
    368 	idImage *			GetFastPathSpecularImage() const { return fastPathSpecularImage; };
    369 
    370 						// get a specific stage
    371 	const shaderStage_t *GetStage( const int index ) const { assert(index >= 0 && index < numStages); return &stages[index]; }
    372 
    373 						// get the first bump map stage, or NULL if not present.
    374 						// used for bumpy-specular
    375 	const shaderStage_t *GetBumpStage() const;
    376 
    377 						// returns true if the material will draw anything at all.  Triggers, portals,
    378 						// etc, will not have anything to draw.  A not drawn surface can still castShadow,
    379 						// which can be used to make a simplified shadow hull for a complex object set
    380 						// as noShadow
    381 	bool				IsDrawn() const { return ( numStages > 0 || entityGui != 0 || gui != NULL ); }
    382 
    383 						// returns true if the material will draw any non light interaction stages
    384 	bool				HasAmbient() const { return ( numAmbientStages > 0 ); }
    385 
    386 						// returns true if material has a gui
    387 	bool				HasGui() const { return ( entityGui != 0 || gui != NULL ); }
    388 
    389 						// returns true if the material will generate another view, either as
    390 						// a mirror or dynamic rendered image
    391 	bool				HasSubview() const { return hasSubview; }
    392 
    393 						// returns true if the material will generate shadows, not making a
    394 						// distinction between global and no-self shadows
    395 	bool				SurfaceCastsShadow() const { return TestMaterialFlag( MF_FORCESHADOWS ) || !TestMaterialFlag( MF_NOSHADOWS ); }
    396 
    397 						// returns true if the material will generate interactions with fog/blend lights
    398 						// All non-translucent surfaces receive fog unless they are explicitly noFog
    399 	bool				ReceivesFog() const { return ( IsDrawn() && !noFog && coverage != MC_TRANSLUCENT ); }
    400 
    401 						// returns true if the material will generate interactions with normal lights
    402 						// Many special effect surfaces don't have any bump/diffuse/specular
    403 						// stages, and don't interact with lights at all
    404 	bool				ReceivesLighting() const { return numAmbientStages != numStages; }
    405 
    406 						// returns true if the material should generate interactions on sides facing away
    407 						// from light centers, as with noshadow and noselfshadow options
    408 	bool				ReceivesLightingOnBackSides() const { return ( materialFlags & (MF_NOSELFSHADOW|MF_NOSHADOWS) ) != 0; }
    409 
    410 						// Standard two-sided triangle rendering won't work with bump map lighting, because
    411 						// the normal and tangent vectors won't be correct for the back sides.  When two
    412 						// sided lighting is desired. typically for alpha tested surfaces, this is
    413 						// addressed by having CleanupModelSurfaces() create duplicates of all the triangles
    414 						// with apropriate order reversal.
    415 	bool				ShouldCreateBackSides() const { return shouldCreateBackSides; }
    416 
    417 						// characters and models that are created by a complete renderbump can use a faster
    418 						// method of tangent and normal vector generation than surfaces which have a flat
    419 						// renderbump wrapped over them.
    420 	bool				UseUnsmoothedTangents() const { return unsmoothedTangents; }
    421 
    422 						// by default, monsters can have blood overlays placed on them, but this can
    423 						// be overrided on a per-material basis with the "noOverlays" material command.
    424 						// This will always return false for translucent surfaces
    425 	bool				AllowOverlays() const { return allowOverlays; }
    426 
    427 						// MC_OPAQUE, MC_PERFORATED, or MC_TRANSLUCENT, for interaction list linking and
    428 						// dmap flood filling
    429 						// The depth buffer will not be filled for MC_TRANSLUCENT surfaces
    430 						// FIXME: what do nodraw surfaces return?
    431 	materialCoverage_t	Coverage() const { return coverage; }
    432 
    433 						// returns true if this material takes precedence over other in coplanar cases
    434 	bool				HasHigherDmapPriority( const idMaterial &other ) const { return ( IsDrawn() && !other.IsDrawn() ) ||
    435 																						( Coverage() < other.Coverage() ); }
    436 
    437 						// returns a idUserInterface if it has a global gui, or NULL if no gui
    438 	idUserInterface	*	GlobalGui() const { return gui; }
    439 
    440 						// a discrete surface will never be merged with other surfaces by dmap, which is
    441 						// necessary to prevent mutliple gui surfaces, mirrors, autosprites, and some other
    442 						// special effects from being combined into a single surface
    443 						// guis, merging sprites or other effects, mirrors and remote views are always discrete
    444 	bool				IsDiscrete() const { return ( entityGui || gui || deform != DFRM_NONE || sort == SS_SUBVIEW ||
    445 												( surfaceFlags & SURF_DISCRETE ) != 0 ); }
    446 
    447 						// Normally, dmap chops each surface by every BSP boundary, then reoptimizes.
    448 						// For gigantic polygons like sky boxes, this can cause a huge number of planar
    449 						// triangles that make the optimizer take forever to turn back into a single
    450 						// triangle.  The "noFragment" option causes dmap to only break the polygons at
    451 						// area boundaries, instead of every BSP boundary.  This has the negative effect
    452 						// of not automatically fixing up interpenetrations, so when this is used, you
    453 						// should manually make the edges of your sky box exactly meet, instead of poking
    454 						// into each other.
    455 	bool				NoFragment() const { return ( surfaceFlags & SURF_NOFRAGMENT ) != 0; }
    456 
    457 	//------------------------------------------------------------------
    458 	// light shader specific functions, only called for light entities
    459 
    460 						// lightshader option to fill with fog from viewer instead of light from center
    461 	bool				IsFogLight() const { return fogLight; }
    462 
    463 						// perform simple blending of the projection, instead of interacting with bumps and textures
    464 	bool				IsBlendLight() const { return blendLight; }
    465 
    466 						// an ambient light has non-directional bump mapping and no specular
    467 	bool				IsAmbientLight() const { return ambientLight; }
    468 
    469 						// implicitly no-shadows lights (ambients, fogs, etc) will never cast shadows
    470 						// but individual light entities can also override this value
    471 	bool				LightCastsShadows() const { return TestMaterialFlag( MF_FORCESHADOWS ) ||
    472 								( !fogLight && !ambientLight && !blendLight && !TestMaterialFlag( MF_NOSHADOWS ) ); }
    473 
    474 						// fog lights, blend lights, ambient lights, etc will all have to have interaction
    475 						// triangles generated for sides facing away from the light as well as those
    476 						// facing towards the light.  It is debatable if noshadow lights should effect back
    477 						// sides, making everything "noSelfShadow", but that would make noshadow lights
    478 						// potentially slower than normal lights, which detracts from their optimization
    479 						// ability, so they currently do not.
    480 	bool				LightEffectsBackSides() const { return fogLight || ambientLight || blendLight; }
    481 
    482 						// NULL unless an image is explicitly specified in the shader with "lightFalloffShader <image>"
    483 	idImage	*			LightFalloffImage() const { return lightFalloffImage; }
    484 
    485 	//------------------------------------------------------------------
    486 
    487 						// returns the renderbump command line for this shader, or an empty string if not present
    488 	const char *		GetRenderBump() const { return renderBump; };
    489 
    490 						// set specific material flag(s)
    491 	void				SetMaterialFlag( const int flag ) const { materialFlags |= flag; }
    492 
    493 						// clear specific material flag(s)
    494 	void				ClearMaterialFlag( const int flag ) const { materialFlags &= ~flag; }
    495 
    496 						// test for existance of specific material flag(s)
    497 	bool				TestMaterialFlag( const int flag ) const { return ( materialFlags & flag ) != 0; }
    498 
    499 						// get content flags
    500 	const int			GetContentFlags() const { return contentFlags; }
    501 
    502 						// get surface flags
    503 	const int			GetSurfaceFlags() const { return surfaceFlags; }
    504 
    505 						// gets name for surface type (stone, metal, flesh, etc.)
    506 	const surfTypes_t	GetSurfaceType() const { return static_cast<surfTypes_t>( surfaceFlags & SURF_TYPE_MASK ); }
    507 
    508 						// get material description
    509 	const char *		GetDescription() const { return desc; }
    510 
    511 						// get sort order
    512 	const float			GetSort() const { return sort; }
    513 
    514 	const int			GetStereoEye() const { return stereoEye; }
    515 
    516 						// this is only used by the gui system to force sorting order
    517 						// on images referenced from tga's instead of materials. 
    518 						// this is done this way as there are 2000 tgas the guis use
    519 	void				SetSort( float s ) const { sort = s; };
    520 
    521 						// DFRM_NONE, DFRM_SPRITE, etc
    522 	deform_t			Deform() const { return deform; }
    523 
    524 						// flare size, expansion size, etc
    525 	const int			GetDeformRegister( int index ) const { return deformRegisters[index]; }
    526 
    527 						// particle system to emit from surface and table for turbulent
    528 	const idDecl		*GetDeformDecl() const { return deformDecl; }
    529 
    530 						// currently a surface can only have one unique texgen for all the stages
    531 	texgen_t			Texgen() const;
    532 
    533 						// wobble sky parms
    534 	const int *			GetTexGenRegisters() const { return texGenRegisters; }
    535 
    536 						// get cull type
    537 	const cullType_t	GetCullType() const { return cullType; }
    538 
    539 	float				GetEditorAlpha() const { return editorAlpha; }
    540 
    541 	int					GetEntityGui() const { return entityGui; }
    542 
    543 	decalInfo_t			GetDecalInfo() const { return decalInfo; }
    544 
    545 						// spectrums are used for "invisible writing" that can only be
    546 						// illuminated by a light of matching spectrum
    547 	int					Spectrum() const { return spectrum; }
    548 
    549 	float				GetPolygonOffset() const { return polygonOffset; }
    550 
    551 	float				GetSurfaceArea() const { return surfaceArea; }
    552 	void				AddToSurfaceArea( float area ) { surfaceArea += area; }
    553 
    554 	//------------------------------------------------------------------
    555 
    556 						// returns the length, in milliseconds, of the videoMap on this material,
    557 						// or zero if it doesn't have one
    558 	int					CinematicLength() const;
    559 
    560 	void				CloseCinematic() const;
    561 
    562 	void				ResetCinematicTime( int time ) const;
    563 
    564 	int					GetCinematicStartTime() const;
    565 
    566 	void				UpdateCinematic( int time ) const;
    567 
    568 	//------------------------------------------------------------------
    569 
    570 						// gets an image for the editor to use
    571 	idImage *			GetEditorImage() const;
    572 	int					GetImageWidth() const;
    573 	int					GetImageHeight() const;
    574 
    575 	void				SetGui( const char *_gui ) const;
    576 
    577 	//------------------------------------------------------------------
    578 
    579 						// returns number of registers this material contains
    580 	const int			GetNumRegisters() const { return numRegisters; }
    581 
    582 						// Regs should point to a float array large enough to hold GetNumRegisters() floats.
    583 						// FloatTime is passed in because different entities, which may be running in parallel,
    584 						// can be in different time groups.
    585 	void				EvaluateRegisters( 
    586 							float *			registers, 
    587 							const float		localShaderParms[MAX_ENTITY_SHADER_PARMS],
    588 							const float		globalShaderParms[MAX_GLOBAL_SHADER_PARMS], 
    589 							const float		floatTime, 
    590 							idSoundEmitter *soundEmitter ) const;
    591 
    592 						// if a material only uses constants (no entityParm or globalparm references), this
    593 						// will return a pointer to an internal table, and EvaluateRegisters will not need
    594 						// to be called.  If NULL is returned, EvaluateRegisters must be used.
    595 	const float *		ConstantRegisters() const				{ return constantRegisters; };
    596 
    597 	bool				SuppressInSubview() const				{ return suppressInSubview; };
    598 	bool				IsPortalSky() const						{ return portalSky; };
    599 	void				AddReference();
    600 
    601 private:
    602 	// parse the entire material
    603 	void				CommonInit();
    604 	void				ParseMaterial( idLexer &src );
    605 	bool				MatchToken( idLexer &src, const char *match );
    606 	void				ParseSort( idLexer &src );
    607 	void				ParseStereoEye( idLexer &src );
    608 	void				ParseBlend( idLexer &src, shaderStage_t *stage );
    609 	void				ParseVertexParm( idLexer &src, newShaderStage_t *newStage );
    610 	void				ParseVertexParm2( idLexer &src, newShaderStage_t *newStage );
    611 	void				ParseFragmentMap( idLexer &src, newShaderStage_t *newStage );
    612 	void				ParseStage( idLexer &src, const textureRepeat_t trpDefault = TR_REPEAT );
    613 	void				ParseDeform( idLexer &src );
    614 	void				ParseDecalInfo( idLexer &src );
    615 	bool				CheckSurfaceParm( idToken *token );
    616 	int					GetExpressionConstant( float f );
    617 	int					GetExpressionTemporary();
    618 	expOp_t	*			GetExpressionOp();
    619 	int					EmitOp( int a, int b, expOpType_t opType );
    620 	int					ParseEmitOp( idLexer &src, int a, expOpType_t opType, int priority );
    621 	int					ParseTerm( idLexer &src );
    622 	int					ParseExpressionPriority( idLexer &src, int priority );
    623 	int					ParseExpression( idLexer &src );
    624 	void				ClearStage( shaderStage_t *ss );
    625 	int					NameToSrcBlendMode( const idStr &name );
    626 	int					NameToDstBlendMode( const idStr &name );
    627 	void				MultiplyTextureMatrix( textureStage_t *ts, int registers[2][3] );	// FIXME: for some reason the const is bad for gcc and Mac
    628 	void				SortInteractionStages();
    629 	void				AddImplicitStages( const textureRepeat_t trpDefault = TR_REPEAT );
    630 	void				CheckForConstantRegisters();
    631 	void				SetFastPathImages();
    632 
    633 private:
    634 	idStr				desc;				// description
    635 	idStr				renderBump;			// renderbump command options, without the "renderbump" at the start
    636 
    637 	idImage	*			lightFalloffImage;	// only for light shaders
    638 
    639 	idImage *			fastPathBumpImage;	// if any of these are set, they all will be
    640 	idImage *			fastPathDiffuseImage;
    641 	idImage *			fastPathSpecularImage;
    642 
    643 	int					entityGui;			// draw a gui with the idUserInterface from the renderEntity_t
    644 											// non zero will draw gui, gui2, or gui3 from renderEnitty_t
    645 	mutable idUserInterface	*gui;			// non-custom guis are shared by all users of a material
    646 
    647 	bool				noFog;				// surface does not create fog interactions
    648 
    649 	int					spectrum;			// for invisible writing, used for both lights and surfaces
    650 
    651 	float				polygonOffset;
    652 
    653 	int					contentFlags;		// content flags
    654 	int					surfaceFlags;		// surface flags	
    655 	mutable int			materialFlags;		// material flags
    656 	
    657 	decalInfo_t			decalInfo;
    658 
    659 
    660 	mutable	float		sort;				// lower numbered shaders draw before higher numbered
    661 	int					stereoEye;
    662 	deform_t			deform;
    663 	int					deformRegisters[4];		// numeric parameter for deforms
    664 	const idDecl		*deformDecl;			// for surface emitted particle deforms and tables
    665 
    666 	int					texGenRegisters[MAX_TEXGEN_REGISTERS];	// for wobbleSky
    667 
    668 	materialCoverage_t	coverage;
    669 	cullType_t			cullType;			// CT_FRONT_SIDED, CT_BACK_SIDED, or CT_TWO_SIDED
    670 	bool				shouldCreateBackSides;
    671 	
    672 	bool				fogLight;
    673 	bool				blendLight;
    674 	bool				ambientLight;
    675 	bool				unsmoothedTangents;
    676 	bool				hasSubview;			// mirror, remote render, etc
    677 	bool				allowOverlays;
    678 
    679 	int					numOps;
    680 	expOp_t *			ops;				// evaluate to make expressionRegisters
    681 																										
    682 	int					numRegisters;																			//
    683 	float *				expressionRegisters;
    684 
    685 	float *				constantRegisters;	// NULL if ops ever reference globalParms or entityParms
    686 
    687 	int					numStages;
    688 	int					numAmbientStages;
    689 																										
    690 	shaderStage_t *		stages;
    691 
    692 	struct mtrParsingData_s	*pd;			// only used during parsing
    693 
    694 	float				surfaceArea;		// only for listSurfaceAreas
    695 
    696 	// we defer loading of the editor image until it is asked for, so the game doesn't load up
    697 	// all the invisible and uncompressed images.
    698 	// If editorImage is NULL, it will atempt to load editorImageName, and set editorImage to that or defaultImage
    699 	idStr				editorImageName;
    700 	mutable idImage *	editorImage;		// image used for non-shaded preview
    701 	float				editorAlpha;
    702 
    703 	bool				suppressInSubview;
    704 	bool				portalSky;
    705 	int					refCount;
    706 };
    707 
    708 typedef idList<const idMaterial *, TAG_MATERIAL> idMatList;
    709 
    710 #endif /* !__MATERIAL_H__ */