Переглянути джерело

+ added orthogonal flag to the camera
~ removed reduntant code from CImage and made use of the new versions of the same code on CEffect, CMaterial and CPass to simplify the rendering code and make it easier to read
TODO: FIX MATRIX THAT VERTICALLY FLIPS THE IMAGES!
~ properly linked output from CMaterial, CEffect and CPass so a full render pass outputs something to the screen

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

Alexis Maiquez 5 роки тому
батько
коміт
c93c72edc0

+ 2 - 2
src/WallpaperEngine/Render/CCamera.cpp

@@ -36,13 +36,13 @@ const irr::core::vector3df& CCamera::getUp () const
 void CCamera::setOrthogonalProjection (irr::f32 width, irr::f32 height)
 {
     irr::core::matrix4 identity; identity.makeIdentity ();
-    irr::core::matrix4 orthogonalProjection; orthogonalProjection.buildProjectionMatrixOrthoLH (
+    irr::core::matrix4 orthogonalProjection; orthogonalProjection.buildProjectionMatrixOrthoRH (
             width, height,
             this->getCenter ().Z,
             this->getEye ().Z
     );
 
-    this->m_sceneCamera->setProjectionMatrix (orthogonalProjection);
+    this->m_sceneCamera->setProjectionMatrix (orthogonalProjection, true);
     this->m_scene->getContext ()->getDevice ()->getVideoDriver ()->setTransform (irr::video::ETS_PROJECTION, orthogonalProjection);
     this->m_scene->getContext ()->getDevice ()->getVideoDriver ()->setTransform (irr::video::ETS_VIEW, identity);
     this->m_scene->getContext ()->getDevice ()->getVideoDriver ()->setTransform (irr::video::ETS_WORLD, identity);

+ 44 - 4
src/WallpaperEngine/Render/Objects/CEffect.cpp

@@ -25,14 +25,15 @@ CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect, Irrlicht::CCont
 
     this->generateFBOs ();
     this->generatePasses ();
+    this->generateOutputMaterial ();
 }
 
-const irr::video::ITexture* CEffect::getInputTexture () const
+irr::video::ITexture* CEffect::getInputTexture () const
 {
     return this->m_inputTexture;
 }
 
-const irr::video::ITexture* CEffect::getOutputTexture () const
+irr::video::ITexture *const CEffect::getOutputTexture () const
 {
     return this->m_outputTexture;
 }
@@ -67,17 +68,19 @@ void CEffect::generatePasses ()
 {
     auto cur = this->m_effect->getMaterials ().begin ();
     auto end = this->m_effect->getMaterials ().end ();
-    const irr::video::ITexture* inputTexture = this->getInputTexture ();
+    irr::video::ITexture* inputTexture = this->getInputTexture ();
 
     for (; cur != end; cur ++)
     {
-        Effects::CMaterial* material = new Effects::CMaterial (this->m_context, this, *cur, inputTexture);
+        Effects::CMaterial* material = new Effects::CMaterial (this->m_context, this->m_image, *cur, inputTexture);
 
         // next input texture will be the output texture of the material
         inputTexture = material->getOutputTexture ();
 
         this->m_materials.push_back (material);
     }
+
+    this->m_outputMaterial.setTexture (0, inputTexture);
 }
 
 void CEffect::generateFBOs ()
@@ -91,4 +94,41 @@ void CEffect::generateFBOs ()
             new Effects::CFBO (*cur, this->m_image->getImage (), this->m_context)
         );
     }
