From fd7427a1cf486defe983e726a56e8991d9e733fe Mon Sep 17 00:00:00 2001
From: vlj <vljn@ovi.com>
Date: Sun, 13 Jul 2014 02:30:37 +0200
Subject: [PATCH] Factorize detail and spheremap

---
 src/graphics/render.cpp           |  4 +--
 src/graphics/shaders.cpp          | 44 ++++++-------------------------
 src/graphics/shaders.hpp          | 22 +++++++---------
 src/graphics/stkanimatedmesh.cpp  |  2 +-
 src/graphics/stkmesh.cpp          |  2 +-
 src/graphics/stkmesh.hpp          |  2 +-
 src/graphics/stkmeshscenenode.cpp |  2 +-
 7 files changed, 24 insertions(+), 54 deletions(-)

diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp
index 1adebc5cf..1bdf8c54c 100644
--- a/src/graphics/render.cpp
+++ b/src/graphics/render.cpp
@@ -690,9 +690,9 @@ void IrrDriver::renderSolidSecondPass()
         renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_STANDARD>(MeshShader::ObjectPass2ShaderInstance, { MeshShader::ObjectPass2ShaderInstance->TU_Albedo }, ListDefaultStandardSM::Arguments);
         renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_TANGENTS>(MeshShader::ObjectPass2ShaderInstance, { MeshShader::ObjectPass2ShaderInstance->TU_Albedo }, ListDefaultTangentSM::Arguments);
         renderMeshes2ndPass<MeshShader::ObjectRefPass2Shader, video::EVT_STANDARD>(MeshShader::ObjectRefPass2ShaderInstance, { MeshShader::ObjectRefPass2ShaderInstance->TU_Albedo }, ListAlphaRefSM::Arguments);
-//        renderMeshes2ndPass<MeshShader::SphereMapShader, video::EVT_STANDARD>({ MeshShader::SphereMapShader::TU_tex }, ListSphereMapSM::Arguments);
+        renderMeshes2ndPass<MeshShader::SphereMapShader, video::EVT_STANDARD>(MeshShader::SphereMapShaderInstance, { MeshShader::SphereMapShaderInstance->TU_tex }, ListSphereMapSM::Arguments);
 //        renderMeshes2ndPass<MeshShader::ObjectUnlitShader, video::EVT_STANDARD>({ MeshShader::ObjectUnlitShader::TU_tex }, ListUnlitSM::Arguments);
-//        renderMeshes2ndPass<MeshShader::DetailledObjectPass2Shader, video::EVT_2TCOORDS>({ MeshShader::DetailledObjectPass2Shader::TU_Albedo, MeshShader::DetailledObjectPass2Shader::TU_detail }, ListDetailSM::Arguments);
+        renderMeshes2ndPass<MeshShader::DetailledObjectPass2Shader, video::EVT_2TCOORDS>(MeshShader::DetailledObjectPass2ShaderInstance, { MeshShader::DetailledObjectPass2ShaderInstance->TU_Albedo, MeshShader::DetailledObjectPass2ShaderInstance->TU_detail }, ListDetailSM::Arguments);
 //        renderMeshes2ndPass<MeshShader::SplattingShader, video::EVT_2TCOORDS>({ 8, MeshShader::SplattingShader::TU_tex_layout, MeshShader::SplattingShader::TU_tex_detail0, MeshShader::SplattingShader::TU_tex_detail1, MeshShader::SplattingShader::TU_tex_detail2, MeshShader::SplattingShader::TU_tex_detail3 }, ListSplattingSM::Arguments);
     }
 }
diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp
index b031d42f0..fe3a77b74 100644
--- a/src/graphics/shaders.cpp
+++ b/src/graphics/shaders.cpp
@@ -335,10 +335,10 @@ void Shaders::loadShaders()
     MeshShader::InstancedObjectPass2Shader::init();
     MeshShader::InstancedObjectRefPass2Shader::init();
     MeshShader::InstancedGrassPass2Shader::init();
