Răsfoiți Sursa

~ changed wrong class name crom CPassess to CPass
+ added parsing of bind section for shader passes
~ various new classes to properly handle texture targets, shader passes and materials

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

Alexis Maiquez 7 ani în urmă
părinte
comite
cbe79b535b

+ 13 - 2
CMakeLists.txt

@@ -57,6 +57,15 @@ add_executable(
         src/WallpaperEngine/Render/Objects/CImage.cpp
         src/WallpaperEngine/Render/Objects/CSound.h
         src/WallpaperEngine/Render/Objects/CSound.cpp
+        src/WallpaperEngine/Render/Objects/CEffect.h
+        src/WallpaperEngine/Render/Objects/CEffect.cpp
+
+        src/WallpaperEngine/Render/Objects/Effects/CFBO.h
+        src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp
+        src/WallpaperEngine/Render/Objects/Effects/CPass.h
+        src/WallpaperEngine/Render/Objects/Effects/CPass.cpp
+        src/WallpaperEngine/Render/Objects/Effects/CMaterial.h
+        src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp
 
         src/WallpaperEngine/FileSystem/FileSystem.cpp
         src/WallpaperEngine/FileSystem/FileSystem.h
@@ -100,6 +109,8 @@ add_executable(
 
         src/WallpaperEngine/Core/Objects/Effects/CFBO.h
         src/WallpaperEngine/Core/Objects/Effects/CFBO.cpp
+        src/WallpaperEngine/Core/Objects/Effects/CBind.h
+        src/WallpaperEngine/Core/Objects/Effects/CBind.cpp
 
         src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h
         src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.cpp
@@ -135,8 +146,8 @@ add_executable(
         src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp
         src/WallpaperEngine/Core/Objects/Images/CMaterial.h
 
-        src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.cpp
-        src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.h
+        src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp
+        src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h
 )
 
 target_link_libraries(wallengine ${X11_LIBRARIES} ${XRANDR_LIBRARIES} ${X11_Xxf86vm_LIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${ZLIB_LIBRARIES} ${IRRLICHT_LIBRARY} ${LZ4_LIBRARY} ${SDL_LIBRARY} ${SDL_MIXER_LIBRARIES})

+ 22 - 8
src/WallpaperEngine/Core/Objects/CEffect.cpp

@@ -167,7 +167,7 @@ CEffect* CEffect::fromJSON (json data, Core::CObject* object)
     return effect;
 }
 
-void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPassess* pass)
+void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass)
 {
     auto cur = (*combos_it).begin ();
     auto end = (*combos_it).end ();
@@ -178,7 +178,7 @@ void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Ima
     }
 }
 
-void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPassess* pass)
+void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass)
 {
     auto cur = (*constants_it).begin ();
     auto end = (*constants_it).end ();
@@ -241,24 +241,38 @@ void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect
     {
         auto materialfile = (*cur).find ("material");
         auto target = (*cur).find ("target");
+        auto bind = (*cur).find ("bind");
 
         if (materialfile == (*cur).end ())
         {
             throw std::runtime_error ("Effect pass must have a material file");
         }
 
+        Images::CMaterial* material = nullptr;
+
         if (target == (*cur).end ())
         {
-            effect->insertMaterial (
-                    Images::CMaterial::fromFile ((*materialfile).get <std::string> ().c_str ())
-            );
+            material = Images::CMaterial::fromFile ((*materialfile).get <std::string> ().c_str ());
         }
         else
         {
-            effect->insertMaterial (
-                    Images::CMaterial::fromFile ((*materialfile).get <std::string> ().c_str (), *target)
-            );
+            material = Images::CMaterial::fromFile ((*materialfile).get <std::string> ().c_str (), *target);
+        }
+
+        if (bind != (*cur).end ())
+        {
+            auto bindCur = (*bind).begin ();
+            auto bindEnd = (*bind).end ();
+
+            for (; bindCur != bindEnd; bindCur ++)
+            {
+                material->insertTextureBind (
+                    Effects::CBind::fromJSON (*bindCur)
+                );
+            }
         }
+
+        effect->insertMaterial (material);
     }
 }
 

+ 2 - 2
src/WallpaperEngine/Core/Objects/CEffect.h

@@ -36,8 +36,8 @@ namespace WallpaperEngine::Core::Objects
 
         Effects::CFBO* findFBO (const std::string& name);
     protected:
-        static void constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPassess* pass);
-        static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPassess* pass);
+        static void constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass);
+        static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass);
         static void fbosFromJSON (json::const_iterator fbos_it, CEffect* effect);
         static void dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect);
         static void materialsFromJSON (json::const_iterator passes_it, CEffect* effect);

+ 39 - 0
src/WallpaperEngine/Core/Objects/Effects/CBind.cpp