+}
+
+void CEffect::generateOutputMaterial ()
+{
+    this->m_outputMaterial.MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+    this->m_outputMaterial.setFlag (irr::video::EMF_LIGHTING, false);
+    this->m_outputMaterial.setFlag (irr::video::EMF_BLEND_OPERATION, true);
+    this->m_outputMaterial.Wireframe = false;
+    this->m_outputMaterial.Lighting = false;
+}
+
+void CEffect::render ()
+{
+    uint16_t indices [] =
+    {
+        3, 2, 1, 0
+    };
+
+    irr::video::IVideoDriver* driver = this->getImage ()->getSceneManager ()->getVideoDriver ();
+
+    auto mainCur = this->getMaterials ().begin ();
+    auto mainEnd = this->getMaterials ().end ();
+
+    for (; mainCur != mainEnd; mainCur ++)
+    {
+        (*mainCur)->render ();
+    }
+
+    // set the proper render target
+    driver->setRenderTarget (this->getOutputTexture (), true, true, irr::video::SColor (0, 0, 0, 0));
+    // set the material
+    driver->setMaterial (this->m_outputMaterial);
+    // draw it
+    driver->drawVertexPrimitiveList (
+        this->m_image->getVertex (), 4, indices, 1,
+        irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT
+    );
 }

+ 6 - 2
src/WallpaperEngine/Render/Objects/CEffect.h

@@ -23,16 +23,19 @@ namespace WallpaperEngine::Render::Objects
     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;
+        irr::video::ITexture *const getOutputTexture () const;
+        irr::video::ITexture* getInputTexture () const;
         const CImage* getImage () const;
 
         const std::vector<Effects::CMaterial*>& getMaterials () const;
 
         Effects::CFBO* findFBO (const std::string& name);
+
+        void render ();
     private:
         void generatePasses ();
         void generateFBOs ();
+        void generateOutputMaterial ();
 
         Irrlicht::CContext* m_context;
         CImage* m_image;
@@ -43,5 +46,6 @@ namespace WallpaperEngine::Render::Objects
 
         irr::video::ITexture* m_inputTexture;
         irr::video::ITexture* m_outputTexture;
+        irr::video::SMaterial m_outputMaterial;
     };
 };

+ 47 - 308
src/WallpaperEngine/Render/Objects/CImage.cpp

@@ -1,33 +1,13 @@
 #include "CImage.h"
 
-#include "WallpaperEngine/Render/Shaders/Compiler.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;
-
-using namespace WallpaperEngine::Core::Objects::Effects::Constants;
-
 using namespace WallpaperEngine::Render::Objects;
-using namespace WallpaperEngine::Render::Shaders::Variables;
 
 extern irr::f32 g_Time;
 
 CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
     Render::CObject (scene, Type, image),
-    m_image (image),
-    m_passes (0)
+    m_image (image)
 {
     // TODO: INITIALIZE NEEDED EFFECTS AND PROPERLY CALCULATE THESE?
     irr::f32 xsize = this->m_image->getSize ().X;
@@ -77,177 +57,74 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
     this->m_vertex [2].Color = irr::video::SColor (255, 255, 255, 255);
     this->m_vertex [3].Color = irr::video::SColor (255, 255, 255, 255);
 
-    this->generateMaterial ();
     this->setAutomaticCulling (irr::scene::EAC_OFF);
     this->m_boundingBox = irr::core::aabbox3d<irr::f32>(0, 0, 0, 0, 0, 0);
-}
 