-    MeshShader::DetailledObjectPass2Shader::init();
+    MeshShader::DetailledObjectPass2ShaderInstance = new MeshShader::DetailledObjectPass2Shader();
     MeshShader::ObjectRefPass2ShaderInstance = new MeshShader::ObjectRefPass2Shader();
     MeshShader::ObjectUnlitShader::init();
-    MeshShader::SphereMapShader::init();
+    MeshShader::SphereMapShaderInstance = new MeshShader::SphereMapShader();
     MeshShader::SplattingShader::init();
     MeshShader::GrassPass1Shader::init();
     MeshShader::GrassPass2Shader::init();
@@ -720,20 +720,13 @@ namespace MeshShader
         glUniform3f(uniform_ambient, s.r, s.g, s.b);
     }
 
-    GLuint DetailledObjectPass2Shader::Program;
-    GLuint DetailledObjectPass2Shader::uniform_MM;
-    GLuint DetailledObjectPass2Shader::uniform_ambient;
-    GLuint DetailledObjectPass2Shader::TU_Albedo;
-    GLuint DetailledObjectPass2Shader::TU_detail;
-
-    void DetailledObjectPass2Shader::init()
+    DetailledObjectPass2Shader::DetailledObjectPass2Shader()
     {
         Program = LoadProgram(
             GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
             GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
             GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/detailledobject_pass2.frag").c_str());
-        uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
-        uniform_ambient = glGetUniformLocation(Program, "ambient");
+        AssignUniforms(Program, uniforms, { "ModelMatrix", "ambient" });
         GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
         glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
         TU_Albedo = 3;
@@ -742,14 +735,7 @@ namespace MeshShader
         AssignTextureUnit(Program, { { 0, "DiffuseMap" }, { 1, "SpecularMap" }, { 2, "SSAO" }, { TU_Albedo, "Albedo" }, { TU_detail, "Detail" } });
     }
 
-    void DetailledObjectPass2Shader::setUniforms(const core::matrix4 &ModelMatrix)
-    {
-        if (UserConfigParams::m_ubo_disabled)
-            bypassUBO(Program);
-        glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
-        const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
-        glUniform3f(uniform_ambient, s.r, s.g, s.b);
-    }
+    DetailledObjectPass2Shader *DetailledObjectPass2ShaderInstance;
 
     GLuint ObjectUnlitShader::Program;
     GLuint ObjectUnlitShader::uniform_MM;
@@ -874,22 +860,15 @@ namespace MeshShader
         glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z);
     }
 
-    GLuint SphereMapShader::Program;
-    GLuint SphereMapShader::uniform_MM;
-    GLuint SphereMapShader::uniform_IMM;
-    GLuint SphereMapShader::uniform_ambient;
-    GLuint SphereMapShader::TU_tex;
 
-    void SphereMapShader::init()
+    SphereMapShader::SphereMapShader()
     {
         Program = LoadProgram(
             GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
             GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
             GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
             GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectpass_spheremap.frag").c_str());
-        uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
-        uniform_IMM = glGetUniformLocation(Program, "InverseModelMatrix");
-        uniform_ambient = glGetUniformLocation(Program, "ambient");
+        AssignUniforms(Program, uniforms, { "ModelMatrix", "InverseModelMatrix", "ambient" });
         if (!UserConfigParams::m_ubo_disabled)
         {
             GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@@ -900,14 +879,7 @@ namespace MeshShader
         AssignTextureUnit(Program, { { 0, "DiffuseMap" }, { 1, "SpecularMap" }, { 2, "SSAO" }, { TU_tex, "tex" } });
     }
 
-    void SphereMapShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const SColorf &ambient)
-    {
-        if (UserConfigParams::m_ubo_disabled)
-            bypassUBO(Program);
-        glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
-        glUniformMatrix4fv(uniform_IMM, 1, GL_FALSE, InverseModelMatrix.pointer());
-        glUniform3f(uniform_ambient, ambient.r, ambient.g, ambient.b);
-    }
+    SphereMapShader *SphereMapShaderInstance;
 
     GLuint SplattingShader::Program;
     GLuint SplattingShader::uniform_MM;
diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp
index d81a49d33..687fc8226 100644
--- a/src/graphics/shaders.hpp
+++ b/src/graphics/shaders.hpp
@@ -194,17 +194,16 @@ public:
     static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix);
 };
 
