Pārlūkot izejas kodu

+ added some extra documentation on rendering based on observations and trial and error
~ deprecated --dir --pkg options, the software will automatically detect the background we're loading
+ first draft of FBO support, there's still some extra work to do
~ texture header is now hidden behind getters so the textures can be any kind of source
~ proper setting of resolution and translation variables for textures
~ simplified call flow for any pass rendering, removing render functions on effect and material
~ framebuffer setup has to happen before object setup in the scene

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

Alexis Maiquez 5 gadi atpakaļ
vecāks
revīzija
5828b2ee80
39 mainītis faili ar 675 papildinājumiem un 332 dzēšanām
  1. 5 2
      CMakeLists.txt
  2. 10 0
      docs/JSON_FORMAT.md
  3. 5 0
      docs/rendering/CAMERA_SETTINGS.md
  4. 12 0
      docs/rendering/GENERAL_SETTINGS.md
  5. 11 0
      docs/rendering/IMAGE_OBJECTS.md
  6. 0 0
      docs/rendering/OBJECTS.md
  7. 12 0
      docs/rendering/SOUND_OBJECTS.md
  8. 8 17
      main.cpp
  9. 2 1
      src/WallpaperEngine/Assets/CContainer.cpp
  10. 2 6
      src/WallpaperEngine/Assets/CContainer.h
  11. 25 0
      src/WallpaperEngine/Assets/CTexture.cpp
  12. 11 14
      src/WallpaperEngine/Assets/CTexture.h
  13. 29 0
      src/WallpaperEngine/Assets/ITexture.h
  14. 3 2
      src/WallpaperEngine/Core/Objects/CEffect.cpp
  15. 17 0
      src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.cpp
  16. 21 0
      src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.h
  17. 0 1
      src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp
  18. 17 0
      src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.cpp
  19. 21 0
      src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h
  20. 99 0
      src/WallpaperEngine/Render/CFBO.cpp
  21. 38 0
      src/WallpaperEngine/Render/CFBO.h
  22. 2 2
      src/WallpaperEngine/Render/CScene.cpp
  23. 1 1
      src/WallpaperEngine/Render/CVideo.cpp
  24. 37 50
      src/WallpaperEngine/Render/CWallpaper.cpp
  25. 31 31
      src/WallpaperEngine/Render/CWallpaper.h
  26. 13 20
      src/WallpaperEngine/Render/Objects/CEffect.cpp
  27. 4 5
      src/WallpaperEngine/Render/Objects/CEffect.h
  28. 94 37
      src/WallpaperEngine/Render/Objects/CImage.cpp
  29. 13 3
      src/WallpaperEngine/Render/Objects/CImage.h
  30. 0 30
      src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp
  31. 0 20
      src/WallpaperEngine/Render/Objects/Effects/CFBO.h
  32. 4 28
      src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp
  33. 3 11
      src/WallpaperEngine/Render/Objects/Effects/CMaterial.h
  34. 103 31
      src/WallpaperEngine/Render/Objects/Effects/CPass.cpp
  35. 4 2
      src/WallpaperEngine/Render/Objects/Effects/CPass.h
  36. 4 4
      src/WallpaperEngine/Render/Shaders/Compiler.cpp
  37. 3 3
      src/WallpaperEngine/Render/Shaders/Compiler.h
  38. 5 5
      src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.cpp
  39. 6 6
      src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.h

+ 5 - 2
CMakeLists.txt