-void CImage::render()
-{
-    uint16_t indices [] =
-    {
-        3, 2, 1, 0
-    };
+    // load the texture in the main material
+    irr::io::path texturepath = this->getScene ()->getContext ()->resolveMaterials (
+        (*(*this->m_image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ())
+    );
+    irr::video::ITexture *texture = this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->getTexture (texturepath);
 
-    irr::video::IVideoDriver* driver = SceneManager->getVideoDriver ();
+    this->m_material = new Render::Objects::Effects::CMaterial (this->getScene ()->getContext (), this, this->m_image->getMaterial (), texture);
 
-    auto cur = this->m_materials.begin ();
-    auto end = this->m_materials.end ();
+    auto effectsCur = this->m_image->getEffects ().begin ();
+    auto effectsEnd = this->m_image->getEffects ().end ();
 
-    auto textureCur = this->m_renderTextures.begin ();
-    auto textureEnd = this->m_renderTextures.end ();
+    texture = this->m_material->getOutputTexture ();
 
-    for (; cur != end; cur ++)
+    for (; effectsCur != effectsEnd; effectsCur ++)
     {
-        if (textureCur == textureEnd)
-        {
-            driver->setRenderTarget (irr::video::ERT_FRAME_BUFFER, false, false);
-        }
-        else
-        {
-            driver->setRenderTarget (*textureCur, true, true, irr::video::SColor (0, 0, 0, 0));
-            textureCur ++;
-        }
-
-        driver->setMaterial (*cur);
-        driver->drawVertexPrimitiveList (
-            this->m_vertex, 4, indices, 1,
-            irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT
-        );
-    }
-}
+        CEffect* effect = new CEffect (this, *effectsCur, this->getScene ()->getContext (), texture);
 
-void CImage::generateMaterial ()
-{
-    auto cur = this->m_image->getMaterial ()->getPasses ().begin ();
-    auto end = this->m_image->getMaterial ()->getPasses ().end ();
+        this->m_effects.push_back (effect);
 
-    for (; cur != end; cur++)
-    {
-        this->generatePass (*cur);
+        texture = effect->getOutputTexture ();
     }
 
-    auto effectCur = this->m_image->getEffects ().begin ();
-    auto effectEnd = this->m_image->getEffects ().end ();
-
-    for (; effectCur != effectEnd; effectCur++)
-    {
-        auto materialCur = (*effectCur)->getMaterials ().begin ();
-        auto materialEnd = (*effectCur)->getMaterials ().end ();
-
-        for (; materialCur != materialEnd; materialCur++)
-        {
-            cur = (*materialCur)->getPasses ().begin ();
-            end = (*materialCur)->getPasses ().end ();
-
-            for (; cur != end; cur++)
-            {
-                this->generatePass (*cur);
-            }
-        }
-    }
+    this->generateMaterial (texture);
 }
 
-void CImage::generatePass (Core::Objects::Images::Materials::CPass* pass)
+void CImage::render()
 {
-    std::vector<std::string> textures = pass->getTextures ();
-    irr::video::SMaterial material;
-
-    auto texturesCur = textures.begin ();
-    auto texturesEnd = textures.end ();
-
-    for (int textureNumber = 0; texturesCur != texturesEnd; texturesCur ++, textureNumber ++)
+    uint16_t indices [] =
     {
-        irr::io::path texturepath = this->getScene ()->getContext ()->resolveMaterials (*texturesCur);
-        irr::video::ITexture* texture = nullptr;
-
-        if (textureNumber == 0 && this->m_passes > 0)
-        {
-            irr::video::ITexture* originalTexture = this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->getTexture (texturepath);
-
-            texture = this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->addRenderTargetTexture (
-                irr::core::dimension2d<irr::u32> (
-                    originalTexture->getSize ().Width,
-                    originalTexture->getSize ().Height
-                ), ("_RT_" + this->m_image->getName () + std::to_string (textureNumber) + "_" + std::to_string (this->m_passes)).c_str ()
-            );
-
-            this->m_renderTextures.push_back (texture);
-        }
-        else
-        {
-            texture = this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->getTexture (texturepath);
-        }
-
-        material.setTexture (textureNumber, texture);
-    }
-
-    // TODO: MOVE SHADER INITIALIZATION ELSEWHERE
-    irr::io::path vertpath = this->getScene ()->getContext ()->resolveVertexShader (pass->getShader ());
-    irr::io::path fragpath = this->getScene ()->getContext ()->resolveFragmentShader (pass->getShader ());
+        3, 2, 1, 0
+    };
 
-    auto vertexShader = new Render::Shaders::Compiler (this->getScene ()->getContext (), vertpath, Render::Shaders::Compiler::Type::Type_Vertex, pass->getCombos (), false);
-    auto pixelShader = new Render::Shaders::Compiler (this->getScene ()->getContext (), fragpath, Render::Shaders::Compiler::Type::Type_Pixel, pass->getCombos (), false);
+    irr::video::IVideoDriver* driver = SceneManager->getVideoDriver ();
 
-    material.MaterialType = (irr::video::E_MATERIAL_TYPE)
-        this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->getGPUProgrammingServices ()->addHighLevelShaderMaterial (
-            vertexShader->precompile ().c_str (), "main", irr::video::EVST_VS_2_0,
-            pixelShader->precompile ().c_str (), "main", irr::video::EPST_PS_2_0,
-            this, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, this->m_passes, irr::video::EGSL_DEFAULT
-        );
+    // first render the base material
+    this->m_material->render ();
 
-    // find variables in the shaders and set the value with the constants if possible
-    auto cur = pass->getConstants ().begin ();
-    auto end = pass->getConstants ().end ();
+    // now render all the effects, they should already be linked to each other
+    auto effectCur = this->m_effects.begin ();
+    auto effectEnd = this->m_effects.end ();
 
-    for (; cur != end; cur ++)
+    for (; effectCur != effectEnd; effectCur ++)
     {
-        CShaderVariable* vertexVar = vertexShader->findParameter ((*cur).first);
-        CShaderVariable* pixelVar = pixelShader->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 ());
-            }
-        }
+        (*effectCur)->render ();
     }
 