@@ -0,0 +1,39 @@
+#include "CBind.h"
+
+#include <utility>
+
+using namespace WallpaperEngine::Core::Objects::Effects;
+
+CBind::CBind (std::string name, irr::u32 index) :
+    m_name (std::move(name)),
+    m_index (index)
+{
+}
+
+CBind* CBind::fromJSON (json data)
+{
+    auto name_it = data.find ("name");
+    auto index_it = data.find ("index");
+
+    if (name_it == data.end ())
+    {
+        throw std::runtime_error ("bind must have texture name");
+    }
+
+    if (index_it == data.end ())
+    {
+        throw std::runtime_error ("bind must have index");
+    }
+
+    return new CBind (*name_it, *index_it);
+}
+
+const std::string& CBind::getName () const
+{
+    return this->m_name;
+}
+
+const irr::u32& CBind::getIndex () const
+{
+    return this->m_index;
+}

+ 26 - 0
src/WallpaperEngine/Core/Objects/Effects/CBind.h

@@ -0,0 +1,26 @@
+#pragma once
+
+#include <string>
+
+#include <irrlicht/irrlicht.h>
+#include <nlohmann/json.hpp>
+
+namespace WallpaperEngine::Core::Objects::Effects
+{
+    using json = nlohmann::json;
+
+    class CBind
+    {
+    public:
+        static CBind* fromJSON (json data);
+
+        CBind (std::string name, irr::u32 index);
+
+        const std::string& getName () const;
+        const irr::u32& getIndex () const;
+
+    private:
+        std::string m_name;
+        irr::u32 m_index;
+    };
+}

+ 14 - 3
src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp

@@ -5,6 +5,7 @@
 
 #include "WallpaperEngine/FileSystem/FileSystem.h"
 
+using namespace WallpaperEngine::Core::Objects;
 using namespace WallpaperEngine::Core::Objects::Images;
 
 CMaterial::CMaterial () :
@@ -51,27 +52,37 @@ CMaterial* CMaterial::fromJSON (json data)
     for (; cur != end; cur ++)
     {
         material->insertPass (
-            Materials::CPassess::fromJSON (*cur)
+            Materials::CPass::fromJSON (*cur)
         );
     }
 
     return material;
 }
 
-void CMaterial::insertPass (Materials::CPassess* mass)
+void CMaterial::insertPass (Materials::CPass* mass)
 {
     this->m_passes.push_back (mass);
 }
 
+void CMaterial::insertTextureBind (Effects::CBind* bind)
+{
+    this->m_textureBindings.push_back (bind);
+}
+
 void CMaterial::setTarget (const std::string& target)
 {
     this->m_target = target;
 }
 
-const std::vector <Materials::CPassess*>& CMaterial::getPasses () const
+const std::vector <Materials::CPass*>& CMaterial::getPasses () const
 {
     return this->m_passes;
 }
+const std::vector <Effects::CBind*>& CMaterial::getTextureBinds () const
+{
+    return this->m_textureBindings;
+}
+
 const std::string& CMaterial::getTarget () const
 {
     return this->m_target;

+ 8 - 4
src/WallpaperEngine/Core/Objects/Images/CMaterial.h

@@ -3,7 +3,8 @@
 #include <irrlicht/irrlicht.h>
 #include <nlohmann/json.hpp>
 
-#include "WallpaperEngine/Core/Objects/Images/Materials/CPassess.h"
+#include "WallpaperEngine/Core/Objects/Images/Materials/CPass.h"
+#include "WallpaperEngine/Core/Objects/Effects/CBind.h"
 
 namespace WallpaperEngine::Core::Objects::Images
 {
@@ -17,9 +18,11 @@ namespace WallpaperEngine::Core::Objects::Images
         static CMaterial* fromFile (const irr::io::path& filename, const std::string& target);
         static CMaterial* fromJSON (json data, const std::string& target);
 
-        void insertPass (Materials::CPassess* mass);
+        void insertPass (Materials::CPass* mass);
+        void insertTextureBind (Effects::CBind* bind);
 
-        const std::vector <Materials::CPassess*>& getPasses () const;
+        const std::vector <Materials::CPass*>& getPasses () const;
+        const std::vector <Effects::CBind*>& getTextureBinds () const;
         const std::string& getTarget () const;
         const bool hasTarget () const;
     protected:
@@ -27,7 +30,8 @@ namespace WallpaperEngine::Core::Objects::Images
 
         void setTarget (const std::string& target);
     private:
-        std::vector <Materials::CPassess*> m_passes;
+        std::vector <Materials::CPass*> m_passes;
+        std::vector <Effects::CBind*> m_textureBindings;
         std::string m_target;
     };
 };

+ 16 - 16
src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.cpp → src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp

@@ -1,9 +1,9 @@
-#include "CPassess.h"
+#include "CPass.h"
 
 using namespace WallpaperEngine::Core::Objects::Effects::Constants;
 using namespace WallpaperEngine::Core::Objects::Images::Materials;
 
