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