/* ** RB_IterateStagesGeneric */ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = tess.xstages[stage]; if ( !pStage ) { break; } ComputeColors( pStage ); ComputeTexCoords( pStage ); if ( !setArraysOnce ) { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); } // // do multitexture // if ( pStage->bundle[1].image[0] != 0 ) { DrawMultitextured( input, stage ); } else { if ( !setArraysOnce ) { qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); } // // set state // if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer ) { GL_Bind( tr.whiteImage ); } else R_BindAnimatedImage( &pStage->bundle[0] ); GL_State( pStage->stateBits ); // // draw // R_DrawElements( input->numIndexes, input->indexes ); } // 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; } } }
/* ** RB_IterateStagesGeneric */ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = tess.xstages[stage]; if ( !pStage ) { break; } ComputeColors( pStage ); ComputeTexCoords( pStage ); if ( !setArraysOnce ) { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); } // // do multitexture // if ( pStage->bundle[1].image[0] != 0 ) { DrawMultitextured( input, stage ); } else { int fadeStart, fadeEnd; if ( !setArraysOnce ) { qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); } // // set state // R_BindAnimatedImage( &pStage->bundle[0] ); // Ridah, per stage fogging (detail textures) if ( tess.shader->noFog && pStage->isFogged ) { R_FogOn(); } else if ( tess.shader->noFog && !pStage->isFogged ) { R_FogOff(); // turn it back off } else { // make sure it's on R_FogOn(); } // done. //----(SA) fading model stuff fadeStart = backEnd.currentEntity->e.fadeStartTime; if ( fadeStart ) { fadeEnd = backEnd.currentEntity->e.fadeEndTime; if ( fadeStart > tr.refdef.time ) { // has not started to fade yet GL_State( pStage->stateBits ); } else { int i; unsigned int tempState; float alphaval; if ( fadeEnd < tr.refdef.time ) { // entity faded out completely continue; } alphaval = (float)( fadeEnd - tr.refdef.time ) / (float)( fadeEnd - fadeStart ); tempState = pStage->stateBits; // remove the current blend, and don't write to Z buffer tempState &= ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_DEPTHMASK_TRUE ); // set the blend to src_alpha, dst_one_minus_src_alpha tempState |= ( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); GL_State( tempState ); GL_Cull( CT_FRONT_SIDED ); // modulate the alpha component of each vertex in the render list for ( i = 0; i < tess.numVertexes; i++ ) { tess.svars.colors[i][0] *= alphaval; tess.svars.colors[i][1] *= alphaval; tess.svars.colors[i][2] *= alphaval; tess.svars.colors[i][3] *= alphaval; } } } //----(SA) end // ydnar: lightmap stages should be GL_ONE GL_ZERO so they can be seen else if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) ) { unsigned int stateBits; stateBits = ( pStage->stateBits & ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) | ( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); GL_State( stateBits ); } else { GL_State( pStage->stateBits ); } // // draw // R_DrawElements( input->numIndexes, input->indexes ); } // allow skipping out to show just lightmaps during development if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) ) { break; } } }
/* ** RB_IterateStagesGeneric */ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; qboolean overridealpha, overridergb; qboolean didanyoverride = qfalse; int oldalphaGen = 0, oldrgbGen = 0; for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = tess.xstages[stage]; if ( !pStage ) { break; } // Override the shader rgb tint if requested. if(backEnd.currentEntity->e.renderfx & RF_RGB_TINT) { overridergb = qtrue; oldrgbGen = pStage->rgbGen; pStage->rgbGen = CGEN_ENTITY; } else overridergb = qfalse; // Override the shader alpha channel if requested. if(backEnd.currentEntity->e.renderfx & RF_FORCE_ENT_ALPHA) { overridealpha = qtrue; oldalphaGen = pStage->alphaGen; pStage->alphaGen = AGEN_ENTITY; } else overridealpha = qfalse; ComputeColors( pStage ); if(overridergb) pStage->rgbGen = (colorGen_t)oldrgbGen; if(overridealpha) pStage->alphaGen = (alphaGen_t)oldalphaGen; ComputeTexCoords( pStage ); if ( !setArraysOnce ) { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); } // // do multitexture // if ( pStage->bundle[1].image[0] != 0 ) { DrawMultitextured( input, stage ); } else { if ( !setArraysOnce ) { qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); } // // set state // if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig2.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer ) { GL_Bind( tr.whiteImage ); } else R_BindAnimatedImage( &pStage->bundle[0] ); if(overridealpha && backEnd.currentEntity->e.shaderRGBA[3] < 0xFF && !(pStage->stateBits & GLS_ATEST_BITS)) { GL_State((pStage->stateBits & ~(GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_ATEST_BITS)) // remove the shader set values. | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_ATEST_GT_0); // Now add the default values. didanyoverride = qtrue; } //if(overridergb && (backEnd.currentEntity->e.shaderRGBA[0] < 0xFF || backEnd.currentEntity->e.shaderRGBA[1] < 0xFF || backEnd.currentEntity->e.shaderRGBA[2] < 0xFF) && !(pStage->stateBits & GLS_ATEST_BITS)) //{ // GL_State((pStage->stateBits & ~(GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_ATEST_BITS)) // remove the shader set values. // | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_ATEST_GT_0); // Now add the default values. // didanyoverride = qtrue; //} //else if(!didanyoverride) GL_State( pStage->stateBits ); // // draw // R_DrawElements( input->numIndexes, input->indexes ); } // 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; } } }
/* ** RB_IterateStagesGeneric */ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; int loc; GLenum prog; char texname[MAX_QPATH]; shaderStage_t *pStage; /*if ( input->shader->GLSL ) { prog = getShaderProgram(input->shader->GLSLName); if(prog == -1) return; for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { pStage = tess.xstages[stage]; if(pStage) { ComputeColors( pStage ); ComputeTexCoords( pStage ); if ( !setArraysOnce ) { qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); } if(pStage->bundle[0].image) { qglActiveTextureARB(GL_TEXTURE0_ARB + stage); qglBindTexture (GL_TEXTURE_2D, pStage->bundle[0].image[0]->texnum); Com_sprintf(texname,sizeof(texname),"texture_%i\n", stage); loc = qglGetUniformLocationARB(prog, texname); qglUniform1iARB(loc, stage); } } } pStage = tess.xstages[0]; GL_State( pStage->stateBits ); R_DrawElements( input->numIndexes, input->indexes ); return; }*/ for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = tess.xstages[stage]; if ( !pStage ) { break; } ComputeColors( pStage ); ComputeTexCoords( pStage ); if ( !setArraysOnce ) { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); } // // do multitexture // if ( pStage->bundle[1].image[0] != 0 ) { //Lightmaps and such DrawMultitextured( input, stage ); } else { if ( !setArraysOnce ) { qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); } //LOL WTF, I don't need to do this! /*if(pStage->clamp) { qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); }*/ // // set state // if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer ) { GL_Bind( tr.whiteImage ); } else R_BindAnimatedImage( &pStage->bundle[0] ); GL_State( pStage->stateBits ); // // draw // R_DrawElements( input->numIndexes, input->indexes ); } // 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; } } }
static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; bool UseGLFog = false; bool FogColorChange = false; fog_t *fog = NULL; if (tess.fogNum && tess.shader->fogPass && (tess.fogNum == tr.world->globalFog || tess.fogNum == tr.world->numfogs) && r_drawfog->value == 2) { // only gl fog global fog and the "special fog" fog = tr.world->fogs + tess.fogNum; if (tr.rangedFog) { //ranged fog, used for sniper scope float fStart = fog->parms.depthForOpaque; if (tr.rangedFog < 0.0f) { //special designer override fStart = -tr.rangedFog; } else { //the greater tr.rangedFog is, the more fog we will get between the view point and cull distance if ((tr.distanceCull-fStart) < tr.rangedFog) { //assure a minimum range between fog beginning and cutoff distance fStart = tr.distanceCull-tr.rangedFog; if (fStart < 16.0f) { fStart = 16.0f; } } } qglFogi(GL_FOG_MODE, GL_LINEAR); qglFogf(GL_FOG_START, fStart); qglFogf(GL_FOG_END, tr.distanceCull); } else { qglFogi(GL_FOG_MODE, GL_EXP2); qglFogf(GL_FOG_DENSITY, logtestExp2 / fog->parms.depthForOpaque); } if ( g_bRenderGlowingObjects ) { const float fogColor[3] = { 0.0f, 0.0f, 0.0f }; qglFogfv(GL_FOG_COLOR, fogColor ); } else { qglFogfv(GL_FOG_COLOR, fog->parms.color); } qglEnable(GL_FOG); UseGLFog = true; } for ( stage = 0; stage < input->shader->numUnfoggedPasses; stage++ ) { shaderStage_t *pStage = &tess.xstages[stage]; int forceRGBGen = 0; int stateBits = 0; if ( !pStage->active ) { break; } // Reject this stage if it's not a glow stage but we are doing a glow pass. if ( g_bRenderGlowingObjects && !pStage->glow ) { continue; } if ( stage && r_lightmap->integer && !( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) ) { break; } stateBits = pStage->stateBits; if ( backEnd.currentEntity ) { assert(backEnd.currentEntity->e.renderfx >= 0); if ( backEnd.currentEntity->e.renderfx & RF_DISINTEGRATE1 ) { // we want to be able to rip a hole in the thing being disintegrated, and by doing the depth-testing it avoids some kinds of artefacts, but will probably introduce others? stateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK_TRUE | GLS_ATEST_GE_C0; } if ( backEnd.currentEntity->e.renderfx & RF_RGB_TINT ) {//want to use RGBGen from ent forceRGBGen = CGEN_ENTITY; } } if (pStage->ss && pStage->ss->surfaceSpriteType) { // We check for surfacesprites AFTER drawing everything else continue; } if (UseGLFog) { if (pStage->mGLFogColorOverride) { qglFogfv(GL_FOG_COLOR, GLFogOverrideColors[pStage->mGLFogColorOverride]); FogColorChange = true; } else if (FogColorChange && fog) { FogColorChange = false; qglFogfv(GL_FOG_COLOR, fog->parms.color); } } if (!input->fading) { //this means ignore this, while we do a fade-out ComputeColors( pStage, forceRGBGen ); } ComputeTexCoords( pStage ); if ( !setArraysOnce ) { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); } // // do multitexture // if ( pStage->bundle[1].image != 0 ) { DrawMultitextured( input, stage ); } else { static bool lStencilled = false; if ( !setArraysOnce ) { qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); } // // set state // if ( (tess.shader == tr.distortionShader) || (backEnd.currentEntity && (backEnd.currentEntity->e.renderfx & RF_DISTORTION)) ) { //special distortion effect -rww //tr.screenImage should have been set for this specific entity before we got in here. GL_Bind( tr.screenImage ); GL_Cull(CT_TWO_SIDED); } else if ( pStage->bundle[0].vertexLightmap && ( r_vertexLight->integer && !r_uiFullScreen->integer ) && r_lightmap->integer ) { GL_Bind( tr.whiteImage ); } else R_BindAnimatedImage( &pStage->bundle[0] ); if (tess.shader == tr.distortionShader && glConfig.stencilBits >= 4) { //draw it to the stencil buffer! tr_stencilled = true; lStencilled = true; qglEnable(GL_STENCIL_TEST); qglStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); qglStencilOp(GL_KEEP, GL_KEEP, GL_INCR); qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); //don't depthmask, don't blend.. don't do anything GL_State(0); } else if (backEnd.currentEntity && (backEnd.currentEntity->e.renderfx & RF_FORCE_ENT_ALPHA)) { ForceAlpha((unsigned char *) tess.svars.colors, backEnd.currentEntity->e.shaderRGBA[3]); if (backEnd.currentEntity->e.renderfx & RF_ALPHA_DEPTH) { //depth write, so faces through the model will be stomped over by nearer ones. this works because //we draw RF_FORCE_ENT_ALPHA stuff after everything else, including standard alpha surfs. GL_State(GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK_TRUE); } else { GL_State(GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } } else { GL_State( stateBits ); } // // draw // R_DrawElements( input->numIndexes, input->indexes ); if (lStencilled) { //re-enable the color buffer, disable stencil test lStencilled = false; qglDisable(GL_STENCIL_TEST); qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } } } if (FogColorChange) { qglFogfv(GL_FOG_COLOR, fog->parms.color); } }
/* ** RB_IterateStagesGeneric */ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; qboolean overridealpha = qfalse; int oldAlphaGen = AGEN_IDENTITY; int oldStateBits = 0; qboolean overridecolor = qfalse; int oldRgbGen = CGEN_IDENTITY; for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = tess.xstages[stage]; if ( !pStage ) { break; } // override the shader alpha channel if requested if ( backEnd.currentEntity && backEnd.currentEntity->e.renderfx & RF_FORCE_ENT_ALPHA ) { overridealpha = qtrue; oldAlphaGen = pStage->alphaGen; oldStateBits = pStage->stateBits; pStage->alphaGen = AGEN_ENTITY; // set bits for blendfunc blend pStage->stateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA; // keep the original alphafunc, if any pStage->stateBits |= ( oldStateBits & GLS_ATEST_BITS ); } else { overridealpha = qfalse; } // override the shader color channels if requested if ( backEnd.currentEntity && backEnd.currentEntity->e.renderfx & RF_RGB_TINT ) { overridecolor = qtrue; oldRgbGen = pStage->rgbGen; pStage->rgbGen = CGEN_ENTITY; } else { overridecolor = qfalse; } ComputeColors( pStage ); ComputeTexCoords( pStage ); if ( !setArraysOnce ) { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); } // per stage fogging (detail textures) if ( !tess.shader->noFog || pStage->isFogged ) { RB_FogOn(); } else { R_FogOff(); } // // do multitexture // if ( pStage->bundle[1].image[0] != 0 ) { DrawMultitextured( input, stage ); } else { if ( !setArraysOnce ) { qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); } // // set state // R_BindAnimatedImage( &pStage->bundle[0] ); // Disable depth test for 2D drawing if ( backEnd.currentEntity == &backEnd.entity2D ) { GL_State( pStage->stateBits | GLS_DEPTHTEST_DISABLE ); } else { GL_State( pStage->stateBits ); } // // draw // R_DrawElements( input->numIndexes, input->indexes ); } if ( overridealpha ) { pStage->alphaGen = oldAlphaGen; pStage->stateBits = oldStateBits; } if ( overridecolor ) { pStage->rgbGen = oldRgbGen; } // allow skipping out to show just lightmaps during development if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) ) { break; } } }
/* ** RB_IterateStagesGeneric */ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; #ifdef ELITEFORCE qboolean overridealpha; int oldalphaGen = 0; #endif for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = tess.xstages[stage]; if ( !pStage ) { break; } #ifdef ELITEFORCE // Override the shader alpha channel if requested. if(backEnd.currentEntity->e.renderfx & RF_FORCE_ENT_ALPHA) { overridealpha = qtrue; oldalphaGen = pStage->alphaGen; pStage->alphaGen = AGEN_ENTITY; } else overridealpha = qfalse; #endif ComputeColors( pStage ); #ifdef ELITEFORCE if(overridealpha) pStage->alphaGen = oldalphaGen; #endif ComputeTexCoords( pStage ); if ( !setArraysOnce ) { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors ); } // // do multitexture // if ( pStage->bundle[1].image[0] != 0 ) { DrawMultitextured( input, stage ); } else { if ( !setArraysOnce ) { qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] ); } // // set state // R_BindAnimatedImage( &pStage->bundle[0] ); #ifdef ELITEFORCE if(overridealpha && backEnd.currentEntity->e.shaderRGBA[3] < 0xFF && !(pStage->stateBits & GLS_ATEST_BITS)) { // set bits for blendfunc blend GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } else #endif GL_State( pStage->stateBits ); // // draw // R_DrawElements( input->numIndexes, input->indexes ); } // allow skipping out to show just lightmaps during development if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) ) { break; } } }