@@ -47,6 +47,7 @@ add_executable(
         src/WallpaperEngine/Assets/CDirectory.cpp
         src/WallpaperEngine/Assets/CPackage.h
         src/WallpaperEngine/Assets/CPackage.cpp
+        src/WallpaperEngine/Assets/ITexture.h
         src/WallpaperEngine/Assets/CTexture.h
         src/WallpaperEngine/Assets/CTexture.cpp
 
@@ -90,8 +91,8 @@ add_executable(
         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/CFBO.h
+        src/WallpaperEngine/Render/CFBO.cpp
         src/WallpaperEngine/Render/Objects/Effects/CPass.h
         src/WallpaperEngine/Render/Objects/Effects/CPass.cpp
         src/WallpaperEngine/Render/Objects/Effects/CMaterial.h
@@ -146,6 +147,8 @@ add_executable(
         src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.cpp
         src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h
         src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp
+        src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h
+        src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.cpp
         src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h
         src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.cpp
 

+ 10 - 0
docs/JSON_FORMAT.md

@@ -0,0 +1,10 @@
+# scene.json
+The scene file contains information about all the objects for the scene with the camera settings in it.
+
+## Structure
+### camera
+[see here](rendering/CAMERA_SETTINGS.md)
+### general
+[see here](rendering/GENERAL_SETTINGS.md)
+### objects
+[see here](rendering/OBJECTS.md)

+ 5 - 0
docs/rendering/CAMERA_SETTINGS.md

@@ -0,0 +1,5 @@
+# camera settings
+- camera:
+ - eye: where the camera is at
+ - center: wherte the camera is pointing at
+ - up: the up vector

+ 12 - 0
docs/rendering/GENERAL_SETTINGS.md

@@ -0,0 +1,12 @@
+# General scene settings
+- ambientcolor: Color to use when clearing the scene
+- bloom: Whether bloom is enabled or not
+
+- orthogonalprojection:
+ - width: width of the orthogonalprojection
+ - height: height of the orthogonal projection
+
+# camera settings
+- farz: projection's far clip (optional)
+- nearz: projection's near clip (optional)
+- fov: field of view (optional)

+ 11 - 0
docs/rendering/IMAGE_OBJECTS.md

@@ -0,0 +1,11 @@
+# Image objects
+Image objects are simple quads that display an image in them. These are usually used in orthogonal scenes to display animated effects.
+
+Looks like every image object has two framebuffers used for ping-pong when rendering, these are usually registered as:
+- _rt_imageLayerComposite_{id}_a
+- _rt_imageLayerComposite_{id}_b
+
+There's special textures used for various things:
+- _rt_FullFrameBuffer: Represents the things currently rendered to the background's output
+- _rt_HalfCompoBuffer1: Unknown for now
+- _rt_HalfCompoBuffer2: Unknown for now

+ 0 - 0
docs/rendering/OBJECTS.md


+ 12 - 0
docs/rendering/SOUND_OBJECTS.md

@@ -0,0 +1,12 @@
+# Sound objects
+These are the simplest ones. They contain a simple list of sounds to play (one after another? needs to be confirmed) and simple information like volume, playmode, etc...
+
+## Specific json entries
+- sound: An array of music files to play
+- volume: The volume to play the music at. 0.0f - 1.0f
+- mintime: The minimum delay between background rendering starting and sound starting
+- maxtime: The maximum delay between background rendering starting and sound starting
+- playbackmode: Whether the sound has to be looped or played oneshot...
+
+## Editor json entries
+- muteineditor: Whether the sound has to be muted by default

+ 8 - 17
main.cpp

@@ -71,9 +71,7 @@ std::string stringPathFixes(const std::string& s)
 int main (int argc, char* argv[])
 {
     std::vector <std::string> screens;
-    bool isRootWindow = false;
 
-    int mode = RUN_MODE_UNKNOWN;
     int maximumFPS = 30;
     bool shouldEnableAudio = true;
     std::string path;
@@ -100,19 +98,12 @@ int main (int argc, char* argv[])
         switch (c)
         {
             case 'r':
-                isRootWindow = true;
                 screens.emplace_back (optarg);
                 break;
 
             case 'p':
-                if (mode == RUN_MODE_UNKNOWN)
-                    mode = RUN_MODE_PACKAGE;
-                path = stringPathFixes (optarg);
-                break;
-
             case 'd':
-                if (mode == RUN_MODE_UNKNOWN)
-                    mode = RUN_MODE_DIRECTORY;
+                std::cout << "--dir/--pkg is deprecated and not used anymore" << std::endl;
                 path = stringPathFixes (optarg);
                 break;
 
@@ -121,7 +112,7 @@ int main (int argc, char* argv[])
                 break;
 
             case 'h':
-                mode = RUN_MODE_HELP;
+                print_help (argv [0]);
                 break;
 
             case 'f':
@@ -133,7 +124,7 @@ int main (int argc, char* argv[])
         }
     }
 
-    if (mode == RUN_MODE_UNKNOWN || mode == RUN_MODE_HELP)
+    if (path.empty () == true && option_index == 0 || strlen (argv [option_index]) == 0)
     {
         print_help (argv [0]);
         return 0;
@@ -161,17 +152,17 @@ int main (int argc, char* argv[])
     containers->add (new WallpaperEngine::Assets::CDirectory ("./assets/"));
     // the background's path is required to load project.json regardless of the type of background we're using
     containers->add (new WallpaperEngine::Assets::CDirectory (path));
-
-    if (mode == RUN_MODE_PACKAGE)
+    // check if scene.pkg exists and add it to the list
+    try
     {
         std::string scene_path = path + "scene.pkg";
 
         // add the package to the list
         containers->add (new WallpaperEngine::Assets::CPackage (scene_path));
     }
-    else if (mode == RUN_MODE_DIRECTORY)
+    catch (std::runtime_error ex)
     {
-        // nothing to do here anymore
+        // ignore the exception, this is to be expected of normal backgrounds
     }
 
     // parse the project.json file
@@ -259,7 +250,7 @@ int main (int argc, char* argv[])
     glDepthFunc (GL_LESS);
 
     // cull anything that doesn't look at the camera (might be useful to disable in the future)
-    //glEnable (GL_CULL_FACE);
+    glDisable (GL_CULL_FACE);
 
     clock_t minimumTime = 1000 / maximumFPS;
     clock_t startTime = 0;

+ 2 - 1
src/WallpaperEngine/Assets/CContainer.cpp

@@ -1,11 +1,12 @@
 #include "CContainer.h"
+#include "CTexture.h"
 
 #include <cstring>
 #include <utility>
 
 using namespace WallpaperEngine::Assets;
 
-CTexture* CContainer::readTexture (std::string filename)
+ITexture* CContainer::readTexture (std::string filename)
 {
     // get the texture's filename (usually .tex)
     filename = "materials/" + filename + ".tex";

+ 2 - 6
src/WallpaperEngine/Assets/CContainer.h

@@ -1,11 +1,7 @@
-//
-// Created by almamu on 8/8/21.
-//
-
 #pragma once
 
 #include <string>
-#include "WallpaperEngine/Assets/CTexture.h"
+#include "WallpaperEngine/Assets/ITexture.h"
 
 namespace WallpaperEngine::Assets
 {
@@ -30,7 +26,7 @@ namespace WallpaperEngine::Assets
          *
          * @return
          */
-        CTexture* readTexture (std::string filename);
+        ITexture* readTexture (std::string filename);
 
         /**
          * Wrapper for readFile, appends the .vert extension at the end and opens the given shader file

+ 25 - 0
src/WallpaperEngine/Assets/CTexture.cpp

@@ -177,6 +177,31 @@ const GLuint CTexture::getTextureID () const
     return this->m_textureID;
 }
 
+const uint32_t CTexture::getTextureWidth () const
+{
+    return this->getHeader ()->textureWidth;
+}
+
+const uint32_t CTexture::getTextureHeight () const
+{
+    return this->getHeader ()->textureHeight;
+}
+
+const uint32_t CTexture::getRealWidth () const
+{
+    return this->getHeader ()->width;
+}
+
+const uint32_t CTexture::getRealHeight () const
+{
+    return this->getHeader ()->height;
+}
+
+const ITexture::TextureFormat CTexture::getFormat () const
+{
+    return this->getHeader ()->format;
+}
+
 const CTexture::TextureHeader* CTexture::getHeader () const
 {
     return this->m_header;

+ 11 - 14
src/WallpaperEngine/Assets/CTexture.h

@@ -8,10 +8,11 @@
 #include <glm/vec4.hpp>
 
 #include <FreeImage.h>
+#include "ITexture.h"
 
 namespace WallpaperEngine::Assets
 {
-    class CTexture
+    class CTexture : public ITexture
     {
         struct TextureHeader;
 
@@ -19,21 +20,17 @@ namespace WallpaperEngine::Assets
         CTexture (void* fileData);
         ~CTexture ();
 
-        const GLuint getTextureID () const;
-        const TextureHeader* getHeader () const;
-        const glm::vec4* getResolution () const;
-
+        const GLuint getTextureID () const override;
+        const uint32_t getTextureWidth () const override;
+        const uint32_t getTextureHeight () const override;
+        const uint32_t getRealWidth () const override;
+        const uint32_t getRealHeight () const override;
+        const TextureFormat getFormat () const override;
+        const glm::vec4* getResolution () const override;
 
-        enum TextureFormat : uint32_t
-        {
-            ARGB8888 = 0,
-            DXT5 = 4,
-            DXT3 = 6,
-            DXT1 = 7,
-            RG88 = 8,
-            R8 = 9,
-        };
     private:
+        const TextureHeader* getHeader () const;
+
         enum ContainerVersion : int
         {
             UNKNOWN = -1,

+ 29 - 0
src/WallpaperEngine/Assets/ITexture.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <glm/vec4.hpp>
+
+namespace WallpaperEngine::Assets
+{
+    class ITexture
+    {
+    public:
+        enum TextureFormat : uint32_t
+        {
+            ARGB8888 = 0,
+            DXT5 = 4,
+            DXT3 = 6,
+            DXT1 = 7,
+            RG88 = 8,
+            R8 = 9,
+        };
+
+        virtual const GLuint getTextureID () const = 0;
+        virtual const uint32_t getTextureWidth () const = 0;
+        virtual const uint32_t getTextureHeight () const = 0;
+        virtual const uint32_t getRealWidth () const = 0;
+        virtual const uint32_t getRealHeight () const = 0;
+        virtual const TextureFormat getFormat () const = 0;
+        virtual const glm::vec4* getResolution () const = 0;
+    };
+};

+ 3 - 2
src/WallpaperEngine/Core/Objects/CEffect.cpp

@@ -5,7 +5,7 @@
 #include "WallpaperEngine/Core/Objects/CImage.h"
 #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
 #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h"
-#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h"
+#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h"
 #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h"
 
 #include "WallpaperEngine/FileSystem/FileSystem.h"
@@ -161,7 +161,8 @@ void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Object
         }
         else if ((*cur).is_string () == true)
         {
-            constant = new Effects::Constants::CShaderConstantVector3 (WallpaperEngine::Core::aToVector3 (*cur));
+            // try a vector 4 first, then a vector3 and then a vector 2
+            constant = new Effects::Constants::CShaderConstantVector4 (WallpaperEngine::Core::aToVector4 (*cur));
         }
         else
         {

+ 17 - 0
src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.cpp

@@ -0,0 +1,17 @@
+#include "CShaderConstantVector2.h"
+
+using namespace WallpaperEngine::Core::Objects::Effects::Constants;
+
+
+CShaderConstantVector2::CShaderConstantVector2 (glm::vec2 value) :
+    CShaderConstant (Type),
+    m_value (value)
+{
+}
+
+glm::vec2* CShaderConstantVector2::getValue ()
+{
+    return &this->m_value;
+}
+
+const std::string CShaderConstantVector3::Type = "vec2";

+ 21 - 0
src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include "CShaderConstant.h"
+
+#include <string>
+#include <glm/vec3.hpp>
+
+namespace WallpaperEngine::Core::Objects::Effects::Constants
+{
+    class CShaderConstantVector2 : public CShaderConstant
+    {
+    public:
+        CShaderConstantVector2 (glm::vec2 value);
+
+        glm::vec2* getValue ();
+
+        static const std::string Type;
+    protected:
+        glm::vec2 m_value;
+    };
+}

+ 0 - 1
src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp

@@ -2,7 +2,6 @@
 
 using namespace WallpaperEngine::Core::Objects::Effects::Constants;
 
-
 CShaderConstantVector3::CShaderConstantVector3 (glm::vec3 value) :
     CShaderConstant (Type),
     m_value (value)

+ 17 - 0
src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.cpp

@@ -0,0 +1,17 @@
+#include "CShaderConstantVector4.h"
+
+using namespace WallpaperEngine::Core::Objects::Effects::Constants;
+
+
+CShaderConstantVector4::CShaderConstantVector4 (glm::vec4 value) :
+    CShaderConstant (Type),
+    m_value (value)
+{
+}
+
+glm::vec4* CShaderConstantVector4::getValue ()
+{
+    return &this->m_value;
+}
+
+const std::string CShaderConstantVector4::Type = "vec4";

+ 21 - 0
src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include "CShaderConstant.h"
+
+#include <string>
+#include <glm/vec4.hpp>
+
+namespace WallpaperEngine::Core::Objects::Effects::Constants
+{
+    class CShaderConstantVector4 : public CShaderConstant
+    {
+    public:
+        CShaderConstantVector4 (glm::vec4 value);
+
+        glm::vec4* getValue ();
+
+        static const std::string Type;
+    protected:
+        glm::vec4 m_value;
+    };
+}

+ 99 - 0
src/WallpaperEngine/Render/CFBO.cpp

@@ -0,0 +1,99 @@
+#include "CFBO.h"
+
+using namespace WallpaperEngine::Render;
+
+CFBO::CFBO (std::string name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight) :
+    m_name (std::move (name)),
+    m_format (format),
+    m_scale (scale)
+{
+    GLenum drawBuffers [1] = {GL_COLOR_ATTACHMENT0};
+    // create the main framebuffer
+    glGenFramebuffers (1, &this->m_framebuffer);
+    glBindFramebuffer (GL_FRAMEBUFFER, this->m_framebuffer);
+    // create the main texture
+    glGenTextures (1, &this->m_texture);
+    // bind the new texture to set settings on it
+    glBindTexture (GL_TEXTURE_2D, this->m_texture);
+    // give OpenGL an empty image
+    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    // set filtering parameters, otherwise the texture is not rendered
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    // create the depth render buffer for the main framebuffer
+    glGenRenderbuffers (1, &this->m_depthbuffer);
+    glBindRenderbuffer (GL_RENDERBUFFER, this->m_depthbuffer);
+    glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT, textureWidth, textureHeight);
+    glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->m_depthbuffer);
+    // set the texture as the colour attachmend #0
+    glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->m_texture, 0);
+    // finally set the list of draw buffers
+    glDrawBuffers (1, drawBuffers);
+
+    // ensure first framebuffer is okay
+    if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+        throw std::runtime_error ("Framebuffers are not properly set");
+
+    this->m_resolution = {
+        textureWidth, textureHeight,
+        realWidth, realHeight
+    };
+}
+
+const std::string& CFBO::getName () const
+{
+    return this->m_name;
+}
+
+const float& CFBO::getScale () const
+{
+    return this->m_scale;
+}
+
+const ITexture::TextureFormat CFBO::getFormat () const
+{
+    return this->m_format;
+}
+
+GLuint CFBO::getFramebuffer () const
+{
+    return this->m_framebuffer;
+}
+
+GLuint CFBO::getDepthbuffer () const
+{
+    return this->m_depthbuffer;
+}
+
+const GLuint CFBO::getTextureID () const
+{
+    return this->m_texture;
+}
+
+const uint32_t CFBO::getTextureWidth () const
+{
+    return this->m_resolution.x;
+}
+const uint32_t CFBO::getTextureHeight () const
+{
+    return this->m_resolution.y;
+}
+
+const uint32_t CFBO::getRealWidth () const
+{
+    return this->m_resolution.z;
+}
+
+const uint32_t CFBO::getRealHeight () const
+{
+    return this->m_resolution.w;
+}
+
+const glm::vec4* CFBO::getResolution () const
+{
+    return &this->m_resolution;
+}

+ 38 - 0
src/WallpaperEngine/Render/CFBO.h

@@ -0,0 +1,38 @@
+#pragma once
+
+#include "WallpaperEngine/Core/Objects/Effects/CFBO.h"
+#include "WallpaperEngine/Core/Objects/CImage.h"
+#include "WallpaperEngine/Assets/ITexture.h"
+
+using namespace WallpaperEngine::Assets;
+
+namespace WallpaperEngine::Render
+{
+    class CFBO : public ITexture
+    {
+    public:
+        CFBO (std::string name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight);
+
+        const std::string& getName () const;
+        const float& getScale () const;
+        const ITexture::TextureFormat getFormat () const override;
+        GLuint getFramebuffer () const;
+        GLuint getDepthbuffer () const;
+        const GLuint getTextureID () const override;
+        const uint32_t getTextureWidth () const override;
+        const uint32_t getTextureHeight () const override;
+        const uint32_t getRealWidth () const override;
+        const uint32_t getRealHeight () const override;
+        const glm::vec4* getResolution () const override;
+
+    private:
+
+        GLuint m_framebuffer;
+        GLuint m_depthbuffer;
+        GLuint m_texture;
+        glm::vec4 m_resolution;
+        float m_scale;
+        std::string m_name;
+        ITexture::TextureFormat m_format;
+    };
+};

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

@@ -18,6 +18,8 @@ CScene::CScene (Core::CScene* scene, CContainer* container) :
         scene->getOrthogonalProjection ()->getWidth (),
         scene->getOrthogonalProjection ()->getHeight ()
     );
+    // setup framebuffers
+    this->setupFramebuffers ();
 
     auto cur = scene->getObjects ().begin ();
     auto end = scene->getObjects ().end ();
@@ -38,8 +40,6 @@ CScene::CScene (Core::CScene* scene, CContainer* container) :
         if (object != nullptr)
             this->m_objects.emplace_back (object);
     }
-
-    this->setupFramebuffers ();
 }
 
 CCamera* CScene::getCamera () const

+ 1 - 1
src/WallpaperEngine/Render/CVideo.cpp

@@ -123,7 +123,7 @@ void CVideo::renderFrame ()
     writeFrameToImage ();
 
     glViewport (0, 0, this->getWidth (), this->getHeight ());
-    
+
     // do the actual rendering
     // write to default's framebuffer
     glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());

+ 37 - 50
src/WallpaperEngine/Render/CWallpaper.cpp

@@ -59,12 +59,12 @@ WallpaperEngine::Core::CWallpaper* CWallpaper::getWallpaperData ()
 
 GLuint CWallpaper::getWallpaperFramebuffer () const
 {
-    return this->m_sceneFramebuffer;
+    return this->m_sceneFBO->getFramebuffer ();
 }
 
 GLuint CWallpaper::getWallpaperTexture () const
 {
-    return this->m_sceneTexture;
+    return this->m_sceneFBO->getTextureID();
 }
 
 void CWallpaper::setupShaders ()
@@ -287,25 +287,21 @@ void CWallpaper::render (glm::vec4 viewport, bool newFrame)
 
 void CWallpaper::pinpongFramebuffer (GLuint* drawTo, GLuint* inputTexture)
 {
-    // get current main framebuffer and texture so we can swap them
-    GLuint currentMainFramebuffer = this->m_mainFramebuffer;
-    GLuint currentMainTexture = this->m_mainTexture;
-    GLuint currentSubFramebuffer = this->m_subFramebuffer;
-    GLuint currentSubTexture = this->m_subTexture;
+    // temporarily store FBOs used
+    CFBO* currentMainFBO = this->m_mainFBO;
+    CFBO* currentSubFBO = this->m_subFBO;
 
     if (drawTo != nullptr)
-        *drawTo = currentSubFramebuffer;
+        *drawTo = currentSubFBO->getFramebuffer ();
     if (inputTexture != nullptr)
-        *inputTexture = currentMainTexture;
+        *inputTexture = currentMainFBO->getTextureID();
 
-    // swap the textures
-    this->m_mainFramebuffer = currentSubFramebuffer;
-    this->m_mainTexture = currentSubTexture;
-    this->m_subFramebuffer = currentMainFramebuffer;
-    this->m_subTexture = currentMainTexture;
+    // swap the FBOs
+    this->m_mainFBO = currentSubFBO;
+    this->m_subFBO = currentMainFBO;
 }
 
-void CWallpaper::createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GLuint* texture)
+void CWallpaper::setupFramebuffers ()
 {
     int windowWidth = 1920;
     int windowHeight = 1080;
@@ -325,42 +321,33 @@ void CWallpaper::createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GL
         windowHeight = video->getHeight ();
     }
 
-    GLenum drawBuffers [1] = {GL_COLOR_ATTACHMENT0};
-    // create the main framebuffer
-    glGenFramebuffers (1, framebuffer);
-    glBindFramebuffer (GL_FRAMEBUFFER, *framebuffer);
-    // create the main texture
-    glGenTextures (1, texture);
-    // bind the new texture to set settings on it
-    glBindTexture (GL_TEXTURE_2D, *texture);
-    // give OpenGL an empty image
-    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, windowWidth, windowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
-
-    // set filtering parameters, otherwise the texture is not rendered
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-    // create the depth render buffer for the main framebuffer
-    glGenRenderbuffers (1, depthbuffer);
-    glBindRenderbuffer (GL_RENDERBUFFER, *depthbuffer);
-    glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT, windowWidth, windowHeight);
-    glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *depthbuffer);
-    // set the texture as the colour attachmend #0
-    glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0);
-    // finally set the list of draw buffers
-    glDrawBuffers (1, drawBuffers);
-
-    // ensure first framebuffer is okay
-    if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
-        throw std::runtime_error ("Framebuffers are not properly set");
+    this->m_mainFBO = this->createFBO ("_rt_FullFrameBuffera", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
+    this->m_subFBO = this->createFBO ("_rt_FullFrameBuffera", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
+    // create framebuffer for the scene
+    this->m_sceneFBO = this->createFBO ("_rt_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
 }
 
-void CWallpaper::setupFramebuffers ()
+CFBO* CWallpaper::createFBO (const std::string& name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight)
 {
-    this->createFramebuffer (&this->m_mainFramebuffer, &this->m_mainDepthBuffer, &this->m_mainTexture);
-    this->createFramebuffer (&this->m_subFramebuffer, &this->m_subDepthBuffer, &this->m_subTexture);
-    // create framebuffer for the scene
-    this->createFramebuffer (&this->m_sceneFramebuffer, &this->m_sceneDepthBuffer, &this->m_sceneTexture);
+    CFBO* fbo = new CFBO (name, format, scale, realWidth, realHeight, textureWidth, textureHeight);
+
+    this->m_fbos.insert (std::make_pair (name, fbo));
+
+    return fbo;
+}
+
+const std::map<std::string, CFBO*>& CWallpaper::getFBOs () const
+{
+    return this->m_fbos;
+}
+
+
+const CFBO* CWallpaper::findFBO (const std::string& name) const
+{
+    auto it = this->m_fbos.find (name);
+
+    if (it == this->m_fbos.end ())
+        throw std::runtime_error ("Cannot find given FBO");
+
+    return it->second;
 }

+ 31 - 31
src/WallpaperEngine/Render/CWallpaper.h

@@ -8,6 +8,7 @@
 #include "WallpaperEngine/Core/CVideo.h"
 
 #include "WallpaperEngine/Assets/CContainer.h"
+#include "CFBO.h"
 
 using namespace WallpaperEngine::Assets;
 
@@ -50,6 +51,25 @@ namespace WallpaperEngine::Render
          * @return The scene's texture
          */
         GLuint getWallpaperTexture () const;
+        /**
+         * Creates a new FBO for this wallpaper
+         *
+         * @param name The name of the FBO
+         * @return
+         */
+        CFBO* createFBO (const std::string& name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight);
+
+        /**
+         * @return The full FBO list to work with
+         */
+        const std::map<std::string, CFBO*>& getFBOs () const;
+        /**
+         * Searches the FBO list for the given FBO
+         *
+         * @param name
+         * @return
+         */
+        const CFBO* findFBO (const std::string& name) const;
 
     protected:
         /**
@@ -62,54 +82,29 @@ namespace WallpaperEngine::Render
          */
         void setupFramebuffers ();
 
-        void createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GLuint* texture);
-
         CContainer* m_container;
         Core::CWallpaper* m_wallpaperData;
 
         Core::CWallpaper* getWallpaperData ();
 
         /**
-         * The main framebuffer
+         * The main FBO used for ping pong
          */
-        GLuint m_mainFramebuffer;
+        CFBO* m_mainFBO;
         /**
-         * The sub framebuffer
+         * The sub FBO used for ping pong
          */
-        GLuint m_subFramebuffer;
+        CFBO* m_subFBO;
 
         /**
-         * The main depth render buffer
+         * The FBO used for scene output
          */
-        GLuint m_mainDepthBuffer;
-        /**
-         * The sub depth render buffer
-         */
-        GLuint m_subDepthBuffer;
-
-        /**
-         * The main texture used on the framebuffer
-         */
-        GLuint m_mainTexture;
-        /**
-         * The sub texture used on the framebuffer
-         */
-        GLuint m_subTexture;
-
-        /**
-         * The framebuffer used for the scene output
-         */
-        GLuint m_sceneFramebuffer;
-        /**
-         * The depthbuffer used for the scene output
-         */
-        GLuint m_sceneDepthBuffer;
+        CFBO* m_sceneFBO;
 
     private:
         /**
          * The texture used for the scene output
          */
-        GLuint m_sceneTexture;
         GLuint m_texCoordBuffer;
         GLuint m_positionBuffer;
         GLuint m_shader;
@@ -125,5 +120,10 @@ namespace WallpaperEngine::Render
          * The type of background this wallpaper is (used
          */
         std::string m_type;
+
+        /**
+         * List of FBOs registered for this wallpaper
+         */
+        std::map<std::string, CFBO*> m_fbos;
     };
 }

+ 13 - 20
src/WallpaperEngine/Render/Objects/CEffect.cpp

@@ -1,6 +1,7 @@
 #include "CEffect.h"
 
 using namespace WallpaperEngine::Render::Objects;
+using namespace WallpaperEngine::Render;
 
 CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect) :
     m_image (image),
@@ -10,7 +11,7 @@ CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect) :
     this->generatePasses ();
 }
 
-const CImage* CEffect::getImage () const
+CImage* CEffect::getImage () const
 {
     return this->m_image;
 }
@@ -20,7 +21,7 @@ const std::vector<Effects::CMaterial*>& CEffect::getMaterials () const
     return this->m_materials;
 }
 
