--- code/renderergl2/tr_local.h Tue Jan 20 00:26:36 1970 +++ code/renderergl2/tr_local.h Tue Jan 20 00:26:36 1970 @@ -465,14 +465,16 @@ int numDeforms; deformStage_t deforms[MAX_SHADER_DEFORMS]; int numUnfoggedPasses; shaderStage_t *stages[MAX_SHADER_STAGES]; + int lightingStage; + void (*optimalStageIteratorFunc)( void ); float clampTime; // time this shader is clamped to float timeOffset; // current time offset for this shader struct shader_s *remappedShader; // current shader this one is remapped too --- code/renderergl2/tr_shade.c Tue Jan 20 00:26:36 1970 +++ code/renderergl2/tr_shade.c Tue Jan 20 00:26:36 1970 @@ -690,15 +690,15 @@ int deformGen; vec5_t deformParams; vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0}; float eyeT = 0; shaderCommands_t *input = &tess; - shaderStage_t *pStage = tess.xstages[0]; + shaderStage_t *pStage = tess.xstages[ tess.shader->lightingStage ]; if ( !backEnd.refdef.num_dlights ) { return; } ComputeDeformValues(&deformGen, deformParams); @@ -1594,18 +1594,16 @@ ProjectPshadowVBOGLSL(); } // // now do any dynamic lighting needed // - if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE - && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) { - if (tess.shader->numUnfoggedPasses == 1 && tess.xstages[0]->glslShaderGroup == tr.lightallShader - && (tess.xstages[0]->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) && r_dlightMode->integer) + if ( tess.dlightBits && tess.shader->lightingStage >= 0 ) { + if ( r_dlightMode->integer ) { ForwardDlight(); } else { ProjectDlightTexture(); } --- code/renderergl2/tr_shader.c Tue Jan 20 00:26:36 1970 +++ code/renderergl2/tr_shader.c Tue Jan 20 00:26:36 1970 @@ -2775,14 +2775,48 @@ hash = generateHashValue(newShader->name, FILE_HASH_SIZE); newShader->next = hashTable[hash]; hashTable[hash] = newShader; return newShader; } + +/* +==================== +FindLightingStages + +Find proper stage for dlight pass +==================== +*/ +#define GLS_BLEND_BITS (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS) +static void FindLightingStages( void ) +{ + int i; + shader.lightingStage = -1; + + if ( shader.isSky || ( shader.surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) || shader.sort > SS_OPAQUE ) + return; + + for ( i = 0; i < shader.numUnfoggedPasses; i++ ) { + if ( !stages[i].bundle[0].isLightmap ) { + if ( stages[i].bundle[0].tcGen != TCGEN_TEXTURE ) + continue; + if ( (stages[i].stateBits & GLS_BLEND_BITS) == (GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE) ) + continue; + if ( stages[i].rgbGen == CGEN_IDENTITY && (stages[i].stateBits & GLS_BLEND_BITS) == (GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO) ) { + if ( shader.lightingStage >= 0 ) { + continue; + } + } + shader.lightingStage = i; + } + } +} + + /* ================= VertexLightingCollapse If vertex lighting is enabled, only render a single pass, trying to guess which is the correct one to best aproximate what it is supposed to look like. @@ -3077,14 +3111,16 @@ } // // compute number of passes // shader.numUnfoggedPasses = stage; + + FindLightingStages(); // fogonly shaders don't have any normal passes if (stage == 0 && !shader.isSky) shader.sort = SS_FOG; // determine which stage iterator function is appropriate ComputeStageIteratorFunc();