diff --git a/src/Core/OpenGL/CShader.cpp b/src/Core/OpenGL/CShader.cpp index 1bca46e0..9d675c47 100644 --- a/src/Core/OpenGL/CShader.cpp +++ b/src/Core/OpenGL/CShader.cpp @@ -159,6 +159,7 @@ bool CShader::LinkShaders() mLightBlockIndex = GetUniformBlockIndex("LightBlock"); mBoneTransformBlockIndex = GetUniformBlockIndex("BoneTransformBlock"); + CacheCommonUniforms(); mProgramExists = true; return true; } @@ -183,6 +184,17 @@ GLuint CShader::GetUniformBlockIndex(const char* pkUniformBlock) return glGetUniformBlockIndex(mProgram, pkUniformBlock); } +void CShader::SetTextureUniforms(u32 NumTextures) +{ + for (u32 iTex = 0; iTex < NumTextures; iTex++) + glUniform1i(mTextureUniforms[iTex], iTex); +} + +void CShader::SetNumLights(u32 NumLights) +{ + glUniform1i(mNumLightsUniform, NumLights); +} + void CShader::SetCurrent() { if (spCurrentShader != this) @@ -238,6 +250,17 @@ void CShader::KillCachedShader() } // ************ PRIVATE ************ +void CShader::CacheCommonUniforms() +{ + for (u32 iTex = 0; iTex < 8; iTex++) + { + TString TexUniform = "Texture" + TString::FromInt32(iTex); + mTextureUniforms[iTex] = glGetUniformLocation(mProgram, *TexUniform); + } + + mNumLightsUniform = glGetUniformLocation(mProgram, "NumLights"); +} + void CShader::DumpShaderSource(GLuint Shader, const TString& rkOut) { GLint SourceLen; diff --git a/src/Core/OpenGL/CShader.h b/src/Core/OpenGL/CShader.h index 6491255a..101996b3 100644 --- a/src/Core/OpenGL/CShader.h +++ b/src/Core/OpenGL/CShader.h @@ -19,6 +19,10 @@ class CShader GLuint mLightBlockIndex; GLuint mBoneTransformBlockIndex; + // Cached uniform locations + GLint mTextureUniforms[8]; + GLint mNumLightsUniform; + static CShader* spCurrentShader; public: @@ -32,6 +36,8 @@ public: GLuint GetProgramID(); GLuint GetUniformLocation(const char* pkUniform); GLuint GetUniformBlockIndex(const char* pkUniformBlock); + void SetTextureUniforms(u32 NumTextures); + void SetNumLights(u32 NumLights); void SetCurrent(); // Static @@ -40,6 +46,7 @@ public: static void KillCachedShader(); private: + void CacheCommonUniforms(); void DumpShaderSource(GLuint Shader, const TString& rkOut); }; diff --git a/src/Core/Render/CDrawUtil.cpp b/src/Core/Render/CDrawUtil.cpp index 912733e5..654d9409 100644 --- a/src/Core/Render/CDrawUtil.cpp +++ b/src/Core/Render/CDrawUtil.cpp @@ -229,10 +229,10 @@ void CDrawUtil::DrawBillboard(CTexture* pTexture, const CVector3f& Position, con // Set uniforms mpBillboardShader->SetCurrent(); - GLuint ScaleLoc = mpBillboardShader->GetUniformLocation("BillboardScale"); + static GLuint ScaleLoc = mpBillboardShader->GetUniformLocation("BillboardScale"); glUniform2f(ScaleLoc, Scale.X, Scale.Y); - GLuint TintLoc = mpBillboardShader->GetUniformLocation("TintColor"); + static GLuint TintLoc = mpBillboardShader->GetUniformLocation("TintColor"); glUniform4f(TintLoc, Tint.R, Tint.G, Tint.B, Tint.A); pTexture->Bind(0); @@ -258,13 +258,13 @@ void CDrawUtil::DrawLightBillboard(ELightType Type, const CColor& LightColor, co // Set uniforms mpLightBillboardShader->SetCurrent(); - GLuint ScaleLoc = mpLightBillboardShader->GetUniformLocation("BillboardScale"); + static GLuint ScaleLoc = mpLightBillboardShader->GetUniformLocation("BillboardScale"); glUniform2f(ScaleLoc, Scale.X, Scale.Y); - GLuint ColorLoc = mpLightBillboardShader->GetUniformLocation("LightColor"); + static GLuint ColorLoc = mpLightBillboardShader->GetUniformLocation("LightColor"); glUniform4f(ColorLoc, LightColor.R, LightColor.G, LightColor.B, LightColor.A); - GLuint TintLoc = mpLightBillboardShader->GetUniformLocation("TintColor"); + static GLuint TintLoc = mpLightBillboardShader->GetUniformLocation("TintColor"); glUniform4f(TintLoc, Tint.R, Tint.G, Tint.B, Tint.A); CTexture *pTexA = GetLightTexture(Type); @@ -272,8 +272,8 @@ void CDrawUtil::DrawLightBillboard(ELightType Type, const CColor& LightColor, co pTexA->Bind(0); pTexB->Bind(1); - GLuint TextureLoc = mpLightBillboardShader->GetUniformLocation("Texture"); - GLuint MaskLoc = mpLightBillboardShader->GetUniformLocation("LightMask"); + static GLuint TextureLoc = mpLightBillboardShader->GetUniformLocation("Texture"); + static GLuint MaskLoc = mpLightBillboardShader->GetUniformLocation("LightMask"); glUniform1i(TextureLoc, 0); glUniform1i(MaskLoc, 1); @@ -293,7 +293,7 @@ void CDrawUtil::UseColorShader(const CColor& kColor) Init(); mpColorShader->SetCurrent(); - GLuint ColorLoc = mpColorShader->GetUniformLocation("ColorIn"); + static GLuint ColorLoc = mpColorShader->GetUniformLocation("ColorIn"); glUniform4f(ColorLoc, kColor.R, kColor.G, kColor.B, kColor.A); CMaterial::KillCachedMaterial(); @@ -304,10 +304,10 @@ void CDrawUtil::UseColorShaderLighting(const CColor& kColor) Init(); mpColorShaderLighting->SetCurrent(); - GLuint NumLightsLoc = mpColorShaderLighting->GetUniformLocation("NumLights"); + static GLuint NumLightsLoc = mpColorShaderLighting->GetUniformLocation("NumLights"); glUniform1i(NumLightsLoc, CGraphics::sNumLights); - GLuint ColorLoc = mpColorShaderLighting->GetUniformLocation("ColorIn"); + static GLuint ColorLoc = mpColorShaderLighting->GetUniformLocation("ColorIn"); glUniform4f(ColorLoc, kColor.R, kColor.G, kColor.B, kColor.A); CMaterial::KillCachedMaterial(); @@ -323,7 +323,7 @@ void CDrawUtil::UseTextureShader(const CColor& TintColor) Init(); mpTextureShader->SetCurrent(); - GLuint TintColorLoc = mpTextureShader->GetUniformLocation("TintColor"); + static GLuint TintColorLoc = mpTextureShader->GetUniformLocation("TintColor"); glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A); CMaterial::KillCachedMaterial(); @@ -335,7 +335,7 @@ void CDrawUtil::UseCollisionShader(const CColor& TintColor /*= CColor::skWhite*/ mpCollisionShader->SetCurrent(); LoadCheckerboardTexture(0); - GLuint TintColorLoc = mpCollisionShader->GetUniformLocation("TintColor"); + static GLuint TintColorLoc = mpCollisionShader->GetUniformLocation("TintColor"); glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A); CMaterial::KillCachedMaterial(); diff --git a/src/Core/Resource/CMaterial.cpp b/src/Core/Resource/CMaterial.cpp index 56b039a4..bd0a6a91 100644 --- a/src/Core/Resource/CMaterial.cpp +++ b/src/Core/Resource/CMaterial.cpp @@ -105,12 +105,6 @@ void CMaterial::GenerateShader(bool AllowRegen /*= true*/) bool CMaterial::SetCurrent(FRenderOptions Options) { - // Bind textures - const char *skpSamplers[8] = { - "Texture0", "Texture1", "Texture2", "Texture3", - "Texture4", "Texture5", "Texture6", "Texture7" - }; - // Skip material setup if the currently bound material is identical if (sCurrentMaterial != HashParameters()) { @@ -177,19 +171,13 @@ bool CMaterial::SetCurrent(FRenderOptions Options) } } - // Bind textures - CShader *pShader = CShader::CurrentShader(); - + // Set up shader uniforms for (u32 iPass = 0; iPass < mPasses.size(); iPass++) - { mPasses[iPass]->LoadTexture(iPass); - GLint sampler = pShader->GetUniformLocation(skpSamplers[iPass]); - glUniform1i(sampler, iPass); - } - // Bind num lights - GLuint NumLightsLoc = pShader->GetUniformLocation("NumLights"); - glUniform1i(NumLightsLoc, CGraphics::sNumLights); + CShader *pShader = CShader::CurrentShader(); + pShader->SetTextureUniforms(mPasses.size()); + pShader->SetNumLights(CGraphics::sNumLights); // Update shader blocks CGraphics::UpdateVertexBlock();