void GLSL_ShutdownGPUShaders(void) { int i; ri.Printf(PRINT_ALL, "------- GLSL_ShutdownGPUShaders -------\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD0); qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD1); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2); qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL); #ifdef USE_VERT_TANGENT_SPACE qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT); #endif qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); #ifdef USE_VERT_TANGENT_SPACE qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); #endif qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR); qglDisableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION); GLSL_BindNullProgram(); for ( i = 0; i < GENERICDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.genericShader[i]); GLSL_DeleteGPUShader(&tr.textureColorShader); for ( i = 0; i < FOGDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.fogShader[i]); for ( i = 0; i < DLIGHTDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.dlightShader[i]); for ( i = 0; i < LIGHTDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.lightallShader[i]); GLSL_DeleteGPUShader(&tr.shadowmapShader); GLSL_DeleteGPUShader(&tr.pshadowShader); GLSL_DeleteGPUShader(&tr.down4xShader); GLSL_DeleteGPUShader(&tr.bokehShader); GLSL_DeleteGPUShader(&tr.tonemapShader); for ( i = 0; i < 2; i++) GLSL_DeleteGPUShader(&tr.calclevels4xShader[i]); GLSL_DeleteGPUShader(&tr.shadowmaskShader); GLSL_DeleteGPUShader(&tr.ssaoShader); for ( i = 0; i < 2; i++) GLSL_DeleteGPUShader(&tr.depthBlurShader[i]); glState.currentProgram = 0; qglUseProgramObjectARB(0); }
void GLSL_ShutdownGPUShaders(void) { int i; ri.Printf(PRINT_ALL, "------- GLSL_ShutdownGPUShaders -------\n"); for (i = 0; i < ATTR_INDEX_COUNT; i++) qglDisableVertexAttribArrayARB(i); GLSL_BindNullProgram(); for ( i = 0; i < GENERICDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.genericShader[i]); GLSL_DeleteGPUShader(&tr.textureColorShader); for ( i = 0; i < FOGDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.fogShader[i]); for ( i = 0; i < DLIGHTDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.dlightShader[i]); for ( i = 0; i < LIGHTDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.lightallShader[i]); GLSL_DeleteGPUShader(&tr.shadowmapShader); GLSL_DeleteGPUShader(&tr.pshadowShader); GLSL_DeleteGPUShader(&tr.down4xShader); GLSL_DeleteGPUShader(&tr.bokehShader); GLSL_DeleteGPUShader(&tr.tonemapShader); for ( i = 0; i < 2; i++) GLSL_DeleteGPUShader(&tr.calclevels4xShader[i]); GLSL_DeleteGPUShader(&tr.shadowmaskShader); GLSL_DeleteGPUShader(&tr.ssaoShader); for ( i = 0; i < 2; i++) GLSL_DeleteGPUShader(&tr.depthBlurShader[i]); glState.currentProgram = 0; qglUseProgramObjectARB(0); }
/* * RB_EnableVertexAttrib */ static void RB_EnableVertexAttrib( int index, bool enable ) { unsigned int bit; unsigned int diff; bit = 1 << index; diff = (rb.gl.vertexAttribEnabled & bit) ^ (enable ? bit : 0); if( !diff ) { return; } if( enable ) { rb.gl.vertexAttribEnabled |= bit; qglEnableVertexAttribArrayARB( index ); } else { rb.gl.vertexAttribEnabled &= ~bit; qglDisableVertexAttribArrayARB( index ); } }
/* ============= RB_ARB2_CreateDrawInteractions ============= */ void RB_ARB2_CreateDrawInteractions( const drawSurf_t *surf ) { if ( !surf ) { return; } // perform setup here that will be constant for all interactions GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc ); // bind the vertex program if ( r_testARBProgram.GetBool() ) { qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_TEST ); qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST ); } else { qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION ); qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION ); } qglEnable(GL_VERTEX_PROGRAM_ARB); qglEnable(GL_FRAGMENT_PROGRAM_ARB); // enable the vertex arrays qglEnableVertexAttribArrayARB( 8 ); qglEnableVertexAttribArrayARB( 9 ); qglEnableVertexAttribArrayARB( 10 ); qglEnableVertexAttribArrayARB( 11 ); qglEnableClientState( GL_COLOR_ARRAY ); // texture 0 is the normalization cube map for the vector towards the light GL_SelectTextureNoClient( 0 ); if ( backEnd.vLight->lightShader->IsAmbientLight() ) { globalImages->ambientNormalMap->Bind(); } else { globalImages->normalCubeMapImage->Bind(); } // texture 6 is the specular lookup table GL_SelectTextureNoClient( 6 ); if ( r_testARBProgram.GetBool() ) { globalImages->specular2DTableImage->Bind(); // variable specularity in alpha channel } else { globalImages->specularTableImage->Bind(); } for ( ; surf ; surf=surf->nextOnLight ) { // perform setup here that will not change over multiple interaction passes // set the vertex pointers idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache ); qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color ); qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); // this may cause RB_ARB2_DrawInteraction to be exacuted multiple // times with different colors and images if the surface or light have multiple layers RB_CreateSingleDrawInteractions( surf, RB_ARB2_DrawInteraction ); } qglDisableVertexAttribArrayARB( 8 ); qglDisableVertexAttribArrayARB( 9 ); qglDisableVertexAttribArrayARB( 10 ); qglDisableVertexAttribArrayARB( 11 ); qglDisableClientState( GL_COLOR_ARRAY ); // disable features GL_SelectTextureNoClient( 6 ); globalImages->BindNull(); GL_SelectTextureNoClient( 5 ); globalImages->BindNull(); GL_SelectTextureNoClient( 4 ); globalImages->BindNull(); GL_SelectTextureNoClient( 3 ); globalImages->BindNull(); GL_SelectTextureNoClient( 2 ); globalImages->BindNull(); GL_SelectTextureNoClient( 1 ); globalImages->BindNull(); backEnd.glState.currenttmu = -1; GL_SelectTexture( 0 ); qglDisable(GL_VERTEX_PROGRAM_ARB); qglDisable(GL_FRAGMENT_PROGRAM_ARB); }
/* ============= RB_GLSL_CreateDrawInteractions ============= */ static void RB_GLSL_CreateDrawInteractions( const drawSurf_t *surf ) { if ( !surf ) { return; } // perform setup here that will be constant for all interactions GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc ); // bind the vertex and fragment program if ( backEnd.vLight->lightShader->IsAmbientLight() ) { qglUseProgramObjectARB( interactionAmbShader.program ); } else { qglUseProgramObjectARB( interactionDirShader.program ); } // enable the vertex arrays qglEnableVertexAttribArrayARB( 8 ); qglEnableVertexAttribArrayARB( 9 ); qglEnableVertexAttribArrayARB( 10 ); qglEnableVertexAttribArrayARB( 11 ); qglEnableClientState( GL_COLOR_ARRAY ); for ( ; surf; surf = surf->nextOnLight ) { // perform setup here that will not change over multiple interaction passes // ---> sikk - Custom Interaction Shaders: Local Parameters const float *regs; regs = surf->shaderRegisters; for ( int i = 0; i < surf->material->GetNumInteractionParms(); i++ ) { float parm[ 4 ]; parm[ 0 ] = regs[ surf->material->GetInteractionParm( i, 0 ) ]; parm[ 1 ] = regs[ surf->material->GetInteractionParm( i, 1 ) ]; parm[ 2 ] = regs[ surf->material->GetInteractionParm( i, 2 ) ]; parm[ 3 ] = regs[ surf->material->GetInteractionParm( i, 3 ) ]; if ( backEnd.vLight->lightShader->IsAmbientLight() ) { qglUniform4fvARB( interactionAmbShader.localParms[ i ], 1, parm ); } else { qglUniform4fvARB( interactionDirShader.localParms[ i ], 1, parm ); } } // <--- sikk - Custom Interaction Shaders: Local Parameters // ---> sikk - Specular Exponent Scale/Bias float parm[ 4 ]; parm[ 0 ] = surf->material->GetSpecExp( 0 ); parm[ 1 ] = surf->material->GetSpecExp( 1 ); parm[ 2 ] = 0.0f; parm[ 3 ] = 0.0f; if ( backEnd.vLight->lightShader->IsAmbientLight() ) { qglUniform4fvARB( interactionAmbShader.specExp, 1, parm ); } else { qglUniform4fvARB( interactionDirShader.specExp, 1, parm ); } // <--- sikk - Custom Interaction Shaders: Local Parameters // set the vertex pointers idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache ); qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color ); qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); // set model matrix //if ( backEnd.vLight->lightShader->IsAmbientLight() ) { // qglUniformMatrix4fvARB( interactionAmbShader.modelMatrix, 1, false, surf->space->modelMatrix ); //} else { // qglUniformMatrix4fvARB( interactionDirShader.modelMatrix, 1, false, surf->space->modelMatrix ); //} // this may cause RB_GLSL_DrawInteraction to be executed multiple // times with different colors and images if the surface or light have multiple layers RB_CreateSingleDrawInteractions( surf, RB_GLSL_DrawInteraction ); } qglDisableVertexAttribArrayARB( 8 ); qglDisableVertexAttribArrayARB( 9 ); qglDisableVertexAttribArrayARB( 10 ); qglDisableVertexAttribArrayARB( 11 ); qglDisableClientState( GL_COLOR_ARRAY ); // disable features // ---> sikk - Auxilary textures for interaction shaders // per-surface auxilary texture 0 - 9 for ( int i = 15; i > 0; i-- ) { GL_SelectTextureNoClient( i ); globalImages->BindNull(); } // <--- sikk - Auxilary textures for interaction shaders backEnd.glState.currenttmu = -1; GL_SelectTexture( 0 ); qglUseProgramObjectARB( 0 ); }
/* ================== RB_STD_T_RenderShaderPasses This is also called for the generated 2D rendering ================== */ void RB_STD_T_RenderShaderPasses( const drawSurf_t *surf ) { int stage; const idMaterial *shader; const shaderStage_t *pStage; const float *regs; float color[4]; const srfTriangles_t *tri; tri = surf->geo; shader = surf->material; if ( !shader->HasAmbient() ) { return; } if ( shader->IsPortalSky() ) { return; } // change the matrix if needed if ( surf->space != backEnd.currentSpace ) { qglLoadMatrixf( surf->space->modelViewMatrix ); backEnd.currentSpace = surf->space; RB_SetProgramEnvironmentSpace(); } // change the scissor if needed if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( surf->scissorRect ) ) { backEnd.currentScissor = surf->scissorRect; qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); } // some deforms may disable themselves by setting numIndexes = 0 if ( !tri->numIndexes ) { return; } if ( !tri->ambientCache ) { common->Printf( "RB_T_RenderShaderPasses: !tri->ambientCache\n" ); return; } // get the expressions for conditionals / color / texcoords regs = surf->shaderRegisters; // set face culling appropriately GL_Cull( shader->GetCullType() ); // set polygon offset if necessary if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) { qglEnable( GL_POLYGON_OFFSET_FILL ); qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() ); } if ( surf->space->weaponDepthHack ) { RB_EnterWeaponDepthHack(); } if ( surf->space->modelDepthHack != 0.0f ) { RB_EnterModelDepthHack( surf->space->modelDepthHack ); } idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), reinterpret_cast<void *>(&ac->st) ); for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) { pStage = shader->GetStage(stage); // check the enable condition if ( regs[ pStage->conditionRegister ] == 0 ) { continue; } // skip the stages involved in lighting if ( pStage->lighting != SL_AMBIENT ) { continue; } // skip if the stage is ( GL_ZERO, GL_ONE ), which is used for some alpha masks if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_ZERO | GLS_DSTBLEND_ONE ) ) { continue; } // see if we are a new-style stage newShaderStage_t *newStage = pStage->newStage; if ( newStage ) { //-------------------------- // // new style stages // //-------------------------- // completely skip the stage if we don't have the capability if ( tr.backEndRenderer != BE_ARB2 ) { continue; } if ( r_skipNewAmbient.GetBool() ) { continue; } qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color ); qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); qglEnableClientState( GL_COLOR_ARRAY ); qglEnableVertexAttribArrayARB( 9 ); qglEnableVertexAttribArrayARB( 10 ); qglEnableClientState( GL_NORMAL_ARRAY ); GL_State( pStage->drawStateBits ); qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, newStage->vertexProgram ); qglEnable( GL_VERTEX_PROGRAM_ARB ); // megaTextures bind a lot of images and set a lot of parameters if ( newStage->megaTexture ) { newStage->megaTexture->SetMappingForSurface( tri ); idVec3 localViewer; R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.viewDef->renderView.vieworg, localViewer ); newStage->megaTexture->BindForViewOrigin( localViewer ); } for ( int i = 0 ; i < newStage->numVertexParms ; i++ ) { float parm[4]; parm[0] = regs[ newStage->vertexParms[i][0] ]; parm[1] = regs[ newStage->vertexParms[i][1] ]; parm[2] = regs[ newStage->vertexParms[i][2] ]; parm[3] = regs[ newStage->vertexParms[i][3] ]; qglProgramLocalParameter4fvARB( GL_VERTEX_PROGRAM_ARB, i, parm ); } for ( int i = 0 ; i < newStage->numFragmentProgramImages ; i++ ) { if ( newStage->fragmentProgramImages[i] ) { GL_SelectTexture( i ); newStage->fragmentProgramImages[i]->Bind(); } } qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, newStage->fragmentProgram ); qglEnable( GL_FRAGMENT_PROGRAM_ARB ); // draw it RB_DrawElementsWithCounters( tri ); for ( int i = 1 ; i < newStage->numFragmentProgramImages ; i++ ) { if ( newStage->fragmentProgramImages[i] ) { GL_SelectTexture( i ); globalImages->BindNull(); } } if ( newStage->megaTexture ) { newStage->megaTexture->Unbind(); } GL_SelectTexture( 0 ); qglDisable( GL_VERTEX_PROGRAM_ARB ); qglDisable( GL_FRAGMENT_PROGRAM_ARB ); // Fixme: Hack to get around an apparent bug in ATI drivers. Should remove as soon as it gets fixed. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, 0 ); qglDisableClientState( GL_COLOR_ARRAY ); qglDisableVertexAttribArrayARB( 9 ); qglDisableVertexAttribArrayARB( 10 ); qglDisableClientState( GL_NORMAL_ARRAY ); continue; } //-------------------------- // // old style stages // //-------------------------- // set the color color[0] = regs[ pStage->color.registers[0] ]; color[1] = regs[ pStage->color.registers[1] ]; color[2] = regs[ pStage->color.registers[2] ]; color[3] = regs[ pStage->color.registers[3] ]; // skip the entire stage if an add would be black if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ) && color[0] <= 0 && color[1] <= 0 && color[2] <= 0 ) { continue; } // skip the entire stage if a blend would be completely transparent if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ) && color[3] <= 0 ) { continue; } // select the vertex color source if ( pStage->vertexColor == SVC_IGNORE ) { qglColor4fv( color ); } else { qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color ); qglEnableClientState( GL_COLOR_ARRAY ); if ( pStage->vertexColor == SVC_INVERSE_MODULATE ) { GL_TexEnv( GL_COMBINE_ARB ); qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB ); qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR ); qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 ); } // for vertex color and modulated color, we need to enable a second // texture stage if ( color[0] != 1 || color[1] != 1 || color[2] != 1 || color[3] != 1 ) { GL_SelectTexture( 1 ); globalImages->whiteImage->Bind(); GL_TexEnv( GL_COMBINE_ARB ); qglTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color ); qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB ); qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB ); qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 ); qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE ); qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB ); qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_CONSTANT_ARB ); qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA ); qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA ); qglTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1 ); GL_SelectTexture( 0 ); } } // bind the texture RB_BindVariableStageImage( &pStage->texture, regs ); // set the state GL_State( pStage->drawStateBits ); RB_PrepareStageTexturing( pStage, surf, ac ); // draw it RB_DrawElementsWithCounters( tri ); RB_FinishStageTexturing( pStage, surf, ac ); if ( pStage->vertexColor != SVC_IGNORE ) { qglDisableClientState( GL_COLOR_ARRAY ); GL_SelectTexture( 1 ); GL_TexEnv( GL_MODULATE ); globalImages->BindNull(); GL_SelectTexture( 0 ); GL_TexEnv( GL_MODULATE ); } } // reset polygon offset if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) { qglDisable( GL_POLYGON_OFFSET_FILL ); } if ( surf->space->weaponDepthHack || surf->space->modelDepthHack != 0.0f ) { RB_LeaveDepthHack(); } }
/* ================ RB_FinishStageTexturing ================ */ void RB_FinishStageTexturing( const shaderStage_t *pStage, const drawSurf_t *surf, idDrawVert *ac ) { // unset privatePolygonOffset if necessary if ( pStage->privatePolygonOffset && !surf->material->TestMaterialFlag(MF_POLYGONOFFSET) ) { qglDisable( GL_POLYGON_OFFSET_FILL ); } if ( pStage->texture.texgen == TG_DIFFUSE_CUBE || pStage->texture.texgen == TG_SKYBOX_CUBE || pStage->texture.texgen == TG_WOBBLESKY_CUBE ) { qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st ); } if ( pStage->texture.texgen == TG_SCREEN ) { qglDisable( GL_TEXTURE_GEN_S ); qglDisable( GL_TEXTURE_GEN_T ); qglDisable( GL_TEXTURE_GEN_Q ); } if ( pStage->texture.texgen == TG_SCREEN2 ) { qglDisable( GL_TEXTURE_GEN_S ); qglDisable( GL_TEXTURE_GEN_T ); qglDisable( GL_TEXTURE_GEN_Q ); } if ( pStage->texture.texgen == TG_GLASSWARP ) { if ( tr.backEndRenderer == BE_ARB2 /*|| tr.backEndRenderer == BE_NV30*/ ) { GL_SelectTexture( 2 ); globalImages->BindNull(); GL_SelectTexture( 1 ); if ( pStage->texture.hasMatrix ) { RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture ); } qglDisable( GL_TEXTURE_GEN_S ); qglDisable( GL_TEXTURE_GEN_T ); qglDisable( GL_TEXTURE_GEN_Q ); qglDisable( GL_FRAGMENT_PROGRAM_ARB ); globalImages->BindNull(); GL_SelectTexture( 0 ); } } if ( pStage->texture.texgen == TG_REFLECT_CUBE ) { if ( tr.backEndRenderer == BE_ARB2 ) { // see if there is also a bump map specified const shaderStage_t *bumpStage = surf->material->GetBumpStage(); if ( bumpStage ) { // per-pixel reflection mapping with bump mapping GL_SelectTexture( 1 ); globalImages->BindNull(); GL_SelectTexture( 0 ); qglDisableVertexAttribArrayARB( 9 ); qglDisableVertexAttribArrayARB( 10 ); } else { // per-pixel reflection mapping without bump mapping } qglDisableClientState( GL_NORMAL_ARRAY ); qglDisable( GL_FRAGMENT_PROGRAM_ARB ); qglDisable( GL_VERTEX_PROGRAM_ARB ); // Fixme: Hack to get around an apparent bug in ATI drivers. Should remove as soon as it gets fixed. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, 0 ); } else { qglDisable( GL_TEXTURE_GEN_S ); qglDisable( GL_TEXTURE_GEN_T ); qglDisable( GL_TEXTURE_GEN_R ); qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); qglDisableClientState( GL_NORMAL_ARRAY ); qglMatrixMode( GL_TEXTURE ); qglLoadIdentity(); qglMatrixMode( GL_MODELVIEW ); } } if ( pStage->texture.hasMatrix ) { qglMatrixMode( GL_TEXTURE ); qglLoadIdentity(); qglMatrixMode( GL_MODELVIEW ); } }
/* ============= RB_GLSL_CreateDrawInteractions ============= */ static void RB_GLSL_CreateDrawInteractions( const drawSurf_t *surf ) { if ( !surf ) { return; } // perform setup here that will be constant for all interactions GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc ); // bind the vertex and fragment program if ( backEnd.vLight->lightShader->IsAmbientLight() ) { if (ambientInteractionShader.program == -1) qglUseProgramObjectARB( 0 ); else qglUseProgramObjectARB( ambientInteractionShader.program ); } else { if (interactionShader.program == -1) qglUseProgramObjectARB( 0 ); else qglUseProgramObjectARB( interactionShader.program ); } // enable the vertex arrays qglEnableVertexAttribArrayARB( 8 ); qglEnableVertexAttribArrayARB( 9 ); qglEnableVertexAttribArrayARB( 10 ); qglEnableVertexAttribArrayARB( 11 ); qglEnableClientState( GL_COLOR_ARRAY ); for ( ; surf ; surf=surf->nextOnLight ) { // perform setup here that will not change over multiple interaction passes // set the vertex pointers idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache ); qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color ); qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); // set model matrix if ( backEnd.vLight->lightShader->IsAmbientLight() ) { qglUniformMatrix4fvARB( ambientInteractionShader.modelMatrix, 1, false, surf->space->modelMatrix ); } else { qglUniformMatrix4fvARB( interactionShader.modelMatrix, 1, false, surf->space->modelMatrix ); } // this may cause RB_GLSL_DrawInteraction to be executed multiple // times with different colors and images if the surface or light have multiple layers RB_CreateSingleDrawInteractions( surf, RB_GLSL_DrawInteraction ); } qglDisableVertexAttribArrayARB( 8 ); qglDisableVertexAttribArrayARB( 9 ); qglDisableVertexAttribArrayARB( 10 ); qglDisableVertexAttribArrayARB( 11 ); qglDisableClientState( GL_COLOR_ARRAY ); // disable features GL_SelectTextureNoClient( 4 ); globalImages->BindNull(); GL_SelectTextureNoClient( 3 ); globalImages->BindNull(); GL_SelectTextureNoClient( 2 ); globalImages->BindNull(); GL_SelectTextureNoClient( 1 ); globalImages->BindNull(); backEnd.glState.currenttmu = -1; GL_SelectTexture( 0 ); qglUseProgramObjectARB( 0 ); }
/* ============= RB_NV20_CreateDrawInteractions ============= */ static void RB_NV20_CreateDrawInteractions(const drawSurf_t *surf) { if (!surf) { return; } qglEnable(GL_VERTEX_PROGRAM_ARB); qglEnable(GL_REGISTER_COMBINERS_NV); #ifdef MACOS_X GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); #else qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglEnableVertexAttribArrayARB(8); qglEnableVertexAttribArrayARB(9); qglEnableVertexAttribArrayARB(10); qglEnableVertexAttribArrayARB(11); #endif for (; surf ; surf=surf->nextOnLight) { // set the vertex pointers idDrawVert *ac = (idDrawVert *)vertexCache.Position(surf->geo->ambientCache); qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(idDrawVert), ac->color); #ifdef MACOS_X GL_SelectTexture(0); qglTexCoordPointer(2, GL_FLOAT, sizeof(idDrawVert), ac->st.ToFloatPtr()); GL_SelectTexture(1); qglTexCoordPointer(3, GL_FLOAT, sizeof(idDrawVert), ac->tangents[0].ToFloatPtr()); GL_SelectTexture(2); qglTexCoordPointer(3, GL_FLOAT, sizeof(idDrawVert), ac->tangents[1].ToFloatPtr()); GL_SelectTexture(3); qglTexCoordPointer(3, GL_FLOAT, sizeof(idDrawVert), ac->normal.ToFloatPtr()); GL_SelectTexture(0); #else qglVertexAttribPointerARB(11, 3, GL_FLOAT, false, sizeof(idDrawVert), ac->normal.ToFloatPtr()); qglVertexAttribPointerARB(10, 3, GL_FLOAT, false, sizeof(idDrawVert), ac->tangents[1].ToFloatPtr()); qglVertexAttribPointerARB(9, 3, GL_FLOAT, false, sizeof(idDrawVert), ac->tangents[0].ToFloatPtr()); qglVertexAttribPointerARB(8, 2, GL_FLOAT, false, sizeof(idDrawVert), ac->st.ToFloatPtr()); #endif qglVertexPointer(3, GL_FLOAT, sizeof(idDrawVert), ac->xyz.ToFloatPtr()); RB_CreateSingleDrawInteractions(surf, RB_NV20_DrawInteraction); } #ifndef MACOS_X qglDisableVertexAttribArrayARB(8); qglDisableVertexAttribArrayARB(9); qglDisableVertexAttribArrayARB(10); qglDisableVertexAttribArrayARB(11); #endif // disable features #ifdef MACOS_X GL_SelectTexture(3); globalImages->BindNull(); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); GL_SelectTexture(2); globalImages->BindNull(); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); GL_SelectTexture(1); globalImages->BindNull(); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); #else GL_SelectTextureNoClient(3); globalImages->BindNull(); GL_SelectTextureNoClient(2); globalImages->BindNull(); GL_SelectTextureNoClient(1); globalImages->BindNull(); #endif backEnd.glState.currenttmu = -1; GL_SelectTexture(0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_VERTEX_PROGRAM_ARB); qglDisable(GL_REGISTER_COMBINERS_NV); }
void GLSL_VertexAttribsState(uint32_t stateBits) { uint32_t diff; diff = stateBits ^ glState.vertexAttribsState; if(diff) { if(diff & ATTR_POSITION) { if(stateBits & ATTR_POSITION) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_POSITION )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_POSITION); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_POSITION )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION); } } if(diff & ATTR_TEXCOORD) { if(stateBits & ATTR_TEXCOORD) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_TEXCOORD )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD0); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_TEXCOORD )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD0); } } if(diff & ATTR_LIGHTCOORD) { if(stateBits & ATTR_LIGHTCOORD) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_LIGHTCOORD )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD1); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_LIGHTCOORD )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD1); } } if(diff & ATTR_NORMAL) { if(stateBits & ATTR_NORMAL) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_NORMAL )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_NORMAL); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_NORMAL )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL); } } #ifdef USE_VERT_TANGENT_SPACE if(diff & ATTR_TANGENT) { if(stateBits & ATTR_TANGENT) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_TANGENT )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_TANGENT); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_TANGENT )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT); } } #endif if(diff & ATTR_COLOR) { if(stateBits & ATTR_COLOR) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_COLOR )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_COLOR); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_COLOR )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR); } } if(diff & ATTR_LIGHTDIRECTION) { if(stateBits & ATTR_LIGHTDIRECTION) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_LIGHTDIRECTION )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_LIGHTDIRECTION )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION); } } if(diff & ATTR_POSITION2) { if(stateBits & ATTR_POSITION2) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_POSITION2 )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_POSITION2); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_POSITION2 )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2); } } if(diff & ATTR_NORMAL2) { if(stateBits & ATTR_NORMAL2) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_NORMAL2 )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_NORMAL2 )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); } } #ifdef USE_VERT_TANGENT_SPACE if(diff & ATTR_TANGENT2) { if(stateBits & ATTR_TANGENT2) { GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_TANGENT2 )\n"); qglEnableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); } else { GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_TANGENT2 )\n"); qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); } } #endif } GLSL_VertexAttribPointers(stateBits); glState.vertexAttribsState = stateBits; }