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

tr_shade.c File Reference

#include "tr_local.h"

Include dependency graph for tr_shade.c:

Include dependency graph

Go to the source code of this file.

Functions

void ComputeColors (shaderStage_t *pStage)
void ComputeTexCoords (shaderStage_t *pStage)
void DrawMultitextured (shaderCommands_t *input, int stage)
void DrawNormals (shaderCommands_t *input)
void DrawTris (shaderCommands_t *input)
void ProjectDlightTexture (void)
void APIENTRY R_ArrayElementDiscrete (GLint index)
void R_BindAnimatedImage (textureBundle_t *bundle)
void R_DrawElements (int numIndexes, const glIndex_t *indexes)
void R_DrawStripElements (int numIndexes, const glIndex_t *indexes, void(APIENTRY *element)(GLint))
void RB_BeginSurface (shader_t *shader, int fogNum)
void RB_EndSurface (void)
void RB_FogPass (void)
void RB_IterateStagesGeneric (shaderCommands_t *input)
void RB_StageIteratorGeneric (void)
void RB_StageIteratorLightmappedMultitexture (void)
void RB_StageIteratorVertexLitTexture (void)

Variables

int c_begins
int c_vertexes
qboolean setArraysOnce
shaderCommands_t tess


Function Documentation

void ComputeColors shaderStage_t pStage  )  [static]
 

Definition at line 653 of file tr_shade.c.

References ACFF_MODULATE_ALPHA, ACFF_MODULATE_RGB, ACFF_MODULATE_RGBA, ACFF_NONE, shaderStage_t::adjustColorsForFog, AGEN_CONST, AGEN_ENTITY, AGEN_IDENTITY, AGEN_LIGHTING_SPECULAR, AGEN_ONE_MINUS_ENTITY, AGEN_ONE_MINUS_VERTEX, AGEN_PORTAL, AGEN_SKIP, AGEN_VERTEX, AGEN_WAVEFORM, alpha, shaderStage_t::alphaGen, shaderStage_t::alphaWave, backEnd, CGEN_CONST, CGEN_ENTITY, CGEN_EXACT_VERTEX, CGEN_FOG, CGEN_IDENTITY, CGEN_IDENTITY_LIGHTING, CGEN_LIGHTING_DIFFUSE, CGEN_ONE_MINUS_ENTITY, CGEN_ONE_MINUS_VERTEX, CGEN_VERTEX, CGEN_WAVEFORM, fog_t::colorInt, stageVars::colors, Com_Memcpy(), Com_Memset(), shaderStage_t::constantColor, shaderCommands_s::fogNum, world_t::fogs, i, trGlobals_t::identityLight, trGlobals_t::identityLightByte, shaderCommands_s::numVertexes, viewParms_t::or, orientationr_t::origin, shader_s::portalRange, RB_CalcAlphaFromEntity(), RB_CalcAlphaFromOneMinusEntity(), RB_CalcColorFromEntity(), RB_CalcColorFromOneMinusEntity(), RB_CalcDiffuseColor(), RB_CalcModulateAlphasByFog(), RB_CalcModulateColorsByFog(), RB_CalcModulateRGBAsByFog(), RB_CalcSpecularAlpha(), RB_CalcWaveAlpha(), RB_CalcWaveColor(), shaderStage_t::rgbGen, shaderStage_t::rgbWave, shaderCommands_s::shader, shaderCommands_s::svars, tess, tr, v, vec3_t, VectorLength(), VectorSubtract, shaderCommands_s::vertexColors, backEndState_t::viewParms, trGlobals_t::world, and shaderCommands_s::xyz.

Referenced by RB_IterateStagesGeneric().

