GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { GL_UseProgramObject(program); qglUniformMatrix4fvARB(location, count, transpose, value); }
qboolean R_Shader_StartLightPass( unsigned int lightIndex ) { GLint valid; R_ShaderLight *light = GetLightFromIndex( lightIndex ); matrix4x4_t *worldToViewMatrix = &r_refdef.lightShader.worldToViewMatrix; vec3_t lightPosition, newcolor; float f; assert( light->active == true ); // setup cubemap texture generation if( gl_support_cubemaps ) { matrix4x4_t worldToLightMatrix; matrix4x4_t viewToWorldMatrix; matrix4x4_t viewToLightMatrix; // setup the cubemap qglSelectTextureARB( GL_TEXTURE1_ARB ); glEnable( GL_TEXTURE_CUBE_MAP_ARB ); glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, GL_LoadCubeTexImage( light->cubemapname, false, true ) ); qglSelectTextureARB( GL_TEXTURE0_ARB ); // invert worldToViewMatrix worldToLightMatrix = GetWorldToLightMatrix( light ); Matrix4x4_Invert_Simple( &viewToWorldMatrix, worldToViewMatrix ); Matrix4x4_Concat( &viewToLightMatrix, &worldToLightMatrix, &viewToWorldMatrix ); qglUniformMatrix4fvARB( r_refdef.lightShader.viewToLightMatrix, 1, true, (float *)&viewToLightMatrix.m ); } Matrix4x4_Transform( worldToViewMatrix, light->origin, lightPosition ); //Con_Printf( "Light distance to origin: %f (vs %f)\n", VectorDistance( light->origin, r_refdef.vieworg ), VectorLength( lightPosition ) ); qglUniform3fvARB( r_refdef.lightShader.lightPosition, 1, lightPosition ); f = (light->style >= 0 ? d_lightstylevalue[light->style] : 128) * (1.0f / 256.0f) * r_shadow_lightintensityscale.value; VectorScale(light->color, f, newcolor); qglUniform3fvARB( r_refdef.lightShader.lightColor, 1, newcolor ); qglUniform1fARB( r_refdef.lightShader.lightMaxDistance, light->maxDistance ); qglValidateProgramARB( r_refdef.lightShader.programObject ); qglGetObjectParameterivARB( r_refdef.lightShader.programObject, GL_OBJECT_VALIDATE_STATUS_ARB, &valid ); return valid == true; }
void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t matrix) { GLint *uniforms = program->uniforms; vec_t *compare = (float *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]); if (uniforms[uniformNum] == -1) return; if (uniformsInfo[uniformNum].type != GLSL_MAT16) { ri.Printf( PRINT_WARNING, "GLSL_SetUniformMat4: wrong type for uniform %i in program %s\n", uniformNum, program->name); return; } if (Mat4Compare(matrix, compare)) { return; } Mat4Copy(matrix, compare); qglUniformMatrix4fvARB(uniforms[uniformNum], 1, GL_FALSE, matrix); }
/* ================== 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_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 ); }