Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

tr_shader.c File Reference

#include "tr_local.h"

Include dependency graph for tr_shader.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  collapse_t
struct  infoParm_t

Defines

#define FILE_HASH_SIZE   1024
#define MAX_SHADER_FILES   4096
#define MAX_SHADERTEXT_HASH   2048

Functions

qboolean CollapseMultitexture (void)
void ComputeStageIteratorFunc (void)
void CreateExternalShaders (void)
void CreateInternalShaders (void)
char * FindShaderInShaderText (const char *shadername)
shader_tFinishShader (void)
void FixRenderCommandList (int newShader)
long generateHashValue (const char *fname, const int size)
shader_tGeneratePermanentShader (void)
unsigned NameToAFunc (const char *funcname)
int NameToDstBlendMode (const char *name)
genFunc_t NameToGenFunc (const char *funcname)
int NameToSrcBlendMode (const char *name)
void ParseDeform (char **text)
qboolean ParseShader (char **text)
void ParseSkyParms (char **text)
void ParseSort (char **text)
qboolean ParseStage (shaderStage_t *stage, char **text)
void ParseSurfaceParm (char **text)
void ParseTexMod (char *_text, shaderStage_t *stage)
qboolean ParseVector (char **text, int count, float *v)
void ParseWaveForm (char **text, waveForm_t *wave)
shader_tR_FindShader (const char *name, int lightmapIndex, qboolean mipRawImage)
shader_tR_FindShaderByName (const char *name)
shader_tR_GetShaderByHandle (qhandle_t hShader)
void R_InitShaders (void)
void R_RemapShader (const char *shaderName, const char *newShaderName, const char *timeOffset)
void R_ShaderList_f (void)
qhandle_t RE_RegisterShader (const char *name)
qhandle_t RE_RegisterShaderFromImage (const char *name, int lightmapIndex, image_t *image, qboolean mipRawImage)
qhandle_t RE_RegisterShaderLightMap (const char *name, int lightmapIndex)
qhandle_t RE_RegisterShaderNoMip (const char *name)
void ScanAndLoadShaderFiles (void)
void SortNewShader (void)
void VertexLightingCollapse (void)

Variables

collapse_t collapse []
qboolean deferLoad
shader_thashTable [FILE_HASH_SIZE]
infoParm_t infoParms []
char * s_shaderText
shader_t shader
char ** shaderTextHashTable [MAX_SHADERTEXT_HASH]
shaderStage_t stages [MAX_SHADER_STAGES]
texModInfo_t texMods [MAX_SHADER_STAGES][TR_MAX_TEXMODS]


Define Documentation

#define FILE_HASH_SIZE   1024
 

Definition at line 35 of file tr_shader.c.

#define MAX_SHADER_FILES   4096
 

Definition at line 2844 of file tr_shader.c.

#define MAX_SHADERTEXT_HASH   2048
 

Definition at line 38 of file tr_shader.c.

Referenced by FindShaderInShaderText(), and ScanAndLoadShaderFiles().


Function Documentation

qboolean CollapseMultitexture void   )  [static]
 

Definition at line 1745 of file tr_shader.c.

References shaderStage_t::active, shaderStage_t::alphaGen, collapse_t::blendA, collapse_t::blendB, shaderStage_t::bundle, collapse, Com_Memset(), glconfig_t::driverType, glConfig, GLS_DSTBLEND_BITS, GLS_SRCBLEND_BITS, i, textureBundle_t::image, textureBundle_t::isLightmap, MAX_SHADER_STAGES, memcmp(), memmove(), collapse_t::multitextureBlend, shader_s::multitextureEnv, collapse_t::multitextureEnv, qboolean, shaderStage_t::rgbGen, shader, stages, shaderStage_t::stateBits, glconfig_t::textureEnvAddAvailable, and image_s::TMU.

Referenced by FinishShader().

