Ver código fonte

~ shader precompilation should be done in order to ensure that the vertex shader has information discovered by the fragment shader (like new combos) should fix some effects on backgrounds
+ added partial support for shader constant values from the scene.json

Signed-off-by: Alexis Maiquez <almamu@almamu.com>

Alexis Maiquez 5 anos atrás
pai
commit
537acb97bd

+ 10 - 4
src/WallpaperEngine/Render/Objects/Effects/CPass.cpp

@@ -42,12 +42,18 @@ CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::I
     irr::io::path fragPath = this->m_context->resolveFragmentShader (pass->getShader ());
     // register fragment shader
     this->m_fragShader = new Render::Shaders::Compiler (
-        this->m_context, fragPath, Render::Shaders::Compiler::Type::Type_Pixel, pass->getCombos (), false
+        this->m_context, fragPath, Render::Shaders::Compiler::Type::Type_Pixel,
+        pass->getCombos (), pass->getConstants (), false
     );
+    // compile fragment shader
+    this->m_fragShader->precompile ();
     // register vertex shader, combos come from the fragment as it can sometimes define them
     this->m_vertShader = new Render::Shaders::Compiler (
-        this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Vertex, this->m_fragShader->getCombos (), false
+            this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Vertex,
+            this->m_fragShader->getCombos (), pass->getConstants (), false
     );
+    // compile vertex shader
+    this->m_vertShader->precompile ();
     this->setupTextures ();
     // initialize material data and compile shader used for this pass
     this->m_irrlichtMaterial.Wireframe = false;
@@ -56,8 +62,8 @@ CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::I
     this->m_irrlichtMaterial.setFlag (irr::video::EMF_BLEND_OPERATION, true);
     this->m_irrlichtMaterial.MaterialType = (irr::video::E_MATERIAL_TYPE)
         this->m_context->getDevice ()->getVideoDriver ()->getGPUProgrammingServices ()->addHighLevelShaderMaterial (
-            this->m_vertShader->precompile ().c_str (), "main", irr::video::EVST_VS_2_0,
-            this->m_fragShader->precompile ().c_str (), "main", irr::video::EPST_PS_2_0,
+            this->m_vertShader->getCompiled ().c_str (), "main", irr::video::EVST_VS_2_0,
+            this->m_fragShader->getCompiled ().c_str (), "main", irr::video::EPST_PS_2_0,
             this, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0, irr::video::EGSL_DEFAULT
         );
 

+ 56 - 15
src/WallpaperEngine/Render/Shaders/Compiler.cpp

@@ -9,6 +9,9 @@
 
 // shader compiler
 #include <WallpaperEngine/Render/Shaders/Compiler.h>
+#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h>
+#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h>
+#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h>
 
 #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
 #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.h"
@@ -21,14 +24,21 @@ using namespace WallpaperEngine::Core;
 
 namespace WallpaperEngine::Render::Shaders
 {
-    Compiler::Compiler (Irrlicht::CContext* context, irr::io::path& file, Type type, std::map<std::string, int> combos, bool recursive) :
-        m_combos (std::move(combos)),
+    Compiler::Compiler (
+            Irrlicht::CContext* context,
+            irr::io::path& file,
+            Type type,
+            std::map<std::string, int> combos,
+            const std::map<std::string, CShaderConstant*>& constants,
+            bool recursive) :
+        m_combos (combos),
         m_recursive (recursive),
         m_type (type),
         m_file (file),
         m_error (""),
         m_errorInfo (""),
-        m_context (context)
+        m_context (context),
+        m_constants (constants)
     {
         this->m_content =WallpaperEngine::FileSystem::loadFullFile (file);
     }
@@ -209,9 +219,11 @@ namespace WallpaperEngine::Render::Shaders
 
         // now compile the new shader
         // do not include the default header (as it's already included in the parent)
-        Compiler loader (this->m_context, shader, this->m_type, this->m_combos, true);
+        Compiler loader (this->m_context, shader, this->m_type, this->m_combos, this->m_constants, true);
 
-        return loader.precompile ();
+        loader.precompile ();
+
+        return loader.getCompiled ();
     }
 
     std::string Compiler::lookupReplaceSymbol (std::string symbol)
@@ -233,7 +245,12 @@ namespace WallpaperEngine::Render::Shaders
         return symbol;
     }
 
-    std::string Compiler::precompile()
+    std::string& Compiler::getCompiled ()
+    {
+        return this->m_compiledContent;
+    }
+
+    void Compiler::precompile()
     {
     #define BREAK_IF_ERROR if (this->m_error == true) { throw std::runtime_error ("ERROR PRE-COMPILING SHADER" + this->m_errorInfo); }
         // parse the shader and find #includes and such things and translate them to the correct name
@@ -475,10 +492,11 @@ namespace WallpaperEngine::Render::Shaders
         if (this->m_recursive == false)
         {
             std::cout << "======================== COMPILED SHADER " << this->m_file.c_str () << " ========================" << std::endl;
-            std::cout << this->m_compiledContent << std::endl;
+            std::cout << finalCode << std::endl;
         }
 
-        return finalCode;
+        // store the final final code here
+        this->m_compiledContent = finalCode;
     #undef BREAK_IF_ERROR
     }
 
