/* ============= 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_GLSL_DrawInteraction ================== */ static void RB_GLSL_DrawInteraction( const drawInteraction_t *din ) { // load all the shader parameters if ( din->ambientLight ) { // ---> sikk - Included non-power-of-two/frag position conversion // screen power of two correction factor, assuming the copy to _currentRender // also copied an extra row and column for the bilerp float parm[ 4 ]; int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1; int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1; parm[0] = (float)w / globalImages->currentRenderImage->uploadWidth; parm[1] = (float)h / globalImages->currentRenderImage->uploadHeight; parm[2] = parm[0] / w; // sikk - added - one less fragment shader instruction parm[3] = parm[1] / h; // sikk - added - one less fragment shader instruction qglUniform4fvARB( interactionAmbShader.nonPoT, 1, parm ); // window coord to 0.0 to 1.0 conversion parm[0] = 1.0 / w; parm[1] = 1.0 / h; parm[2] = w; // sikk - added - can be useful to have resolution size in shader parm[3] = h; // sikk - added - can be useful to have resolution size in shader qglUniform4fvARB( interactionAmbShader.invRes, 1, parm ); // <--- sikk - Included non-power-of-two/frag position conversion qglUniform4fvARB( interactionAmbShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.localViewOrigin, 1, din->localViewOrigin.ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.specularMatrixS, 1, din->specularMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.specularMatrixT, 1, din->specularMatrix[1].ToFloatPtr() ); // ---> sikk - Include model matrix for to-world-space transformations const struct viewEntity_s *space = backEnd.currentSpace; qglUniformMatrix4fvARB( interactionAmbShader.modelMatrix, 1, 0, space->modelMatrix ); // <--- sikk - Include model matrix for to-world-space transformations static const float ignore[ 4 ] = { 0.0, 1.0, 1.0, 1.0 }; static const float modulate[ 4 ] = { 1.0, 0.0, 1.0, 1.0 }; static const float inv_modulate[ 4 ] = { -1.0, 1.0, 1.0, 1.0 }; switch ( din->vertexColor ) { case SVC_IGNORE: qglUniform4fvARB( interactionAmbShader.colorMAD, 1, ignore ); break; case SVC_MODULATE: qglUniform4fvARB( interactionAmbShader.colorMAD, 1, modulate ); break; case SVC_INVERSE_MODULATE: qglUniform4fvARB( interactionAmbShader.colorMAD, 1, inv_modulate ); break; } // set the constant color qglUniform4fvARB( interactionAmbShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() ); qglUniform4fvARB( interactionAmbShader.specularColor, 1, din->specularColor.ToFloatPtr() ); } else { // ---> sikk - Included non-power-of-two/frag position conversion // screen power of two correction factor, assuming the copy to _currentRender // also copied an extra row and column for the bilerp float parm[ 4 ]; int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1; int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1; parm[0] = (float)w / globalImages->currentRenderImage->uploadWidth; parm[1] = (float)h / globalImages->currentRenderImage->uploadHeight; parm[2] = parm[0] / w; // sikk - added - one less fragment shader instruction parm[3] = parm[1] / h; // sikk - added - one less fragment shader instruction qglUniform4fvARB( interactionDirShader.nonPoT, 1, parm ); // window coord to 0.0 to 1.0 conversion parm[0] = 1.0 / w; parm[1] = 1.0 / h; parm[2] = w; // sikk - added - can be useful to have resolution size in shader parm[3] = h; // sikk - added - can be useful to have resolution size in shader qglUniform4fvARB( interactionDirShader.invRes, 1, parm ); // <--- sikk - Included non-power-of-two/frag position conversion qglUniform4fvARB( interactionDirShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.localViewOrigin, 1, din->localViewOrigin.ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.specularMatrixS, 1, din->specularMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.specularMatrixT, 1, din->specularMatrix[1].ToFloatPtr() ); // ---> sikk - Include model matrix for to-world-space transformations const struct viewEntity_s *space = backEnd.currentSpace; qglUniformMatrix4fvARB( interactionDirShader.modelMatrix, 1, 0, space->modelMatrix ); // <--- sikk - Include model matrix for to-world-space transformations if ( !backEnd.vLight->lightDef->parms.pointLight ) { // 2D Light Shader (projected lights) qglUniform1iARB( interactionDirShader.falloffType, 2 ); //qglUseProgramObjectARB( interactionDirShader.program ); //qglUniform1iARB( interactionDirShader.u_lightProjectionTexture, 0 ); //qglUseProgramObjectARB( 0 ); } else { // 3D Light Shader (point lights) if ( backEnd.vLight->lightDef->parms.parallel ) { // shader specific for sun light (no attenuation) qglUniform1iARB( interactionDirShader.falloffType, 1 ); } else { // default quadratic attenuation qglUniform1iARB( interactionDirShader.falloffType, 0 ); } } static const float ignore[ 4 ] = { 0.0, 1.0, 1.0, 1.0 }; static const float modulate[ 4 ] = { 1.0, 0.0, 1.0, 1.0 }; static const float inv_modulate[ 4 ] = { -1.0, 1.0, 1.0, 1.0 }; switch ( din->vertexColor ) { case SVC_IGNORE: qglUniform4fvARB( interactionDirShader.colorMAD, 1, ignore ); break; case SVC_MODULATE: qglUniform4fvARB( interactionDirShader.colorMAD, 1, modulate ); break; case SVC_INVERSE_MODULATE: qglUniform4fvARB( interactionDirShader.colorMAD, 1, inv_modulate ); break; } // set the constant colors qglUniform4fvARB( interactionDirShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() ); qglUniform4fvARB( interactionDirShader.specularColor, 1, din->specularColor.ToFloatPtr() ); } // set the textures // texture 0 will be the light projection texture GL_SelectTextureNoClient( 0 ); din->lightImage->Bind(); if ( !din->ambientLight ) { GL_SelectTextureNoClient( 16 ); din->lightImage->Bind(); } // texture 1 will be the light falloff texture GL_SelectTextureNoClient( 1 ); din->lightFalloffImage->Bind(); // texture 1 will be the per-surface bump map GL_SelectTextureNoClient( 2 ); din->bumpImage->Bind(); // texture 2 is the per-surface diffuse map GL_SelectTextureNoClient( 3 ); din->diffuseImage->Bind(); // texture 3 is the per-surface specular map GL_SelectTextureNoClient( 4 ); din->specularImage->Bind(); // texture 4 is the ssao buffer GL_SelectTextureNoClient( 5 ); globalImages->ssaoImage->Bind(); // ---> sikk - Auxilary textures for interaction shaders // per-surface auxilary texture 0 - 9 for ( int i = 0; i < din->surf->material->GetNumInteractionImages(); i++ ) { GL_SelectTextureNoClient( i + 6 ); din->surf->material->GetInteractionImage( i )->Bind(); } // <--- sikk - Auxilary textures for interaction shaders // draw it RB_DrawElementsWithCounters( din->surf->geo ); }
/* ================== RB_GLSL_DrawInteraction ================== */ static void RB_GLSL_DrawInteraction( const drawInteraction_t *din ) { // load all the shader parameters if ( din->ambientLight ) { qglUniform4fvARB( ambientInteractionShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() ); qglUniform4fvARB( ambientInteractionShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() ); qglUniform4fvARB( ambientInteractionShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() ); qglUniform4fvARB( ambientInteractionShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() ); qglUniform4fvARB( ambientInteractionShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() ); qglUniform4fvARB( ambientInteractionShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() ); qglUniform4fvARB( ambientInteractionShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() ); qglUniform4fvARB( ambientInteractionShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() ); qglUniform4fvARB( ambientInteractionShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() ); static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; static const float negOne[4] = { -1, -1, -1, -1 }; switch ( din->vertexColor ) { case SVC_IGNORE: qglUniform4fARB( ambientInteractionShader.colorModulate, zero[0], zero[1], zero[2], zero[3] ); qglUniform4fARB( ambientInteractionShader.colorAdd, one[0], one[1], one[2], one[3] ); break; case SVC_MODULATE: qglUniform4fARB( ambientInteractionShader.colorModulate, one[0], one[1], one[2], one[3] ); qglUniform4fARB( ambientInteractionShader.colorAdd, zero[0], zero[1], zero[2], zero[3] ); break; case SVC_INVERSE_MODULATE: qglUniform4fARB( ambientInteractionShader.colorModulate, negOne[0], negOne[1], negOne[2], negOne[3] ); qglUniform4fARB( ambientInteractionShader.colorAdd, one[0], one[1], one[2], one[3] ); break; } // set the constant color qglUniform4fvARB( ambientInteractionShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() ); } else { qglUniform4fvARB( interactionShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() ); qglUniform4fvARB( interactionShader.localViewOrigin, 1, din->localViewOrigin.ToFloatPtr() ); qglUniform4fvARB( interactionShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() ); qglUniform4fvARB( interactionShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() ); qglUniform4fvARB( interactionShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() ); qglUniform4fvARB( interactionShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() ); qglUniform4fvARB( interactionShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() ); qglUniform4fvARB( interactionShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() ); qglUniform4fvARB( interactionShader.specularMatrixS, 1, din->specularMatrix[0].ToFloatPtr() ); qglUniform4fvARB( interactionShader.specularMatrixT, 1, din->specularMatrix[1].ToFloatPtr() ); static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; static const float negOne[4] = { -1, -1, -1, -1 }; switch ( din->vertexColor ) { case SVC_IGNORE: qglUniform4fARB( interactionShader.colorModulate, zero[0], zero[1], zero[2], zero[3] ); qglUniform4fARB( interactionShader.colorAdd, one[0], one[1], one[2], one[3] ); break; case SVC_MODULATE: qglUniform4fARB( interactionShader.colorModulate, one[0], one[1], one[2], one[3] ); qglUniform4fARB( interactionShader.colorAdd, zero[0], zero[1], zero[2], zero[3] ); break; case SVC_INVERSE_MODULATE: qglUniform4fARB( interactionShader.colorModulate, negOne[0], negOne[1], negOne[2], negOne[3] ); qglUniform4fARB( interactionShader.colorAdd, one[0], one[1], one[2], one[3] ); break; } // set the constant colors qglUniform4fvARB( interactionShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() ); qglUniform4fvARB( interactionShader.specularColor, 1, din->specularColor.ToFloatPtr() ); } // set the textures // texture 0 will be the per-surface bump map GL_SelectTextureNoClient( 0 ); din->bumpImage->Bind(); // texture 1 will be the light falloff texture GL_SelectTextureNoClient( 1 ); din->lightFalloffImage->Bind(); // texture 2 will be the light projection texture GL_SelectTextureNoClient( 2 ); din->lightImage->Bind(); // texture 3 is the per-surface diffuse map GL_SelectTextureNoClient( 3 ); din->diffuseImage->Bind(); if ( !din->ambientLight ) { // texture 4 is the per-surface specular map GL_SelectTextureNoClient( 4 ); din->specularImage->Bind(); } // draw it RB_DrawElementsWithCounters( din->surf->geo ); }