00654 {
00655     int     i;
00656 
00657     //
00658     // rgbGen
00659     //
00660     switch ( pStage->rgbGen )
00661     {
00662         case CGEN_IDENTITY:
00663             Com_Memset( tess.svars.colors, 0xff, tess.numVertexes * 4 );
00664             break;
00665         default:
00666         case CGEN_IDENTITY_LIGHTING:
00667             Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 );
00668             break;
00669         case CGEN_LIGHTING_DIFFUSE:
00670             RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors );
00671             break;
00672         case CGEN_EXACT_VERTEX:
00673             Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
00674             break;
00675         case CGEN_CONST:
00676             for ( i = 0; i < tess.numVertexes; i++ ) {
00677                 *(int *)tess.svars.colors[i] = *(int *)pStage->constantColor;
00678             }
00679             break;
00680         case CGEN_VERTEX:
00681             if ( tr.identityLight == 1 )
00682             {
00683                 Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
00684             }
00685             else
00686             {
00687                 for ( i = 0; i < tess.numVertexes; i++ )
00688                 {
00689                     tess.svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight;
00690                     tess.svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight;
00691                     tess.svars.colors[i][2] = tess.vertexColors[i][2] * tr.identityLight;
00692                     tess.svars.colors[i][3] = tess.vertexColors[i][3];
00693                 }
00694             }
00695             break;
00696         case CGEN_ONE_MINUS_VERTEX:
00697             if ( tr.identityLight == 1 )
00698             {
00699                 for ( i = 0; i < tess.numVertexes; i++ )
00700                 {
00701                     tess.svars.colors[i][0] = 255 - tess.vertexColors[i][0];
00702                     tess.svars.colors[i][1] = 255 - tess.vertexColors[i][1];
00703                     tess.svars.colors[i][2] = 255 - tess.vertexColors[i][2];
00704                 }
00705             }
00706             else
00707             {
00708                 for ( i = 0; i < tess.numVertexes; i++ )
00709                 {
00710                     tess.svars.colors[i][0] = ( 255 - tess.vertexColors[i][0] ) * tr.identityLight;
00711                     tess.svars.colors[i][1] = ( 255 - tess.vertexColors[i][1] ) * tr.identityLight;
00712                     tess.svars.colors[i][2] = ( 255 - tess.vertexColors[i][2] ) * tr.identityLight;
00713                 }
00714             }
00715             break;
00716         case CGEN_FOG:
00717             {
00718                 fog_t       *fog;
00719 
00720                 fog = tr.world->fogs + tess.fogNum;
00721 
00722                 for ( i = 0; i < tess.numVertexes; i++ ) {
00723                     * ( int * )&tess.svars.colors[i] = fog->colorInt;
00724                 }
00725             }
00726             break;
00727         case CGEN_WAVEFORM:
00728             RB_CalcWaveColor( &pStage->rgbWave, ( unsigned char * ) tess.svars.colors );
00729             break;
00730         case CGEN_ENTITY:
00731             RB_CalcColorFromEntity( ( unsigned char * ) tess.svars.colors );
00732             break;
00733         case CGEN_ONE_MINUS_ENTITY:
00734             RB_CalcColorFromOneMinusEntity( ( unsigned char * ) tess.svars.colors );
00735             break;
00736     }
00737 
00738     //
00739     // alphaGen
00740     //
00741     switch ( pStage->alphaGen )
00742     {
00743     case AGEN_SKIP:
00744         break;
00745     case AGEN_IDENTITY:
00746         if ( pStage->rgbGen != CGEN_IDENTITY ) {
00747             if ( ( pStage->rgbGen == CGEN_VERTEX && tr.identityLight != 1 ) ||
00748                  pStage->rgbGen != CGEN_VERTEX ) {
00749                 for ( i = 0; i < tess.numVertexes; i++ ) {
00750                     tess.svars.colors[i][3] = 0xff;
00751                 }
00752             }
00753         }
00754         break;
00755     case AGEN_CONST:
00756         if ( pStage->rgbGen != CGEN_CONST ) {
00757             for ( i = 0; i < tess.numVertexes; i++ ) {
00758                 tess.svars.colors[i][3] = pStage->constantColor[3];
00759             }
00760         }
00761         break;
00762     case AGEN_WAVEFORM:
00763         RB_CalcWaveAlpha( &pStage->alphaWave, ( unsigned char * ) tess.svars.colors );
00764         break;
00765     case AGEN_LIGHTING_SPECULAR:
00766         RB_CalcSpecularAlpha( ( unsigned char * ) tess.svars.colors );
00767         break;
00768     case AGEN_ENTITY:
00769         RB_CalcAlphaFromEntity( ( unsigned char * ) tess.svars.colors );
00770         break;
00771     case AGEN_ONE_MINUS_ENTITY:
00772         RB_CalcAlphaFromOneMinusEntity( ( unsigned char * ) tess.svars.colors );
00773         break;
00774     case AGEN_VERTEX:
00775         if ( pStage->rgbGen != CGEN_VERTEX ) {
00776             for ( i = 0; i < tess.numVertexes; i++ ) {
00777                 tess.svars.colors[i][3] = tess.vertexColors[i][3];
00778             }
00779         }
00780         break;
00781     case AGEN_ONE_MINUS_VERTEX:
00782         for ( i = 0; i < tess.numVertexes; i++ )
00783         {
00784             tess.svars.colors[i][3] = 255 - tess.vertexColors[i][3];
00785         }
00786         break;
00787     case AGEN_PORTAL:
00788         {
00789             unsigned char alpha;
00790 
00791             for ( i = 0; i < tess.numVertexes; i++ )
00792             {
00793                 float len;
00794                 vec3_t v;
00795 
00796                 VectorSubtract( tess.xyz[i], backEnd.viewParms.or.origin, v );
00797                 len = VectorLength( v );
00798 
00799                 len /= tess.shader->portalRange;
00800 
00801                 if ( len < 0 )
00802                 {
00803                     alpha = 0;
00804                 }
00805                 else if ( len > 1 )
00806                 {
00807                     alpha = 0xff;
00808                 }
00809                 else
00810                 {
00811                     alpha = len * 0xff;
00812                 }
00813 
00814                 tess.svars.colors[i][3] = alpha;
00815             }
00816         }
00817         break;
00818     }
00819 
00820     //
00821     // fog adjustment for colors to fade out as fog increases
00822     //
00823     if ( tess.fogNum )
00824     {
00825         switch ( pStage->adjustColorsForFog )
00826         {
00827         case ACFF_MODULATE_RGB:
00828             RB_CalcModulateColorsByFog( ( unsigned char * ) tess.svars.colors );
00829             break;
00830         case ACFF_MODULATE_ALPHA:
00831             RB_CalcModulateAlphasByFog( ( unsigned char * ) tess.svars.colors );
00832             break;
00833         case ACFF_MODULATE_RGBA:
00834             RB_CalcModulateRGBAsByFog( ( unsigned char * ) tess.svars.colors );
00835             break;
00836         case ACFF_NONE:
00837             break;
00838         }
00839     }
00840 }