@@ -526,16 +544,19 @@ namespace WallpaperEngine::Render::Shaders
         auto range = data.find ("range");
 
         // this is not a real parameter
-        if (material == data.end () || defvalue == data.end ())
+        if (material == data.end ())
+            return;
+        auto constant = this->m_constants.find (*material);
+
+        if (constant == this->m_constants.end () && defvalue == data.end ())
         {
             if (type != "sampler2D")
-                throw std::runtime_error ("cannot parse parameter info for " + name);
-
-            return;
+                throw std::runtime_error ("cannot parse parameter data");
         }
 
         Variables::CShaderVariable* parameter = nullptr;
 
+        // TODO: SUPPORT VALUES FOR ALL THESE TYPES
         if (type == "vec4")
         {
             parameter = new Variables::CShaderVariableVector4 (
@@ -545,7 +566,9 @@ namespace WallpaperEngine::Render::Shaders
         else if (type == "vec3")
         {
             parameter = new Variables::CShaderVariableVector3 (
-                WallpaperEngine::Core::ato3vf (*defvalue)
+                constant == this->m_constants.end ()
+                ? WallpaperEngine::Core::ato3vf (*defvalue)
+                : *(*constant).second->as <CShaderConstantVector3> ()->getValue ()
             );
         }
         else if (type == "vec2")
@@ -556,11 +579,29 @@ namespace WallpaperEngine::Render::Shaders
         }
         else if (type == "float")
         {
-            parameter = new Variables::CShaderVariableFloat ((*defvalue).get <irr::f32> ());
+            irr::f32 value = 0;
+
+            if (constant == this->m_constants.end ())
+                value = (*defvalue).get <irr::f32> ();
+            else if ((*constant).second->is <CShaderConstantFloat> () == true)
+                value = *(*constant).second->as <CShaderConstantFloat> ()->getValue ();
+            else if ((*constant).second->is <CShaderConstantInteger> () == true)
+                value = *(*constant).second->as <CShaderConstantInteger> ()->getValue ();
+
+            parameter = new Variables::CShaderVariableFloat (value);
         }
         else if (type == "int")
         {
-            parameter = new Variables::CShaderVariableInteger ((*defvalue).get <irr::s32> ());
+            irr::s32 value = 0;
+
+            if (constant == this->m_constants.end ())
+                value = (*defvalue).get <irr::s32> ();
+            else if ((*constant).second->is <CShaderConstantFloat> () == true)
+                value = *(*constant).second->as <CShaderConstantFloat> ()->getValue ();
+            else if ((*constant).second->is <CShaderConstantInteger> () == true)
+                value = *(*constant).second->as <CShaderConstantInteger> ()->getValue ();
+
+            parameter = new Variables::CShaderVariableInteger (value);
         }
         else if (type == "sampler2D")
         {

+ 20 - 4
src/WallpaperEngine/Render/Shaders/Compiler.h

@@ -16,6 +16,7 @@
 namespace WallpaperEngine::Render::Shaders
 {
     using json = nlohmann::json;
+    using namespace WallpaperEngine::Core::Objects::Effects::Constants;
 
     /**
      * A basic shader loader that adds basic function definitions to every loaded shader
@@ -50,18 +51,29 @@ namespace WallpaperEngine::Render::Shaders
          * @param file The file to load
          * @param type The type of shader
          * @param combos Settings for the shader
+         * @param constants Default values for shader variables
          * @param recursive Whether the compiler should add base definitions or not
          */
-        Compiler (Irrlicht::CContext* context, irr::io::path& file, Type type, std::map<std::string, int> combos, bool recursive = false);
+        Compiler (
+            Irrlicht::CContext* context,
+            irr::io::path& file,
+            Type type,
+            std::map<std::string, int> combos,
+            const std::map<std::string, CShaderConstant*>& constants,
+            bool recursive = false
+        );
         /**
          * Performs the actual pre-compilation/pre-processing over the shader files
          * This step is kinda big, replaces variables names on sVariableReplacement,
          * ensures #include directives are correctly handled
          * and takes care of attribute comments for the wallpaper engine specifics
-         *
-         * @return The shader contents ready to be used by OpenGL
          */
-        std::string precompile ();
+        void precompile ();
+        /**
+         * @return The compiled shader's text (if available)
+         */
+        std::string& getCompiled ();
+
         /**
          * Searches the list of parameters available for the parameter with the given value
          *
@@ -225,6 +237,10 @@ namespace WallpaperEngine::Render::Shaders
          * The combos the shader should be generated with
          */
          std::map <std::string, int> m_combos;
+         /**
+          * The shader constants with values for variables inside the shader
+          */
+         const std::map<std::string, CShaderConstant*>& m_constants;
          /**
           * Whether this compilation is a recursive one or not
           */