-class DetailledObjectPass2Shader
+class DetailledObjectPass2Shader : public ShaderHelper<core::matrix4, video::SColorf>
 {
 public:
-    static GLuint Program;
-    static GLuint uniform_MM, uniform_ambient;
-    static GLuint TU_Albedo, TU_detail;
+    GLuint TU_Albedo, TU_detail;
 
-    static void init();
-    static void setUniforms(const core::matrix4 &ModelMatrix);
+    DetailledObjectPass2Shader();
 };
 
+extern DetailledObjectPass2Shader *DetailledObjectPass2ShaderInstance;
+
 class ObjectUnlitShader
 {
 public:
@@ -248,17 +247,16 @@ public:
     static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &InverseViewMatrix, const core::matrix4 &invproj, const core::vector3df &windDirection, const core::vector3df &SunDir);
 };
 
-class SphereMapShader
+class SphereMapShader : public ShaderHelper<core::matrix4, core::matrix4, video::SColorf>
 {
 public:
-    static GLuint Program;
-    static GLuint uniform_MM, uniform_IMM, uniform_ambient;
-    static GLuint TU_tex;
+    GLuint TU_tex;
 
-    static void init();
-    static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const video::SColorf &ambient);
+    SphereMapShader();
 };
 
+extern SphereMapShader *SphereMapShaderInstance;
+
 class SplattingShader
 {
 public:
diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp
index 6439b507f..a71f2ffc8 100644
--- a/src/graphics/stkanimatedmesh.cpp
+++ b/src/graphics/stkanimatedmesh.cpp
@@ -176,7 +176,7 @@ void STKAnimatedMesh::render()
             ListUnlitSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation));
 
         for_in(mesh, ShadedMesh[SM_DETAILS])
-            ListDetailSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation));
+            ListDetailSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, irr_driver->getSceneManager()->getAmbientLight()));
 
         return;
     }
diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp
index d4c15137b..7d86a4bbc 100644
--- a/src/graphics/stkmesh.cpp
+++ b/src/graphics/stkmesh.cpp
@@ -375,7 +375,7 @@ std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, video::SColorf> >
 std::vector<std::tuple<GLMesh *, core::matrix4> > ListSplattingSM::Arguments;
 std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, video::SColorf> > ListSphereMapSM::Arguments;
 std::vector<std::tuple<GLMesh *, core::matrix4> > ListUnlitSM::Arguments;
-std::vector<std::tuple<GLMesh *, core::matrix4> > ListDetailSM::Arguments;
+std::vector<std::tuple<GLMesh *, core::matrix4, video::SColorf> > ListDetailSM::Arguments;
 std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListBlendTransparent::Arguments;
 std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListAdditiveTransparent::Arguments;
 std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, core::vector3df, core::vector3df> > ListBlendTransparentFog::Arguments;
diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp
index dd5824fb6..f0542c353 100644
--- a/src/graphics/stkmesh.hpp
+++ b/src/graphics/stkmesh.hpp
@@ -185,7 +185,7 @@ public:
 class ListDetailSM
 {
 public:
-    static std::vector<std::tuple<GLMesh *, core::matrix4> > Arguments;
+    static std::vector<std::tuple<GLMesh *, core::matrix4, video::SColorf> > Arguments;
 };
 
 class ListBlendTransparent
diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp
index 94c59bede..022ca5371 100644
--- a/src/graphics/stkmeshscenenode.cpp
+++ b/src/graphics/stkmeshscenenode.cpp
@@ -355,7 +355,7 @@ void STKMeshSceneNode::render()
             ListUnlitSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation));
 
         for_in(mesh, ShadedMesh[SM_DETAILS])
-            ListDetailSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation));
+            ListDetailSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, irr_driver->getSceneManager()->getAmbientLight()));
 
         if (!ShadedMesh[SM_GRASS].empty())
             glUseProgram(MeshShader::GrassPass2Shader::Program);