Here is the call graph for this function:

void ComputeTexCoords shaderStage_t pStage  )  [static]
 

Definition at line 847 of file tr_shade.c.

References b, backEnd, shaderStage_t::bundle, Com_Memset(), backEndState_t::currentEntity, DotProduct, trRefEntity_t::e, ERR_DROP, i, shader_s::name, textureBundle_t::numTexMods, shaderCommands_s::numVertexes, RB_CalcEnvironmentTexCoords(), RB_CalcFogTexCoords(), RB_CalcRotateTexCoords(), RB_CalcScaleTexCoords(), RB_CalcScrollTexCoords(), RB_CalcStretchTexCoords(), RB_CalcTransformTexCoords(), RB_CalcTurbulentTexCoords(), ri, texModInfo_t::rotateSpeed, texModInfo_t::scale, texModInfo_t::scroll, shaderCommands_s::shader, refEntity_t::shaderTexCoord, shaderCommands_s::svars, textureBundle_t::tcGen, TCGEN_BAD, TCGEN_ENVIRONMENT_MAPPED, TCGEN_FOG, TCGEN_IDENTITY, TCGEN_LIGHTMAP, TCGEN_TEXTURE, TCGEN_VECTOR, textureBundle_t::tcGenVectors, tess, shaderCommands_s::texCoords, stageVars::texcoords, textureBundle_t::texMods, TMOD_ENTITY_TRANSLATE, TMOD_NONE, TMOD_ROTATE, TMOD_SCALE, TMOD_SCROLL, TMOD_STRETCH, TMOD_TRANSFORM, TMOD_TURBULENT, texModInfo_t::type, texModInfo_t::wave, and shaderCommands_s::xyz.

Referenced by RB_IterateStagesGeneric().

00847                                                       {
00848     int     i;
00849     int     b;
00850 
00851     for ( b = 0; b < NUM_TEXTURE_BUNDLES; b++ ) {
00852         int tm;
00853 
00854         //
00855         // generate the texture coordinates
00856         //
00857         switch ( pStage->bundle[b].tcGen )
00858         {
00859         case TCGEN_IDENTITY:
00860             Com_Memset( tess.svars.texcoords[b], 0, sizeof( float ) * 2 * tess.numVertexes );
00861             break;
00862         case TCGEN_TEXTURE:
00863             for ( i = 0 ; i < tess.numVertexes ; i++ ) {
00864                 tess.svars.texcoords[b][i][0] = tess.texCoords[i][0][0];
00865                 tess.svars.texcoords[b][i][1] = tess.texCoords[i][0][1];
00866             }
00867             break;
00868         case TCGEN_LIGHTMAP:
00869             for ( i = 0 ; i < tess.numVertexes ; i++ ) {
00870                 tess.svars.texcoords[b][i][0] = tess.texCoords[i][1][0];
00871                 tess.svars.texcoords[b][i][1] = tess.texCoords[i][1][1];
00872             }
00873             break;
00874         case TCGEN_VECTOR:
00875             for ( i = 0 ; i < tess.numVertexes ; i++ ) {
00876                 tess.svars.texcoords[b][i][0] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[0] );
00877                 tess.svars.texcoords[b][i][1] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[1] );
00878             }
00879             break;
00880         case TCGEN_FOG:
00881             RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[b] );
00882             break;
00883         case TCGEN_ENVIRONMENT_MAPPED:
00884             RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] );
00885             break;
00886         case TCGEN_BAD:
00887             return;
00888         }
00889 
00890         //
00891         // alter texture coordinates
00892         //
00893         for ( tm = 0; tm < pStage->bundle[b].numTexMods ; tm++ ) {
00894             switch ( pStage->bundle[b].texMods[tm].type )
00895             {
00896             case TMOD_NONE:
00897                 tm = TR_MAX_TEXMODS;        // break out of for loop
00898                 break;
00899 
00900             case TMOD_TURBULENT:
00901                 RB_CalcTurbulentTexCoords( &pStage->bundle[b].texMods[tm].wave, 
00902                                          ( float * ) tess.svars.texcoords[b] );
00903                 break;
00904 
00905             case TMOD_ENTITY_TRANSLATE:
00906                 RB_CalcScrollTexCoords( backEnd.currentEntity->e.shaderTexCoord,
00907                                      ( float * ) tess.svars.texcoords[b] );
00908                 break;
00909 
00910             case TMOD_SCROLL:
00911                 RB_CalcScrollTexCoords( pStage->bundle[b].texMods[tm].scroll,
00912                                          ( float * ) tess.svars.texcoords[b] );
00913                 break;
00914 
00915             case TMOD_SCALE:
00916                 RB_CalcScaleTexCoords( pStage->bundle[b].texMods[tm].scale,
00917                                      ( float * ) tess.svars.texcoords[b] );
00918                 break;
00919             
00920             case TMOD_STRETCH:
00921                 RB_CalcStretchTexCoords( &pStage->bundle[b].texMods[tm].wave, 
00922                                        ( float * ) tess.svars.texcoords[b] );
00923                 break;
00924 
00925             case TMOD_TRANSFORM:
00926                 RB_CalcTransformTexCoords( &pStage->bundle[b].texMods[tm],
00927                                          ( float * ) tess.svars.texcoords[b] );
00928                 break;
00929 
00930             case TMOD_ROTATE:
00931                 RB_CalcRotateTexCoords( pStage->bundle[b].texMods[tm].rotateSpeed,
00932                                         ( float * ) tess.svars.texcoords[b] );
00933                 break;
00934 
00935             default:
00936                 ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'\n", pStage->bundle[b].texMods[tm].type, tess.shader->name );
00937                 break;
00938             }
00939         }
00940     }
00941 }

