Преглед на файлове

Ignore composelayers for now
Added support for color blend mode
Main pass' blendmode should be normal
Last pass' blendmode should be the first's
Fixed order of glClear's so _rt_FullFrameBuffer is the right color at the right time
Simplified effect and pass creation code a bit more
Non-visible images should render the full chain into the pingpong framebuffers instead of to screen
Fixed an integer division not producing float numbers

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

Alexis Maiquez преди 3 години
родител
ревизия
5521e90155

+ 4 - 0
src/WallpaperEngine/Core/CObject.cpp

@@ -68,6 +68,10 @@ CObject* CObject::fromJSON (json data, CContainer* container)
 
     if (image_it != data.end () && (*image_it).is_null () == false)
     {
+        // composelayer should be ignored for now, or artifacts will appear
+        if (*image_it == "models/util/composelayer.json")
+            return nullptr;
+
         object = Objects::CImage::fromJSON (
                 data,
                 container,

+ 12 - 3
src/WallpaperEngine/Core/Objects/CImage.cpp

@@ -19,14 +19,16 @@ CImage::CImage (
         std::string alignment,
         const glm::vec3& color,
         float alpha,
-        float brightness) :
+        float brightness,
+        uint32_t colorBlendMode) :
         CObject (visible, id, std::move(name), Type, origin, scale, angles),
         m_size (size),
         m_material (material),
         m_alignment (std::move(alignment)),
         m_color (color),
         m_alpha (alpha),
-        m_brightness (brightness)
+        m_brightness (brightness),
+        m_colorBlendMode (colorBlendMode)
 {
 }
 
@@ -46,6 +48,7 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
     auto alpha = jsonFindDefault <float> (data, "alpha", 1.0);
     auto color_val = jsonFindDefault <std::string> (data, "color", "1.0 1.0 1.0");
     auto brightness_val = jsonFindDefault <float> (data, "brightness", 1.0);
+    auto colorBlendMode_val = jsonFindDefault <uint32_t> (data, "colorBlendMode", 0);
 
     json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get <std::string> (), container));
 
@@ -63,7 +66,8 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
         alignment,
         WallpaperEngine::Core::aToVector3 (color_val),
         alpha,
-        brightness_val
+        brightness_val,
+        colorBlendMode_val
     );
 }
 
@@ -97,4 +101,9 @@ const float CImage::getBrightness () const
     return this->m_brightness;
 }
 
+const uint32_t CImage::getColorBlendMode () const
+{
+    return this->m_colorBlendMode;
+}
+
 const std::string CImage::Type = "image";

+ 4 - 1
src/WallpaperEngine/Core/Objects/CImage.h

@@ -34,6 +34,7 @@ namespace WallpaperEngine::Core::Objects
         const float getAlpha () const;
         const glm::vec3& getColor () const;
         const float getBrightness () const;
+        const uint32_t getColorBlendMode () const;
 
     protected:
         CImage (
@@ -48,7 +49,8 @@ namespace WallpaperEngine::Core::Objects
                 std::string alignment,
                 const glm::vec3& color,
                 float alpha,
-                float brightness
+                float brightness,
+                uint32_t colorBlendMode
         );
 
         static const std::string Type;
@@ -60,5 +62,6 @@ namespace WallpaperEngine::Core::Objects
         float m_alpha;
         float m_brightness;
         glm::vec3 m_color;
+        uint32_t m_colorBlendMode;
     };
 };

+ 5 - 0
src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp

@@ -139,6 +139,11 @@ const std::string& CPass::getDepthWrite ()const
     return this->m_depthwrite;
 }
 
+void CPass::setBlendingMode (std::string mode)
+{
+    this->m_blending = mode;
+}
+
 void CPass::insertConstant (const std::string& name, CShaderConstant* constant)
 {
     this->m_constants.insert (std::pair <std::string, CShaderConstant*> (name, constant));

+ 1 - 0
src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h

@@ -28,6 +28,7 @@ namespace WallpaperEngine::Core::Objects::Images::Materials
         const std::string& getCullingMode () const;
         const std::string& getDepthTest () const;
         const std::string& getDepthWrite () const;
+        void setBlendingMode (std::string mode);
 
         void insertCombo (const std::string& name, int value);
         void insertConstant (const std::string& name, Effects::Constants::CShaderConstant* constant);

+ 7 - 8
src/WallpaperEngine/Render/CScene.cpp

@@ -39,6 +39,11 @@ CScene::CScene (Core::CScene* scene, CContainer* container, CContext* context) :
         scene->getOrthogonalProjection ()->getHeight ()
     );
 