01745                                              {
01746     int abits, bbits;
01747     int i;
01748     textureBundle_t tmpBundle;
01749 
01750     if ( !qglActiveTextureARB ) {
01751         return qfalse;
01752     }
01753 
01754     // make sure both stages are active
01755     if ( !stages[0].active || !stages[1].active ) {
01756         return qfalse;
01757     }
01758 
01759     // on voodoo2, don't combine different tmus
01760     if ( glConfig.driverType == GLDRV_VOODOO ) {
01761         if ( stages[0].bundle[0].image[0]->TMU ==
01762              stages[1].bundle[0].image[0]->TMU ) {
01763             return qfalse;
01764         }
01765     }
01766 
01767     abits = stages[0].stateBits;
01768     bbits = stages[1].stateBits;
01769 
01770     // make sure that both stages have identical state other than blend modes
01771     if ( ( abits & ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS | GLS_DEPTHMASK_TRUE ) ) !=
01772         ( bbits & ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS | GLS_DEPTHMASK_TRUE ) ) ) {
01773         return qfalse;
01774     }
01775 
01776     abits &= ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
01777     bbits &= ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
01778 
01779     // search for a valid multitexture blend function
01780     for ( i = 0; collapse[i].blendA != -1 ; i++ ) {
01781         if ( abits == collapse[i].blendA
01782             && bbits == collapse[i].blendB ) {
01783             break;
01784         }
01785     }
01786 
01787     // nothing found
01788     if ( collapse[i].blendA == -1 ) {
01789         return qfalse;
01790     }
01791 
01792     // GL_ADD is a separate extension
01793     if ( collapse[i].multitextureEnv == GL_ADD && !glConfig.textureEnvAddAvailable ) {
01794         return qfalse;
01795     }
01796 
01797     // make sure waveforms have identical parameters
01798     if ( ( stages[0].rgbGen != stages[1].rgbGen ) ||
01799         ( stages[0].alphaGen != stages[1].alphaGen ) )  {
01800         return qfalse;
01801     }
01802 
01803     // an add collapse can only have identity colors
01804     if ( collapse[i].multitextureEnv == GL_ADD && stages[0].rgbGen != CGEN_IDENTITY ) {
01805         return qfalse;
01806     }
01807 
01808     if ( stages[0].rgbGen == CGEN_WAVEFORM )
01809     {
01810         if ( memcmp( &stages[0].rgbWave,
01811                      &stages[1].rgbWave,
01812                      sizeof( stages[0].rgbWave ) ) )
01813         {
01814             return qfalse;
01815         }
01816     }
01817     if ( stages[0].alphaGen == CGEN_WAVEFORM )
01818     {
01819         if ( memcmp( &stages[0].alphaWave,
01820                      &stages[1].alphaWave,
01821                      sizeof( stages[0].alphaWave ) ) )
01822         {
01823             return qfalse;
01824         }
01825     }
01826 
01827 
01828     // make sure that lightmaps are in bundle 1 for 3dfx
01829     if ( stages[0].bundle[0].isLightmap )
01830     {
01831         tmpBundle = stages[0].bundle[0];
01832         stages[0].bundle[0] = stages[1].bundle[0];
01833         stages[0].bundle[1] = tmpBundle;
01834     }
01835     else
01836     {
01837         stages[0].bundle[1] = stages[1].bundle[0];
01838     }
01839 
01840     // set the new blend state bits
01841     shader.multitextureEnv = collapse[i].multitextureEnv;
01842     stages[0].stateBits &= ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
01843     stages[0].stateBits |= collapse[i].multitextureBlend;
01844 
01845     //
01846     // move down subsequent shaders
01847     //
01848     memmove( &stages[1], &stages[2], sizeof( stages[0] ) * ( MAX_SHADER_STAGES - 2 ) );
01849     Com_Memset( &stages[MAX_SHADER_STAGES-1], 0, sizeof( stages[0] ) );
01850 
01851     return qtrue;
01852 }

Here is the call graph for this function:

void ComputeStageIteratorFunc void   )  [static]
 

Definition at line 1624 of file tr_shader.c.

References shaderStage_t::alphaGen, shaderStage_t::bundle, cvar_s::integer, shader_s::isSky, shader_s::multitextureEnv, shader_s::numDeforms, shader_s::numUnfoggedPasses, shader_s::optimalStageIteratorFunc, shader_s::polygonOffset, r_ignoreFastPath, shaderStage_t::rgbGen, shader, stages, textureBundle_t::tcGen, and TCGEN_TEXTURE.

Referenced by FinishShader().

01625 {
01626     shader.optimalStageIteratorFunc = RB_StageIteratorGeneric;
01627 
01628     //
01629     // see if this should go into the sky path
01630     //
01631     if ( shader.isSky )
01632     {
01633         shader.optimalStageIteratorFunc = RB_StageIteratorSky;
01634         goto done;
01635     }
01636 
01637     if ( r_ignoreFastPath->integer )
01638     {
01639         return;
01640     }
01641 
01642     //
01643     // see if this can go into the vertex lit fast path
01644     //
01645     if ( shader.numUnfoggedPasses == 1 )
01646     {
01647         if ( stages[0].rgbGen == CGEN_LIGHTING_DIFFUSE )
01648         {
01649             if ( stages[0].alphaGen == AGEN_IDENTITY )
01650             {
01651                 if ( stages[0].bundle[0].tcGen == TCGEN_TEXTURE )
01652                 {
01653                     if ( !shader.polygonOffset )
01654                     {
01655                         if ( !shader.multitextureEnv )
01656                         {
01657                             if ( !shader.numDeforms )
01658                             {
01659                                 shader.optimalStageIteratorFunc = RB_StageIteratorVertexLitTexture;
01660                                 goto done;
01661                             }
01662                         }
01663                     }
01664                 }
01665             }
01666         }
01667     }
01668 
01669     //
01670     // see if this can go into an optimized LM, multitextured path
01671     //
01672     if ( shader.numUnfoggedPasses == 1 )
01673     {
01674         if ( ( stages[0].rgbGen == CGEN_IDENTITY ) && ( stages[0].alphaGen == AGEN_IDENTITY ) )
01675         {
01676             if ( stages[0].bundle[0].tcGen == TCGEN_TEXTURE && 
01677                 stages[0].bundle[1].tcGen == TCGEN_LIGHTMAP )
01678             {
01679                 if ( !shader.polygonOffset )
01680                 {
01681                     if ( !shader.numDeforms )
01682                     {
01683                         if ( shader.multitextureEnv )
01684                         {
01685                             shader.optimalStageIteratorFunc = RB_StageIteratorLightmappedMultitexture;
01686                             goto done;
01687                         }
01688                     }
01689                 }
01690             }
01691         }
01692     }
01693 
01694 done:
01695     return;
01696 }