Here is the call graph for this function:

void DrawMultitextured shaderCommands_t input,
int  stage
[static]
 

Definition at line 345 of file tr_shade.c.

References backEnd, shaderStage_t::bundle, GL_SelectTexture(), GL_State(), GL_TexEnv(), shaderCommands_s::indexes, input, cvar_s::integer, viewParms_t::isPortal, shader_s::multitextureEnv, shaderCommands_s::numIndexes, qglDisable, qglEnable, qglEnableClientState, qglPolygonMode, qglTexCoordPointer, R_BindAnimatedImage(), R_DrawElements(), r_lightmap, shaderCommands_s::shader, shaderCommands_t, shaderStage_t::stateBits, shaderCommands_s::svars, tess, stageVars::texcoords, backEndState_t::viewParms, and shaderCommands_s::xstages.

Referenced by RB_IterateStagesGeneric().

00345                                                                     {
00346     shaderStage_t   *pStage;
00347 
00348     pStage = tess.xstages[stage];
00349 
00350     GL_State( pStage->stateBits );
00351 
00352     // this is an ugly hack to work around a GeForce driver
00353     // bug with multitexture and clip planes
00354     if ( backEnd.viewParms.isPortal ) {
00355         qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
00356     }
00357 
00358     //
00359     // base
00360     //
00361     GL_SelectTexture( 0 );
00362     qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] );
00363     R_BindAnimatedImage( &pStage->bundle[0] );
00364 
00365     //
00366     // lightmap/secondary pass
00367     //
00368     GL_SelectTexture( 1 );
00369     qglEnable( GL_TEXTURE_2D );
00370     qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
00371 
00372     if ( r_lightmap->integer ) {
00373         GL_TexEnv( GL_REPLACE );
00374     } else {
00375         GL_TexEnv( tess.shader->multitextureEnv );
00376     }
00377 
00378     qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[1] );
00379 
00380     R_BindAnimatedImage( &pStage->bundle[1] );
00381 
00382     R_DrawElements( input->numIndexes, input->indexes );
00383 
00384     //
00385     // disable texturing on TEXTURE1, then select TEXTURE0
00386     //
00387     //qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
00388     qglDisable( GL_TEXTURE_2D );
00389 
00390     GL_SelectTexture( 0 );
00391 }

Here is the call graph for this function:

void DrawNormals shaderCommands_t input  )  [static]
 

Definition at line 285 of file tr_shade.c.

References GL_Bind(), GL_State(), GLS_DEPTHMASK_TRUE, GLS_POLYMODE_LINE, i, input, shaderCommands_s::normal, shaderCommands_s::numVertexes, qglBegin, qglColor3f, qglDepthRange, qglEnd, qglVertex3fv, shaderCommands_t, tr, vec3_t, VectorMA, trGlobals_t::whiteImage, and shaderCommands_s::xyz.

Referenced by RB_EndSurface().