+    // set clear color
+    FloatColor clearColor = this->getScene ()->getClearColor ();
+
+    glClearColor (clearColor.r, clearColor.g, clearColor.b, 1.0f);
+
     // setup framebuffers
     this->setupFramebuffers ();
 
@@ -136,21 +141,15 @@ void CScene::renderFrame (glm::ivec4 viewport)
     // ensure the virtual mouse position is up to date
     this->updateMouse (viewport);
 
-    // clear screen
-    FloatColor clearColor = this->getScene ()->getClearColor ();
-
-    glClearColor (clearColor.r, clearColor.g, clearColor.b, 0.0f);
-
     // use the scene's framebuffer by default
     glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());
     // ensure we render over the whole screen
     glViewport (0, 0, projection->getWidth (), projection->getHeight ());
 
+    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
     for (; cur != end; cur ++)
         (*cur)->render ();
-
-    // ensure we render over the whole screen
-    glViewport (0, 0, projection->getWidth (), projection->getHeight ());
 }
 
 void CScene::updateMouse (glm::ivec4 viewport)

+ 59 - 35
src/WallpaperEngine/Render/Objects/CImage.cpp

@@ -94,8 +94,8 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
         this->m_texture->getRealWidth (), this->m_texture->getRealHeight ()
     );
 
-    GLfloat realWidth = this->m_texture->getRealWidth () / 2;
-    GLfloat realHeight = this->m_texture->getRealHeight () / 2;
+    GLfloat realWidth = this->m_texture->getRealWidth () / 2.0f;
+    GLfloat realHeight = this->m_texture->getRealHeight () / 2.0f;
 
     // build a list of vertices, these might need some change later (or maybe invert the camera)
     GLfloat sceneSpacePosition [] = {
@@ -216,32 +216,35 @@ void CImage::setup ()
     if (this->m_initialized)
         return;
 
-    // generate the main material used to render the image
-    this->m_material = new Effects::CMaterial (
-        new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)),
-        this->m_image->getMaterial ()
-    );
+    // TODO: SUPPORT PASSTHROUGH (IT'S A SHADER)
 
-    if (this->getImage ()->getEffects ().empty () == false)
     {
-        // generate the effects used by this material
-        auto cur = this->getImage ()->getEffects ().begin ();
-        auto end = this->getImage ()->getEffects ().end ();
+        // generate the main material used to render the image
+        this->m_material = new Effects::CMaterial (
+            new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)),
+            this->m_image->getMaterial ()
+        );
+
+        // add blendmode to the combos
+        auto cur = this->m_material->getPasses ().begin ();
+        auto end = this->m_material->getPasses ().end ();
 
         for (; cur != end; cur ++)
-            this->m_effects.emplace_back (new CEffect (this, *cur));
+            this->m_passes.push_back (*cur);
     }
 
     // prepare the passes list
-    if (this->getEffects ().empty () == false)
+    if (this->getImage ()->getEffects ().empty () == false)
     {
-        auto effectCur = this->getEffects ().begin ();
-        auto effectEnd = this->getEffects ().end ();
+        // generate the effects used by this material
+        auto cur = this->getImage ()->getEffects ().begin ();
+        auto end = this->getImage ()->getEffects ().end ();
 
-        for (; effectCur != effectEnd; effectCur ++)
+        for (; cur != end; cur ++)
         {
-            auto materialCur = (*effectCur)->getMaterials ().begin ();
-            auto materialEnd = (*effectCur)->getMaterials ().end ();
+            auto effect = new CEffect (this, *cur);
+            auto materialCur = effect->getMaterials ().begin ();
+            auto materialEnd = effect->getMaterials ().end ();
 
             for (; materialCur != materialEnd; materialCur ++)
             {
@@ -251,27 +254,52 @@ void CImage::setup ()
                 for (; passCur != passEnd; passCur ++)
                     this->m_passes.push_back (*passCur);
             }
+
+            this->m_effects.push_back (effect);
         }
     }
 
-    // add the final passes too
-    if (this->m_material->getPasses ().empty () == false)
+    if (this->m_image->getColorBlendMode () > 0)
     {
-        auto cur = this->m_material->getPasses ().begin ();
-        auto end = this->m_material->getPasses ().end ();
+        auto material = Core::Objects::Images::CMaterial::fromFile ("materials/util/effectpassthrough.json", this->getContainer ());
+
+        // effectpasshthrough only has one pass
+        (*material->getPasses ().begin ())->insertCombo ("BLENDMODE", this->m_image->getColorBlendMode ());
+
+        // generate the main material used to render the image
+        this->m_colorBlendMaterial = new Effects::CMaterial(
+            new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)),
+            material
+        );
+
+        // add blendmode to the combos
+        auto cur = this->m_colorBlendMaterial->getPasses ().begin ();
+        auto end = this->m_colorBlendMaterial->getPasses ().end ();
 
         for (; cur != end; cur ++)
             this->m_passes.push_back (*cur);
     }
 