void CreateExternalShaders void   )  [static]
 

Definition at line 2990 of file tr_shader.c.

References trGlobals_t::flareShader, LIGHTMAP_NONE, trGlobals_t::projectionShadowShader, qtrue, R_FindShader(), trGlobals_t::sunShader, and tr.

Referenced by R_InitShaders().

02990                                           {
02991     tr.projectionShadowShader = R_FindShader( "projectionShadow", LIGHTMAP_NONE, qtrue );
02992     tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue );
02993     tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue );
02994 }

Here is the call graph for this function:

void CreateInternalShaders void   )  [static]
 

Definition at line 2969 of file tr_shader.c.

References shaderStage_t::active, shaderStage_t::bundle, Com_Memset(), trGlobals_t::defaultImage, trGlobals_t::defaultShader, FinishShader(), textureBundle_t::image, shader_s::lightmapIndex, shader_s::name, trGlobals_t::numShaders, Q_strncpyz(), shader, trGlobals_t::shadowShader, shader_s::sort, stages, shaderStage_t::stateBits, and tr.

Referenced by R_InitShaders().

02969                                           {
02970     tr.numShaders = 0;
02971 
02972     // init the default shader
02973     Com_Memset( &shader, 0, sizeof( shader ) );
02974     Com_Memset( &stages, 0, sizeof( stages ) );
02975 
02976     Q_strncpyz( shader.name, "<default>", sizeof( shader.name ) );
02977 
02978     shader.lightmapIndex = LIGHTMAP_NONE;
02979     stages[0].bundle[0].image[0] = tr.defaultImage;
02980     stages[0].active = qtrue;
02981     stages[0].stateBits = GLS_DEFAULT;
02982     tr.defaultShader = FinishShader();
02983 
02984     // shadow shader is just a marker
02985     Q_strncpyz( shader.name, "<stencil shadow>", sizeof( shader.name ) );
02986     shader.sort = SS_STENCIL_SHADOW;
02987     tr.shadowShader = FinishShader();
02988 }

Here is the call graph for this function:

char* FindShaderInShaderText const char *  shadername  )  [static]
 

Definition at line 2295 of file tr_shader.c.

References COM_ParseExt(), generateHashValue(), i, MAX_SHADERTEXT_HASH, p, Q_stricmp(), qtrue, shaderTextHashTable, SkipBracedSection(), and token.

Referenced by R_FindShader().

02295                                                               {
02296 
02297     char *token, *p;
02298 
02299     int i, hash;
02300 
02301     hash = generateHashValue(shadername, MAX_SHADERTEXT_HASH);
02302 
02303     for (i = 0; shaderTextHashTable[hash][i]; i++) {
02304         p = shaderTextHashTable[hash][i];
02305         token = COM_ParseExt(&p, qtrue);
02306         if ( !Q_stricmp( token, shadername ) ) {
02307             return p;
02308         }
02309     }
02310 
02311     p = s_shaderText;
02312 
02313     if ( !p ) {
02314         return NULL;
02315     }
02316 
02317     // look for label
02318     while ( 1 ) {
02319         token = COM_ParseExt( &p, qtrue );
02320         if ( token[0] == 0 ) {
02321             break;
02322         }
02323 
02324         if ( !Q_stricmp( token, shadername ) ) {
02325             return p;
02326         }
02327         else {
02328             // skip the definition
02329             SkipBracedSection( &p );
02330         }
02331     }
02332 
02333     return NULL;
02334 }

Here is the call graph for this function:

shader_t* FinishShader void   )  [static]
 

Definition at line 2116 of file tr_shader.c.

References shaderStage_t::active, shaderStage_t::adjustColorsForFog, shaderStage_t::bundle, CollapseMultitexture(), Com_Memset(), ComputeStageIteratorFunc(), GeneratePermanentShader(), glConfig, GLS_SRCBLEND_BITS, glconfig_t::hardwareType, textureBundle_t::image, cvar_s::integer, shaderStage_t::isDetail, textureBundle_t::isLightmap, shader_s::isSky, shader_s::lightmapIndex, MAX_SHADER_STAGES, memmove(), shader_s::name, shader_s::numUnfoggedPasses, shader_s::polygonOffset, PRINT_DEVELOPER, PRINT_WARNING, qboolean, r_detailTextures, r_uiFullScreen, r_vertexLight, ri, shader, shader_t, shader_s::sort, stages, shaderStage_t::stateBits, textureBundle_t::tcGen, and VertexLightingCollapse().