-Effects::CFBO* CEffect::findFBO (const std::string& name)
+const CFBO* CEffect::findFBO (const std::string& name) const
 {
     auto cur = this->m_fbos.begin ();
     auto end = this->m_fbos.end ();
@@ -42,7 +43,7 @@ void CEffect::generatePasses ()
     auto end = this->m_effect->getMaterials ().end ();
 
     for (; cur != end; cur ++)
-        this->m_materials.emplace_back (new Effects::CMaterial (this->getImage (), *cur));
+        this->m_materials.emplace_back (new Effects::CMaterial (this, *cur));
 }
 
 void CEffect::generateFBOs ()
@@ -53,23 +54,15 @@ void CEffect::generateFBOs ()
     for (; cur != end; cur ++)
     {
         this->m_fbos.push_back (
-            new Effects::CFBO (*cur, this->m_image->getImage ())
+            new CFBO (
+                (*cur)->getName (),
+                ITexture::TextureFormat::ARGB8888, // TODO: CHANGE
+                (*cur)->getScale (),
+                this->m_image->getImage ()->getSize ().x,
+                this->m_image->getImage ()->getSize ().y,
+                this->m_image->getImage ()->getSize ().x,
+                this->m_image->getImage ()->getSize ().y
+            )
         );
     }
-}
-
-void CEffect::render (GLuint drawTo, GLuint inputTexture)
-{
-    auto begin = this->getMaterials ().begin ();
-    auto cur = this->getMaterials ().begin ();
-    auto end = this->getMaterials ().end ();
-
-    for (; cur != end; cur ++)
-    {
-        // pingpong buffer only if not the first pass (as it would be taken care by the CImage)
-        if (cur != begin)
-            this->getImage ()->getScene ()->pinpongFramebuffer (&drawTo, &inputTexture);
-
-        (*cur)->render (drawTo, inputTexture);
-    }
 }