00285                                                   {
00286     int     i;
00287     vec3_t  temp;
00288 
00289     GL_Bind( tr.whiteImage );
00290     qglColor3f (1,1,1);
00291     qglDepthRange( 0, 0 );  // never occluded
00292     GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
00293 
00294     qglBegin (GL_LINES);
00295     for (i = 0 ; i < input->numVertexes ; i++) {
00296         qglVertex3fv (input->xyz[i]);
00297         VectorMA (input->xyz[i], 2, input->normal[i], temp);
00298         qglVertex3fv (temp);
00299     }
00300     qglEnd ();
00301 
00302     qglDepthRange( 0, 1 );
00303 }

Here is the call graph for this function:

void DrawTris shaderCommands_t input  )  [static]
 

Definition at line 251 of file tr_shade.c.

References GL_Bind(), GL_State(), GLimp_LogComment(), GLS_DEPTHMASK_TRUE, GLS_POLYMODE_LINE, shaderCommands_s::indexes, input, shaderCommands_s::numIndexes, shaderCommands_s::numVertexes, qglColor3f, qglDepthRange, qglDisableClientState, qglLockArraysEXT, qglUnlockArraysEXT, qglVertexPointer, R_DrawElements(), shaderCommands_t, tr, trGlobals_t::whiteImage, and shaderCommands_s::xyz.

Referenced by RB_EndSurface().

00251                                                {
00252     GL_Bind( tr.whiteImage );
00253     qglColor3f (1,1,1);
00254 
00255     GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
00256     qglDepthRange( 0, 0 );
00257 
00258     qglDisableClientState (GL_COLOR_ARRAY);
00259     qglDisableClientState (GL_TEXTURE_COORD_ARRAY);
00260 
00261     qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD
00262 
00263     if (qglLockArraysEXT) {
00264         qglLockArraysEXT(0, input->numVertexes);
00265         GLimp_LogComment( "glLockArraysEXT\n" );
00266     }
00267 
00268     R_DrawElements( input->numIndexes, input->indexes );
00269 
00270     if (qglUnlockArraysEXT) {
00271         qglUnlockArraysEXT();
00272         GLimp_LogComment( "glUnlockArraysEXT\n" );
00273     }
00274     qglDepthRange( 0, 1 );
00275 }

Here is the call graph for this function:

void ProjectDlightTexture void   )  [static]
 

Definition at line 402 of file tr_shade.c.

References a, dlight_s::additive, b, backEnd, byte, c, backEndCounters_t::c_dlightIndexes, backEndCounters_t::c_dlightVertexes, backEndCounters_t::c_totalIndexes, dlight_s::color, dlight_t, shaderCommands_s::dlightBits, trGlobals_t::dlightImage, trRefdef_t::dlights, GL_Bind(), GL_State(), GLS_DEPTHFUNC_EQUAL, GLS_DSTBLEND_ONE, GLS_SRCBLEND_DST_COLOR, GLS_SRCBLEND_ONE, i, shaderCommands_s::indexes, l, myftol, trRefdef_t::num_dlights, shaderCommands_s::numIndexes, shaderCommands_s::numVertexes, backEndState_t::pc, Q_fabs(), qglColorPointer, qglEnableClientState, qglTexCoordPointer, R_DrawElements(), dlight_s::radius, backEndState_t::refdef, tess, tr, dlight_s::transformed, vec3_t, vec_t, VectorCopy, VectorSubtract, shaderCommands_s::xyz, and zero().

Referenced by RB_StageIteratorGeneric(), RB_StageIteratorLightmappedMultitexture(), and RB_StageIteratorVertexLitTexture().