Referenced by CreateInternalShaders(), R_FindShader(), and RE_RegisterShaderFromImage().

02116                                       {
02117     int stage;
02118     qboolean        hasLightmapStage;
02119     qboolean        vertexLightmap;
02120 
02121     hasLightmapStage = qfalse;
02122     vertexLightmap = qfalse;
02123 
02124     //
02125     // set sky stuff appropriate
02126     //
02127     if ( shader.isSky ) {
02128         shader.sort = SS_ENVIRONMENT;
02129     }
02130 
02131     //
02132     // set polygon offset
02133     //
02134     if ( shader.polygonOffset && !shader.sort ) {
02135         shader.sort = SS_DECAL;
02136     }
02137 
02138     //
02139     // set appropriate stage information
02140     //
02141     for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) {
02142         shaderStage_t *pStage = &stages[stage];
02143 
02144         if ( !pStage->active ) {
02145             break;
02146         }
02147 
02148     // check for a missing texture
02149         if ( !pStage->bundle[0].image[0] ) {
02150             ri.Printf( PRINT_WARNING, "Shader %s has a stage with no image\n", shader.name );
02151             pStage->active = qfalse;
02152             continue;
02153         }
02154 
02155         //
02156         // ditch this stage if it's detail and detail textures are disabled
02157         //
02158         if ( pStage->isDetail && !r_detailTextures->integer ) {
02159             if ( stage < ( MAX_SHADER_STAGES - 1 ) ) {
02160                 memmove( pStage, pStage + 1, sizeof( *pStage ) * ( MAX_SHADER_STAGES - stage - 1 ) );
02161                 Com_Memset(  pStage + 1, 0, sizeof( *pStage ) );
02162             }
02163             continue;
02164         }
02165 
02166         //
02167         // default texture coordinate generation
02168         //
02169         if ( pStage->bundle[0].isLightmap ) {
02170             if ( pStage->bundle[0].tcGen == TCGEN_BAD ) {
02171                 pStage->bundle[0].tcGen = TCGEN_LIGHTMAP;
02172             }
02173             hasLightmapStage = qtrue;
02174         } else {
02175             if ( pStage->bundle[0].tcGen == TCGEN_BAD ) {
02176                 pStage->bundle[0].tcGen = TCGEN_TEXTURE;
02177             }
02178         }
02179 
02180 
02181     // not a true lightmap but we want to leave existing 
02182     // behaviour in place and not print out a warning
02183     //if (pStage->rgbGen == CGEN_VERTEX) {
02184     //  vertexLightmap = qtrue;
02185     //}
02186 
02187 
02188 
02189         //
02190         // determine sort order and fog color adjustment
02191         //
02192         if ( ( pStage->stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) &&
02193              ( stages[0].stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) ) {
02194             int blendSrcBits = pStage->stateBits & GLS_SRCBLEND_BITS;
02195             int blendDstBits = pStage->stateBits & GLS_DSTBLEND_BITS;
02196 
02197             // fog color adjustment only works for blend modes that have a contribution
02198             // that aproaches 0 as the modulate values aproach 0 --
02199             // GL_ONE, GL_ONE
02200             // GL_ZERO, GL_ONE_MINUS_SRC_COLOR
02201             // GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
02202 
02203             // modulate, additive
02204             if ( ( ( blendSrcBits == GLS_SRCBLEND_ONE ) && ( blendDstBits == GLS_DSTBLEND_ONE ) ) ||
02205                 ( ( blendSrcBits == GLS_SRCBLEND_ZERO ) && ( blendDstBits == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR ) ) ) {
02206                 pStage->adjustColorsForFog = ACFF_MODULATE_RGB;
02207             }
02208             // strict blend
02209             else if ( ( blendSrcBits == GLS_SRCBLEND_SRC_ALPHA ) && ( blendDstBits == GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ) )
02210             {
02211                 pStage->adjustColorsForFog = ACFF_MODULATE_ALPHA;
02212             }
02213             // premultiplied alpha
02214             else if ( ( blendSrcBits == GLS_SRCBLEND_ONE ) && ( blendDstBits == GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ) )
02215             {
02216                 pStage->adjustColorsForFog = ACFF_MODULATE_RGBA;
02217             } else {
02218                 // we can't adjust this one correctly, so it won't be exactly correct in fog
02219             }
02220 
02221             // don't screw with sort order if this is a portal or environment
02222             if ( !shader.sort ) {
02223                 // see through item, like a grill or grate
02224                 if ( pStage->stateBits & GLS_DEPTHMASK_TRUE ) {
02225                     shader.sort = SS_SEE_THROUGH;
02226                 } else {
02227                     shader.sort = SS_BLEND0;
02228                 }
02229             }
02230         }
02231     }
02232 
02233     // there are times when you will need to manually apply a sort to
02234     // opaque alpha tested shaders that have later blend passes
02235     if ( !shader.sort ) {
02236         shader.sort = SS_OPAQUE;
02237     }
02238 
02239     //
02240     // if we are in r_vertexLight mode, never use a lightmap texture
02241     //
02242     if ( stage > 1 && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) ) {
02243         VertexLightingCollapse();
02244         stage = 1;
02245         hasLightmapStage = qfalse;
02246     }
02247 
02248     //
02249     // look for multitexture potential
02250     //
02251     if ( stage > 1 && CollapseMultitexture() ) {
02252         stage--;
02253     }
02254 
02255     if ( shader.lightmapIndex >= 0 && !hasLightmapStage ) {
02256         if (vertexLightmap) {
02257             ri.Printf( PRINT_DEVELOPER, "WARNING: shader '%s' has VERTEX forced lightmap!\n", shader.name );
02258         } else {
02259             ri.Printf( PRINT_DEVELOPER, "WARNING: shader '%s' has lightmap but no lightmap stage!\n", shader.name );
02260             shader.lightmapIndex = LIGHTMAP_NONE;
02261         }
02262     }
02263 
02264 
02265     //
02266     // compute number of passes
02267     //
02268     shader.numUnfoggedPasses = stage;
02269 
02270     // fogonly shaders don't have any normal passes
02271     if ( stage == 0 ) {
02272         shader.sort = SS_FOG;
02273     }
02274 
02275     // determine which stage iterator function is appropriate
02276     ComputeStageIteratorFunc();
02277 
02278     return GeneratePermanentShader();
02279 }