+ 4 - 5
src/WallpaperEngine/Render/Objects/CEffect.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include "WallpaperEngine/Render/Objects/CImage.h"
-#include "WallpaperEngine/Render/Objects/Effects/CFBO.h"
+#include "WallpaperEngine/Render/CFBO.h"
 #include "WallpaperEngine/Render/Objects/Effects/CPass.h"
 #include "WallpaperEngine/Render/Objects/Effects/CMaterial.h"
 
@@ -19,13 +19,12 @@ namespace WallpaperEngine::Render::Objects
     public:
         CEffect (CImage* image, Core::Objects::CEffect* effect);
 
-        const CImage* getImage () const;
+        CImage* getImage () const;
 
         const std::vector<Effects::CMaterial*>& getMaterials () const;
 
-        Effects::CFBO* findFBO (const std::string& name);
+        const CFBO* findFBO (const std::string& name) const;
 
-        void render (GLuint drawTo, GLuint inputTexture);
     private:
         void generatePasses ();
         void generateFBOs ();
@@ -33,7 +32,7 @@ namespace WallpaperEngine::Render::Objects
         CImage* m_image;
         Core::Objects::CEffect* m_effect;
 
-        std::vector<Effects::CFBO*> m_fbos;
+        std::vector<CFBO*> m_fbos;
         std::vector<Effects::CMaterial*> m_materials;
     };
 };