-CPassess::CPassess (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader) :
+CPass::CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader) :
     m_blending (std::move(blending)),
     m_cullmode (std::move(cullmode)),
     m_depthtest (std::move(depthtest)),
@@ -12,7 +12,7 @@ CPassess::CPassess (std::string blending, std::string cullmode, std::string dept
 {
 }
 
-CPassess* CPassess::fromJSON (json data)
+CPass* CPass::fromJSON (json data)
 {
     auto blending_it = data.find ("blending");
     auto cullmode_it = data.find ("cullmode");
@@ -56,7 +56,7 @@ CPassess* CPassess::fromJSON (json data)
         }
     }
 
-    CPassess* pass = new CPassess (
+    CPass* pass = new CPass (
         *blending_it,
         *cullmode_it,
         *depthtest_it,
@@ -105,62 +105,62 @@ CPassess* CPassess::fromJSON (json data)
     return pass;
 }
 
-void CPassess::insertTexture (const std::string& texture)
+void CPass::insertTexture (const std::string& texture)
 {
     this->m_textures.push_back (texture);
 }
 
-void CPassess::setTexture (int index, const std::string& texture)
+void CPass::setTexture (int index, const std::string& texture)
 {
     this->m_textures.at (index) = texture;
 }
 
-void CPassess::insertCombo (const std::string& name, int value)
+void CPass::insertCombo (const std::string& name, int value)
 {
     this->m_combos.insert (std::pair <std::string, int> (name, value));
 }
 
-const std::vector<std::string>& CPassess::getTextures () const
+const std::vector<std::string>& CPass::getTextures () const
 {
     return this->m_textures;
 }
 
-const std::map<std::string, CShaderConstant*>& CPassess::getConstants () const
+const std::map<std::string, CShaderConstant*>& CPass::getConstants () const
 {
     return this->m_constants;
 }
 
-const std::map<std::string, int>& CPassess::getCombos () const
+const std::map<std::string, int>& CPass::getCombos () const
 {
     return this->m_combos;
 }
 
-const std::string& CPassess::getShader () const
+const std::string& CPass::getShader () const
 {
     return this->m_shader;
 }
 
-const std::string& CPassess::getBlendingMode () const
+const std::string& CPass::getBlendingMode () const
 {
     return this->m_blending;
 }
 
-const std::string& CPassess::getCullingMode () const
+const std::string& CPass::getCullingMode () const
 {
     return this->m_cullmode;
 }
 
-const std::string& CPassess::getDepthTest () const
+const std::string& CPass::getDepthTest () const
 {
     return this->m_depthtest;
 }
 
-const std::string& CPassess::getDepthWrite ()const
+const std::string& CPass::getDepthWrite ()const
 {
     return this->m_depthwrite;
 }
 
-void CPassess::insertConstant (const std::string& name, CShaderConstant* constant)
+void CPass::insertConstant (const std::string& name, CShaderConstant* constant)
 {
     this->m_constants.insert (std::pair <std::string, CShaderConstant*> (name, constant));
 }

+ 3 - 3
src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.h → src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h

@@ -13,11 +13,11 @@ namespace WallpaperEngine::Core::Objects::Images::Materials
 {
     using json = nlohmann::json;
 
-    class CPassess
+    class CPass
     {
         friend class Core::Objects::CEffect;
     public:
-        static CPassess* fromJSON (json data);
+        static CPass* fromJSON (json data);
 
         const std::vector<std::string>& getTextures () const;
         const std::map<std::string, Effects::Constants::CShaderConstant*>& getConstants () const;
@@ -33,7 +33,7 @@ namespace WallpaperEngine::Core::Objects::Images::Materials
         void insertConstant (const std::string& name, Effects::Constants::CShaderConstant* constant);
 
     protected:
-        CPassess (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader);
+        CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader);
 
         void insertTexture (const std::string& texture);
         void setTexture (int index, const std::string& texture);

+ 90 - 0
src/WallpaperEngine/Render/Objects/CEffect.cpp

@@ -0,0 +1,90 @@
+#include "CEffect.h"
+
+using namespace WallpaperEngine::Render::Objects;
+
+CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect, Irrlicht::CContext* context, irr::video::ITexture* input) :
+    m_context (context),
+    m_image (image),
+    m_effect (effect),
+    m_inputTexture (input)
+{
+    irr::core::dimension2du size = irr::core::dimension2du (
+        this->m_image->getImage ()->getSize ().X,
+        this->m_image->getImage ()->getSize ().Y
+    );
+
+    this->m_outputTexture = this->m_context->getDevice ()->getVideoDriver ()->addRenderTargetTexture (
+        size,
+        (
+            "_rt_WALLENGINELINUX_OUTPUT_" +
+            std::to_string (image->getImage ()->getId ()) + "_" +
+            std::to_string (this->m_image->getEffects ().size ()) +
+            "_output"
+        ).c_str ()
+    );
+
+    this->generateFBOs ();
+    this->generatePasses ();
+}
+
+const irr::video::ITexture* CEffect::getInputTexture () const
+{
+    return this->m_inputTexture;
+}
+
+const irr::video::ITexture* CEffect::getOutputTexture () const
+{
+    return this->m_outputTexture;
+}
+
+const CImage* CEffect::getImage () const
+{
+    return this->m_image;
+}
+
+const std::vector<Effects::CMaterial*>& CEffect::getMaterials () const
+{
+    return this->m_materials;
+}
+
+Effects::CFBO* CEffect::findFBO (const std::string& name)
+{
+    auto cur = this->m_fbos.begin ();
+    auto end = this->m_fbos.end ();
+
+    for (; cur != end; cur ++)
+    {
+        if ((*cur)->getName () == name)
+        {
+            return *cur;
+        }
+    }
+
+    return nullptr;
+}
+
+void CEffect::generatePasses ()
+{
+    auto cur = this->m_effect->getMaterials ().begin ();
+    auto end = this->m_effect->getMaterials ().end ();
+
+    for (; cur != end; cur ++)
+    {
+        this->m_materials.push_back (
+            new Effects::CMaterial (this->m_context, this, *cur)
+        );
+    }
+}
+
+void CEffect::generateFBOs ()
+{
+    auto cur = this->m_effect->getFbos ().begin ();
+    auto end = this->m_effect->getFbos ().end ();
+
+    for (; cur != end; cur ++)
+    {
+        this->m_fbos.push_back (
+            new Effects::CFBO (*cur, this->m_image->getImage (), this->m_context)
+        );
+    }
+}

+ 47 - 0
src/WallpaperEngine/Render/Objects/CEffect.h

@@ -0,0 +1,47 @@
+#pragma once
+
+#include <irrlicht/irrlicht.h>
+
+#include "WallpaperEngine/Irrlicht/CContext.h"
+
+#include "WallpaperEngine/Render/Objects/CImage.h"
+#include "WallpaperEngine/Render/Objects/Effects/CFBO.h"
+#include "WallpaperEngine/Render/Objects/Effects/CPass.h"
+#include "WallpaperEngine/Render/Objects/Effects/CMaterial.h"
+
+namespace WallpaperEngine::Render::Objects::Effects
+{
+    class CMaterial;
+}
+
+namespace WallpaperEngine::Render::Objects
+{
+    class CImage;
+
+    class CEffect
+    {
+    public:
+        CEffect (CImage* image, Core::Objects::CEffect* effect, Irrlicht::CContext* context, irr::video::ITexture* input);
+
+        const irr::video::ITexture* getOutputTexture () const;
+        const irr::video::ITexture* getInputTexture () const;
+        const CImage* getImage () const;
+
+        const std::vector<Effects::CMaterial*>& getMaterials () const;
+
+        Effects::CFBO* findFBO (const std::string& name);
+    private:
+        void generatePasses ();
+        void generateFBOs ();
+
+        Irrlicht::CContext* m_context;
+        CImage* m_image;
+        Core::Objects::CEffect* m_effect;
+
+        std::vector<Effects::CFBO*> m_fbos;
+        std::vector<Effects::CMaterial*> m_materials;
+
+        irr::video::ITexture* m_inputTexture;
+        irr::video::ITexture* m_outputTexture;
+    };
+};

+ 13 - 3
src/WallpaperEngine/Render/Objects/CImage.cpp

@@ -102,7 +102,7 @@ void CImage::generateMaterial ()
 
     for (; cur != end; cur++)
     {
-        this->generatePass (*cur, nullptr);
+        this->generatePass (*cur);
     }
 
     auto effectCur = this->m_image->getEffects ().begin ();
@@ -120,13 +120,13 @@ void CImage::generateMaterial ()
 
             for (; cur != end; cur++)
             {
-                this->generatePass (*cur, *effectCur);
+                this->generatePass (*cur);
             }
         }
     }
 }
 