Here is the call graph for this function:

void FixRenderCommandList int  newShader  )  [static]
 

Definition at line 1865 of file tr_shader.c.

References backEndData, renderCommandList_t::cmds, backEndData_t::commands, drawSurf_t, drawSurfsCommand_t::drawSurfs, i, MAX_SHADERS, drawSurfsCommand_t::numDrawSurfs, R_DecomposeSort(), RC_DRAW_BUFFER, RC_DRAW_SURFS, RC_END_OF_LIST, RC_SET_COLOR, RC_STRETCH_PIC, RC_SWAP_BUFFERS, shader, shader_t, trGlobals_t::smpFrame, drawSurf_s::sort, and tr.

Referenced by SortNewShader().

01865                                                   {
01866     renderCommandList_t *cmdList = &backEndData[tr.smpFrame]->commands;
01867 
01868     if( cmdList ) {
01869         const void *curCmd = cmdList->cmds;
01870 
01871         while ( 1 ) {
01872             switch ( *(const int *)curCmd ) {
01873             case RC_SET_COLOR:
01874                 {
01875                 const setColorCommand_t *sc_cmd = (const setColorCommand_t *)curCmd;
01876                 curCmd = (const void *)(sc_cmd + 1);
01877                 break;
01878                 }
01879             case RC_STRETCH_PIC:
01880                 {
01881                 const stretchPicCommand_t *sp_cmd = (const stretchPicCommand_t *)curCmd;
01882                 curCmd = (const void *)(sp_cmd + 1);
01883                 break;
01884                 }
01885             case RC_DRAW_SURFS:
01886                 {
01887                 int i;
01888                 drawSurf_t  *drawSurf;
01889                 shader_t    *shader;
01890                 int         fogNum;
01891                 int         entityNum;
01892                 int         dlightMap;
01893                 int         sortedIndex;
01894                 const drawSurfsCommand_t *ds_cmd =  (const drawSurfsCommand_t *)curCmd;
01895 
01896                 for( i = 0, drawSurf = ds_cmd->drawSurfs; i < ds_cmd->numDrawSurfs; i++, drawSurf++ ) {
01897                     R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlightMap );
01898                     sortedIndex = (( drawSurf->sort >> QSORT_SHADERNUM_SHIFT ) & (MAX_SHADERS-1));
01899                     if( sortedIndex >= newShader ) {
01900                         sortedIndex++;
01901                         drawSurf->sort = (sortedIndex << QSORT_SHADERNUM_SHIFT) | entityNum | ( fogNum << QSORT_FOGNUM_SHIFT ) | (int)dlightMap;
01902                     }
01903                 }
01904                 curCmd = (const void *)(ds_cmd + 1);
01905                 break;
01906                 }
01907             case RC_DRAW_BUFFER:
01908                 {
01909                 const drawBufferCommand_t *db_cmd = (const drawBufferCommand_t *)curCmd;
01910                 curCmd = (const void *)(db_cmd + 1);
01911                 break;
01912                 }
01913             case RC_SWAP_BUFFERS:
01914                 {
01915                 const swapBuffersCommand_t *sb_cmd = (const swapBuffersCommand_t *)curCmd;
01916                 curCmd = (const void *)(sb_cmd + 1);
01917                 break;
01918                 }
01919             case RC_END_OF_LIST:
01920             default:
01921                 return;
01922             }
01923         }
01924     }
01925 }