+ 94 - 37
src/WallpaperEngine/Render/Objects/CImage.cpp

@@ -1,3 +1,4 @@
+#include <sstream>
 #include "CImage.h"
 
 using namespace WallpaperEngine;
@@ -5,7 +6,8 @@ using namespace WallpaperEngine::Render::Objects;
 
 CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
     Render::CObject (scene, Type, image),
-    m_image (image)
+    m_image (image),
+    m_texture (nullptr)
 {
     auto projection = this->getScene ()->getScene ()->getOrthogonalProjection ();
 
@@ -22,24 +24,40 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
     // depending on the alignment these values might change, for now just support center
     if (this->getImage ()->getAlignment () == "center")
     {
+        glm::vec2 size = this->getImage ()->getSize ();
+        glm::vec3 scale = this->getImage ()->getScale ();
+
         // calculate the real position of the image
-        xleft = this->getImage ()->getOrigin ().x - (this->getImage ()->getSize ().x / 2);
-        xright = this->getImage ()->getOrigin ().x + (this->getImage ()->getSize ().x / 2);
-        ytop = this->getImage ()->getOrigin ().y - (this->getImage ()->getSize ().y / 2);
-        ybottom = this->getImage ()->getOrigin ().y + (this->getImage ()->getSize ().y / 2);
+        xleft = this->getImage ()->getOrigin ().x - (size.x * scale.x / 2);
+        xright = this->getImage ()->getOrigin ().x + (size.x * scale.x / 2);
+        ytop = this->getImage ()->getOrigin ().y - (size.y * scale.y / 2);
+        ybottom = this->getImage ()->getOrigin ().y + (size.y * scale.y / 2);
     }
     else
     {
         throw std::runtime_error ("Only centered images are supported for now!");
     }
 
-    // load image from the .tex file
-    uint32_t textureSize = 0;
+    std::string textureName = (*(*this->m_image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ());
 
-    // get the first texture on the first pass (this one represents the image assigned to this object)
-    this->m_texture = this->getScene ()->getContainer ()->readTexture (
-            (*(*this->m_image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ())
-    );
+    if (textureName.find ("_rt_") == 0)
+    {
+        this->m_texture = this->getScene ()->findFBO (textureName);
+    }
+    else
+    {
+        // get the first texture on the first pass (this one represents the image assigned to this object)
+        this->m_texture = this->getScene ()->getContainer ()->readTexture (textureName);
+    }
+
+    // register both FBOs into the scene
+    std::ostringstream nameA, nameB;
+
+    nameA << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_a";
+    nameA << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_b";
+
+    this->m_mainFBO = scene->createFBO (nameA.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getRealWidth (), this->m_texture->getRealHeight (), this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight ());
+    this->m_subFBO = scene->createFBO (nameB.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getRealWidth (), this->m_texture->getRealHeight (), this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight ());
 
     // build a list of vertices, these might need some change later (or maybe invert the camera)
     GLfloat data [] = {
@@ -68,17 +86,21 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
     float height = 1.0f;
 
     // calculate the correct texCoord limits for the texture based on the texture screen size and real size
-    if (this->getTexture ()->getHeader ()->textureWidth != this->getTexture ()->getHeader ()->width ||
-        this->getTexture ()->getHeader ()->textureHeight != this->getTexture ()->getHeader ()->height)
+    if (this->getTexture () != nullptr &&
+            (this->getTexture ()->getTextureWidth () != this->getTexture ()->getRealWidth () ||
+             this->getTexture ()->getTextureHeight () != this->getTexture ()->getRealHeight ())
+        )
     {
         uint32_t x = 1;
         uint32_t y = 1;
+        glm::vec2 size = this->getImage ()->getSize ();
+        glm::vec3 scale = this->getImage ()->getScale ();
 
-        while (x < this->getImage ()->getSize ().x) x <<= 1;
-        while (y < this->getImage ()->getSize ().y) y <<= 1;
+        while (x < size.x) x <<= 1;
+        while (y < size.y) y <<= 1;
 
-        width = this->getImage ()->getSize ().x / x;
-        height = this->getImage ()->getSize ().y / y;
+        width = size.x * scale.x / x;
+        height = size.y * scale.y / y;
     }
 
     GLfloat data2 [] = {
@@ -122,7 +144,10 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
     glBufferData (GL_ARRAY_BUFFER, sizeof (this->m_passTexCoordList), this->m_passTexCoordList, GL_STATIC_DRAW);
 
     // generate the main material used to render the image
-    this->m_material = new Effects::CMaterial (this, this->m_image->getMaterial ());
+    this->m_material = new Effects::CMaterial (
+        new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)),
+        this->m_image->getMaterial ()
+    );
 
     // generate the effects used by this material
     auto cur = this->getImage ()->getEffects ().begin ();
@@ -132,40 +157,72 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
         this->m_effects.emplace_back (new CEffect (this, *cur));
 }
 
-void CImage::render ()
+void CImage::pinpongFramebuffer (GLuint* drawTo, GLuint* inputTexture)
 {
-    // ensure this image is visible first
-    if (this->getImage ()->isVisible () == false)
-        return;
+    // temporarily store FBOs used
+    CFBO* currentMainFBO = this->m_mainFBO;
+    CFBO* currentSubFBO = this->m_subFBO;
+
+    if (drawTo != nullptr)
+        *drawTo = currentSubFBO->getFramebuffer ();
+    if (inputTexture != nullptr)
+        *inputTexture = currentMainFBO->getTextureID ();
+
+    // swap the FBOs
+    this->m_mainFBO = currentSubFBO;
+    this->m_subFBO = currentMainFBO;
+}
 
-    GLuint drawTo = this->getScene()->getWallpaperFramebuffer();
-    GLuint inputTexture = this->m_texture->getTextureID ();
+void CImage::render ()
+{
+    // start drawing to the main framebuffer
+    GLuint drawTo = this->m_mainFBO->getFramebuffer ();
+    GLuint inputTexture = this->getTexture ()->getTextureID ();
 
-    // pinpong current buffer
-    this->getScene ()->pinpongFramebuffer (&drawTo, nullptr);
     // render all the other materials
     auto cur = this->getEffects ().begin ();
     auto end = this->getEffects ().end ();
-    auto begin = this->getEffects ().begin ();
 
+    inputTexture = this->getTexture ()->getTextureID ();
+
+    // set the correct viewport
+    glViewport (0, 0, this->getTexture ()->getRealWidth (), this->getTexture ()->getRealHeight ());
+
+    // render all the passes first
     for (; cur != end; cur ++)
     {
-        if (cur != begin)
-            // pinpong current buffer
-            this->getScene ()->pinpongFramebuffer (&drawTo, &inputTexture);
+        auto materialCur = (*cur)->getMaterials ().begin ();
+        auto materialEnd = (*cur)->getMaterials ().end ();
+
+        for (; materialCur != materialEnd; materialCur ++)
+        {
+            auto passCur = (*materialCur)->getPasses ().begin ();
+            auto passEnd = (*materialCur)->getPasses ().end ();
 
-        // render now
-        (*cur)->render (drawTo, inputTexture);
+            for (; passCur != passEnd; passCur ++)
+            {
+                (*passCur)->render (drawTo, inputTexture);
+
+                this->pinpongFramebuffer (&drawTo, &inputTexture);
+            }
+        }
     }
 
-    if (this->getEffects ().size () > 0)
-        this->getScene ()->pinpongFramebuffer (nullptr, &inputTexture);
+    if (this->getImage ()->isVisible () == false)
+        return;
+
+    // this material only has one pass that we know of
+    // so just take that and render it to the screen's framebuffer
+    auto pass = this->m_material->getPasses ().begin ();
+    auto projection = this->getScene ()->getScene ()->getOrthogonalProjection ();
+
+    // set the viewport properly
+    glViewport (0, 0, projection->getWidth (), projection->getHeight ());
 
-    // render the main material
-    this->m_material->render (this->getScene()->getWallpaperFramebuffer(), inputTexture);
+    (*pass)->render (this->getScene ()->getWallpaperFramebuffer (), inputTexture);
 }
 
-const CTexture* CImage::getTexture () const
+const ITexture* CImage::getTexture () const
 {
     return this->m_texture;
 }

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

@@ -9,7 +9,7 @@
 
 #include "WallpaperEngine/Render/Shaders/Compiler.h"
 
-#include "WallpaperEngine/Assets/CTexture.h"
+#include "WallpaperEngine/Assets/ITexture.h"
 
 #include <glm/vec3.hpp>
 
@@ -40,13 +40,21 @@ namespace WallpaperEngine::Render::Objects
         const GLuint* getPassVertexBuffer () const;
         const GLuint* getTexCoordBuffer () const;
         const GLuint* getPassTexCoordBuffer () const;
-        const CTexture* getTexture () const;
+        const ITexture* getTexture () const;
+
+        /**
+         * Performs a ping-pong on the available framebuffers to be able to continue rendering things to them
+         *
+         * @param drawTo The framebuffer to use
+         * @param asInput The last texture used as output (if needed)
+         */
+        void pinpongFramebuffer (GLuint* drawTo, GLuint* inputTexture);
 
     protected:
         static const std::string Type;
 
     private:
-        CTexture* m_texture;
+        const ITexture* m_texture;
         GLfloat m_vertexList [6 * 3];
         GLfloat m_passesVertexList [6 * 3];
         GLfloat m_texCoordList [6 * 2];
@@ -57,6 +65,8 @@ namespace WallpaperEngine::Render::Objects
         GLuint m_passTexCoordBuffer;
         uint16_t m_vertexIndices [6];
 
+        CFBO* m_mainFBO;
+        CFBO* m_subFBO;
 
         Core::Objects::CImage* m_image;
 

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

@@ -1,30 +0,0 @@
-#include "CFBO.h"
-
-using namespace WallpaperEngine::Render::Objects::Effects;
-
-CFBO::CFBO (Core::Objects::Effects::CFBO* fbo, const Core::Objects::CImage* image) :
-    m_fbo (fbo)
-{
-    // TODO: REWRITE
-    /*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 std::string& CFBO::getName () const
-{
-    return this->m_fbo->getName ();
-}
-
-const float& CFBO::getScale () const
-{
-    return this->m_fbo->getScale ();
-}
-
-const std::string& CFBO::getFormat () const
-{
-    return this->m_fbo->getFormat ();
-}

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

@@ -1,20 +0,0 @@
-#pragma once
-
-#include "WallpaperEngine/Core/Objects/Effects/CFBO.h"
-#include "WallpaperEngine/Core/Objects/CImage.h"
-
-namespace WallpaperEngine::Render::Objects::Effects
-{
-    class CFBO
-    {
-    public:
-        CFBO (Core::Objects::Effects::CFBO* fbo, const Core::Objects::CImage* image);
-
-        const std::string& getName () const;
-        const float& getScale () const;
-        const std::string& getFormat () const;
-
-    private:
-        const Core::Objects::Effects::CFBO* m_fbo;
-    };
-};

+ 4 - 28
src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp

@@ -4,8 +4,8 @@ using namespace WallpaperEngine::Render::Objects;
 
 using namespace WallpaperEngine::Render::Objects::Effects;
 
-CMaterial::CMaterial (const Render::Objects::CImage* image, const Core::Objects::Images::CMaterial* material) :
-    m_image (image),
+CMaterial::CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material) :
+    m_effect (effect),
     m_material (material)
 {
     this->generatePasses ();
@@ -16,9 +16,9 @@ const std::vector<CPass*>& CMaterial::getPasses () const
     return this->m_passes;
 }
 
-const CImage* CMaterial::getImage () const
+CImage* CMaterial::getImage () const
 {
-    return this->m_image;
+    return this->m_effect->getImage ();
 }
 
 void CMaterial::generatePasses ()
@@ -29,28 +29,4 @@ void CMaterial::generatePasses ()
     // these are simple now, just create the entries and done
     for (; cur != end; cur ++)
         this->m_passes.emplace_back (new CPass (this, *cur));
-}
-
-void CMaterial::render (GLuint drawTo, GLuint inputTexture)
-{
-    // get the orthogonal projection
-    auto projection = this->getImage ()->getScene ()->getScene ()->getOrthogonalProjection ();
-
-    auto begin = this->getPasses ().begin ();
-    auto cur = this->getPasses ().begin ();
-    auto end = this->getPasses ().end ();
-
-    for (; cur != end; cur ++)
-    {
-        // get the current framebuffer to use (only after the first iteration)
-        if (cur != begin)
-            this->getImage ()->getScene ()->pinpongFramebuffer (&drawTo, &inputTexture);
-
-        // bind to this new framebuffer
-        glBindFramebuffer (GL_FRAMEBUFFER, drawTo);
-        // set the viewport, for now use the scene width/height but we might want to use image's size TODO: INVESTIGATE THAT
-        glViewport (0, 0, projection->getWidth (), projection->getHeight ());
-        // render the pass
-        (*cur)->render (drawTo, inputTexture);
-    }
 }

+ 3 - 11
src/WallpaperEngine/Render/Objects/Effects/CMaterial.h

@@ -24,23 +24,15 @@ namespace WallpaperEngine::Render::Objects::Effects
     {
         friend class CPass;
     public:
-        CMaterial (const Render::Objects::CImage* image, const Core::Objects::Images::CMaterial* material);
+        CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material);
 
         const std::vector<CPass*>& getPasses () const;
-        const CImage* getImage () const;
-
-        /**
-         * Renders the given material, using inputTexture as first texture of the shader
-         *
-         * @param drawTo
-         * @param inputTexture
-         */
-        void render (GLuint drawTo, GLuint inputTexture);
+        CImage* getImage () const;
 
     private:
         void generatePasses ();
 
-        const Render::Objects::CImage* m_image;
+        const Render::Objects::CEffect* m_effect;
         const Core::Objects::Images::CMaterial* m_material;
 
         std::vector<CPass*> m_passes;

+ 103 - 31
src/WallpaperEngine/Render/Objects/Effects/CPass.cpp

@@ -1,5 +1,6 @@
 #include <sstream>
 #include "CPass.h"
+#include "WallpaperEngine/Render/CFBO.h"
 
 #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
 #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.h"
@@ -11,7 +12,7 @@
 #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"
+#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h"
 
 using namespace WallpaperEngine::Core::Objects::Effects::Constants;
 using namespace WallpaperEngine::Render::Shaders::Variables;
@@ -31,6 +32,9 @@ CPass::CPass (CMaterial* material, Core::Objects::Images::Materials::CPass* pass
 
 void CPass::render (GLuint drawTo, GLuint input)
 {
+    // set the framebuffer we're drawing to
+    glBindFramebuffer (GL_FRAMEBUFFER, drawTo);
+
     // clear whatever buffer we're drawing to if we're not drawing to screen
     if (drawTo != this->m_material->getImage()->getScene()->getWallpaperFramebuffer())
         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -66,6 +70,8 @@ void CPass::render (GLuint drawTo, GLuint input)
         glEnable (GL_DEPTH_TEST);
     }
 
+    // TODO: SUPPORT TARGET TO DRAW TEXTURE TO
+
     // update variables used in the render process (like g_ModelViewProjectionMatrix)
     this->m_modelViewProjectionMatrix =
             this->m_material->getImage ()->getScene ()->getCamera ()->getProjection () *
@@ -75,12 +81,20 @@ void CPass::render (GLuint drawTo, GLuint input)
     // update a_TexCoord and a_Position based on what to draw to
     // this should not be required once we do some prediction on rendering things
     // but for now should be enough
-    this->a_TexCoord = (input == this->m_material->getImage ()->getTexture ()->getTextureID ()) ? *this->m_material->getImage ()->getTexCoordBuffer () : *this->m_material->getImage ()->getPassTexCoordBuffer ();
-    this->a_Position = (drawTo != this->m_material->getImage()->getScene()->getWallpaperFramebuffer()) ? *this->m_material->getImage ()->getPassVertexBuffer () : *this->m_material->getImage ()->getVertexBuffer ();
+    this->a_TexCoord = *this->m_material->getImage ()->getTexCoordBuffer ();
+    this->a_Position = *this->m_material->getImage ()->getVertexBuffer ();
+
     // use the shader we have registered
     glUseProgram (this->m_programID);
 
-    // bind the input texture
+    // bind the input texture (take into account input fbos)
+    auto it = this->m_fbos.find (0);
+
+    if (it != this->m_fbos.end ())
+    {
+        input = (*it).second->getTextureID();
+    }
+
     glActiveTexture (GL_TEXTURE0);
     glBindTexture (GL_TEXTURE_2D, input);
     int lastTextureIndex = 0;
@@ -93,10 +107,25 @@ void CPass::render (GLuint drawTo, GLuint input)
 
         for (int index = 1; cur != end; cur ++, index ++)
         {
-            // set the active texture index
-            glActiveTexture (GL_TEXTURE0 + index);
-            // bind the correct texture there
-            glBindTexture (GL_TEXTURE_2D, (*cur)->getTextureID ());
+            if ((*cur) == nullptr)
+            {
+                auto it = this->m_fbos.find (index);
+
+                if (it == this->m_fbos.end ())
+                    continue;
+
+                // set the active texture index
+                glActiveTexture (GL_TEXTURE0 + index);
+                // bind the correct texture there
+                glBindTexture (GL_TEXTURE_2D, (*it).second->getTextureID());
+            }
+            else
+            {
+                // set the active texture index
+                glActiveTexture (GL_TEXTURE0 + index);
+                // bind the correct texture there
+                glBindTexture (GL_TEXTURE_2D, (*cur)->getTextureID ());
+            }
             // increase the number of textures counter
             lastTextureIndex ++;
         }
@@ -174,11 +203,11 @@ void CPass::render (GLuint drawTo, GLuint input)
 
     if (this->g_Texture0Rotation != -1)
     {
-        glUniform2f (this->g_Texture0Rotation, 0.0f, 0.0f);
+        glUniform4f (this->g_Texture0Rotation, 1.0f, 0.0f, 1.0f, 0.0f);
     }
     if (this->g_Texture0Translation != -1)
     {
-        glUniform4f (this->g_Texture0Translation, 0.0f, 0.0f, 0.0f, 0.0f);
+        glUniform2f (this->g_Texture0Translation, 0.0f, 0.0f);
     }
     {
         auto cur = this->m_attribs.begin ();
@@ -245,16 +274,19 @@ GLuint CPass::compileShader (Render::Shaders::Compiler* shader, GLuint type)
 void CPass::setupShaders ()
 {
     // ensure the constants are defined
-    const CTexture* texture0 = this->m_material->getImage ()->getTexture ();
+    const ITexture* texture0 = this->m_material->getImage ()->getTexture ();
 
     // TODO: THE VALUES ARE THE SAME AS THE ENUMERATION, SO MAYBE IT HAS TO BE SPECIFIED FOR THE TEXTURE 0 OF ALL ELEMENTS?
-    if (texture0->getHeader ()->format == CTexture::TextureFormat::RG88)
-    {
-        this->m_pass->insertCombo ("TEX0FORMAT", 8);
-    }
-    else if (texture0->getHeader ()->format == CTexture::TextureFormat::R8)
+    if (texture0 != nullptr)
     {
-        this->m_pass->insertCombo ("TEX0FORMAT", 9);
+        if (texture0->getFormat () == ITexture::TextureFormat::RG88)
+        {
+            this->m_pass->insertCombo ("TEX0FORMAT", 8);
+        }
+        else if (texture0->getFormat () == ITexture::TextureFormat::R8)
+        {
+            this->m_pass->insertCombo ("TEX0FORMAT", 9);
+        }
     }
 
     // prepare the shaders
@@ -342,8 +374,14 @@ void CPass::setupUniforms ()
     this->addUniform ("g_Texture5", 5);
     this->addUniform ("g_Texture6", 6);
     this->addUniform ("g_Texture7", 7);
-    // register all the texture sizes required
-    this->addUniform ("g_Texture0Resolution", this->m_material->getImage ()->getTexture ()->getResolution ());
+    // check if the input is an fbo
+    auto it = this->m_fbos.find (0);
+
+    if (it == this->m_fbos.end ())
+        this->addUniform ("g_Texture0Resolution", this->m_material->getImage ()->getTexture ()->getResolution ());
+    else
+        this->addUniform ("g_Texture0Resolution", (*it).second->getResolution ());
+
     int lastTextureIndex = 0;
     // register the extra texture resolutions
     {
@@ -356,7 +394,20 @@ void CPass::setupUniforms ()
 
             namestream << "g_Texture" << index << "Resolution";
 
-            this->addUniform (namestream.str (), (*cur)->getResolution ());
+            if ((*cur) == nullptr)
+            {
+                // fbo used
+                auto it = this->m_fbos.find (index);
+
+                if (it == this->m_fbos.end ())
+                    continue;
+
+                this->addUniform (namestream.str (), (*it).second->getResolution ());
+            }
+            else
+            {
+                this->addUniform (namestream.str (), (*cur)->getResolution ());
+            }
             lastTextureIndex ++;
         }
     }
@@ -459,14 +510,29 @@ void CPass::setupTextures ()
 
     for (int index = 0; cur != end; cur ++, index ++)
     {
-        // ignore first texture as that'll be the input of the last pass/image
+        // ignore first texture as that'll be the input of the last pass/image (unless the image is an FBO)
         if (index == 0)
             continue;
 
-        // get the first texture on the first pass (this one represents the image assigned to this object)
-        this->m_textures.emplace_back (
-            this->m_material->getImage ()->getContainer ()->readTexture ((*cur))
-        );
+        if ((*cur).find ("_rt_") == 0)
+        {
+            const CFBO* fbo = this->m_material->m_effect->findFBO ((*cur));
+
+            if (fbo != nullptr)
+            {
+                this->m_fbos.insert (std::make_pair (index, const_cast <CFBO*> (fbo)));
+                this->m_textures.emplace_back (
+                    nullptr
+                );
+            }
+            // _rt_texture
+        }
+        else
+        {
+            this->m_textures.emplace_back (
+                this->m_material->getImage ()->getContainer ()->readTexture ((*cur))
+            );
+        }
     }
 }
 
@@ -487,11 +553,11 @@ void CPass::setupShaderVariables ()
                 continue;
 
             // if both can be found, ensure they're the correct type
-            if (vertexVar != nullptr && pixelVar != nullptr)
+            /*if (vertexVar != nullptr && pixelVar != nullptr)
             {
                 if (vertexVar->getType () != pixelVar->getType ())
                     throw std::runtime_error ("Pixel and vertex shader variable types do not match");
-            }
+            }*/
 
             // get one instance of it
             CShaderVariable* var = vertexVar == nullptr ? pixelVar : vertexVar;
@@ -514,13 +580,19 @@ void CPass::setupShaderVariables ()
                     // create a float value from an integer
                     this->addUniform (var->getName (), static_cast <float> (*(*cur).second->as <CShaderConstantInteger> ()->getValue ()));
                 }
-                else if ((*cur).second->is <CShaderConstantVector3> () == true && var->is <CShaderVariableVector2> () == true)
+                else if ((*cur).second->is <CShaderConstantVector4> () == true && var->is <CShaderVariableVector2> () == true)
                 {
-                    CShaderConstantVector3* val = (*cur).second->as <CShaderConstantVector3> ();
+                    CShaderConstantVector4* val = (*cur).second->as <CShaderConstantVector4> ();
 
                     // create a new vector2 with the first two values
                     this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y});
                 }
+                else if ((*cur).second->is <CShaderConstantVector4> () == true && var->is <CShaderVariableVector3> () == true)
+                {
+                    CShaderConstantVector4* val = (*cur).second->as <CShaderConstantVector4> ();
+
+                    this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y, val->getValue ()->z});
+                }
                 else
                 {
                     throw std::runtime_error ("Constant and pixel/vertex variable are not of the same type");
@@ -533,8 +605,8 @@ void CPass::setupShaderVariables ()
                     this->addUniform (var->getName (), (*cur).second->as <CShaderConstantFloat> ()->getValue ());
                 else if ((*cur).second->is <CShaderConstantInteger> ())
                     this->addUniform (var->getName (), (*cur).second->as <CShaderConstantInteger> ()->getValue ());
-                else if ((*cur).second->is <CShaderConstantVector3> ())
-                    this->addUniform (var->getName (), (*cur).second->as <CShaderConstantVector3> ()->getValue ());
+                else if ((*cur).second->is <CShaderConstantVector4> ())
+                    this->addUniform (var->getName (), (*cur).second->as <CShaderConstantVector4> ()->getValue ());
             }
         }
     }

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

