/* ** RB_StageIteratorGeneric */ void RB_StageIteratorGeneric( void ) { shaderCommands_t *input; shader_t *shader; input = &tess; shader = input->shader; RB_DeformTessGeometry(); // // 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 // GL_Cull( shader->cullType ); // set polygon offset if necessary if ( shader->polygonOffset ) { qglEnable( GL_POLYGON_OFFSET_FILL ); qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); } // // if there is only a single pass then we can enable color // and texture arrays before we compile, otherwise we need // to avoid compiling those arrays since they will change // during multipass rendering // if ( tess.numPasses > 1 || shader->multitextureEnv ) { setArraysOnce = qfalse; qglDisableClientState (GL_COLOR_ARRAY); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); } else { setArraysOnce = qtrue; qglEnableClientState( GL_COLOR_ARRAY); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] ); } // // lock XYZ // qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD if (qglLockArraysEXT) { qglLockArraysEXT(0, input->numVertexes); GLimp_LogComment( "glLockArraysEXT\n" ); } // // enable color and texcoord arrays after the lock if necessary // if ( !setArraysOnce ) { qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglEnableClientState( GL_COLOR_ARRAY ); } // // call shader function // RB_IterateStagesGeneric( input ); // // now do any dynamic lighting needed // if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) { ProjectDlightTexture(); } // // now do fog // if ( tess.fogNum && tess.shader->fogPass ) { RB_FogPass(); } // // unlock arrays // if (qglUnlockArraysEXT) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } // // reset polygon offset // if ( shader->polygonOffset ) { qglDisable( GL_POLYGON_OFFSET_FILL ); } }
/* ** 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) ); } if ( qglPNTrianglesiATI && tess.ATI_tess ) { // RF< so we can send the normals as an array qglEnableClientState( GL_NORMAL_ARRAY ); qglEnable( GL_PN_TRIANGLES_ATI ); // ATI PN-Triangles extension } // // 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 && r_shadows->integer == 4 && 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(); } } // // now do fog // if ( tess.fogNum && tess.shader->fogPass ) { RB_FogPass(0); } // // RTCW fog // may not match original RTCW fog, since that's done per stage // if ( r_wolffog->integer && tess.shader->fogPass && tess.shader->sort <= SS_OPAQUE ) { int stage, stageFog = 0; // make sure at least one stage has fog for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { shaderStage_t *pStage = tess.xstages[stage]; if ( !pStage ) { break; } if (pStage->isFogged) { stageFog = 1; break; } } // FIXME: this logic sucks if (tess.shader->noFog && stageFog) { RB_FogPass(1); } else if (tess.shader->noFog && !stageFog) { } else { RB_FogPass(1); } } // // reset polygon offset // if ( input->shader->polygonOffset ) { qglDisable( GL_POLYGON_OFFSET_FILL ); } // turn truform back off if ( qglPNTrianglesiATI && tess.ATI_tess ) { qglDisable( GL_PN_TRIANGLES_ATI ); // ATI PN-Triangles extension qglDisableClientState( GL_NORMAL_ARRAY ); } }
/* ** 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_StageIteratorGeneric */ void RB_StageIteratorGeneric( void ) { shaderCommands_t *input; input = &tess; RB_DeformTessGeometry(); // // 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 GL fog SetIteratorFog(); if ( qglPNTrianglesiATI && tess.ATI_tess ) { // RF< so we can send the normals as an array qglEnableClientState( GL_NORMAL_ARRAY ); #ifdef __MACOS__ //DAJ ATI qglPNTrianglesiATI( GL_PN_TRIANGLES_ATI, 1 ); #else qglEnable( GL_PN_TRIANGLES_ATI ); // ATI PN-Triangles extension #endif } // // set face culling appropriately // 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 ); } // // if there is only a single pass then we can enable color // and texture arrays before we compile, otherwise we need // to avoid compiling those arrays since they will change // during multipass rendering // if ( tess.numPasses > 1 || input->shader->multitextureEnv ) { setArraysOnce = qfalse; qglDisableClientState( GL_COLOR_ARRAY ); qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); } else { setArraysOnce = qtrue; qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] ); } // RF, send normals only if required // This must be done first, since we can't change the arrays once they have been // locked if ( qglPNTrianglesiATI && tess.ATI_tess ) { qglNormalPointer( GL_FLOAT, 16, input->normal ); } // // lock XYZ // qglVertexPointer( 3, GL_FLOAT, 16, input->xyz ); // padded for SIMD if ( qglLockArraysEXT ) { qglLockArraysEXT( 0, input->numVertexes ); GLimp_LogComment( "glLockArraysEXT\n" ); } // // enable color and texcoord arrays after the lock if necessary // if ( !setArraysOnce ) { qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglEnableClientState( GL_COLOR_ARRAY ); } // // call shader function // RB_IterateStagesGeneric( input ); // // now do any dynamic lighting needed // if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE && !( tess.shader->surfaceFlags & ( SURF_NODLIGHT | SURF_SKY ) ) ) { ProjectDlightTexture(); } // // now do fog // if ( tess.fogNum && tess.shader->fogPass ) { RB_FogPass(); } // // unlock arrays // if ( qglUnlockArraysEXT ) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } // // reset polygon offset // if ( input->shader->polygonOffset ) { qglDisable( GL_POLYGON_OFFSET_FILL ); } // turn truform back off if ( qglPNTrianglesiATI && tess.ATI_tess ) { #ifdef __MACOS__ //DAJ ATI qglPNTrianglesiATI( GL_PN_TRIANGLES_ATI, 0 ); #else qglDisable( GL_PN_TRIANGLES_ATI ); // ATI PN-Triangles extension #endif qglDisableClientState( GL_NORMAL_ARRAY ); } }