Here is the call graph for this function:

long generateHashValue const char *  fname,
const int  size
[static]
 

Definition at line 46 of file tr_shader.c.

References i, and tolower().

Referenced by Cvar_FindVar(), Cvar_Get(), FindShaderInShaderText(), GeneratePermanentShader(), R_CreateImage(), R_FindImageFile(), R_FindShader(), R_FindShaderByName(), R_RemapShader(), RE_RegisterShaderFromImage(), and ScanAndLoadShaderFiles().

00046                                                                    {
00047     int     i;
00048     long    hash;
00049     char    letter;
00050 
00051     hash = 0;
00052     i = 0;
00053     while (fname[i] != '\0') {
00054         letter = tolower(fname[i]);
00055         if (letter =='.') break;                // don't include extension
00056         if (letter =='\\') letter = '/';        // damn path names
00057         if (letter == PATH_SEP) letter = '/';       // damn path names
00058         hash+=(long)(letter)*(i+119);
00059         i++;
00060     }
00061     hash = (hash ^ (hash >> 10) ^ (hash >> 20));
00062     hash &= (size-1);
00063     return hash;
00064 }

Here is the call graph for this function:

shader_t* GeneratePermanentShader void   )  [static]
 

Definition at line 1968 of file tr_shader.c.

References shaderStage_t::active, b, shaderStage_t::bundle, Com_Memcpy(), shader_s::contentFlags, trGlobals_t::defaultShader, FILE_HASH_SIZE, shader_s::fogPass, generateHashValue(), h_low, hashTable, refimport_t::Hunk_Alloc, i, shader_s::index, shader_s::name, shader_s::next, trGlobals_t::numShaders, textureBundle_t::numTexMods, shader_s::numUnfoggedPasses, PRINT_WARNING, ri, shader, shader_t, trGlobals_t::shaders, shader_s::sort, shader_s::sortedIndex, trGlobals_t::sortedShaders, SortNewShader(), shader_s::stages, stages, textureBundle_t::texMods, and tr.

Referenced by FinishShader().

01968                                                  {
01969     shader_t    *newShader;
01970     int         i, b;
01971     int         size, hash;
01972 
01973     if ( tr.numShaders == MAX_SHADERS ) {
01974         ri.Printf( PRINT_WARNING, "WARNING: GeneratePermanentShader - MAX_SHADERS hit\n");
01975         return tr.defaultShader;
01976     }
01977 
01978     newShader = ri.Hunk_Alloc( sizeof( shader_t ), h_low );
01979 
01980     *newShader = shader;
01981 
01982     if ( shader.sort <= SS_OPAQUE ) {
01983         newShader->fogPass = FP_EQUAL;
01984     } else if ( shader.contentFlags & CONTENTS_FOG ) {
01985         newShader->fogPass = FP_LE;
01986     }
01987 
01988     tr.shaders[ tr.numShaders ] = newShader;
01989     newShader->index = tr.numShaders;
01990     
01991     tr.sortedShaders[ tr.numShaders ] = newShader;
01992     newShader->sortedIndex = tr.numShaders;
01993 
01994     tr.numShaders++;
01995 
01996     for ( i = 0 ; i < newShader->numUnfoggedPasses ; i++ ) {
01997         if ( !stages[i].active ) {
01998             break;
01999         }
02000         newShader->stages[i] = ri.Hunk_Alloc( sizeof( stages[i] ), h_low );
02001         *newShader->stages[i] = stages[i];
02002 
02003         for ( b = 0 ; b < NUM_TEXTURE_BUNDLES ; b++ ) {
02004             size = newShader->stages[i]->bundle[b].numTexMods * sizeof( texModInfo_t );
02005             newShader->stages[i]->bundle[b].texMods = ri.Hunk_Alloc( size, h_low );
02006             Com_Memcpy( newShader->stages[i]->bundle[b].texMods, stages[i].bundle[b].texMods, size );
02007         }
02008     }
02009 
02010     SortNewShader();
02011 
02012     hash = generateHashValue(newShader->name, FILE_HASH_SIZE);
02013     newShader->next = hashTable[hash];
02014     hashTable[hash] = newShader;
02015 
02016     return newShader;
02017 }

Here is the call graph for this function:

unsigned NameToAFunc const char *  funcname  )  [static]
 

Definition at line 151 of file tr_shader.c.

References funcname(), shader_s::name, PRINT_WARNING, Q_stricmp(), ri, and shader.

Referenced by ParseStage().