@@ -6,7 +6,8 @@
 #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
 #include "WallpaperEngine/Render/Objects/Effects/CMaterial.h"
 #include "WallpaperEngine/Render/Shaders/Compiler.h"
-#include "WallpaperEngine/Assets/CTexture.h"
+#include "WallpaperEngine/Assets/ITexture.h"
+#include "WallpaperEngine/Render/CFBO.h"
 
 namespace WallpaperEngine::Render::Objects::Effects
 {
@@ -85,7 +86,8 @@ namespace WallpaperEngine::Render::Objects::Effects
 
         CMaterial* m_material;
         Core::Objects::Images::Materials::CPass* m_pass;
-        std::vector<CTexture*> m_textures;
+        std::vector<ITexture*> m_textures;
+        std::map<int, CFBO*> m_fbos;
         std::vector<AttribEntry*> m_attribs;
         std::map<std::string, UniformEntry*> m_uniforms;
         glm::mat4 m_modelViewProjectionMatrix;

+ 4 - 4
src/WallpaperEngine/Render/Shaders/Compiler.cpp

@@ -8,7 +8,7 @@
 
 // shader compiler
 #include <WallpaperEngine/Render/Shaders/Compiler.h>
-#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h>
+#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h>
 #include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h>
 #include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h>
 
@@ -554,7 +554,7 @@ namespace WallpaperEngine::Render::Shaders
             parameter = new Variables::CShaderVariableVector3 (
                 constant == this->m_constants.end ()
                 ? WallpaperEngine::Core::aToVector3 (*defvalue)
-                : *(*constant).second->as <CShaderConstantVector3> ()->getValue ()
+                : *(*constant).second->as <CShaderConstantVector4> ()->getValue ()
             );
         }
         else if (type == "vec2")