00402                                          {
00403     int     i, l;
00404 #if idppc_altivec
00405     vec_t   origin0, origin1, origin2;
00406     float   texCoords0, texCoords1;
00407     vector float floatColorVec0, floatColorVec1;
00408     vector float modulateVec, colorVec, zero;
00409     vector short colorShort;
00410     vector signed int colorInt;
00411     vector unsigned char floatColorVecPerm, modulatePerm, colorChar;
00412     vector unsigned char vSel = (vector unsigned char)(0x00, 0x00, 0x00, 0xff,
00413                                0x00, 0x00, 0x00, 0xff,
00414                                0x00, 0x00, 0x00, 0xff,
00415                                0x00, 0x00, 0x00, 0xff);
00416 #else
00417     vec3_t  origin;
00418 #endif
00419     float   *texCoords;
00420     byte    *colors;
00421     byte    clipBits[SHADER_MAX_VERTEXES];
00422     MAC_STATIC float    texCoordsArray[SHADER_MAX_VERTEXES][2];
00423     byte    colorArray[SHADER_MAX_VERTEXES][4];
00424     unsigned    hitIndexes[SHADER_MAX_INDEXES];
00425     int     numIndexes;
00426     float   scale;
00427     float   radius;
00428     vec3_t  floatColor;
00429     float   modulate;
00430 
00431     if ( !backEnd.refdef.num_dlights ) {
00432         return;
00433     }
00434 
00435 #if idppc_altivec
00436     // There has to be a better way to do this so that floatColor 
00437     // and/or modulate are already 16-byte aligned.
00438     floatColorVecPerm = vec_lvsl(0,(float *)floatColor);
00439     modulatePerm = vec_lvsl(0,(float *)&modulate);
00440     modulatePerm = (vector unsigned char)vec_splat((vector unsigned int)modulatePerm,0);
00441     zero = (vector float)vec_splat_s8(0);
00442 #endif
00443 
00444     for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {
00445         dlight_t    *dl;
00446 
00447         if ( !( tess.dlightBits & ( 1 << l ) ) ) {
00448             continue;   // this surface definately doesn't have any of this light
00449         }
00450         texCoords = texCoordsArray[0];
00451         colors = colorArray[0];
00452 
00453         dl = &backEnd.refdef.dlights[l];
00454 #if idppc_altivec
00455         origin0 = dl->transformed[0];
00456         origin1 = dl->transformed[1];
00457         origin2 = dl->transformed[2];
00458 #else
00459         VectorCopy( dl->transformed, origin );
00460 #endif
00461         radius = dl->radius;
00462         scale = 1.0f / radius;
00463 
00464         floatColor[0] = dl->color[0] * 255.0f;
00465         floatColor[1] = dl->color[1] * 255.0f;
00466         floatColor[2] = dl->color[2] * 255.0f;
00467 #if idppc_altivec
00468         floatColorVec0 = vec_ld(0, floatColor);
00469         floatColorVec1 = vec_ld(11, floatColor);
00470         floatColorVec0 = vec_perm(floatColorVec0,floatColorVec0,floatColorVecPerm);
00471 #endif
00472         for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {
00473 #if idppc_altivec
00474             vec_t dist0, dist1, dist2;
00475 #else
00476             vec3_t  dist;
00477 #endif
00478             int     clip;
00479 
00480             backEnd.pc.c_dlightVertexes++;
00481 
00482 #if idppc_altivec
00483             //VectorSubtract( origin, tess.xyz[i], dist );
00484             dist0 = origin0 - tess.xyz[i][0];
00485             dist1 = origin1 - tess.xyz[i][1];
00486             dist2 = origin2 - tess.xyz[i][2];
00487             texCoords0 = 0.5f + dist0 * scale;
00488             texCoords1 = 0.5f + dist1 * scale;
00489 
00490             clip = 0;
00491             if ( texCoords0 < 0.0f ) {
00492                 clip |= 1;
00493             } else if ( texCoords0 > 1.0f ) {
00494                 clip |= 2;
00495             }
00496             if ( texCoords1 < 0.0f ) {
00497                 clip |= 4;
00498             } else if ( texCoords1 > 1.0f ) {
00499                 clip |= 8;
00500             }
00501             texCoords[0] = texCoords0;
00502             texCoords[1] = texCoords1;
00503             
00504             // modulate the strength based on the height and color
00505             if ( dist2 > radius ) {
00506                 clip |= 16;
00507                 modulate = 0.0f;
00508             } else if ( dist2 < -radius ) {
00509                 clip |= 32;
00510                 modulate = 0.0f;
00511             } else {
00512                 dist2 = Q_fabs(dist2);
00513                 if ( dist2 < radius * 0.5f ) {
00514                     modulate = 1.0f;
00515                 } else {
00516                     modulate = 2.0f * (radius - dist2) * scale;
00517                 }
00518             }
00519             clipBits[i] = clip;
00520 
00521             modulateVec = vec_ld(0,(float *)&modulate);
00522             modulateVec = vec_perm(modulateVec,modulateVec,modulatePerm);
00523             colorVec = vec_madd(floatColorVec0,modulateVec,zero);
00524             colorInt = vec_cts(colorVec,0); // RGBx
00525             colorShort = vec_pack(colorInt,colorInt);       // RGBxRGBx
00526             colorChar = vec_packsu(colorShort,colorShort);  // RGBxRGBxRGBxRGBx
00527             colorChar = vec_sel(colorChar,vSel,vSel);       // RGBARGBARGBARGBA replace alpha with 255
00528             vec_ste((vector unsigned int)colorChar,0,(unsigned int *)colors);   // store color
00529 #else
00530             VectorSubtract( origin, tess.xyz[i], dist );
00531             texCoords[0] = 0.5f + dist[0] * scale;
00532             texCoords[1] = 0.5f + dist[1] * scale;
00533 
00534             clip = 0;
00535             if ( texCoords[0] < 0.0f ) {
00536                 clip |= 1;
00537             } else if ( texCoords[0] > 1.0f ) {
00538                 clip |= 2;
00539             }
00540             if ( texCoords[1] < 0.0f ) {
00541                 clip |= 4;
00542             } else if ( texCoords[1] > 1.0f ) {
00543                 clip |= 8;
00544             }
00545             // modulate the strength based on the height and color
00546             if ( dist[2] > radius ) {
00547                 clip |= 16;
00548                 modulate = 0.0f;
00549             } else if ( dist[2] < -radius ) {
00550                 clip |= 32;
00551                 modulate = 0.0f;
00552             } else {
00553                 dist[2] = Q_fabs(dist[2]);
00554                 if ( dist[2] < radius * 0.5f ) {
00555                     modulate = 1.0f;
00556                 } else {
00557                     modulate = 2.0f * (radius - dist[2]) * scale;
00558                 }
00559             }
00560             clipBits[i] = clip;
00561 
00562             colors[0] = myftol(floatColor[0] * modulate);
00563             colors[1] = myftol(floatColor[1] * modulate);
00564             colors[2] = myftol(floatColor[2] * modulate);
00565             colors[3] = 255;
00566 #endif
00567         }
00568 
00569         // build a list of triangles that need light
00570         numIndexes = 0;
00571         for ( i = 0 ; i < tess.numIndexes ; i += 3 ) {
00572             int     a, b, c;
00573 
00574             a = tess.indexes[i];
00575             b = tess.indexes[i+1];
00576             c = tess.indexes[i+2];
00577             if ( clipBits[a] & clipBits[b] & clipBits[c] ) {
00578                 continue;   // not lighted
00579             }
00580             hitIndexes[numIndexes] = a;
00581             hitIndexes[numIndexes+1] = b;
00582             hitIndexes[numIndexes+2] = c;
00583             numIndexes += 3;
00584         }
00585 
00586         if ( !numIndexes ) {
00587             continue;
00588         }
00589 
00590         qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
00591         qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] );
00592 
00593         qglEnableClientState( GL_COLOR_ARRAY );
00594         qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray );
00595 
00596         GL_Bind( tr.dlightImage );
00597         // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
00598         // where they aren't rendered
00599         if ( dl->additive ) {
00600             GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
00601         }
00602         else {
00603             GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
00604         }
00605         R_DrawElements( numIndexes, hitIndexes );
00606         backEnd.pc.c_totalIndexes += numIndexes;
00607         backEnd.pc.c_dlightIndexes += numIndexes;
00608     }
00609 }