00152 {   
00153     if ( !Q_stricmp( funcname, "GT0" ) )
00154     {
00155         return GLS_ATEST_GT_0;
00156     }
00157     else if ( !Q_stricmp( funcname, "LT128" ) )
00158     {
00159         return GLS_ATEST_LT_80;
00160     }
00161     else if ( !Q_stricmp( funcname, "GE128" ) )
00162     {
00163         return GLS_ATEST_GE_80;
00164     }
00165 
00166     ri.Printf( PRINT_WARNING, "WARNING: invalid alphaFunc name '%s' in shader '%s'\n", funcname, shader.name );
00167     return 0;
00168 }

Here is the call graph for this function:

int NameToDstBlendMode const char *  name  )  [static]
 

Definition at line 224 of file tr_shader.c.

References shader_s::name, name, PRINT_WARNING, Q_stricmp(), ri, and shader.

Referenced by ParseStage().

00225 {
00226     if ( !Q_stricmp( name, "GL_ONE" ) )
00227     {
00228         return GLS_DSTBLEND_ONE;
00229     }
00230     else if ( !Q_stricmp( name, "GL_ZERO" ) )
00231     {
00232         return GLS_DSTBLEND_ZERO;
00233     }
00234     else if ( !Q_stricmp( name, "GL_SRC_ALPHA" ) )
00235     {
00236         return GLS_DSTBLEND_SRC_ALPHA;
00237     }
00238     else if ( !Q_stricmp( name, "GL_ONE_MINUS_SRC_ALPHA" ) )
00239     {
00240         return GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
00241     }
00242     else if ( !Q_stricmp( name, "GL_DST_ALPHA" ) )
00243     {
00244         return GLS_DSTBLEND_DST_ALPHA;
00245     }
00246     else if ( !Q_stricmp( name, "GL_ONE_MINUS_DST_ALPHA" ) )
00247     {
00248         return GLS_DSTBLEND_ONE_MINUS_DST_ALPHA;
00249     }
00250     else if ( !Q_stricmp( name, "GL_SRC_COLOR" ) )
00251     {
00252         return GLS_DSTBLEND_SRC_COLOR;
00253     }
00254     else if ( !Q_stricmp( name, "GL_ONE_MINUS_SRC_COLOR" ) )
00255     {
00256         return GLS_DSTBLEND_ONE_MINUS_SRC_COLOR;
00257     }
00258 
00259     ri.Printf( PRINT_WARNING, "WARNING: unknown blend mode '%s' in shader '%s', substituting GL_ONE\n", name, shader.name );
00260     return GLS_DSTBLEND_ONE;
00261 }

Here is the call graph for this function:

genFunc_t NameToGenFunc const char *  funcname  )  [static]
 

Definition at line 268 of file tr_shader.c.

References funcname(), genFunc_t, shader_s::name, PRINT_WARNING, Q_stricmp(), ri, and shader.

Referenced by ParseTexMod(), and ParseWaveForm().

00269 {
00270     if ( !Q_stricmp( funcname, "sin" ) )
00271     {
00272         return GF_SIN;
00273     }
00274     else if ( !Q_stricmp( funcname, "square" ) )
00275     {
00276         return GF_SQUARE;
00277     }
00278     else if ( !Q_stricmp( funcname, "triangle" ) )
00279     {
00280         return GF_TRIANGLE;
00281     }
00282     else if ( !Q_stricmp( funcname, "sawtooth" ) )
00283     {
00284         return GF_SAWTOOTH;
00285     }
00286     else if ( !Q_stricmp( funcname, "inversesawtooth" ) )
00287     {
00288         return GF_INVERSE_SAWTOOTH;
00289     }
00290     else if ( !Q_stricmp( funcname, "noise" ) )
00291     {
00292         return GF_NOISE;
00293     }
00294 
00295     ri.Printf( PRINT_WARNING, "WARNING: invalid genfunc name '%s' in shader '%s'\n", funcname, shader.name );
00296     return GF_SIN;
00297 }

Here is the call graph for this function:

int NameToSrcBlendMode const char *  name  )  [static]
 

Definition at line 176 of file tr_shader.c.

References shader_s::name, name, PRINT_WARNING, Q_stricmp(), ri, and shader.

Referenced by ParseStage().

00177 {
00178     if ( !Q_stricmp( name, "GL_ONE" ) )
00179     {
00180         return GLS_SRCBLEND_ONE;
00181     }
00182     else if ( !Q_stricmp( name, "GL_ZERO" ) )
00183     {
00184         return GLS_SRCBLEND_ZERO;
00185     }
00186     else if ( !Q_stricmp( name, "GL_DST_COLOR" ) )
00187     {
00188         return GLS_SRCBLEND_DST_COLOR;
00189     }
00190     else if ( !Q_stricmp( name, "GL_ONE_MINUS_DST_COLOR" ) )
00191     {
00192         return GLS_SRCBLEND_ONE_MINUS_DST_COLOR;
00193     }
00194     else if ( !Q_stricmp( name, "GL_SRC_ALPHA" ) )
00195     {
00196         return GLS_SRCBLEND_SRC_ALPHA;
00197     }
00198     else if ( !Q_stricmp( name, "GL_ONE_MINUS_SRC_ALPHA" ) )
00199     {
00200         return GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA;
00201     }
00202     else if ( !Q_stricmp( name, "GL_DST_ALPHA" ) )
00203     {
00204         return GLS_SRCBLEND_DST_ALPHA;
00205     }
00206     else if ( !Q_stricmp( name, "GL_ONE_MINUS_DST_ALPHA" ) )
00207     {
00208         return GLS_SRCBLEND_ONE_MINUS_DST_ALPHA;
00209     }
00210     else if ( !Q_stricmp( name, "GL_SRC_ALPHA_SATURATE" ) )
00211     {
00212         return GLS_SRCBLEND_ALPHA_SATURATE;
00213     }
00214 
00215     ri.Printf( PRINT_WARNING, "WARNING: unknown blend mode '%s' in shader '%s', substituting GL_ONE\n", name, shader.name );
00216     return GLS_SRCBLEND_ONE;
00217 }

