static void ForwardDlight( void ) { int l; //vec3_t origin; //float scale; float radius; 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]; if ( !backEnd.refdef.num_dlights ) { return; } ComputeDeformValues(&deformGen, deformParams); ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT); for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { dlight_t *dl; shaderProgram_t *sp; vec4_t vector; matrix_t matrix; if ( !( tess.dlightBits & ( 1 << l ) ) ) { continue; // this surface definately doesn't have any of this light } dl = &backEnd.refdef.dlights[l]; //VectorCopy( dl->transformed, origin ); radius = dl->radius; //scale = 1.0f / radius; //if (pStage->glslShaderGroup == tr.lightallShader) { int index = pStage->glslShaderIndex; index &= ~(LIGHTDEF_LIGHTTYPE_MASK | LIGHTDEF_USE_DELUXEMAP); index |= LIGHTDEF_USE_LIGHT_VECTOR; sp = &tr.lightallShader[index]; } backEnd.pc.c_lightallDraws++; GLSL_BindProgram(sp); GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen); if (deformGen != DGEN_NONE) { GLSL_SetUniformFloat5(sp, UNIFORM_DEFORMPARAMS, deformParams); GLSL_SetUniformFloat(sp, UNIFORM_TIME, tess.shaderTime); } if ( input->fogNum ) { vec4_t fogColorMask; GLSL_SetUniformVec4(sp, UNIFORM_FOGDISTANCE, fogDistanceVector); GLSL_SetUniformVec4(sp, UNIFORM_FOGDEPTH, fogDepthVector); GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT); ComputeFogColorMask(pStage, fogColorMask); GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask); } { vec4_t baseColor; vec4_t vertColor; ComputeShaderColors(pStage, baseColor, vertColor); GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor); GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor); } if (pStage->alphaGen == AGEN_PORTAL) { GLSL_SetUniformFloat(sp, UNIFORM_PORTALRANGE, tess.shader->portalRange); } GLSL_SetUniformInt(sp, UNIFORM_COLORGEN, pStage->rgbGen); GLSL_SetUniformInt(sp, UNIFORM_ALPHAGEN, pStage->alphaGen); GLSL_SetUniformVec3(sp, UNIFORM_DIRECTEDLIGHT, dl->color); VectorSet(vector, 0, 0, 0); GLSL_SetUniformVec3(sp, UNIFORM_AMBIENTLIGHT, vector); VectorCopy(dl->origin, vector); vector[3] = 1.0f; GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, vector); GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, radius); GLSL_SetUniformVec2(sp, UNIFORM_MATERIALINFO, pStage->materialInfo); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); GLSL_SetUniformMatrix16(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); if (pStage->bundle[TB_DIFFUSEMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP); if (pStage->bundle[TB_NORMALMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP); if (pStage->bundle[TB_SPECULARMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP); if (r_dlightMode->integer >= 2) { GL_SelectTexture(TB_SHADOWMAP); GL_BindCubemap(tr.shadowCubemaps[l]); GL_SelectTexture(0); } ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix ); VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector); VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector); GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); // // draw // if (input->multiDrawPrimitives) { R_DrawMultiElementsVBO(input->multiDrawPrimitives, input->multiDrawMinIndex, input->multiDrawMaxIndex, input->multiDrawNumIndexes, input->multiDrawFirstIndex); } else { R_DrawElementsVBO(input->numIndexes, input->firstIndex, input->minIndex, input->maxIndex); } backEnd.pc.c_totalIndexes += tess.numIndexes; backEnd.pc.c_dlightIndexes += tess.numIndexes; } }
static void ForwardSunlight( void ) { // int l; //vec3_t origin; //float scale; int stage; int stageGlState[2]; qboolean alphaOverride = qfalse; int deformGen; vec5_t deformParams; vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0}; float eyeT = 0; shaderCommands_t *input = &tess; ComputeDeformValues(&deformGen, deformParams); ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT); // deal with vertex alpha blended surfaces if (input->xstages[0] && input->xstages[1] && (input->xstages[1]->alphaGen == AGEN_VERTEX || input->xstages[1]->alphaGen == AGEN_ONE_MINUS_VERTEX)) { stageGlState[0] = input->xstages[0]->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS); if (stageGlState[0] == 0 || stageGlState[0] == (GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO)) { stageGlState[1] = input->xstages[1]->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS); if (stageGlState[1] == (GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA)) { alphaOverride = qtrue; stageGlState[0] = GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL; stageGlState[1] = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL; } else if (stageGlState[1] == (GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_SRC_ALPHA)) { alphaOverride = qtrue; stageGlState[0] = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL; stageGlState[1] = GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL; } } } if (!alphaOverride) { stageGlState[0] = stageGlState[1] = GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL; } for ( stage = 0; stage < 2 /*MAX_SHADER_STAGES */; stage++ ) { shaderStage_t *pStage = input->xstages[stage]; shaderProgram_t *sp; vec4_t vector; matrix_t matrix; if ( !pStage ) { break; } //VectorCopy( dl->transformed, origin ); //if (pStage->glslShaderGroup == tr.lightallShader) { int index = pStage->glslShaderIndex; index &= ~(LIGHTDEF_LIGHTTYPE_MASK | LIGHTDEF_USE_DELUXEMAP); index |= LIGHTDEF_USE_LIGHT_VECTOR | LIGHTDEF_USE_SHADOWMAP; if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) { index |= LIGHTDEF_ENTITY; } sp = &tr.lightallShader[index]; } backEnd.pc.c_lightallDraws++; GLSL_BindProgram(sp); GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen); if (deformGen != DGEN_NONE) { GLSL_SetUniformFloat5(sp, UNIFORM_DEFORMPARAMS, deformParams); GLSL_SetUniformFloat(sp, UNIFORM_TIME, tess.shaderTime); } if ( input->fogNum ) { vec4_t fogColorMask; GLSL_SetUniformVec4(sp, UNIFORM_FOGDISTANCE, fogDistanceVector); GLSL_SetUniformVec4(sp, UNIFORM_FOGDEPTH, fogDepthVector); GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT); ComputeFogColorMask(pStage, fogColorMask); GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask); } { vec4_t baseColor; vec4_t vertColor; ComputeShaderColors(pStage, baseColor, vertColor); if (alphaOverride) { if (input->xstages[1]->alphaGen == AGEN_VERTEX) { baseColor[3] = 0.0f; vertColor[3] = 1.0f; } else if (input->xstages[1]->alphaGen == AGEN_ONE_MINUS_VERTEX) { baseColor[3] = 1.0f; vertColor[3] = -1.0f; } } GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor); GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor); } if (pStage->alphaGen == AGEN_PORTAL) { GLSL_SetUniformFloat(sp, UNIFORM_PORTALRANGE, tess.shader->portalRange); } GLSL_SetUniformInt(sp, UNIFORM_COLORGEN, pStage->rgbGen); GLSL_SetUniformInt(sp, UNIFORM_ALPHAGEN, pStage->alphaGen); GLSL_SetUniformVec3(sp, UNIFORM_DIRECTEDLIGHT, backEnd.refdef.sunCol); GLSL_SetUniformVec3(sp, UNIFORM_AMBIENTLIGHT, backEnd.refdef.sunAmbCol); GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir); GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 9999999999.9f); GLSL_SetUniformVec2(sp, UNIFORM_MATERIALINFO, pStage->materialInfo); GL_State( stageGlState[stage] ); GLSL_SetUniformMatrix16(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); if (pStage->bundle[TB_DIFFUSEMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP); if (pStage->bundle[TB_NORMALMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP); if (pStage->bundle[TB_SPECULARMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP); /* { GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP); GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2); GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3); GLSL_SetUniformMatrix16(sp, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]); GLSL_SetUniformMatrix16(sp, UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]); GLSL_SetUniformMatrix16(sp, UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]); } */ GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP); ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix ); VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector); VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector); GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); // // draw // if (input->multiDrawPrimitives) { R_DrawMultiElementsVBO(input->multiDrawPrimitives, input->multiDrawMinIndex, input->multiDrawMaxIndex, input->multiDrawNumIndexes, input->multiDrawFirstIndex); } else { R_DrawElementsVBO(input->numIndexes, input->firstIndex, input->minIndex, input->maxIndex); } backEnd.pc.c_totalIndexes += tess.numIndexes; backEnd.pc.c_dlightIndexes += tess.numIndexes; } }
static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; matrix_t matrix; vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0}; float eyeT = 0; int deformGen; vec5_t deformParams; ComputeDeformValues(&deformGen, deformParams); ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT); for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = input->xstages[stage]; shaderProgram_t *sp; if ( !pStage ) { break; } if (backEnd.depthFill) { if (pStage->glslShaderGroup) { int index = 0; if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) { index |= LIGHTDEF_ENTITY; } if (pStage->stateBits & GLS_ATEST_BITS) { index |= LIGHTDEF_USE_TCGEN_AND_TCMOD; } sp = &pStage->glslShaderGroup[index]; } else { int shaderAttribs = 0; if (tess.shader->numDeforms && !ShaderRequiresCPUDeforms(tess.shader)) { shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES; } if (glState.vertexAttribsInterpolation > 0.0f && backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) { shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION; } if (pStage->stateBits & GLS_ATEST_BITS) { shaderAttribs |= GENERICDEF_USE_TCGEN_AND_TCMOD; } sp = &tr.genericShader[shaderAttribs]; } } else if (pStage->glslShaderGroup) { int index = pStage->glslShaderIndex; if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) { index |= LIGHTDEF_ENTITY; } if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP) { index = LIGHTDEF_USE_LIGHTMAP; } sp = &pStage->glslShaderGroup[index]; if (pStage->glslShaderGroup == tr.lightallShader) { backEnd.pc.c_lightallDraws++; } } else { sp = GLSL_GetGenericShaderProgram(stage); backEnd.pc.c_genericDraws++; } GLSL_BindProgram(sp); GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen); if (deformGen != DGEN_NONE) { GLSL_SetUniformFloat5(sp, UNIFORM_DEFORMPARAMS, deformParams); GLSL_SetUniformFloat(sp, UNIFORM_TIME, tess.shaderTime); } if ( input->fogNum ) { GLSL_SetUniformVec4(sp, UNIFORM_FOGDISTANCE, fogDistanceVector); GLSL_SetUniformVec4(sp, UNIFORM_FOGDEPTH, fogDepthVector); GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT); } GL_State( pStage->stateBits ); { vec4_t baseColor; vec4_t vertColor; qboolean tint = qtrue; int stage2; ComputeShaderColors(pStage, baseColor, vertColor); for ( stage2 = stage + 1; stage2 < MAX_SHADER_STAGES; stage2++ ) { shaderStage_t *pStage2 = input->xstages[stage2]; unsigned int srcBlendBits; //unsigned int dstBlendBits; if ( !pStage2 ) { break; } srcBlendBits = pStage2->stateBits & GLS_SRCBLEND_BITS; //dstBlendBits = pStage2->stateBits & GLS_DSTBLEND_BITS; if (srcBlendBits == GLS_SRCBLEND_DST_COLOR) { tint = qfalse; break; } } if (!((tr.sunShadows || r_forceSun->integer) && tess.shader->sort <= SS_OPAQUE && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader)) { tint = qfalse; } if (tint) { // use VectorScale to only scale first three values, not alpha VectorScale(baseColor, backEnd.refdef.colorScale, baseColor); VectorScale(vertColor, backEnd.refdef.colorScale, vertColor); } GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor); GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor); } if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE) { vec4_t vec; VectorScale(backEnd.currentEntity->ambientLight, 1.0f / 255.0f, vec); GLSL_SetUniformVec3(sp, UNIFORM_AMBIENTLIGHT, vec); VectorScale(backEnd.currentEntity->directedLight, 1.0f / 255.0f, vec); GLSL_SetUniformVec3(sp, UNIFORM_DIRECTEDLIGHT, vec); VectorCopy(backEnd.currentEntity->lightDir, vec); vec[3] = 0.0f; GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, vec); GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 999999.0f); } if (pStage->alphaGen == AGEN_PORTAL) { GLSL_SetUniformFloat(sp, UNIFORM_PORTALRANGE, tess.shader->portalRange); } GLSL_SetUniformInt(sp, UNIFORM_COLORGEN, pStage->rgbGen); GLSL_SetUniformInt(sp, UNIFORM_ALPHAGEN, pStage->alphaGen); if ( input->fogNum ) { vec4_t fogColorMask; ComputeFogColorMask(pStage, fogColorMask); GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask); } ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix ); { vec4_t vector; VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector); VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector); } GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); if (pStage->bundle[0].tcGen == TCGEN_VECTOR) { vec3_t vec; VectorCopy(pStage->bundle[0].tcGenVectors[0], vec); GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR0, vec); VectorCopy(pStage->bundle[0].tcGenVectors[1], vec); GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec); } GLSL_SetUniformMatrix16(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); GLSL_SetUniformVec2(sp, UNIFORM_MATERIALINFO, pStage->materialInfo); //GLSL_SetUniformFloat(sp, UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale); // // do multitexture // if ( backEnd.depthFill ) { if (!(pStage->stateBits & GLS_ATEST_BITS)) GL_BindToTMU( tr.whiteImage, 0 ); else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 ) R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP ); } else if ( pStage->glslShaderGroup ) { int i; if ((r_lightmap->integer == 1 || r_lightmap->integer == 2) && pStage->bundle[TB_LIGHTMAP].image[0]) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { if (i == TB_LIGHTMAP) { R_BindAnimatedImageToTMU( &pStage->bundle[i], i); } else if (pStage->bundle[i].image[0]) { GL_BindToTMU( tr.whiteImage, i); } } } else if (r_lightmap->integer == 3 && pStage->bundle[TB_DELUXEMAP].image[0]) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { if (i == TB_LIGHTMAP) { R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i); } else if (pStage->bundle[i].image[0]) { GL_BindToTMU( tr.whiteImage, i); } } } else { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { if (pStage->bundle[i].image[0]) { R_BindAnimatedImageToTMU( &pStage->bundle[i], i); } } } } else if ( pStage->bundle[1].image[0] != 0 ) { R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); // // lightmap/secondary pass // if ( r_lightmap->integer ) { GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, GL_REPLACE); } else { GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, tess.shader->multitextureEnv); } R_BindAnimatedImageToTMU( &pStage->bundle[1], 1 ); } else { // // set state // if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer ) { GL_BindToTMU( tr.whiteImage, 0 ); } else R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, 0); } // // draw // if (input->multiDrawPrimitives) { R_DrawMultiElementsVBO(input->multiDrawPrimitives, input->multiDrawMinIndex, input->multiDrawMaxIndex, input->multiDrawNumIndexes, input->multiDrawFirstIndex); } else { R_DrawElementsVBO(input->numIndexes, input->firstIndex, input->minIndex, input->maxIndex); } // allow skipping out to show just lightmaps during development if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) ) { break; } if (backEnd.depthFill) break; } }
/* =================== RB_FogPass Blends a fog texture on top of everything else =================== */ static void RB_FogPass( void ) { fog_t *fog; vec4_t color; vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0}; float eyeT = 0; shaderProgram_t *sp; int deformGen; vec5_t deformParams; ComputeDeformValues(&deformGen, deformParams); { int index = 0; if (deformGen != DGEN_NONE) index |= FOGDEF_USE_DEFORM_VERTEXES; if (glState.vertexAttribsInterpolation) index |= FOGDEF_USE_VERTEX_ANIMATION; sp = &tr.fogShader[index]; } backEnd.pc.c_fogDraws++; GLSL_BindProgram(sp); fog = tr.world->fogs + tess.fogNum; GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen); if (deformGen != DGEN_NONE) { GLSL_SetUniformFloat5(sp, UNIFORM_DEFORMPARAMS, deformParams); GLSL_SetUniformFloat(sp, UNIFORM_TIME, tess.shaderTime); } color[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f; color[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f; color[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f; color[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f; GLSL_SetUniformVec4(sp, UNIFORM_COLOR, color); ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT); GLSL_SetUniformVec4(sp, UNIFORM_FOGDISTANCE, fogDistanceVector); GLSL_SetUniformVec4(sp, UNIFORM_FOGDEPTH, fogDepthVector); GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT); if ( tess.shader->fogPass == FP_EQUAL ) { GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); } else { GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } if (tess.multiDrawPrimitives) { shaderCommands_t *input = &tess; R_DrawMultiElementsVBO(input->multiDrawPrimitives, input->multiDrawMinIndex, input->multiDrawMaxIndex, input->multiDrawNumIndexes, input->multiDrawFirstIndex); } else { R_DrawElementsVBO(tess.numIndexes, tess.firstIndex, tess.minIndex, tess.maxIndex); } }
static void ForwardDlight( void ) { int l; //vec3_t origin; //float scale; float radius; 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]; if ( !backEnd.refdef.num_dlights ) { return; } ComputeDeformValues(&deformGen, deformParams); ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT); for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { dlight_t *dl; shaderProgram_t *sp; vec4_t vector; vec4_t texMatrix; vec4_t texOffTurb; if ( !( tess.dlightBits & ( 1 << l ) ) ) { continue; // this surface definately doesn't have any of this light } dl = &backEnd.refdef.dlights[l]; //VectorCopy( dl->transformed, origin ); radius = dl->radius; //scale = 1.0f / radius; //if (pStage->glslShaderGroup == tr.lightallShader) { int index = pStage->glslShaderIndex; index &= ~LIGHTDEF_LIGHTTYPE_MASK; index |= LIGHTDEF_USE_LIGHT_VECTOR; sp = &tr.lightallShader[index]; } backEnd.pc.c_lightallDraws++; GLSL_BindProgram(sp); GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); GLSL_SetUniformVec3(sp, UNIFORM_LOCALVIEWORIGIN, backEnd.or.viewOrigin); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen); if (deformGen != DGEN_NONE) { GLSL_SetUniformFloat5(sp, UNIFORM_DEFORMPARAMS, deformParams); GLSL_SetUniformFloat(sp, UNIFORM_TIME, tess.shaderTime); } if ( input->fogNum ) { vec4_t fogColorMask; GLSL_SetUniformVec4(sp, UNIFORM_FOGDISTANCE, fogDistanceVector); GLSL_SetUniformVec4(sp, UNIFORM_FOGDEPTH, fogDepthVector); GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT); ComputeFogColorMask(pStage, fogColorMask); GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask); } { vec4_t baseColor; vec4_t vertColor; ComputeShaderColors(pStage, baseColor, vertColor, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor); GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor); } if (pStage->alphaGen == AGEN_PORTAL) { GLSL_SetUniformFloat(sp, UNIFORM_PORTALRANGE, tess.shader->portalRange); } GLSL_SetUniformInt(sp, UNIFORM_COLORGEN, pStage->rgbGen); GLSL_SetUniformInt(sp, UNIFORM_ALPHAGEN, pStage->alphaGen); GLSL_SetUniformVec3(sp, UNIFORM_DIRECTEDLIGHT, dl->color); VectorSet(vector, 0, 0, 0); GLSL_SetUniformVec3(sp, UNIFORM_AMBIENTLIGHT, vector); VectorCopy(dl->origin, vector); vector[3] = 1.0f; GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, vector); GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, radius); GLSL_SetUniformVec4(sp, UNIFORM_NORMALSCALE, pStage->normalScale); GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, pStage->specularScale); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); if (pStage->bundle[TB_DIFFUSEMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP); // bind textures that are sampled and used in the glsl shader, and // bind whiteImage to textures that are sampled but zeroed in the glsl shader // // alternatives: // - use the last bound texture // -> costs more to sample a higher res texture then throw out the result // - disable texture sampling in glsl shader with #ifdefs, as before // -> increases the number of shaders that must be compiled // if (pStage->bundle[TB_NORMALMAP].image[0]) { R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP); } else if (r_normalMapping->integer) GL_BindToTMU( tr.whiteImage, TB_NORMALMAP ); if (pStage->bundle[TB_SPECULARMAP].image[0]) { R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP); } else if (r_specularMapping->integer) GL_BindToTMU( tr.whiteImage, TB_SPECULARMAP ); { vec4_t enableTextures; VectorSet4(enableTextures, 0.0f, 0.0f, 0.0f, 0.0f); GLSL_SetUniformVec4(sp, UNIFORM_ENABLETEXTURES, enableTextures); } if (r_dlightMode->integer >= 2) { GL_SelectTexture(TB_SHADOWMAP); GL_Bind(tr.shadowCubemaps[l]); GL_SelectTexture(0); } ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb); GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); // // draw // if (input->multiDrawPrimitives) { R_DrawMultiElementsVao(input->multiDrawPrimitives, input->multiDrawMinIndex, input->multiDrawMaxIndex, input->multiDrawNumIndexes, input->multiDrawFirstIndex); } else { R_DrawElementsVao(input->numIndexes, input->firstIndex, input->minIndex, input->maxIndex); } backEnd.pc.c_totalIndexes += tess.numIndexes; backEnd.pc.c_dlightIndexes += tess.numIndexes; backEnd.pc.c_dlightVertexes += tess.numVertexes; } }
static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0}; float eyeT = 0; int deformGen; vec5_t deformParams; ComputeDeformValues(&deformGen, deformParams); ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT); for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = input->xstages[stage]; shaderProgram_t *sp; vec4_t texMatrix; vec4_t texOffTurb; if ( !pStage ) { break; } if (backEnd.depthFill) { if (pStage->glslShaderGroup == tr.lightallShader) { int index = 0; if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) { index |= LIGHTDEF_ENTITY; } if (pStage->stateBits & GLS_ATEST_BITS) { index |= LIGHTDEF_USE_TCGEN_AND_TCMOD; } sp = &pStage->glslShaderGroup[index]; } else { int shaderAttribs = 0; if (tess.shader->numDeforms && !ShaderRequiresCPUDeforms(tess.shader)) { shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES; } if (glState.vertexAnimation) { shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION; } if (pStage->stateBits & GLS_ATEST_BITS) { shaderAttribs |= GENERICDEF_USE_TCGEN_AND_TCMOD; } sp = &tr.genericShader[shaderAttribs]; } } else if (pStage->glslShaderGroup == tr.lightallShader) { int index = pStage->glslShaderIndex; if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) { index |= LIGHTDEF_ENTITY; } if (r_sunlightMode->integer && (backEnd.viewParms.flags & VPF_USESUNLIGHT) && (index & LIGHTDEF_LIGHTTYPE_MASK)) { index |= LIGHTDEF_USE_SHADOWMAP; } if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP) { index = LIGHTDEF_USE_LIGHTMAP; } sp = &pStage->glslShaderGroup[index]; backEnd.pc.c_lightallDraws++; } else { sp = GLSL_GetGenericShaderProgram(stage); backEnd.pc.c_genericDraws++; } GLSL_BindProgram(sp); GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); GLSL_SetUniformVec3(sp, UNIFORM_LOCALVIEWORIGIN, backEnd.or.viewOrigin); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen); if (deformGen != DGEN_NONE) { GLSL_SetUniformFloat5(sp, UNIFORM_DEFORMPARAMS, deformParams); GLSL_SetUniformFloat(sp, UNIFORM_TIME, tess.shaderTime); } if ( input->fogNum ) { GLSL_SetUniformVec4(sp, UNIFORM_FOGDISTANCE, fogDistanceVector); GLSL_SetUniformVec4(sp, UNIFORM_FOGDEPTH, fogDepthVector); GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT); } GL_State( pStage->stateBits ); { vec4_t baseColor; vec4_t vertColor; ComputeShaderColors(pStage, baseColor, vertColor, pStage->stateBits); if ((backEnd.refdef.colorScale != 1.0f) && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL)) { // use VectorScale to only scale first three values, not alpha VectorScale(baseColor, backEnd.refdef.colorScale, baseColor); VectorScale(vertColor, backEnd.refdef.colorScale, vertColor); } GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor); GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor); } if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE) { vec4_t vec; VectorScale(backEnd.currentEntity->ambientLight, 1.0f / 255.0f, vec); GLSL_SetUniformVec3(sp, UNIFORM_AMBIENTLIGHT, vec); VectorScale(backEnd.currentEntity->directedLight, 1.0f / 255.0f, vec); GLSL_SetUniformVec3(sp, UNIFORM_DIRECTEDLIGHT, vec); VectorCopy(backEnd.currentEntity->lightDir, vec); vec[3] = 0.0f; GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, vec); GLSL_SetUniformVec3(sp, UNIFORM_MODELLIGHTDIR, backEnd.currentEntity->modelLightDir); GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 0.0f); } if (pStage->alphaGen == AGEN_PORTAL) { GLSL_SetUniformFloat(sp, UNIFORM_PORTALRANGE, tess.shader->portalRange); } GLSL_SetUniformInt(sp, UNIFORM_COLORGEN, pStage->rgbGen); GLSL_SetUniformInt(sp, UNIFORM_ALPHAGEN, pStage->alphaGen); if ( input->fogNum ) { vec4_t fogColorMask; ComputeFogColorMask(pStage, fogColorMask); GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask); } ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb); GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); if (pStage->bundle[0].tcGen == TCGEN_VECTOR) { vec3_t vec; VectorCopy(pStage->bundle[0].tcGenVectors[0], vec); GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR0, vec); VectorCopy(pStage->bundle[0].tcGenVectors[1], vec); GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec); } GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); GLSL_SetUniformVec4(sp, UNIFORM_NORMALSCALE, pStage->normalScale); GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, pStage->specularScale); //GLSL_SetUniformFloat(sp, UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale); // // do multitexture // if ( backEnd.depthFill ) { if (!(pStage->stateBits & GLS_ATEST_BITS)) GL_BindToTMU( tr.whiteImage, 0 ); else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 ) R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP ); } else if ( pStage->glslShaderGroup == tr.lightallShader ) { int i; vec4_t enableTextures; if (r_sunlightMode->integer && (backEnd.viewParms.flags & VPF_USESUNLIGHT) && (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK)) { GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP); GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTAMBIENT, backEnd.refdef.sunAmbCol); GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol); GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir); } VectorSet4(enableTextures, 0, 0, 0, 0); if ((r_lightmap->integer == 1 || r_lightmap->integer == 2) && pStage->bundle[TB_LIGHTMAP].image[0]) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { if (i == TB_LIGHTMAP) R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i); else GL_BindToTMU( tr.whiteImage, i ); } } else if (r_lightmap->integer == 3 && pStage->bundle[TB_DELUXEMAP].image[0]) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { if (i == TB_LIGHTMAP) R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i); else GL_BindToTMU( tr.whiteImage, i ); } } else { qboolean light = (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) != 0; qboolean fastLight = !(r_normalMapping->integer || r_specularMapping->integer); if (pStage->bundle[TB_DIFFUSEMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP); if (pStage->bundle[TB_LIGHTMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], TB_LIGHTMAP); // bind textures that are sampled and used in the glsl shader, and // bind whiteImage to textures that are sampled but zeroed in the glsl shader // // alternatives: // - use the last bound texture // -> costs more to sample a higher res texture then throw out the result // - disable texture sampling in glsl shader with #ifdefs, as before // -> increases the number of shaders that must be compiled // if (light && !fastLight) { if (pStage->bundle[TB_NORMALMAP].image[0]) { R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP); enableTextures[0] = 1.0f; } else if (r_normalMapping->integer) GL_BindToTMU( tr.whiteImage, TB_NORMALMAP ); if (pStage->bundle[TB_DELUXEMAP].image[0]) { R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], TB_DELUXEMAP); enableTextures[1] = 1.0f; } else if (r_deluxeMapping->integer) GL_BindToTMU( tr.whiteImage, TB_DELUXEMAP ); if (pStage->bundle[TB_SPECULARMAP].image[0]) { R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP); enableTextures[2] = 1.0f; } else if (r_specularMapping->integer) GL_BindToTMU( tr.whiteImage, TB_SPECULARMAP ); } enableTextures[3] = (r_cubeMapping->integer && !(tr.viewParms.flags & VPF_NOCUBEMAPS) && input->cubemapIndex) ? 1.0f : 0.0f; } GLSL_SetUniformVec4(sp, UNIFORM_ENABLETEXTURES, enableTextures); } else if ( pStage->bundle[1].image[0] != 0 ) { R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); R_BindAnimatedImageToTMU( &pStage->bundle[1], 1 ); } else { // // set state // R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); } // // testing cube map // if (!(tr.viewParms.flags & VPF_NOCUBEMAPS) && input->cubemapIndex && r_cubeMapping->integer) { vec4_t vec; GL_BindToTMU( tr.cubemaps[input->cubemapIndex - 1], TB_CUBEMAP); vec[0] = tr.cubemapOrigins[input->cubemapIndex - 1][0] - backEnd.viewParms.or.origin[0]; vec[1] = tr.cubemapOrigins[input->cubemapIndex - 1][1] - backEnd.viewParms.or.origin[1]; vec[2] = tr.cubemapOrigins[input->cubemapIndex - 1][2] - backEnd.viewParms.or.origin[2]; vec[3] = 1.0f; VectorScale4(vec, 1.0f / 1000.0f, vec); GLSL_SetUniformVec4(sp, UNIFORM_CUBEMAPINFO, vec); } // // draw // if (input->multiDrawPrimitives) { R_DrawMultiElementsVao(input->multiDrawPrimitives, input->multiDrawMinIndex, input->multiDrawMaxIndex, input->multiDrawNumIndexes, input->multiDrawFirstIndex); } else { R_DrawElementsVao(input->numIndexes, input->firstIndex, input->minIndex, input->maxIndex); } // allow skipping out to show just lightmaps during development if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) ) { break; } if (backEnd.depthFill) break; } }
/* =================== RB_FogPass Blends a fog texture on top of everything else =================== */ static void RB_FogPass( int wolfFog ) { fog_t *fog = NULL; vec4_t color; vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0}; float eyeT = 0; shaderProgram_t *sp; glfog_t *glFog = NULL; int deformGen; vec5_t deformParams; if ( tr.refdef.rdflags & RDF_SNOOPERVIEW ) { // no fog pass in snooper return; } if (!fogIsOn) return; if (wolfFog) { // from R_Fog(), altered slightly if ( backEnd.projection2D ) { return; } if ( backEnd.refdef.rdflags & RDF_DRAWINGSKY ) { if ( glfogsettings[FOG_SKY].registered ) { glFog = &glfogsettings[FOG_SKY]; } } if ( skyboxportal && backEnd.refdef.rdflags & RDF_SKYBOXPORTAL ) { if ( glfogsettings[FOG_PORTALVIEW].registered ) { glFog = &glfogsettings[FOG_PORTALVIEW]; } } else { if ( glfogNum > FOG_NONE ) { glFog = &glfogsettings[FOG_CURRENT]; } } if (!glFog) return; } ComputeDeformValues(&deformGen, deformParams); { int index = 0; if (deformGen != DGEN_NONE) index |= FOGDEF_USE_DEFORM_VERTEXES; if (glState.vertexAnimation) index |= FOGDEF_USE_VERTEX_ANIMATION; if (wolfFog) { if (glFog->mode == GL_LINEAR) index |= FOGDEF_USE_WOLF_FOG_LINEAR; else // if (glFog->mode == GL_EXP) index |= FOGDEF_USE_WOLF_FOG_EXPONENTIAL; } sp = &tr.fogShader[index]; } backEnd.pc.c_fogDraws++; GLSL_BindProgram(sp); if (!wolfFog) fog = tr.world->fogs + tess.fogNum; GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen); if (deformGen != DGEN_NONE) { GLSL_SetUniformFloat5(sp, UNIFORM_DEFORMPARAMS, deformParams); GLSL_SetUniformFloat(sp, UNIFORM_TIME, tess.shaderTime); } if (wolfFog) { color[0] = glFog->color[0]; color[1] = glFog->color[1]; color[2] = glFog->color[2]; color[3] = glFog->color[3]; } else { color[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f; color[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f; color[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f; color[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f; } GLSL_SetUniformVec4(sp, UNIFORM_COLOR, color); ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT, glFog); GLSL_SetUniformVec4(sp, UNIFORM_FOGDISTANCE, fogDistanceVector); GLSL_SetUniformVec4(sp, UNIFORM_FOGDEPTH, fogDepthVector); GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT); if ( tess.shader->fogPass == FP_EQUAL ) { GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); } else { GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } if (tess.multiDrawPrimitives) { shaderCommands_t *input = &tess; R_DrawMultiElementsVBO(input->multiDrawPrimitives, input->multiDrawMinIndex, input->multiDrawMaxIndex, input->multiDrawNumIndexes, input->multiDrawFirstIndex); } else { R_DrawElementsVBO(tess.numIndexes, tess.firstIndex, tess.minIndex, tess.maxIndex); } }