-void CImage::generatePass (Core::Objects::Images::Materials::CPassess* pass, Core::Objects::CEffect* effect)
+void CImage::generatePass (Core::Objects::Images::Materials::CPass* pass)
 {
     std::vector<std::string> textures = pass->getTextures ();
     irr::video::SMaterial material;
@@ -233,6 +233,16 @@ const irr::core::aabbox3d<irr::f32>& CImage::getBoundingBox() const
     return this->m_boundingBox;
 }
 
+const Core::Objects::CImage* CImage::getImage () const
+{
+    return this->m_image;
+}
+
+const std::vector<CEffect*>& CImage::getEffects () const
+{
+    return this->m_effects;
+}
+
 void CImage::OnSetConstants (irr::video::IMaterialRendererServices *services, int32_t userData)
 {
     irr::f32 g_Texture0 = 0;

+ 11 - 2
src/WallpaperEngine/Render/Objects/CImage.h

@@ -2,6 +2,7 @@
 
 #include "WallpaperEngine/Core/Objects/CImage.h"
 
+#include "WallpaperEngine/Render/Objects/CEffect.h"
 #include "WallpaperEngine/Render/CObject.h"
 #include "WallpaperEngine/Render/CScene.h"
 
@@ -11,22 +12,28 @@ using namespace WallpaperEngine;
 
 namespace WallpaperEngine::Render::Objects
 {
+    class CEffect;
+
     class CImage : public CObject, public irr::video::IShaderConstantSetCallBack
     {
     public:
         CImage (CScene* scene, Core::Objects::CImage* image);
 
-        virtual void OnSetConstants (irr::video::IMaterialRendererServices* services, int32_t userData);
+        void OnSetConstants (irr::video::IMaterialRendererServices* services, int32_t userData) override;
 
         void render () override;
         const irr::core::aabbox3d<irr::f32>& getBoundingBox() const override;
 
+        const Core::Objects::CImage* getImage () const;
+        const std::vector<CEffect*>& getEffects () const;
+
     protected:
         static const std::string Type;
 
     private:
+        void generateFBOs ();
         void generateMaterial ();
-        void generatePass (Core::Objects::Images::Materials::CPassess* pass, Core::Objects::CEffect* effect);
+        void generatePass (Core::Objects::Images::Materials::CPass* pass);
 
         irr::video::S3DVertex m_vertex [4];
         irr::u32 m_passes;
@@ -36,6 +43,8 @@ namespace WallpaperEngine::Render::Objects
         Core::Objects::CImage* m_image;
         irr::core::aabbox3d<irr::f32> m_boundingBox;
 
+        std::vector<CEffect*> m_effects;
+
         std::vector<Render::Shaders::Compiler*> m_vertexShaders;
         std::vector<Render::Shaders::Compiler*> m_pixelShaders;
     };

+ 34 - 0
src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp

@@ -0,0 +1,34 @@
+#include "CFBO.h"
+
+using namespace WallpaperEngine::Render::Objects::Effects;
+
+CFBO::CFBO (Core::Objects::Effects::CFBO* fbo, const Core::Objects::CImage* image, Irrlicht::CContext* context) :
+    m_fbo (fbo)
+{
+    irr::core::dimension2du size = irr::core::dimension2du (
+        image->getSize ().X * this->getScale (),
+        image->getSize ().Y * this->getScale ()
+    );
+
+    context->getDevice ()->getVideoDriver ()->addRenderTargetTexture (size, this->getName ().c_str ());
+}
+
+const irr::video::ITexture* CFBO::getTexture () const
+{
+    return this->m_texture;
+}
+
+const std::string& CFBO::getName () const
+{
+    return this->m_fbo->getName ();
+}
+
+const irr::f32& CFBO::getScale () const
+{
+    return this->m_fbo->getScale ();
+}
+
+const std::string& CFBO::getFormat () const
+{
+    return this->m_fbo->getFormat ();
+}

+ 25 - 0
src/WallpaperEngine/Render/Objects/Effects/CFBO.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include <irrlicht/irrlicht.h>
+
+#include "WallpaperEngine/Core/Objects/Effects/CFBO.h"
+#include "WallpaperEngine/Core/Objects/CImage.h"
+
+#include "WallpaperEngine/Irrlicht/CContext.h"
+
+namespace WallpaperEngine::Render::Objects::Effects
+{
+    class CFBO
+    {
+    public:
+        CFBO (Core::Objects::Effects::CFBO* fbo, const Core::Objects::CImage* image, Irrlicht::CContext* context);
+
+        const irr::video::ITexture* getTexture () const;
+        const std::string& getName () const;
+        const irr::f32& getScale () const;
+        const std::string& getFormat () const;
+    private:
+        irr::video::ITexture* m_texture;
+        const Core::Objects::Effects::CFBO* m_fbo;
+    };
+};

+ 46 - 0
src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp

@@ -0,0 +1,46 @@
+#include "CMaterial.h"
+
+using namespace WallpaperEngine::Render::Objects;
+
+using namespace WallpaperEngine::Render::Objects::Effects;
+
+CMaterial::CMaterial (Irrlicht::CContext* context, Render::Objects::CEffect* effect, Core::Objects::Images::CMaterial* material) :
+    m_context (context),
+    m_effect (effect),
+    m_material (material)
+{
+    this->generatePasses ();
+}
+
+const std::vector<CPass*>& CMaterial::getPasses () const
+{
+    return this->m_passes;
+}
+
+const CImage* CMaterial::getImage () const
+{
+    return this->m_effect->getImage ();
+}
+
+const irr::video::ITexture* CMaterial::getOutputTexture () const
+{
+    return this->m_outputTexture;
+}
+
+const irr::video::ITexture* CMaterial::getInputTexture () const
+{
+    return this->m_inputTexture;
+}
+
+void CMaterial::generatePasses ()
+{
+    auto cur = this->m_material->getPasses ().begin ();
+    auto end = this->m_material->getPasses ().end ();
+
+    for (; cur != end; cur ++)
+    {
+        this->m_passes.push_back (
+            new CPass (this->m_context, this, *cur)
+        );
+    }
+}

+ 52 - 0
src/WallpaperEngine/Render/Objects/Effects/CMaterial.h

@@ -0,0 +1,52 @@
+#pragma once
+
+#include <irrlicht/irrlicht.h>
+
+#include "WallpaperEngine/Core/Objects/Images/CMaterial.h"
+#include "WallpaperEngine/Core/Objects/CEffect.h"
+
+#include "WallpaperEngine/Irrlicht/CContext.h"
+
+#include "WallpaperEngine/Render/Objects/Effects/CPass.h"
+#include "WallpaperEngine/Render/Objects/CEffect.h"
+
+#include "CPass.h"
+
+using namespace WallpaperEngine;
+
+namespace WallpaperEngine::Render::Objects
+{
+    class CEffect;
+    class CImage;
+}
+
+namespace WallpaperEngine::Render::Objects::Effects
+{
+    class CPass;
+
+    class CMaterial
+    {
+        friend class CPass;
+    public:
+        CMaterial (Irrlicht::CContext* context, Render::Objects::CEffect* effect, Core::Objects::Images::CMaterial* material);
+
+        const irr::video::ITexture* getOutputTexture () const;
+        const irr::video::ITexture* getInputTexture () const;
+
+        const std::vector<CPass*>& getPasses () const;
+        const CImage* getImage () const;
+
+    private:
+        void generatePasses ();
+
+        Irrlicht::CContext* m_context;
+
+        irr::video::ITexture* m_inputTexture;
+        irr::video::ITexture* m_outputTexture;
+
+        Render::Objects::CEffect* m_effect;
+        Core::Objects::Images::CMaterial* m_material;
+
+        std::vector<CPass*> m_passes;
+    };
+};

+ 255 - 0
src/WallpaperEngine/Render/Objects/Effects/CPass.cpp

@@ -0,0 +1,255 @@
+#include "CPass.h"
+
+#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
+#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.h"
+#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableInteger.h"
+#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector2.h"
+#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector3.h"
+#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.h"
+#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloatPointer.h"
+#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector2Pointer.h"
+
+#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
+#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h"
+#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h"
+#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h"
+
+using namespace WallpaperEngine::Core::Objects::Effects::Constants;
+using namespace WallpaperEngine::Render::Shaders::Variables;
+
+using namespace WallpaperEngine::Render::Objects::Effects;
+
+CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::Images::Materials::CPass* pass) :
+    m_material (material),
+    m_pass (pass),
+    m_context (context),
+    m_inputTexture (nullptr),
+    m_outputTexture (nullptr)
+{
+    irr::io::path vertPath = this->m_context->resolveVertexShader (pass->getShader ());
+    irr::io::path fragPath = this->m_context->resolveFragmentShader (pass->getShader ());
+    // register fragment shader
+    this->m_fragShader = new Render::Shaders::Compiler (
+        this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Pixel, pass->getCombos (), false
+    );
+    // register vertex shader
+    this->m_vertShader = new Render::Shaders::Compiler (
+        this->m_context, fragPath, Render::Shaders::Compiler::Type::Type_Vertex, pass->getCombos (), false
+    );
+
+    // initialize material data and compile shader used for this pass
+    this->m_irrlichtMaterial.Wireframe = false;
+    this->m_irrlichtMaterial.Lighting = false;
+    this->m_irrlichtMaterial.setFlag (irr::video::EMF_LIGHTING, false);
+    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, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0, irr::video::EGSL_DEFAULT
+        );
+
+    this->setupShaderVariables ();
+}
+
+const irr::video::ITexture* CPass::getOutputTexture () const
+{
+    return this->m_outputTexture;
+}
+
+const irr::video::ITexture* CPass::getInputTexture () const
+{
+    return this->m_inputTexture;
+}
+
+const irr::video::SMaterial& CPass::getMaterial () const
+{
+    return this->m_irrlichtMaterial;
+}
+
+void CPass::OnSetConstants (irr::video::IMaterialRendererServices *services, int32_t userData)
+{
+    irr::f32 g_Texture0 = 0;
+    irr::f32 g_Texture1 = 1;
+    irr::f32 g_Texture2 = 2;
+    irr::f32 g_Texture3 = 3;
+    irr::f32 g_Texture4 = 4;
+    irr::f32 g_Texture5 = 5;
+    irr::f32 g_Texture6 = 6;
+    irr::f32 g_Texture7 = 7;
+
+    const Core::Objects::CImage* image = this->m_material->getImage ()->getImage ();
+
+    irr::f32 g_Texture0Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z };
+    irr::f32 g_Texture1Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z };
+    irr::f32 g_Texture2Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z };
+    irr::f32 g_Texture3Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z };
+    irr::f32 g_Texture4Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z };
+    irr::f32 g_Texture5Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z };
+    irr::f32 g_Texture6Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z };
+    irr::f32 g_Texture7Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z };
+
+    irr::f32 g_Texture0Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y };
+    irr::f32 g_Texture1Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y };
+    irr::f32 g_Texture2Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y };
+    irr::f32 g_Texture3Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y };
+    irr::f32 g_Texture4Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y };
+    irr::f32 g_Texture5Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y };
+    irr::f32 g_Texture6Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y };
+    irr::f32 g_Texture7Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y };
+
+    irr::video::IVideoDriver* driver = services->getVideoDriver ();
+
+    irr::core::matrix4 worldViewProj;
+    worldViewProj = driver->getTransform (irr::video::ETS_PROJECTION);
+    worldViewProj *= driver->getTransform (irr::video::ETS_VIEW);
+    worldViewProj *= driver->getTransform (irr::video::ETS_WORLD);
+
+    auto cur = this->m_vertShader->getParameters ().begin ();
+    auto end = this->m_vertShader->getParameters ().end ();
+
+    for (; cur != end; cur ++)
+    {
+        if ((*cur)->is <CShaderVariableInteger> () == true)
+        {
+            services->setVertexShaderConstant (
+                (*cur)->getName ().c_str (),
+                (irr::s32*) (*cur)->getValue (),
+                (*cur)->getSize ()
+            );
+        }
+        else if (
+            (*cur)->is <CShaderVariableFloat> () == true ||
+            (*cur)->is <CShaderVariableVector2> () == true ||
+            (*cur)->is <CShaderVariableVector3> () == true ||
+            (*cur)->is <CShaderVariableVector4> () == true)
+        {
+            services->setVertexShaderConstant (
+                (*cur)->getName ().c_str (),
+                (irr::f32*) (*cur)->getValue (),
+                (*cur)->getSize ()
+            );
+        }
+    }
+
+    cur = this->m_fragShader->getParameters ().begin ();
+    end = this->m_fragShader->getParameters ().end ();
+
+    for (; cur != end; cur ++)
+    {
+        if ((*cur)->is <CShaderVariableInteger> () == true)
+        {
+            services->setPixelShaderConstant (
+                (*cur)->getName ().c_str (),
+                (irr::s32*) (*cur)->getValue (),
+                (*cur)->getSize ()
+            );
+        }
+        else if (
+            (*cur)->is <CShaderVariableFloat> () == true ||
+            (*cur)->is <CShaderVariableVector2> () == true ||
+            (*cur)->is <CShaderVariableVector3> () == true ||
+            (*cur)->is <CShaderVariableVector4> () == true)
+        {
+            services->setPixelShaderConstant (
+                (*cur)->getName ().c_str (),
+                (irr::f32*) (*cur)->getValue (),
+                (*cur)->getSize ()
+            );
+        }
+    }
+
+    cur = this->m_context->getShaderVariables ().begin ();
+    end = this->m_context->getShaderVariables ().end ();
+
+    for (; cur != end; cur ++)
+    {
+        if ((*cur)->is <CShaderVariableFloatPointer> () == true)
+        {
+            services->setPixelShaderConstant (
+                (*cur)->getName ().c_str (),
+                (irr::f32*) (*cur)->getValue (),
+                (*cur)->getSize ()
+            );
+            services->setVertexShaderConstant (
+                (*cur)->getName ().c_str (),
+                (irr::f32*) (*cur)->getValue (),
+                (*cur)->getSize ()
+            );
+        }
+    }
+
+    services->setVertexShaderConstant ("g_ModelViewProjectionMatrix", worldViewProj.pointer(), 16);
+
+    services->setVertexShaderConstant ("g_Texture0Resolution", g_Texture0Resolution, 4);
+    services->setVertexShaderConstant ("g_Texture1Resolution", g_Texture1Resolution, 4);
+    services->setVertexShaderConstant ("g_Texture2Resolution", g_Texture2Resolution, 4);
+    services->setVertexShaderConstant ("g_Texture3Resolution", g_Texture3Resolution, 4);
+    services->setVertexShaderConstant ("g_Texture4Resolution", g_Texture4Resolution, 4);
+    services->setVertexShaderConstant ("g_Texture5Resolution", g_Texture5Resolution, 4);
+    services->setVertexShaderConstant ("g_Texture6Resolution", g_Texture6Resolution, 4);
+    services->setVertexShaderConstant ("g_Texture7Resolution", g_Texture7Resolution, 4);
+
+    services->setVertexShaderConstant ("g_Texture0Rotation", g_Texture0Rotation, 4);
+    services->setVertexShaderConstant ("g_Texture1Rotation", g_Texture1Rotation, 4);
+    services->setVertexShaderConstant ("g_Texture2Rotation", g_Texture2Rotation, 4);
+    services->setVertexShaderConstant ("g_Texture3Rotation", g_Texture3Rotation, 4);
+    services->setVertexShaderConstant ("g_Texture4Rotation", g_Texture4Rotation, 4);
+    services->setVertexShaderConstant ("g_Texture5Rotation", g_Texture5Rotation, 4);
+    services->setVertexShaderConstant ("g_Texture6Rotation", g_Texture6Rotation, 4);
+    services->setVertexShaderConstant ("g_Texture7Rotation", g_Texture7Rotation, 4);
+
+    services->setPixelShaderConstant ("g_Texture0", &g_Texture0, 1);
+    services->setPixelShaderConstant ("g_Texture1", &g_Texture1, 1);
+    services->setPixelShaderConstant ("g_Texture2", &g_Texture2, 1);
+    services->setPixelShaderConstant ("g_Texture3", &g_Texture3, 1);
+    services->setPixelShaderConstant ("g_Texture4", &g_Texture4, 1);
+    services->setPixelShaderConstant ("g_Texture5", &g_Texture5, 1);
+    services->setPixelShaderConstant ("g_Texture6", &g_Texture6, 1);
+    services->setPixelShaderConstant ("g_Texture7", &g_Texture7, 1);
+}
+
+void CPass::setupShaderVariables ()
+{
+    // find variables in the shaders and set the value with the constants if possible
+    auto cur = this->m_pass->getConstants ().begin ();
+    auto end = this->m_pass->getConstants ().end ();
+
+    for (; cur != end; cur ++)
+    {
+        CShaderVariable* vertexVar = this->m_vertShader->findParameter ((*cur).first);
+        CShaderVariable* pixelVar = this->m_fragShader->findParameter ((*cur).first);
+
+        if (pixelVar)
+        {
+            if (pixelVar->is <CShaderVariableFloat> () && (*cur).second->is <CShaderConstantFloat> ())
+            {
+                pixelVar->as <CShaderVariableFloat> ()->setValue (*(*cur).second->as <CShaderConstantFloat> ()->getValue ());
+            }
+            else if (pixelVar->is <CShaderVariableInteger> () && (*cur).second->is <CShaderConstantInteger> ())
+            {
+                pixelVar->as <CShaderVariableInteger> ()->setValue (*(*cur).second->as <CShaderConstantInteger> ()->getValue ());
+            }
+            else if (pixelVar->is <CShaderVariableVector3> () && (*cur).second->is <CShaderConstantVector3> ())
+            {
+                pixelVar->as <CShaderVariableVector3> ()->setValue (*(*cur).second->as <CShaderConstantVector3> ()->getValue ());
+            }
+        }
+
+        if (vertexVar)
+        {
+            if (vertexVar->is <CShaderVariableFloat> () && (*cur).second->is <CShaderConstantFloat> ())
+            {
+                vertexVar->as <CShaderVariableFloat> ()->setValue (*(*cur).second->as <CShaderConstantFloat> ()->getValue ());
+            }
+            else if (vertexVar->is <CShaderVariableInteger> () && (*cur).second->is <CShaderConstantInteger> ())
+            {
+                vertexVar->as <CShaderVariableInteger> ()->setValue (*(*cur).second->as <CShaderConstantInteger> ()->getValue ());
+            }
+            else if (vertexVar->is <CShaderVariableVector3> () && (*cur).second->is <CShaderConstantVector3> ())
+            {
+                vertexVar->as <CShaderVariableVector3> ()->setValue (*(*cur).second->as <CShaderConstantVector3> ()->getValue ());
+            }
+        }
+    }
+}

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