-    // TODO: TAKE INTO ACCOUNT BLENDING AND CULLING METHODS FROM THE JSON
-    material.setFlag (irr::video::EMF_LIGHTING, false);
-    material.setFlag (irr::video::EMF_BLEND_OPERATION, true);
-    material.Wireframe = false;
-    material.Lighting = false;
+    // set render target to the screen
+    driver->setRenderTarget (irr::video::ERT_FRAME_BUFFER, false, false);
+    // set the material to use
+    driver->setMaterial (this->m_irrlichtMaterial);
+    // draw it
+    driver->drawVertexPrimitiveList (
+        this->m_vertex, 4, indices, 1,
+        irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT
+    );
+}
 
-    this->m_vertexShaders.push_back (vertexShader);
-    this->m_pixelShaders.push_back (pixelShader);
-    this->m_materials.push_back (material);
-    this->m_passes ++;
+void CImage::generateMaterial (irr::video::ITexture* resultTexture)
+{
+    this->m_irrlichtMaterial.setTexture (0, resultTexture);
+    this->m_irrlichtMaterial.MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+    this->m_irrlichtMaterial.setFlag (irr::video::EMF_LIGHTING, false);
+    this->m_irrlichtMaterial.setFlag (irr::video::EMF_BLEND_OPERATION, true);
+    this->m_irrlichtMaterial.Wireframe = false;
+    this->m_irrlichtMaterial.Lighting = false;
 }
 
 const irr::core::aabbox3d<irr::f32>& CImage::getBoundingBox() const
@@ -265,147 +142,9 @@ const std::vector<CEffect*>& CImage::getEffects () const
     return this->m_effects;
 }
 