@@ -601,7 +601,7 @@ namespace WallpaperEngine::Render::Shaders
                 // add the new combo to the list
                 this->m_combos->insert (std::make_pair <std::string, int> (*combo, 1));
                 // also ensure that the textureName is loaded and we know about it
-                CTexture* texture = this->m_container->readTexture ((*textureName).get <std::string> ());
+                ITexture* texture = this->m_container->readTexture ((*textureName).get <std::string> ());
                 // extract the texture number from the name
                 char value = name.at (std::string("g_Texture").length ());
                 // now convert it to integer
@@ -654,7 +654,7 @@ namespace WallpaperEngine::Render::Shaders
         return this->m_combos;
     }
 
-    const std::map <int, CTexture*>& Compiler::getTextures () const
+    const std::map <int, ITexture*>& Compiler::getTextures () const
     {
         return this->m_textures;
     }

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

@@ -6,7 +6,7 @@
 
 #include "WallpaperEngine/Core/Core.h"
 #include "WallpaperEngine/Assets/CContainer.h"
-#include "WallpaperEngine/Assets/CTexture.h"
+#include "WallpaperEngine/Assets/ITexture.h"
 #include "WallpaperEngine/FileSystem/FileSystem.h"
 #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
 #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
@@ -89,7 +89,7 @@ namespace WallpaperEngine::Render::Shaders
         /**
          * @return The list of textures inferred from the shader's code
          */