Here is the call graph for this function:

void APIENTRY R_ArrayElementDiscrete GLint  index  )  [static]
 

Definition at line 40 of file tr_shade.c.

References stageVars::colors, glstate_t::currenttmu, glState, qglColor4ubv, qglMultiTexCoord2fARB, qglTexCoord2fv, qglVertex3fv, shaderCommands_s::svars, tess, stageVars::texcoords, and shaderCommands_s::xyz.

Referenced by R_DrawElements().

00040                                                            {
00041     qglColor4ubv( tess.svars.colors[ index ] );
00042     if ( glState.currenttmu ) {
00043         qglMultiTexCoord2fARB( 0, tess.svars.texcoords[ 0 ][ index ][0], tess.svars.texcoords[ 0 ][ index ][1] );
00044         qglMultiTexCoord2fARB( 1, tess.svars.texcoords[ 1 ][ index ][0], tess.svars.texcoords[ 1 ][ index ][1] );
00045     } else {
00046         qglTexCoord2fv( tess.svars.texcoords[ 0 ][ index ] );
00047     }
00048     qglVertex3fv( tess.xyz[ index ] );
00049 }

void R_BindAnimatedImage textureBundle_t bundle  )  [static]
 

Definition at line 217 of file tr_shade.c.

References refimport_t::CIN_RunCinematic, refimport_t::CIN_UploadCinematic, FUNCTABLE_SIZE, GL_Bind(), textureBundle_t::image, textureBundle_t::imageAnimationSpeed, textureBundle_t::isVideoMap, myftol, textureBundle_t::numImageAnimations, ri, shaderCommands_s::shaderTime, tess, and textureBundle_t::videoMapHandle.

Referenced by DrawMultitextured(), RB_IterateStagesGeneric(), RB_StageIteratorLightmappedMultitexture(), and RB_StageIteratorVertexLitTexture().

00217                                                            {
00218     int     index;
00219 
00220     if ( bundle->isVideoMap ) {
00221         ri.CIN_RunCinematic(bundle->videoMapHandle);
00222         ri.CIN_UploadCinematic(bundle->videoMapHandle);
00223         return;
00224     }
00225 
00226     if ( bundle->numImageAnimations <= 1 ) {
00227         GL_Bind( bundle->image[0] );
00228         return;
00229     }
00230 
00231     // it is necessary to do this messy calc to make sure animations line up
00232     // exactly with waveforms of the same frequency
00233     index = myftol( tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE );
00234     index >>= FUNCTABLE_SIZE2;
00235 
00236     if ( index < 0 ) {
00237         index = 0;  // may happen with shader time offsets
00238     }
00239     index %= bundle->numImageAnimations;
00240 
00241     GL_Bind( bundle->image[ index ] );
00242 }