-void CImage::OnSetConstants (irr::video::IMaterialRendererServices *services, int32_t userData)
+const irr::video::S3DVertex* CImage::getVertex () const
 {
-    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;
-
-    irr::f32 g_Texture0Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
-    irr::f32 g_Texture1Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
-    irr::f32 g_Texture2Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
-    irr::f32 g_Texture3Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
-    irr::f32 g_Texture4Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
-    irr::f32 g_Texture5Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
-    irr::f32 g_Texture6Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
-    irr::f32 g_Texture7Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
-
-    irr::f32 g_Texture0Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
-    irr::f32 g_Texture1Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
-    irr::f32 g_Texture2Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
-    irr::f32 g_Texture3Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
-    irr::f32 g_Texture4Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
-    irr::f32 g_Texture5Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
-    irr::f32 g_Texture6Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
-    irr::f32 g_Texture7Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_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);
-
-    Render::Shaders::Compiler* vertexShader = this->m_vertexShaders.at (userData);
-    Render::Shaders::Compiler* pixelShader = this->m_pixelShaders.at (userData);
-
-    auto cur = vertexShader->getParameters ().begin ();
-    auto end = vertexShader->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 = pixelShader->getParameters ().begin ();
-    end = pixelShader->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->getScene ()->getContext ()->getShaderVariables ().begin ();
-    end = this->getScene ()->getContext ()->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);
+    return this->m_vertex;
 }
 
 const std::string CImage::Type = "image";

+ 12 - 12
src/WallpaperEngine/Render/Objects/CImage.h

@@ -2,6 +2,7 @@
 
 #include "WallpaperEngine/Core/Objects/CImage.h"
 
+#include "WallpaperEngine/Render/Objects/Effects/CMaterial.h"
 #include "WallpaperEngine/Render/Objects/CEffect.h"
 #include "WallpaperEngine/Render/CObject.h"
 #include "WallpaperEngine/Render/CScene.h"
@@ -10,42 +11,41 @@
 
 using namespace WallpaperEngine;
 
+namespace WallpaperEngine::Render::Objects::Effects
+{
+    class CMaterial;
+}
+
 namespace WallpaperEngine::Render::Objects
 {
     class CEffect;
 
-    class CImage : public CObject, public irr::video::IShaderConstantSetCallBack
+    class CImage : public CObject
     {
     public:
         CImage (CScene* scene, Core::Objects::CImage* image);
 
-        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;
 
+        const irr::video::S3DVertex* getVertex () const;
+
     protected:
         static const std::string Type;
 
     private:
-        void generateFBOs ();
-        void generateMaterial ();
-        void generatePass (Core::Objects::Images::Materials::CPass* pass);
+        void generateMaterial (irr::video::ITexture* resultTexture);
 
         irr::video::S3DVertex m_vertex [4];
-        irr::u32 m_passes;
-        std::vector<irr::video::SMaterial> m_materials;
-        std::vector<irr::video::ITexture*> m_renderTextures;
 
         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;
+        Effects::CMaterial* m_material;
+        irr::video::SMaterial m_irrlichtMaterial;
     };
 }

+ 57 - 8
src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp

@@ -4,9 +4,9 @@ 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, const irr::video::ITexture* texture) :
+CMaterial::CMaterial (Irrlicht::CContext* context, Render::Objects::CImage* image, const Core::Objects::Images::CMaterial* material, irr::video::ITexture* texture) :
     m_context (context),
-    m_effect (effect),
+    m_image (image),
     m_material (material),
     m_inputTexture (texture)
 {
@@ -14,13 +14,14 @@ CMaterial::CMaterial (Irrlicht::CContext* context, Render::Objects::CEffect* eff
         this->m_inputTexture->getSize (),
         (
             "_rt_WALLENGINELINUX_OUTPUT_" +
-            std::to_string (this->m_effect->getImage ()->getImage ()->getId ()) + "_" +
-            std::to_string (this->m_effect->getImage ()->getEffects ().size ()) +
+            std::to_string (this->m_image->getImage ()->getId ()) + "_" +
+            std::to_string (this->m_image->getEffects ().size ()) +
             "_material_output"
         ).c_str ()
     );
 
     this->generatePasses ();
+    this->generateOutputMaterial ();
 }
 
 const std::vector<CPass*>& CMaterial::getPasses () const
@@ -30,15 +31,15 @@ const std::vector<CPass*>& CMaterial::getPasses () const
 
 const CImage* CMaterial::getImage () const
 {
-    return this->m_effect->getImage ();
+    return this->m_image;
 }
 