-        const std::map <int, CTexture*>& getTextures () const;
+        const std::map <int, ITexture*>& getTextures () const;
 
     private:
         /**
@@ -244,6 +244,6 @@ namespace WallpaperEngine::Render::Shaders
          /**
           * List of textures that the shader expects (inferred from sampler2D and it's JSON data)
           */
-         std::map<int, CTexture*> m_textures;
+         std::map<int, ITexture*> m_textures;
     };
 }

+ 5 - 5
src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.cpp

@@ -4,22 +4,22 @@
 
 using namespace WallpaperEngine::Render::Shaders::Variables;
 
-CShaderVariableVector4::CShaderVariableVector4 (const glm::vec3& defaultValue) :
+CShaderVariableVector4::CShaderVariableVector4 (const glm::vec4& defaultValue) :
     m_defaultValue (defaultValue),
-    m_value (glm::vec3 ()),
+    m_value (glm::vec4 ()),
     CShaderVariable (&this->m_defaultValue, nullptr, Type)
 {
 }
 
-CShaderVariableVector4::CShaderVariableVector4 (const glm::vec3& defaultValue, std::string name) :
+CShaderVariableVector4::CShaderVariableVector4 (const glm::vec4& defaultValue, std::string name) :
     m_defaultValue (defaultValue),
-    m_value (glm::vec3 ()),
+    m_value (glm::vec4 ()),
     CShaderVariable (&this->m_defaultValue, nullptr, Type)
 {
     this->setName (std::move(name));
 }
 
-void CShaderVariableVector4::setValue (const glm::vec3& value)
+void CShaderVariableVector4::setValue (const glm::vec4& value)
 {
     this->m_value = value;
     CShaderVariable::setValue (&this->m_value);

+ 6 - 6
src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.h

@@ -1,5 +1,5 @@
 #pragma once
-#include <glm/vec3.hpp>
+#include <glm/vec4.hpp>
 
 #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
 
@@ -8,17 +8,17 @@ namespace WallpaperEngine::Render::Shaders::Variables
     class CShaderVariableVector4 : public CShaderVariable
     {
     public:
-        explicit CShaderVariableVector4 (const glm::vec3& defaultValue);
-        CShaderVariableVector4 (const glm::vec3& defaultValue, std::string name);
+        explicit CShaderVariableVector4 (const glm::vec4& defaultValue);
+        CShaderVariableVector4 (const glm::vec4& defaultValue, std::string name);
 
         const int getSize () const override;
 
-        void setValue (const glm::vec3& value);
+        void setValue (const glm::vec4& value);
 
         static const std::string Type;
 
     private:
-        glm::vec3 m_defaultValue;
-        glm::vec3 m_value;
+        glm::vec4 m_defaultValue;
+        glm::vec4 m_value;
     };
 }