Here is the call graph for this function:

void ParseDeform char **  text  )  [static]
 

Definition at line 1066 of file tr_shader.c.

References waveForm_t::amplitude, atof(), deformStage_t::bulgeHeight, deformStage_t::bulgeSpeed, deformStage_t::bulgeWidth, COM_ParseExt(), DEFORM_TEXT0, deformStage_t::deformation, deformStage_t::deformationSpread, deformStage_t::deformationWave, shader_s::deforms, waveForm_t::frequency, i, deformStage_t::moveVector, n, shader_s::name, shader_s::numDeforms, ParseWaveForm(), PRINT_WARNING, Q_stricmp(), Q_stricmpn(), qfalse, ri, shader, and token.

Referenced by ParseShader().

01066                                        {
01067     char    *token;
01068     deformStage_t   *ds;
01069 
01070     token = COM_ParseExt( text, qfalse );
01071     if ( token[0] == 0 )
01072     {
01073         ri.Printf( PRINT_WARNING, "WARNING: missing deform parm in shader '%s'\n", shader.name );
01074         return;
01075     }
01076 
01077     if ( shader.numDeforms == MAX_SHADER_DEFORMS ) {
01078         ri.Printf( PRINT_WARNING, "WARNING: MAX_SHADER_DEFORMS in '%s'\n", shader.name );
01079         return;
01080     }
01081 
01082     ds = &shader.deforms[ shader.numDeforms ];
01083     shader.numDeforms++;
01084 
01085     if ( !Q_stricmp( token, "projectionShadow" ) ) {
01086         ds->deformation = DEFORM_PROJECTION_SHADOW;
01087         return;
01088     }
01089 
01090     if ( !Q_stricmp( token, "autosprite" ) ) {
01091         ds->deformation = DEFORM_AUTOSPRITE;
01092         return;
01093     }
01094 
01095     if ( !Q_stricmp( token, "autosprite2" ) ) {
01096         ds->deformation = DEFORM_AUTOSPRITE2;
01097         return;
01098     }
01099 
01100     if ( !Q_stricmpn( token, "text", 4 ) ) {
01101         int     n;
01102         
01103         n = token[4] - '0';
01104         if ( n < 0 || n > 7 ) {
01105             n = 0;
01106         }
01107         ds->deformation = DEFORM_TEXT0 + n;
01108         return;
01109     }
01110 
01111     if ( !Q_stricmp( token, "bulge" ) ) {
01112         token = COM_ParseExt( text, qfalse );
01113         if ( token[0] == 0 )
01114         {
01115             ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes bulge parm in shader '%s'\n", shader.name );
01116             return;
01117         }
01118         ds->bulgeWidth = atof( token );
01119 
01120         token = COM_ParseExt( text, qfalse );
01121         if ( token[0] == 0 )
01122         {
01123             ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes bulge parm in shader '%s'\n", shader.name );
01124             return;
01125         }
01126         ds->bulgeHeight = atof( token );
01127 
01128         token = COM_ParseExt( text, qfalse );
01129         if ( token[0] == 0 )
01130         {
01131             ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes bulge parm in shader '%s'\n", shader.name );
01132             return;
01133         }
01134         ds->bulgeSpeed = atof( token );
01135 
01136         ds->deformation = DEFORM_BULGE;
01137         return;
01138     }
01139 
01140     if ( !Q_stricmp( token, "wave" ) )
01141     {
01142         token = COM_ParseExt( text, qfalse );
01143         if ( token[0] == 0 )
01144         {
01145             ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes parm in shader '%s'\n", shader.name );
01146             return;
01147         }
01148 
01149         if ( atof( token ) != 0 )
01150         {
01151             ds->deformationSpread = 1.0f / atof( token );
01152         }
01153         else
01154         {
01155             ds->deformationSpread = 100.0f;
01156             ri.Printf( PRINT_WARNING, "WARNING: illegal div value of 0 in deformVertexes command for shader '%s'\n", shader.name );
01157         }
01158 
01159         ParseWaveForm( text, &ds->deformationWave );
01160         ds->