-const irr::video::ITexture* CMaterial::getOutputTexture () const
+irr::video::ITexture* CMaterial::getOutputTexture () const
 {
     return this->m_outputTexture;
 }
 
-const irr::video::ITexture* CMaterial::getInputTexture () const
+irr::video::ITexture* CMaterial::getInputTexture () const
 {
     return this->m_inputTexture;
 }
@@ -47,7 +48,7 @@ void CMaterial::generatePasses ()
 {
     auto cur = this->m_material->getPasses ().begin ();
     auto end = this->m_material->getPasses ().end ();
-    const irr::video::ITexture* inputTexture = this->getInputTexture ();
+    irr::video::ITexture* inputTexture = this->getInputTexture ();
 
     for (; cur != end; cur ++)
     {
@@ -57,4 +58,52 @@ void CMaterial::generatePasses ()
 
         this->m_passes.push_back (pass);
     }
+
+    this->m_outputMaterial.setTexture (0, inputTexture);
+}
+
+void CMaterial::generateOutputMaterial ()
+{
+    this->m_outputMaterial.MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+    this->m_outputMaterial.setFlag (irr::video::EMF_LIGHTING, false);
+    this->m_outputMaterial.setFlag (irr::video::EMF_BLEND_OPERATION, true);
+    this->m_outputMaterial.Wireframe = false;
+    this->m_outputMaterial.Lighting = false;
+}
+
+void CMaterial::render ()
+{
+    uint16_t indices [] =
+    {
+        3, 2, 1, 0
+    };
+
+    irr::video::IVideoDriver* driver = this->getImage ()->getSceneManager ()->getVideoDriver ();
+
+    auto mainCur = this->getPasses ().begin ();
+    auto mainEnd = this->getPasses ().end ();
+
+    for (; mainCur != mainEnd; mainCur ++)
+    {
+        // set the proper render target
+        driver->setRenderTarget ((*mainCur)->getOutputTexture (), true, true, irr::video::SColor (0, 0, 0, 0));
+        // set the material
+        driver->setMaterial ((*mainCur)->getMaterial ());
+        // draw it
+        driver->drawVertexPrimitiveList (
+            this->m_image->getVertex (), 4, indices, 1,
+            irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT
+        );
+    }
+
+    // render last pass' output into our output
+    // set the proper render target
+    driver->setRenderTarget (this->getOutputTexture (), true, true, irr::video::SColor (0, 0, 0, 0));
+    // set the material
+    driver->setMaterial (this->m_outputMaterial);
+    // draw it
+    driver->drawVertexPrimitiveList (
+        this->m_image->getVertex (), 4, indices, 1,
+        irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT
+    );
 }

+ 10 - 6
src/WallpaperEngine/Render/Objects/Effects/CMaterial.h

@@ -28,24 +28,28 @@ namespace WallpaperEngine::Render::Objects::Effects
     {
         friend class CPass;
     public:
-        CMaterial (Irrlicht::CContext* context, Render::Objects::CEffect* effect, Core::Objects::Images::CMaterial* material, const irr::video::ITexture* texture);
+        CMaterial (Irrlicht::CContext* context, Render::Objects::CImage* image, const Core::Objects::Images::CMaterial* material, irr::video::ITexture* texture);
 
-        const irr::video::ITexture* getOutputTexture () const;
-        const irr::video::ITexture* getInputTexture () const;
+        irr::video::ITexture* getOutputTexture () const;
+        irr::video::ITexture* getInputTexture () const;
 
         const std::vector<CPass*>& getPasses () const;
         const CImage* getImage () const;
 
+        void render ();
+
     private:
         void generatePasses ();
+        void generateOutputMaterial ();
 
         Irrlicht::CContext* m_context;
 
-        const irr::video::ITexture* m_inputTexture;
+        irr::video::ITexture* m_inputTexture;
         irr::video::ITexture* m_outputTexture;
+        irr::video::SMaterial m_outputMaterial;
 
-        Render::Objects::CEffect* m_effect;
-        Core::Objects::Images::CMaterial* m_material;
+        Render::Objects::CImage* m_image;
+        const Core::Objects::Images::CMaterial* m_material;
 
         std::vector<CPass*> m_passes;
     };

