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