@@ -0,0 +1,41 @@
+#pragma once
+
+#include <irrlicht/irrlicht.h>
+
+#include "WallpaperEngine/Irrlicht/CContext.h"
+
+#include "WallpaperEngine/Render/Objects/Effects/CMaterial.h"
+#include "WallpaperEngine/Render/Shaders/Compiler.h"
+
+namespace WallpaperEngine::Render::Objects::Effects
+{
+    class CMaterial;
+
+    class CPass : public irr::video::IShaderConstantSetCallBack
+    {
+    public:
+        CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::Images::Materials::CPass* pass);
+
+        void OnSetConstants (irr::video::IMaterialRendererServices* services, int32_t userData) override;
+
+        const irr::video::ITexture* getOutputTexture () const;
+        const irr::video::ITexture* getInputTexture () const;
+
+        const irr::video::SMaterial& getMaterial () const;
+
+    private:
+        void setupShaderVariables ();
+
+        CMaterial* m_material;
+        Core::Objects::Images::Materials::CPass* m_pass;
+        Irrlicht::CContext* m_context;
+
+        irr::video::ITexture* m_inputTexture;
+        irr::video::ITexture* m_outputTexture;
+
+        irr::video::SMaterial m_irrlichtMaterial;
+
+        Render::Shaders::Compiler* m_fragShader;
+        Render::Shaders::Compiler* m_vertShader;
+    };
+}