2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
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.
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.
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/>.
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.
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.
26 ===========================================================================
29 #ifndef __MATERIAL_H__
30 #define __MATERIAL_H__
33 ===============================================================================
37 ===============================================================================
42 class idUserInterface;
45 // moved from image.h for default parm
49 TF_DEFAULT // use the user-specified r_textureFilter
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
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)
85 DI_SCRATCH, // video, screen wipe, etc
92 // note: keep opNames[] in sync with changes
136 EXP_REG_NUM_PREDEFINED
154 TG_SCREEN, // screen aligned, for mirrorRenders and screen space temporaries
160 idCinematic * cinematic;
164 int matrix[2][3]; // we only allow a subset of the full projection matrix
166 // dynamic image variables
167 dynamicidImage_t dynamic;
169 int dynamicFrameCount;
172 // the order BUMP / DIFFUSE / SPECULAR is necessary for interactions to draw correctly on low end cards
174 SL_AMBIENT, // execute after lighting
180 // cross-blended terrain textures need to modulate the color by
181 // the vertex color to smoothly blend between two textures
186 } stageVertexColor_t;
188 static const int MAX_FRAGMENT_IMAGES = 8;
189 static const int MAX_VERTEX_PARMS = 4;
194 int vertexParms[MAX_VERTEX_PARMS][4]; // evaluated register indexes
197 int numFragmentProgramImages;
198 idImage * fragmentProgramImages[MAX_FRAGMENT_IMAGES];
200 idMegaTexture *megaTexture; // handles all the binding and parameter setting
204 int conditionRegister; // if registers[conditionRegister] == 0, skip stage
205 stageLighting_t lighting; // determines which passes interact with lights
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
216 newShaderStage_t *newStage; // vertex / fragment program based stage
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;
227 SS_SUBVIEW = -3, // mirrors, viewscreens, etc
234 SS_DECAL, // scorch marks, etc.
237 SS_MEDIUM, // normal translucent
240 SS_ALMOST_NEAREST, // gun smoke puffs
242 SS_NEAREST, // screen blood blobs
244 SS_POST_PROCESS = 100 // after a screen copy to texture
253 // these don't effect per-material storage, so they can be very large
254 const int MAX_SHADER_STAGES = 256;
256 const int MAX_TEXGEN_REGISTERS = 4;
258 const int MAX_ENTITY_SHADER_PARMS = 12;
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
271 // contents flags, NOTE: make sure to keep the defines in doom_defs.script up to date with these!
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
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
294 CONTENTS_REMOVE_UTIL = ~(CONTENTS_AREAPORTAL|CONTENTS_NOCSG)
298 const int NUM_SURFACE_BITS = 4;
299 const int MAX_SURFACE_TYPES = 1 << NUM_SURFACE_BITS;
302 SURFTYPE_NONE, // default type
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,
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
340 class idSoundEmitter;
342 class idMaterial : public idDecl {
345 virtual ~idMaterial();
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;
354 //BSM Nerve: Added for material editor
355 bool Save( const char *fileName = NULL );
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;
362 void ReloadImages( bool force ) const;
364 // returns number of stages this material contains
365 const int GetNumStages( void ) const { return numStages; }
367 // get a specific stage
368 const shaderStage_t *GetStage( const int index ) const { assert(index >= 0 && index < numStages); return &stages[index]; }
370 // get the first bump map stage, or NULL if not present.
371 // used for bumpy-specular
372 const shaderStage_t *GetBumpStage( void ) const;
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
378 bool IsDrawn( void ) const { return ( numStages > 0 || entityGui != 0 || gui != NULL ); }
380 // returns true if the material will draw any non light interaction stages
381 bool HasAmbient( void ) const { return ( numAmbientStages > 0 ); }
383 // returns true if material has a gui
384 bool HasGui( void ) const { return ( entityGui != 0 || gui != NULL ); }
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; }
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 ); }
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 ); }
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; }
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; }
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; }
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; }
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; }
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; }
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() ); }
434 // returns a idUserInterface if it has a global gui, or NULL if no gui
435 idUserInterface * GlobalGui( void ) const { return gui; }
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 ); }
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
452 bool NoFragment( void ) const { return ( surfaceFlags & SURF_NOFRAGMENT ) != 0; }
454 //------------------------------------------------------------------
455 // light shader specific functions, only called for light entities
457 // lightshader option to fill with fog from viewer instead of light from center
458 bool IsFogLight() const { return fogLight; }
460 // perform simple blending of the projection, instead of interacting with bumps and textures
461 bool IsBlendLight() const { return blendLight; }
463 // an ambient light has non-directional bump mapping and no specular
464 bool IsAmbientLight() const { return ambientLight; }
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 ) ); }
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; }
479 // NULL unless an image is explicitly specified in the shader with "lightFalloffShader <image>"
480 idImage * LightFalloffImage() const { return lightFalloffImage; }
482 //------------------------------------------------------------------
484 // returns the renderbump command line for this shader, or an empty string if not present
485 const char * GetRenderBump() const { return renderBump; };
487 // set specific material flag(s)
488 void SetMaterialFlag( const int flag ) const { materialFlags |= flag; }
490 // clear specific material flag(s)
491 void ClearMaterialFlag( const int flag ) const { materialFlags &= ~flag; }
493 // test for existance of specific material flag(s)
494 bool TestMaterialFlag( const int flag ) const { return ( materialFlags & flag ) != 0; }
497 const int GetContentFlags( void ) const { return contentFlags; }
500 const int GetSurfaceFlags( void ) const { return surfaceFlags; }
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 ); }
505 // get material description
506 const char * GetDescription( void ) const { return desc; }
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; };
515 // DFRM_NONE, DFRM_SPRITE, etc
516 deform_t Deform( void ) const { return deform; }
518 // flare size, expansion size, etc
519 const int GetDeformRegister( int index ) const { return deformRegisters[index]; }
521 // particle system to emit from surface and table for turbulent
522 const idDecl *GetDeformDecl( void ) const { return deformDecl; }
524 // currently a surface can only have one unique texgen for all the stages
525 texgen_t Texgen() const;
528 const int * GetTexGenRegisters( void ) const { return texGenRegisters; }
531 const cullType_t GetCullType( void ) const { return cullType; }
533 float GetEditorAlpha( void ) const { return editorAlpha; }
535 int GetEntityGui( void ) const { return entityGui; }
537 decalInfo_t GetDecalInfo( void ) const { return decalInfo; }
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; }
543 float GetPolygonOffset( void ) const { return polygonOffset; }
545 float GetSurfaceArea( void ) const { return surfaceArea; }
546 void AddToSurfaceArea( float area ) { surfaceArea += area; }
548 //------------------------------------------------------------------
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;
554 void CloseCinematic( void ) const;
556 void ResetCinematicTime( int time ) const;
558 void UpdateCinematic( int time ) const;
560 //------------------------------------------------------------------
562 // gets an image for the editor to use
563 idImage * GetEditorImage( void ) const;
564 int GetImageWidth( void ) const;
565 int GetImageHeight( void ) const;
567 void SetGui( const char *_gui ) const;
569 // just for resource tracking
570 void SetImageClassifications( int tag ) const;
572 //------------------------------------------------------------------
574 // returns number of registers this material contains
575 const int GetNumRegisters() const { return numRegisters; }
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;
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;
586 bool SuppressInSubview() const { return suppressInSubview; };
587 bool IsPortalSky() const { return portalSky; };
591 // parse the entire material
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();
620 idStr desc; // description
621 idStr renderBump; // renderbump command options, without the "renderbump" at the start
623 idImage * lightFalloffImage;
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
629 bool noFog; // surface does not create fog interactions
631 int spectrum; // for invisible writing, used for both lights and surfaces
635 int contentFlags; // content flags
636 int surfaceFlags; // surface flags
637 mutable int materialFlags; // material flags
639 decalInfo_t decalInfo;
642 mutable float sort; // lower numbered shaders draw before higher numbered
644 int deformRegisters[4]; // numeric parameter for deforms
645 const idDecl *deformDecl; // for surface emitted particle deforms and tables
647 int texGenRegisters[MAX_TEXGEN_REGISTERS]; // for wobbleSky
649 materialCoverage_t coverage;
650 cullType_t cullType; // CT_FRONT_SIDED, CT_BACK_SIDED, or CT_TWO_SIDED
651 bool shouldCreateBackSides;
656 bool unsmoothedTangents;
657 bool hasSubview; // mirror, remote render, etc
661 expOp_t * ops; // evaluate to make expressionRegisters
664 float * expressionRegisters;
666 float * constantRegisters; // NULL if ops ever reference globalParms or entityParms
669 int numAmbientStages;
671 shaderStage_t * stages;
673 struct mtrParsingData_s *pd; // only used during parsing
675 float surfaceArea; // only for listSurfaceAreas
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
684 bool suppressInSubview;
689 typedef idList<const idMaterial *> idMatList;
691 #endif /* !__MATERIAL_H__ */