diff options
Diffstat (limited to 'src/rend2/tr_shade.c')
-rw-r--r-- | src/rend2/tr_shade.c | 1866 |
1 files changed, 0 insertions, 1866 deletions
diff --git a/src/rend2/tr_shade.c b/src/rend2/tr_shade.c deleted file mode 100644 index b4758a86..00000000 --- a/src/rend2/tr_shade.c +++ /dev/null @@ -1,1866 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// tr_shade.c - -#include "tr_local.h" -#if idppc_altivec && !defined(MACOS_X) -#include <altivec.h> -#endif - -/* - - THIS ENTIRE FILE IS BACK END - - This file deals with applying shaders to surface data in the tess struct. -*/ - - -/* -================== -R_DrawElements - -================== -*/ - -void R_DrawElementsVBO( int numIndexes, glIndex_t firstIndex, glIndex_t minIndex, glIndex_t maxIndex ) -{ - if (glRefConfig.drawRangeElements) - qglDrawRangeElementsEXT(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE))); - else - qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE))); - -} - - -static void R_DrawMultiElementsVBO( int multiDrawPrimitives, glIndex_t *multiDrawMinIndex, glIndex_t *multiDrawMaxIndex, - GLsizei *multiDrawNumIndexes, glIndex_t **multiDrawFirstIndex) -{ - if (glRefConfig.multiDrawArrays) - { - qglMultiDrawElementsEXT(GL_TRIANGLES, multiDrawNumIndexes, GL_INDEX_TYPE, (const GLvoid **)multiDrawFirstIndex, multiDrawPrimitives); - } - else - { - int i; - - if (glRefConfig.drawRangeElements) - { - for (i = 0; i < multiDrawPrimitives; i++) - { - qglDrawRangeElementsEXT(GL_TRIANGLES, multiDrawMinIndex[i], multiDrawMaxIndex[i], multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]); - } - } - else - { - for (i = 0; i < multiDrawPrimitives; i++) - { - qglDrawElements(GL_TRIANGLES, multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]); - } - } - } -} - - -/* -============================================================= - -SURFACE SHADERS - -============================================================= -*/ - -shaderCommands_t tess; - - -/* -================= -R_BindAnimatedImageToTMU - -================= -*/ -static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) { - int index; - - if ( bundle->isVideoMap ) { - int oldtmu = glState.currenttmu; - GL_SelectTexture(tmu); - ri.CIN_RunCinematic(bundle->videoMapHandle); - ri.CIN_UploadCinematic(bundle->videoMapHandle); - GL_SelectTexture(oldtmu); - return; - } - - if ( bundle->numImageAnimations <= 1 ) { - GL_BindToTMU( bundle->image[0], tmu); - return; - } - - // it is necessary to do this messy calc to make sure animations line up - // exactly with waveforms of the same frequency - index = ri.ftol(tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE); - index >>= FUNCTABLE_SIZE2; - - if ( index < 0 ) { - index = 0; // may happen with shader time offsets - } - index %= bundle->numImageAnimations; - - GL_BindToTMU( bundle->image[ index ], tmu ); -} - - -/* -================ -DrawTris - -Draws triangle outlines for debugging -================ -*/ -static void DrawTris (shaderCommands_t *input) { - GL_Bind( tr.whiteImage ); - - GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); - qglDepthRange( 0, 0 ); - - { - shaderProgram_t *sp = &tr.textureColorShader; - vec4_t color; - - GLSL_VertexAttribsState(ATTR_POSITION); - GLSL_BindProgram(sp); - - GLSL_SetUniformMatrix16(sp, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - VectorSet4(color, 1, 1, 1, 1); - GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color); - - 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); - } - } - - qglDepthRange( 0, 1 ); -} - - -/* -================ -DrawNormals - -Draws vertex normals for debugging -================ -*/ -static void DrawNormals (shaderCommands_t *input) { - //FIXME: implement this -} - -/* -============== -RB_BeginSurface - -We must set some things up before beginning any tesselation, -because a surface may be forced to perform a RB_End due -to overflow. -============== -*/ -void RB_BeginSurface( shader_t *shader, int fogNum ) { - - shader_t *state = (shader->remappedShader) ? shader->remappedShader : shader; - - tess.numIndexes = 0; - tess.firstIndex = 0; - tess.numVertexes = 0; - tess.multiDrawPrimitives = 0; - tess.shader = state; - tess.fogNum = fogNum; - tess.dlightBits = 0; // will be OR'd in by surface functions - tess.pshadowBits = 0; // will be OR'd in by surface functions - tess.xstages = state->stages; - tess.numPasses = state->numUnfoggedPasses; - tess.currentStageIteratorFunc = state->optimalStageIteratorFunc; - tess.useInternalVBO = qtrue; - - tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset; - if (tess.shader->clampTime && tess.shaderTime >= tess.shader->clampTime) { - tess.shaderTime = tess.shader->clampTime; - } - - if (backEnd.viewParms.flags & VPF_SHADOWMAP) - { - tess.currentStageIteratorFunc = RB_StageIteratorGeneric; - } -} - - - -extern float EvalWaveForm( const waveForm_t *wf ); -extern float EvalWaveFormClamped( const waveForm_t *wf ); - - -static void ComputeTexMatrix( shaderStage_t *pStage, int bundleNum, float *outmatrix) -{ - int tm; - float matrix[16], currentmatrix[16]; - textureBundle_t *bundle = &pStage->bundle[bundleNum]; - - Matrix16Identity(outmatrix); - Matrix16Identity(currentmatrix); - - for ( tm = 0; tm < bundle->numTexMods ; tm++ ) { - switch ( bundle->texMods[tm].type ) - { - - case TMOD_NONE: - tm = TR_MAX_TEXMODS; // break out of for loop - break; - - case TMOD_TURBULENT: - RB_CalcTurbulentTexMatrix( &bundle->texMods[tm].wave, - matrix ); - outmatrix[12] = matrix[12]; - outmatrix[13] = matrix[13]; - Matrix16Copy(outmatrix, currentmatrix); - break; - - case TMOD_ENTITY_TRANSLATE: - RB_CalcScrollTexMatrix( backEnd.currentEntity->e.shaderTexCoord, - matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); - break; - - case TMOD_SCROLL: - RB_CalcScrollTexMatrix( bundle->texMods[tm].scroll, - matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); - break; - - case TMOD_SCALE: - RB_CalcScaleTexMatrix( bundle->texMods[tm].scale, - matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); - break; - - case TMOD_STRETCH: - RB_CalcStretchTexMatrix( &bundle->texMods[tm].wave, - matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); - break; - - case TMOD_TRANSFORM: - RB_CalcTransformTexMatrix( &bundle->texMods[tm], - matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); - break; - - case TMOD_ROTATE: - RB_CalcRotateTexMatrix( bundle->texMods[tm].rotateSpeed, - matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); - break; - - default: - ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'", bundle->texMods[tm].type, tess.shader->name ); - break; - } - } -} - - -static void ComputeDeformValues(int *deformGen, vec5_t deformParams) -{ - // u_DeformGen - *deformGen = DGEN_NONE; - if(!ShaderRequiresCPUDeforms(tess.shader)) - { - deformStage_t *ds; - - // only support the first one - ds = &tess.shader->deforms[0]; - - switch (ds->deformation) - { - case DEFORM_WAVE: - *deformGen = ds->deformationWave.func; - - deformParams[0] = ds->deformationWave.base; - deformParams[1] = ds->deformationWave.amplitude; - deformParams[2] = ds->deformationWave.phase; - deformParams[3] = ds->deformationWave.frequency; - deformParams[4] = ds->deformationSpread; - break; - - case DEFORM_BULGE: - *deformGen = DGEN_BULGE; - - deformParams[0] = 0; - deformParams[1] = ds->bulgeHeight; // amplitude - deformParams[2] = ds->bulgeWidth; // phase - deformParams[3] = ds->bulgeSpeed; // frequency - deformParams[4] = 0; - break; - - default: - break; - } - } -} - - -static void ProjectDlightTexture( void ) { - int l; - vec3_t origin; - float scale; - float radius; - int deformGen; - vec5_t deformParams; - - if ( !backEnd.refdef.num_dlights ) { - return; - } - - ComputeDeformValues(&deformGen, deformParams); - - for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { - dlight_t *dl; - shaderProgram_t *sp; - vec4_t vector; - - 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; - - sp = &tr.dlightShader[deformGen == DGEN_NONE ? 0 : 1]; - - backEnd.pc.c_dlightDraws++; - - GLSL_BindProgram(sp); - - GLSL_SetUniformMatrix16(sp, DLIGHT_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - - GLSL_SetUniformFloat(sp, DLIGHT_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); - - GLSL_SetUniformInt(sp, DLIGHT_UNIFORM_DEFORMGEN, deformGen); - if (deformGen != DGEN_NONE) - { - GLSL_SetUniformFloat5(sp, DLIGHT_UNIFORM_DEFORMPARAMS, deformParams); - GLSL_SetUniformFloat(sp, DLIGHT_UNIFORM_TIME, tess.shaderTime); - } - - vector[0] = dl->color[0]; - vector[1] = dl->color[1]; - vector[2] = dl->color[2]; - vector[3] = 1.0f; - GLSL_SetUniformVec4(sp, DLIGHT_UNIFORM_COLOR, vector); - - vector[0] = origin[0]; - vector[1] = origin[1]; - vector[2] = origin[2]; - vector[3] = scale; - GLSL_SetUniformVec4(sp, DLIGHT_UNIFORM_DLIGHTINFO, vector); - - GL_Bind( tr.dlightImage ); - - // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light - // where they aren't rendered - if ( dl->additive ) { - GL_State( GLS_ATEST_GT_0 | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); - } - else { - GL_State( GLS_ATEST_GT_0 | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); - } - - 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); - } - - backEnd.pc.c_totalIndexes += tess.numIndexes; - backEnd.pc.c_dlightIndexes += tess.numIndexes; - } -} - - -static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor ) -{ - // - // rgbGen - // - switch ( pStage->rgbGen ) - { - case CGEN_IDENTITY: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; - case CGEN_IDENTITY_LIGHTING: - baseColor[0] = - baseColor[1] = - baseColor[2] = tr.identityLight; - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; - case CGEN_EXACT_VERTEX: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 0.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 1.0f; - break; - case CGEN_EXACT_VERTEX_LIT: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 0.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 1.0f; - break; - case CGEN_CONST: - baseColor[0] = pStage->constantColor[0] / 255.0f; - baseColor[1] = pStage->constantColor[1] / 255.0f; - baseColor[2] = pStage->constantColor[2] / 255.0f; - baseColor[3] = pStage->constantColor[3] / 255.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; - case CGEN_VERTEX: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 0.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = tr.identityLight; - vertColor[3] = 1.0f; - break; - case CGEN_VERTEX_LIT: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 0.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = tr.identityLight; - break; - case CGEN_ONE_MINUS_VERTEX: - baseColor[0] = - baseColor[1] = - baseColor[2] = tr.identityLight; - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = -tr.identityLight; - vertColor[3] = 0.0f; - break; - case CGEN_FOG: - { - fog_t *fog; - - fog = tr.world->fogs + tess.fogNum; - - baseColor[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f; - baseColor[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f; - baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f; - baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f; - } - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; - case CGEN_WAVEFORM: - baseColor[0] = - baseColor[1] = - baseColor[2] = RB_CalcWaveColorSingle( &pStage->rgbWave ); - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; - case CGEN_ENTITY: - if (backEnd.currentEntity) - { - baseColor[0] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[0] / 255.0f; - baseColor[1] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[1] / 255.0f; - baseColor[2] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f; - baseColor[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f; - } - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; - case CGEN_ONE_MINUS_ENTITY: - if (backEnd.currentEntity) - { - baseColor[0] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[0] / 255.0f; - baseColor[1] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[1] / 255.0f; - baseColor[2] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f; - baseColor[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f; - } - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; - case CGEN_LIGHTING_DIFFUSE: - case CGEN_BAD: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; - } - - // - // alphaGen - // - switch ( pStage->alphaGen ) - { - case AGEN_SKIP: - break; - case AGEN_IDENTITY: - baseColor[3] = 1.0f; - vertColor[3] = 0.0f; - break; - case AGEN_CONST: - baseColor[3] = pStage->constantColor[3] / 255.0f; - vertColor[3] = 0.0f; - break; - case AGEN_WAVEFORM: - baseColor[3] = RB_CalcWaveAlphaSingle( &pStage->alphaWave ); - vertColor[3] = 0.0f; - break; - case AGEN_ENTITY: - if (backEnd.currentEntity) - { - baseColor[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f; - } - vertColor[3] = 0.0f; - break; - case AGEN_ONE_MINUS_ENTITY: - if (backEnd.currentEntity) - { - baseColor[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f; - } - vertColor[3] = 0.0f; - break; - case AGEN_VERTEX: - baseColor[3] = 0.0f; - vertColor[3] = 1.0f; - break; - case AGEN_ONE_MINUS_VERTEX: - baseColor[3] = 1.0f; - vertColor[3] = -1.0f; - break; - case AGEN_LIGHTING_SPECULAR: - case AGEN_PORTAL: - case AGEN_FRESNEL: - // Done entirely in vertex program - baseColor[3] = 1.0f; - vertColor[3] = 0.0f; - break; - } - - // FIXME: find some way to implement this. -#if 0 - // if in greyscale rendering mode turn all color values into greyscale. - if(r_greyscale->integer) - { - int scale; - - for(i = 0; i < tess.numVertexes; i++) - { - scale = (tess.svars.colors[i][0] + tess.svars.colors[i][1] + tess.svars.colors[i][2]) / 3; - tess.svars.colors[i][0] = tess.svars.colors[i][1] = tess.svars.colors[i][2] = scale; - } - } -#endif -} - - -static void ComputeFogValues(vec4_t fogDistanceVector, vec4_t fogDepthVector, float *eyeT) -{ - // from RB_CalcFogTexCoords() - fog_t *fog; - vec3_t local; - - if (!tess.fogNum) - return; - - fog = tr.world->fogs + tess.fogNum; - - VectorSubtract( backEnd.or.origin, backEnd.viewParms.or.origin, local ); - fogDistanceVector[0] = -backEnd.or.modelMatrix[2]; - fogDistanceVector[1] = -backEnd.or.modelMatrix[6]; - fogDistanceVector[2] = -backEnd.or.modelMatrix[10]; - fogDistanceVector[3] = DotProduct( local, backEnd.viewParms.or.axis[0] ); - - // scale the fog vectors based on the fog's thickness - VectorScale4(fogDistanceVector, fog->tcScale, fogDistanceVector); - - // rotate the gradient vector for this orientation - if ( fog->hasSurface ) { - fogDepthVector[0] = fog->surface[0] * backEnd.or.axis[0][0] + - fog->surface[1] * backEnd.or.axis[0][1] + fog->surface[2] * backEnd.or.axis[0][2]; - fogDepthVector[1] = fog->surface[0] * backEnd.or.axis[1][0] + - fog->surface[1] * backEnd.or.axis[1][1] + fog->surface[2] * backEnd.or.axis[1][2]; - fogDepthVector[2] = fog->surface[0] * backEnd.or.axis[2][0] + - fog->surface[1] * backEnd.or.axis[2][1] + fog->surface[2] * backEnd.or.axis[2][2]; - fogDepthVector[3] = -fog->surface[3] + DotProduct( backEnd.or.origin, fog->surface ); - - *eyeT = DotProduct( backEnd.or.viewOrigin, fogDepthVector ) + fogDepthVector[3]; - } else { - *eyeT = 1; // non-surface fog always has eye inside - } -} - - -static void ComputeFogColorMask( shaderStage_t *pStage, vec4_t fogColorMask ) -{ - switch(pStage->adjustColorsForFog) - { - case ACFF_MODULATE_RGB: - fogColorMask[0] = - fogColorMask[1] = - fogColorMask[2] = 1.0f; - fogColorMask[3] = 0.0f; - break; - case ACFF_MODULATE_ALPHA: - fogColorMask[0] = - fogColorMask[1] = - fogColorMask[2] = 0.0f; - fogColorMask[3] = 1.0f; - break; - case ACFF_MODULATE_RGBA: - fogColorMask[0] = - fogColorMask[1] = - fogColorMask[2] = - fogColorMask[3] = 1.0f; - break; - default: - fogColorMask[0] = - fogColorMask[1] = - fogColorMask[2] = - fogColorMask[3] = 0.0f; - break; - } -} - - -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, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); - - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); - - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, deformGen); - if (deformGen != DGEN_NONE) - { - GLSL_SetUniformFloat5(sp, GENERIC_UNIFORM_DEFORMPARAMS, deformParams); - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime); - } - - if ( input->fogNum ) { - vec4_t fogColorMask; - - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector); - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_FOGEYET, eyeT); - - ComputeFogColorMask(pStage, fogColorMask); - - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGCOLORMASK, fogColorMask); - } - - { - vec4_t baseColor; - vec4_t vertColor; - - ComputeShaderColors(pStage, baseColor, vertColor); - - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_BASECOLOR, baseColor); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_VERTCOLOR, vertColor); - } - - if (pStage->alphaGen == AGEN_PORTAL) - { - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_PORTALRANGE, tess.shader->portalRange); - } - - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, pStage->rgbGen); - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, pStage->alphaGen); - - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, dl->color); - - VectorSet(vector, 0, 0, 0); - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, vector); - - VectorCopy(dl->origin, vector); - vector[3] = 1.0f; - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, vector); - - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_LIGHTRADIUS, radius); - - GLSL_SetUniformVec2(sp, GENERIC_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, GENERIC_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, GENERIC_UNIFORM_DIFFUSETEXMATRIX, vector); - - VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_DIFFUSETEXOFFTURB, vector); - - GLSL_SetUniformInt(sp, GENERIC_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, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); - - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); - - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, deformGen); - if (deformGen != DGEN_NONE) - { - GLSL_SetUniformFloat5(sp, GENERIC_UNIFORM_DEFORMPARAMS, deformParams); - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime); - } - - if ( input->fogNum ) { - vec4_t fogColorMask; - - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector); - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_FOGEYET, eyeT); - - ComputeFogColorMask(pStage, fogColorMask); - - GLSL_SetUniformVec4(sp, GENERIC_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, GENERIC_UNIFORM_BASECOLOR, baseColor); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_VERTCOLOR, vertColor); - } - - if (pStage->alphaGen == AGEN_PORTAL) - { - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_PORTALRANGE, tess.shader->portalRange); - } - - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, pStage->rgbGen); - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, pStage->alphaGen); - - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, backEnd.refdef.sunCol); - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, backEnd.refdef.sunAmbCol); - - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir); - - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_LIGHTRADIUS, 9999999999.9f); - - GLSL_SetUniformVec2(sp, GENERIC_UNIFORM_MATERIALINFO, pStage->materialInfo); - - GL_State( stageGlState[stage] ); - - GLSL_SetUniformMatrix16(sp, GENERIC_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, GENERIC_UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]); - GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]); - GLSL_SetUniformMatrix16(sp, GENERIC_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, GENERIC_UNIFORM_DIFFUSETEXMATRIX, vector); - - VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_DIFFUSETEXOFFTURB, vector); - - GLSL_SetUniformInt(sp, GENERIC_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 ProjectPshadowVBOGLSL( void ) { - int l; - vec3_t origin; - float radius; - - int deformGen; - vec5_t deformParams; - - shaderCommands_t *input = &tess; - - if ( !backEnd.refdef.num_pshadows ) { - return; - } - - ComputeDeformValues(&deformGen, deformParams); - - for ( l = 0 ; l < backEnd.refdef.num_pshadows ; l++ ) { - pshadow_t *ps; - shaderProgram_t *sp; - vec4_t vector; - - if ( !( tess.pshadowBits & ( 1 << l ) ) ) { - continue; // this surface definately doesn't have any of this shadow - } - - ps = &backEnd.refdef.pshadows[l]; - VectorCopy( ps->lightOrigin, origin ); - radius = ps->lightRadius; - - sp = &tr.pshadowShader; - - GLSL_BindProgram(sp); - - GLSL_SetUniformMatrix16(sp, PSHADOW_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - - VectorCopy(origin, vector); - vector[3] = 1.0f; - GLSL_SetUniformVec4(sp, PSHADOW_UNIFORM_LIGHTORIGIN, vector); - - VectorScale(ps->lightViewAxis[0], 1.0f / ps->viewRadius, vector); - GLSL_SetUniformVec3(sp, PSHADOW_UNIFORM_LIGHTFORWARD, vector); - - VectorScale(ps->lightViewAxis[1], 1.0f / ps->viewRadius, vector); - GLSL_SetUniformVec3(sp, PSHADOW_UNIFORM_LIGHTRIGHT, vector); - - VectorScale(ps->lightViewAxis[2], 1.0f / ps->viewRadius, vector); - GLSL_SetUniformVec3(sp, PSHADOW_UNIFORM_LIGHTUP, vector); - - GLSL_SetUniformFloat(sp, PSHADOW_UNIFORM_LIGHTRADIUS, radius); - - // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light - // where they aren't rendered - GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); - - GL_BindToTMU( tr.pshadowMaps[l], TB_DIFFUSEMAP ); - - // - // 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; - } -} - - - -/* -=================== -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, FOGPASS_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - - GLSL_SetUniformFloat(sp, FOGPASS_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); - - GLSL_SetUniformInt(sp, FOGPASS_UNIFORM_DEFORMGEN, deformGen); - if (deformGen != DGEN_NONE) - { - GLSL_SetUniformFloat5(sp, FOGPASS_UNIFORM_DEFORMPARAMS, deformParams); - GLSL_SetUniformFloat(sp, FOGPASS_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, FOGPASS_UNIFORM_COLOR, color); - - ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT); - - GLSL_SetUniformVec4(sp, FOGPASS_UNIFORM_FOGDISTANCE, fogDistanceVector); - GLSL_SetUniformVec4(sp, FOGPASS_UNIFORM_FOGDEPTH, fogDepthVector); - GLSL_SetUniformFloat(sp, FOGPASS_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 unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input ) -{ - unsigned int vertexAttribs = input->shader->vertexAttribs; - - if(glState.vertexAttribsInterpolation > 0.0f) - { - vertexAttribs |= ATTR_POSITION2; - if (vertexAttribs & ATTR_NORMAL) - { - vertexAttribs |= ATTR_NORMAL2; -#ifdef USE_VERT_TANGENT_SPACE - vertexAttribs |= ATTR_TANGENT2; - vertexAttribs |= ATTR_BITANGENT2; -#endif - } - } - - return vertexAttribs; -} - -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, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); - - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); - - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, deformGen); - if (deformGen != DGEN_NONE) - { - GLSL_SetUniformFloat5(sp, GENERIC_UNIFORM_DEFORMPARAMS, deformParams); - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime); - } - - if ( input->fogNum ) { - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector); - GLSL_SetUniformFloat(sp, GENERIC_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, GENERIC_UNIFORM_BASECOLOR, baseColor); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_VERTCOLOR, vertColor); - } - - if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE) - { - vec4_t vec; - - VectorScale(backEnd.currentEntity->ambientLight, 1.0f / 255.0f, vec); - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, vec); - - VectorScale(backEnd.currentEntity->directedLight, 1.0f / 255.0f, vec); - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, vec); - - VectorCopy(backEnd.currentEntity->lightDir, vec); - vec[3] = 0.0f; - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, vec); - - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_LIGHTRADIUS, 999999.0f); - } - - if (pStage->alphaGen == AGEN_PORTAL) - { - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_PORTALRANGE, tess.shader->portalRange); - } - - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, pStage->rgbGen); - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, pStage->alphaGen); - - if ( input->fogNum ) - { - vec4_t fogColorMask; - - ComputeFogColorMask(pStage, fogColorMask); - - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGCOLORMASK, fogColorMask); - } - - ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix ); - - { - vec4_t vector; - VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_DIFFUSETEXMATRIX, vector); - - VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]); - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_DIFFUSETEXOFFTURB, vector); - } - - GLSL_SetUniformInt(sp, GENERIC_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, GENERIC_UNIFORM_TCGEN0VECTOR0, vec); - VectorCopy(pStage->bundle[0].tcGenVectors[1], vec); - GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_TCGEN0VECTOR1, vec); - } - - GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); - - GLSL_SetUniformVec2(sp, GENERIC_UNIFORM_MATERIALINFO, pStage->materialInfo); - - //GLSL_SetUniformFloat(sp, GENERIC_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, GENERIC_UNIFORM_TEXTURE1ENV, GL_REPLACE); - } else { - GLSL_SetUniformInt(sp, GENERIC_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, GENERIC_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; - } -} - - -static void RB_RenderShadowmap( shaderCommands_t *input ) -{ - int deformGen; - vec5_t deformParams; - - ComputeDeformValues(&deformGen, deformParams); - - { - shaderProgram_t *sp = &tr.shadowmapShader; - - vec4_t vector; - - GLSL_BindProgram(sp); - - GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - - GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); - - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); - - GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, deformGen); - if (deformGen != DGEN_NONE) - { - GLSL_SetUniformFloat5(sp, GENERIC_UNIFORM_DEFORMPARAMS, deformParams); - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime); - } - - VectorCopy(backEnd.viewParms.or.origin, vector); - vector[3] = 1.0f; - GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, vector); - GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_LIGHTRADIUS, backEnd.viewParms.zFar); - - GL_State( 0 ); - - // - // do multitexture - // - //if ( pStage->glslShaderGroup ) - { - // - // 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); - } - } - } -} - - - -/* -** RB_StageIteratorGeneric -*/ -void RB_StageIteratorGeneric( void ) -{ - shaderCommands_t *input; - unsigned int vertexAttribs = 0; - - input = &tess; - - if (!input->numVertexes || !input->numIndexes) - { - return; - } - - if (tess.useInternalVBO) - { - RB_DeformTessGeometry(); - } - - vertexAttribs = RB_CalcShaderVertexAttribs( input ); - - if (tess.useInternalVBO) - { - RB_UpdateVBOs(vertexAttribs); - } - else - { - backEnd.pc.c_staticVboDraws++; - } - - // - // log this call - // - if ( r_logFile->integer ) - { - // don't just call LogComment, or we will get - // a call to va() every frame! - GLimp_LogComment( va("--- RB_StageIteratorGeneric( %s ) ---\n", tess.shader->name) ); - } - - // - // set face culling appropriately - // - if ((backEnd.viewParms.flags & VPF_DEPTHSHADOW)) - { - //GL_Cull( CT_TWO_SIDED ); - - if (input->shader->cullType == CT_TWO_SIDED) - GL_Cull( CT_TWO_SIDED ); - else if (input->shader->cullType == CT_FRONT_SIDED) - GL_Cull( CT_BACK_SIDED ); - else - GL_Cull( CT_FRONT_SIDED ); - - } - else - GL_Cull( input->shader->cullType ); - - // set polygon offset if necessary - if ( input->shader->polygonOffset ) - { - qglEnable( GL_POLYGON_OFFSET_FILL ); - qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); - } - - // - // Set vertex attribs and pointers - // - GLSL_VertexAttribsState(vertexAttribs); - - // - // render depth if in depthfill mode - // - if (backEnd.depthFill) - { - RB_IterateStagesGeneric( input ); - - // - // reset polygon offset - // - if ( input->shader->polygonOffset ) - { - qglDisable( GL_POLYGON_OFFSET_FILL ); - } - - return; - } - - // - // render shadowmap if in shadowmap mode - // - if (backEnd.viewParms.flags & VPF_SHADOWMAP) - { - if ( input->shader->sort == SS_OPAQUE ) - { - RB_RenderShadowmap( input ); - } - // - // reset polygon offset - // - if ( input->shader->polygonOffset ) - { - qglDisable( GL_POLYGON_OFFSET_FILL ); - } - - return; - } - - // - // - // call shader function - // - RB_IterateStagesGeneric( input ); - - // - // pshadows! - // - if (glRefConfig.framebufferObject && tess.pshadowBits && tess.shader->sort <= SS_OPAQUE - && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) { - 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) - { - ForwardDlight(); - } - else - { - ProjectDlightTexture(); - } - } - - if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && tess.shader->sort <= SS_OPAQUE - //if ((tr.sunShadows || r_forceSunlight->value > 0.0f) && tess.shader->sort <= SS_OPAQUE - && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) { - ForwardSunlight(); - } - - // - // now do fog - // - if ( tess.fogNum && tess.shader->fogPass ) { - RB_FogPass(); - } - - // - // reset polygon offset - // - if ( input->shader->polygonOffset ) - { - qglDisable( GL_POLYGON_OFFSET_FILL ); - } -} - - -/* -** RB_EndSurface -*/ -void RB_EndSurface( void ) { - shaderCommands_t *input; - - input = &tess; - - if (input->numIndexes == 0 || input->numVertexes == 0) { - return; - } - - if (input->indexes[SHADER_MAX_INDEXES-1] != 0) { - ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_INDEXES hit"); - } - if (input->xyz[SHADER_MAX_VERTEXES-1][0] != 0) { - ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_VERTEXES hit"); - } - - if ( tess.shader == tr.shadowShader ) { - RB_ShadowTessEnd(); - return; - } - - // for debugging of sort order issues, stop rendering after a given sort value - if ( r_debugSort->integer && r_debugSort->integer < tess.shader->sort ) { - return; - } - - // - // update performance counters - // - backEnd.pc.c_shaders++; - backEnd.pc.c_vertexes += tess.numVertexes; - backEnd.pc.c_indexes += tess.numIndexes; - backEnd.pc.c_totalIndexes += tess.numIndexes * tess.numPasses; - - // - // call off to shader specific tess end function - // - tess.currentStageIteratorFunc(); - - // - // draw debugging stuff - // - if ( r_showtris->integer ) { - DrawTris (input); - } - if ( r_shownormals->integer ) { - DrawNormals (input); - } - // clear shader so we can tell we don't have any unclosed surfaces - tess.numIndexes = 0; - tess.numVertexes = 0; - tess.firstIndex = 0; - tess.multiDrawPrimitives = 0; - - GLimp_LogComment( "----------\n" ); -} |