-    // calculate full animation time (if any)
-    this->m_animationTime = 0.0f;
+    // if there's more than one pass the blendmode has to be moved from the beginning to the end
+    if (this->m_passes.size () > 1)
+    {
+        auto first = this->m_passes.begin ();
+        auto last = this->m_passes.rbegin ();
 
-    auto cur = this->getTexture ()->getFrames ().begin ();
-    auto end = this->getTexture ()->getFrames ().end ();
+        (*last)->getPass ()->setBlendingMode ((*first)->getPass ()->getBlendingMode ());
+        (*first)->getPass ()->setBlendingMode ("normal");
+    }
 
-    for (; cur != end; cur ++)
-        this->m_animationTime += (*cur)->frametime;
+    {
+        // calculate full animation time (if any)
+        this->m_animationTime = 0.0f;
+
+        auto cur = this->getTexture ()->getFrames ().begin ();
+        auto end = this->getTexture ()->getFrames ().end ();
+
+        for (; cur != end; cur++)
+            this->m_animationTime += (*cur)->frametime;
+    }
 
     this->m_initialized = true;
 }
@@ -299,8 +327,8 @@ void CImage::render ()
         return;
 
     // reset the framebuffers so the drawing always happens on the same order
-    this->m_currentMainFBO = this->m_subFBO;
-    this->m_currentSubFBO = this->m_mainFBO;
+    this->m_currentMainFBO = this->m_mainFBO;
+    this->m_currentSubFBO = this->m_subFBO;
 
     glColorMask (true, true, true, true);
 
@@ -334,12 +362,8 @@ void CImage::render ()
         }
 
         // determine if it's the last element in the list as this is a screen-copy-like process
-        else if (std::next (cur) == end)
+        else if (std::next (cur) == end && this->getImage ()->isVisible () == true)
         {
-            // do not draw to screen if the image is not visible
-            if (this->getImage ()->isVisible () == false)
-                return;
-
             spacePosition = *this->getSceneSpacePosition ();
             drawTo = this->getScene ()->getFBO ();
             projection = this->m_modelViewProjectionScreen;

+ 1 - 0
src/WallpaperEngine/Render/Objects/CImage.h

@@ -79,6 +79,7 @@ namespace WallpaperEngine::Render::Objects
 
         std::vector<CEffect*> m_effects;
         Effects::CMaterial* m_material;
+        Effects::CMaterial* m_colorBlendMaterial;
         std::vector <Effects::CPass*> m_passes;
 
         double m_animationTime;

+ 58 - 12
src/WallpaperEngine/Render/Objects/Effects/CPass.cpp

@@ -289,6 +289,11 @@ const CMaterial* CPass::getMaterial () const
     return this->m_material;
 }
 
+Core::Objects::Images::Materials::CPass* CPass::getPass ()
+{
+    return this->m_pass;
+}
+
 GLuint CPass::compileShader (Render::Shaders::Compiler* shader, GLuint type)
 {
     // reserve shaders in OpenGL
@@ -464,6 +469,7 @@ void CPass::setupUniforms ()
             if (bindCur != bindEnd)
             {
                 this->m_finalTextures.insert (std::make_pair ((*bindCur).first, nullptr));
+                bindCur ++;
             }
 
             if (cur != end)
@@ -472,26 +478,66 @@ void CPass::setupUniforms ()
                     this->m_finalTextures.insert (std::make_pair (index, *cur));
 
                 index ++;
+                cur ++;
             }
 
-            if (fragCur != fragEnd && (*fragCur).second != nullptr)
+            if (fragCur != fragEnd)
             {
-                this->m_finalTextures.insert (std::make_pair ((*fragCur).first, (*fragCur).second));
-            }
+                std::string textureName = (*fragCur).second;
 
-            if (vertCur != vertEnd && (*vertCur).second != nullptr)
-            {
-                this->m_finalTextures.insert (std::make_pair ((*vertCur).first, (*vertCur).second));
-            }
+                try
+                {
+                    // resolve the texture first
+                    ITexture* textureRef = nullptr;
+
+                    if (textureName.find ("_rt_") == 0)
+                    {
+                        textureRef = this->getMaterial ()->getEffect ()->findFBO (textureName);
+
+                        if (textureRef == nullptr)
+                            textureRef = this->getMaterial ()->getImage ()->getScene ()->findFBO (textureName);
+                    }
+                    else
+                        textureRef = this->getMaterial ()->getImage ()->getContainer ()->readTexture (textureName);
+
+                    this->m_finalTextures.insert (std::make_pair ((*fragCur).first, textureRef));
+                }
+                catch (std::runtime_error& ex)
+                {
+                    std::cerr << "Cannot resolve texture " << textureName << " for fragment shader: " << ex.what () << std::endl;
+                }
 
