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