Here is the call graph for this function:

void R_DrawElements int  numIndexes,
const glIndex_t indexes
[static]
 

Definition at line 163 of file tr_shade.c.

References GL_INDEX_TYPE, glIndex_t, cvar_s::integer, qglArrayElement, qglDrawElements, R_ArrayElementDiscrete(), R_DrawStripElements(), and r_primitives.

Referenced by DrawMultitextured(), DrawTris(), ProjectDlightTexture(), RB_FogPass(), RB_IterateStagesGeneric(), RB_StageIteratorLightmappedMultitexture(), and RB_StageIteratorVertexLitTexture().

00163                                                                        {
00164     int     primitives;
00165 
00166     primitives = r_primitives->integer;
00167 
00168     // default is to use triangles if compiled vertex arrays are present
00169     if ( primitives == 0 ) {
00170         if ( qglLockArraysEXT ) {
00171             primitives = 2;
00172         } else {
00173             primitives = 1;
00174         }
00175     }
00176 
00177 
00178     if ( primitives == 2 ) {
00179         qglDrawElements( GL_TRIANGLES, 
00180                         numIndexes,
00181                         GL_INDEX_TYPE,
00182                         indexes );
00183         return;
00184     }
00185 
00186     if ( primitives == 1 ) {
00187         R_DrawStripElements( numIndexes,  indexes, qglArrayElement );
00188         return;
00189     }
00190     
00191     if ( primitives == 3 ) {
00192         R_DrawStripElements( numIndexes,  indexes, R_ArrayElementDiscrete );
00193         return;
00194     }
00195 
00196     // anything else will cause no drawing
00197 }

Here is the call graph for this function:

void R_DrawStripElements int  numIndexes,
const glIndex_t indexes,
void(APIENTRY *element)(GLint) 
[static]
 

Definition at line 59 of file tr_shade.c.

References assert, c_begins, c_vertexes, glIndex_t, i, shaderCommands_s::numVertexes, qboolean, qglBegin, qglEnd, and tess.

Referenced by R_DrawElements().

00059                                                                                                                {
00060     int i;
00061     int last[3] = { -1, -1, -1 };
00062     qboolean even;
00063 
00064     c_begins++;
00065 
00066     if ( numIndexes <= 0 ) {
00067         return;
00068     }
00069 
00070     qglBegin( GL_TRIANGLE_STRIP );
00071 
00072     // prime the strip
00073     element( indexes[0] );
00074     element( indexes[1] );
00075     element( indexes[2] );
00076     c_vertexes += 3;
00077 
00078     last[0] = indexes[0];
00079     last[1] = indexes[1];
00080     last[2] = indexes[2];
00081 
00082     even = qfalse;
00083 
00084     for ( i = 3; i < numIndexes; i += 3 )
00085     {
00086         // odd numbered triangle in potential strip
00087         if ( !even )
00088         {
00089             // check previous triangle to see if we're continuing a strip
00090             if ( ( indexes[i+0] == last[2] ) && ( indexes[i+1] == last[1] ) )
00091             {
00092                 element( indexes[i+2] );
00093                 c_vertexes++;
00094                 assert( indexes[i+2] < tess.numVertexes );
00095                 even = qtrue;
00096             }
00097             // otherwise we're done with this strip so finish it and start
00098             // a new one
00099             else
00100             {
00101                 qglEnd();
00102 
00103                 qglBegin( GL_TRIANGLE_STRIP );
00104                 c_begins++;
00105 
00106                 element( indexes[i+0] );
00107                 element( indexes[i+1] );
00108                 element( indexes[i+2] );
00109 
00110                 c_vertexes += 3;
00111 
00112                 even = qfalse;
00113             }
00114         }
00115         else
00116         {
00117             // check previous triangle to see if we're continuing a strip
00118             if ( ( last[2] == indexes[i+1] ) && ( last[0] == indexes[i+0] ) )
00119             {
00120                 element( indexes[i+2] );
00121                 c_vertexes++;
00122 
00123                 even = qfalse;
00124             }
00125             // otherwise we're done with this strip so finish it and start
00126             // a new one
00127             else
00128             {
00129                 qglEnd();
00130 
00131                 qglBegin( GL_TRIANGLE_STRIP );
00132                 c_begins++;
00133 
00134                 element( indexes[i+0] );
00135                 element( indexes[i+1] );
00136                 element( indexes[i+2] );
00137                 c_vertexes += 3;
00138 
00139                 even = qfalse;
00140             }
00141         }
00142 
00143         // cache the last three vertices
00144         last[0] = indexes[i+0];
00145         last[1] = indexes[i+1];
00146         last[2] = indexes[i+2];
00147     }
00148 
00149     qglEnd();
00150 }

void RB_BeginSurface