-            if (bindCur != bindEnd)
-                bindCur ++;
-            if (cur != end)
-                cur ++;
-            if (fragCur != fragEnd)
                 fragCur ++;
+            }
+
             if (vertCur != vertEnd)
+            {
+                std::string textureName = (*vertCur).second;
+
+                try
+                {
+                    // resolve the texture first
+                    ITexture* textureRef = nullptr;
+
+                    if (textureName.find ("_rt_") == 0)
+                    {
+                        textureRef = this->getMaterial ()->getEffect ()->findFBO (textureName);
+
+                        if (textureRef == nullptr)
+                            textureRef = this->getMaterial ()->getImage ()->getScene ()->findFBO (textureName);
+                    }
+                    else
+                        textureRef = this->getMaterial ()->getImage ()->getContainer ()->readTexture (textureName);
+
+                    this->m_finalTextures.insert (std::make_pair ((*vertCur).first, textureRef));
+                }
+                catch (std::runtime_error& ex)
+                {
+                    std::cerr << "Cannot resolve texture " << textureName << " for vertex shader: " << ex.what () << std::endl;
+                }
+
                 vertCur ++;
+            }
         }
     }
 

+ 1 - 0
src/WallpaperEngine/Render/Objects/Effects/CPass.h

@@ -24,6 +24,7 @@ namespace WallpaperEngine::Render::Objects::Effects
         void render (CFBO* drawTo, ITexture* input, GLuint position, GLuint texcoord, glm::mat4 projection);
 
         const CMaterial* getMaterial () const;
+        Core::Objects::Images::Materials::CPass* getPass ();
 
     private:
         enum UniformType

+ 3 - 40
src/WallpaperEngine/Render/Shaders/Compiler.cpp

@@ -711,47 +711,10 @@ namespace WallpaperEngine::Render::Shaders
                         this->m_foundCombos->insert (std::make_pair <std::string, bool> (*combo, true));
                 }
 
-                if (textureName != data.end ())
-                {
-                    // also ensure that the textureName is loaded and we know about it
-                    ITexture* texture = this->m_container->readTexture ((*textureName).get <std::string> ());
-
-                    this->m_textures.insert (
-                            std::make_pair (index, texture)
-                    );
-                }
             }
-            else
-            {
-                // check for texture name too
-                if (textureName != data.end ())
-                {
-                    try
-                    {
-                        // also ensure that the textureName is loaded and we know about it
-                        ITexture* texture = this->m_container->readTexture ((*textureName).get <std::string> ());
-
-                        this->m_textures.insert (
-                            std::make_pair (index, texture)
-                        );
-                    }
-                    catch (CAssetLoadException& ex)
-                    {
-                        // cannot resolve texture
-                        // TODO: TAKE CARE OF FBOS
-                        this->m_textures.insert (
-                            std::make_pair (index, nullptr)
-                        );
-                    }
-                }
-                else
-                {
-                    this->m_textures.insert (
-                        std::make_pair (index, nullptr)
-                    );
-                }
 
-            }
+            if (textureName != data.end ())
+                this->m_textures.insert (std::make_pair (index, *textureName));
 
             // samplers are not saved, we can ignore them for now
             return;
@@ -798,7 +761,7 @@ namespace WallpaperEngine::Render::Shaders
         return this->m_combos;
     }
 
-    const std::map <int, ITexture*>& Compiler::getTextures () const
+    const std::map <int, std::string>& Compiler::getTextures () const
     {
         return this->m_textures;
     }

+ 2 - 2
src/WallpaperEngine/Render/Shaders/Compiler.h

@@ -91,7 +91,7 @@ namespace WallpaperEngine::Render::Shaders
         /**
          * @return The list of textures inferred from the shader's code
          */
-        const std::map <int, ITexture*>& getTextures () const;
+        const std::map <int, std::string>& getTextures () const;
 
     private:
         /**
@@ -263,7 +263,7 @@ namespace WallpaperEngine::Render::Shaders
          /**
           * List of textures that the shader expects (inferred from sampler2D and it's JSON data)
           */
-         std::map<int, ITexture*> m_textures;
+         std::map<int, std::string> m_textures;
          bool m_includesProcessed = false;
     };
 }