+ 26 - 5
src/WallpaperEngine/Render/Objects/Effects/CPass.cpp

@@ -19,7 +19,7 @@ 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, const irr::video::ITexture* texture) :
+CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::Images::Materials::CPass* pass, irr::video::ITexture* texture) :
     m_material (material),
     m_pass (pass),
     m_context (context),
@@ -40,12 +40,13 @@ 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, vertPath, Render::Shaders::Compiler::Type::Type_Pixel, pass->getCombos (), false
+        this->m_context, fragPath, 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
+        this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Vertex, pass->getCombos (), false
     );
+    this->setupTextures ();
     // initialize material data and compile shader used for this pass
     this->m_irrlichtMaterial.Wireframe = false;
     this->m_irrlichtMaterial.Lighting = false;
@@ -61,12 +62,12 @@ CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::I
     this->setupShaderVariables ();
 }
 
-const irr::video::ITexture* CPass::getOutputTexture () const
+irr::video::ITexture *CPass::getOutputTexture () const
 {
     return this->m_outputTexture;
 }
 
-const irr::video::ITexture* CPass::getInputTexture () const
+irr::video::ITexture* CPass::getInputTexture () const
 {
     return this->m_inputTexture;
 }
@@ -261,4 +262,24 @@ void CPass::setupShaderVariables ()
             }
         }
     }
+}
+
+void CPass::setupTextures ()
+{
+    auto textureCur = this->m_pass->getTextures ().begin ();
+    auto textureEnd = this->m_pass->getTextures ().end ();
+
+    for (int textureNumber = 0; textureCur != textureEnd; textureCur ++, textureNumber ++)
+    {
+        // XXXHACK: TODO: PROPERLY DETECT WHERE THE INPUT TEXTURE SHOULD BE USED IN THE SHADER GRAPH
+        if (textureNumber == 0)
+            this->m_irrlichtMaterial.setTexture (0, this->m_inputTexture);
+        else
+        {
+            irr::io::path texturepath = this->m_context->resolveMaterials (*textureCur);
+            irr::video::ITexture* texture = this->m_context->getDevice ()->getVideoDriver ()->getTexture (texturepath);
+
+            this->m_irrlichtMaterial.setTexture (textureNumber, texture);
+        }
+    }
 }

+ 5 - 4
src/WallpaperEngine/Render/Objects/Effects/CPass.h

@@ -14,23 +14,24 @@ namespace WallpaperEngine::Render::Objects::Effects
     class CPass : public irr::video::IShaderConstantSetCallBack
     {
     public:
-        CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::Images::Materials::CPass* pass, const irr::video::ITexture* texture);
+        CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::Images::Materials::CPass* pass, irr::video::ITexture* texture);
 
         void OnSetConstants (irr::video::IMaterialRendererServices* services, int32_t userData) override;
 
-        const irr::video::ITexture* getOutputTexture () const;
-        const irr::video::ITexture* getInputTexture () const;
+        irr::video::ITexture *getOutputTexture () const;
+        irr::video::ITexture* getInputTexture () const;
 
         const irr::video::SMaterial& getMaterial () const;
 
     private:
         void setupShaderVariables ();
+        void setupTextures ();
 
         CMaterial* m_material;
         Core::Objects::Images::Materials::CPass* m_pass;
         Irrlicht::CContext* m_context;
 
-        const irr::video::ITexture* m_inputTexture;
+        irr::video::ITexture* m_inputTexture;
         irr::video::ITexture* m_outputTexture;
 
         irr::video::SMaterial m_irrlichtMaterial;