Forráskód Böngészése

Added a basic (and somewhat convincing) parallax effect for the camera

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
Alexis Maiquez 3 éve
szülő
commit
625397ea0c

+ 33 - 22
src/WallpaperEngine/Core/Objects/CImage.cpp

@@ -8,27 +8,30 @@
 using namespace WallpaperEngine::Core::Objects;
 
 CImage::CImage (
-        Images::CMaterial* material,
-        bool visible,
-        uint32_t id,
-        std::string name,
-        const glm::vec3& origin,
-        const glm::vec3& scale,
-        const glm::vec3& angles,
-        const glm::vec2& size,
-        std::string alignment,
-        const glm::vec3& color,
-        float alpha,
-        float brightness,
-        uint32_t colorBlendMode) :
-        CObject (visible, id, std::move(name), Type, origin, scale, angles),
-        m_size (size),
-        m_material (material),
-        m_alignment (std::move(alignment)),
-        m_color (color),
-        m_alpha (alpha),
-        m_brightness (brightness),
-        m_colorBlendMode (colorBlendMode)
+    Images::CMaterial* material,
+    bool visible,
+    uint32_t id,
+    std::string name,
+    const glm::vec3& origin,
+    const glm::vec3& scale,
+    const glm::vec3& angles,
+    const glm::vec2& size,
+    std::string alignment,
+    const glm::vec3& color,
+    float alpha,
+    float brightness,
+    uint32_t colorBlendMode,
+    const glm::vec2& parallaxDepth
+) :
+    CObject (visible, id, std::move(name), Type, origin, scale, angles),
+    m_size (size),
+    m_material (material),
+    m_alignment (std::move(alignment)),
+    m_color (color),
+    m_alpha (alpha),
+    m_brightness (brightness),
+    m_colorBlendMode (colorBlendMode),
+    m_parallaxDepth(parallaxDepth)
 {
 }
 
@@ -49,6 +52,7 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
     auto color_val = jsonFindDefault <std::string> (data, "color", "1.0 1.0 1.0");
     auto brightness_val = jsonFindDefault <float> (data, "brightness", 1.0);
     auto colorBlendMode_val = jsonFindDefault <uint32_t> (data, "colorBlendMode", 0);
+    auto parallaxDepth_val = jsonFindDefault <std::string> (data, "parallaxDepth", "0 0");
 
     json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get <std::string> (), container));
 
@@ -67,7 +71,8 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
         WallpaperEngine::Core::aToVector3 (color_val),
         alpha,
         brightness_val,
-        colorBlendMode_val
+        colorBlendMode_val,
+        WallpaperEngine::Core::aToVector2 (parallaxDepth_val)
     );
 }
 
@@ -106,4 +111,10 @@ const uint32_t CImage::getColorBlendMode () const
     return this->m_colorBlendMode;
 }
 
+
+const glm::vec2& CImage::getParallaxDepth () const
+{
+    return this->m_parallaxDepth;
+}
+
 const std::string CImage::Type = "image";

+ 24 - 21
src/WallpaperEngine/Core/Objects/CImage.h

@@ -18,14 +18,14 @@ namespace WallpaperEngine::Core::Objects
 
     public:
         static CObject* fromJSON (
-                json data,
-                CContainer* container,
-                bool visible,
-                uint32_t id,
-                std::string name,
-                const glm::vec3& origin,
-                const glm::vec3& scale,
-                const glm::vec3& angles
+            json data,
+            CContainer* container,
+            bool visible,
+            uint32_t id,
+            std::string name,
+            const glm::vec3& origin,
+            const glm::vec3& scale,
+            const glm::vec3& angles
         );
 
         const Images::CMaterial* getMaterial () const;
@@ -35,28 +35,31 @@ namespace WallpaperEngine::Core::Objects
         const glm::vec3& getColor () const;
         const float getBrightness () const;
         const uint32_t getColorBlendMode () const;
+        const glm::vec2& getParallaxDepth () const;
 
     protected:
         CImage (
-                Images::CMaterial* material,
-                bool visible,
-                uint32_t id,
-                std::string name,
-                const glm::vec3& origin,
-                const glm::vec3& scale,
-                const glm::vec3& angles,
-                const glm::vec2& size,
-                std::string alignment,
-                const glm::vec3& color,
-                float alpha,
-                float brightness,
-                uint32_t colorBlendMode
+            Images::CMaterial* material,
+            bool visible,
+            uint32_t id,
+            std::string name,
+            const glm::vec3& origin,
+            const glm::vec3& scale,
+            const glm::vec3& angles,
+            const glm::vec2& size,
+            std::string alignment,
+            const glm::vec3& color,
+            float alpha,
+            float brightness,
+            uint32_t colorBlendMode,
+            const glm::vec2& parallaxDepth
         );
 
         static const std::string Type;
 
     private:
         glm::vec2 m_size;
+        const glm::vec2 m_parallaxDepth;
         Images::CMaterial* m_material;
         std::string m_alignment;
         float m_alpha;

+ 19 - 4
src/WallpaperEngine/Render/CScene.cpp

@@ -34,6 +34,8 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
         }
     }
 
+    this->m_parallaxDisplacement = {0, 0};
+
     this->m_camera->setOrthogonalProjection (
         scene->getOrthogonalProjection ()->getWidth (),
         scene->getOrthogonalProjection ()->getHeight ()
@@ -49,7 +51,6 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
 
     // create all objects based off their dependencies
     {
-
         auto cur = scene->getObjects ().begin ();
         auto end = scene->getObjects ().end ();
 
@@ -71,7 +72,6 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
 
         this->m_objectsByRenderOrder.emplace_back ((*obj).second);
     }
-
 }
 
 Render::CObject* CScene::createObject (Core::CObject* object)
@@ -141,6 +141,17 @@ void CScene::renderFrame (glm::ivec4 viewport)
     // ensure the virtual mouse position is up to date
     this->updateMouse (viewport);
 
+    // update the parallax position if required
+    if (this->getScene ()->isCameraParallax () == true)
+    {
+        float influence = this->getScene ()->getCameraParallaxMouseInfluence ();
+        float amount = this->getScene ()->getCameraParallaxAmount ();
+        float delay = this->getScene ()->getCameraParallaxDelay ();
+
+        this->m_parallaxDisplacement.x = glm::mix (this->m_parallaxDisplacement.x, (this->m_mousePosition.x * amount) * influence, delay);
+        this->m_parallaxDisplacement.y = glm::mix (this->m_parallaxDisplacement.y, (this->m_mousePosition.y * amount) * influence, delay);
+    }
+
     // use the scene's framebuffer by default
     glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());
     // ensure we render over the whole screen
@@ -154,8 +165,6 @@ void CScene::renderFrame (glm::ivec4 viewport)
 
 void CScene::updateMouse (glm::ivec4 viewport)
 {
-    // projection also affects the mouse position
-    auto projection = this->getScene ()->getOrthogonalProjection ();
     // update virtual mouse position first
     CMouseInput* mouse = this->getContext ()->getMouse ();
     // TODO: PROPERLY TRANSLATE THESE TO WHAT'S VISIBLE ON SCREEN (FOR BACKGROUNDS THAT DO NOT EXACTLY FIT ON SCREEN)
@@ -176,4 +185,10 @@ glm::vec2* CScene::getMousePosition ()
     return &this->m_mousePosition;
 }
 
+
+glm::vec2* CScene::getParallaxDisplacement ()
+{
+    return &this->m_parallaxDisplacement;
+}
+
 const std::string CScene::Type = "scene";

+ 2 - 0
src/WallpaperEngine/Render/CScene.h

@@ -22,6 +22,7 @@ namespace WallpaperEngine::Render
         Core::CScene* getScene ();
 
         glm::vec2* getMousePosition ();
+        glm::vec2* getParallaxDisplacement ();
 
     protected:
         void renderFrame (glm::ivec4 viewport) override;
@@ -38,5 +39,6 @@ namespace WallpaperEngine::Render
         std::map<int, CObject*> m_objects;
         std::vector<CObject*> m_objectsByRenderOrder;
         glm::vec2 m_mousePosition;
+        glm::vec2 m_parallaxDisplacement;
     };
 }

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

@@ -20,19 +20,14 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
     glm::vec2 size = this->getSize ();
     glm::vec3 scale = this->getImage ()->getScale ();
 
-    float xleft = 0.0f;
-    float ytop = 0.0f;
-    float xright = 0.0f;
-    float ybottom = 0.0f;
-
     // depending on the alignment these values might change, for now just support center
     if (this->getImage ()->getAlignment () == "center")
     {
         // calculate the real position of the image
-        xleft = (-scene_width / 2) + (origin.x - (size.x * scale.x / 2));
-        xright = (-scene_width / 2) + (origin.x + (size.x * scale.x / 2));
-        ytop = (-scene_height / 2) + origin.y + (size.y * scale.y / 2);
-        ybottom = (-scene_height / 2) + (origin.y - (size.y * scale.y / 2));
+        this->m_pos.x = (-scene_width / 2) + (origin.x - (size.x * scale.x / 2));
+        this->m_pos.z = (-scene_width / 2) + (origin.x + (size.x * scale.x / 2));
+        this->m_pos.y = (-scene_height / 2) + origin.y + (size.y * scale.y / 2);
+        this->m_pos.w = (-scene_height / 2) + (origin.y - (size.y * scale.y / 2));
     }
     else
     {
@@ -99,12 +94,12 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
 
     // build a list of vertices, these might need some change later (or maybe invert the camera)
     GLfloat sceneSpacePosition [] = {
-        xleft, ytop, 0.0f,
-        xright, ytop, 0.0f,
-        xleft, ybottom, 0.0f,
-        xleft, ybottom, 0.0f,
-        xright, ytop, 0.0f,
-        xright, ybottom, 0.0f
+        this->m_pos.x, this->m_pos.y, 0.0f,
+        this->m_pos.z, this->m_pos.y, 0.0f,
+        this->m_pos.x, this->m_pos.w, 0.0f,
+        this->m_pos.x, this->m_pos.w, 0.0f,
+        this->m_pos.z, this->m_pos.y, 0.0f,
+        this->m_pos.z, this->m_pos.w, 0.0f
     };
 
     GLfloat copySpacePosition [] = {
@@ -364,6 +359,11 @@ void CImage::render ()
         // determine if it's the last element in the list as this is a screen-copy-like process
         else if (std::next (cur) == end && this->getImage ()->isVisible () == true)
         {
+            if (this->getScene ()->getScene ()->isCameraParallax () == true)
+            {
+                this->updateScreenSpacePosition ();
+            }
+
             spacePosition = *this->getSceneSpacePosition ();
             drawTo = this->getScene ()->getFBO ();
             projection = this->m_modelViewProjectionScreen;
@@ -381,6 +381,26 @@ void CImage::render ()
     }
 }
 
+void CImage::updateScreenSpacePosition ()
+{
+    double parallaxAmount = this->getScene ()->getScene ()->getCameraParallaxAmount ();
+    glm::vec2 depth = this->getImage ()->getParallaxDepth ();
+    glm::vec2* displacement = this->getScene ()->getParallaxDisplacement ();
+
+    // no need to update if the depth is 0
+    if (depth.x == 0.0 && depth.y == 0.0)
+        return;
+
+    float x = (depth.x + parallaxAmount) * displacement->x * this->getSize ().x;
+    float y = (depth.y + parallaxAmount) * displacement->y * this->getSize ().x;
+    this->m_modelViewProjectionScreen =
+        glm::translate (
+            this->getScene ()->getCamera ()->getProjection () *
+            this->getScene ()->getCamera ()->getLookAt (),
+            {x, y, 0.0f}
+        );
+}
+
 const ITexture* CImage::getTexture () const
 {
     return this->m_texture;

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

@@ -59,6 +59,8 @@ namespace WallpaperEngine::Render::Objects
 
     protected:
         static const std::string Type;
+
+        void updateScreenSpacePosition ();
     private:
         const ITexture* m_texture;
         GLuint m_sceneSpacePosition;
@@ -82,6 +84,8 @@ namespace WallpaperEngine::Render::Objects
         Effects::CMaterial* m_colorBlendMaterial;
         std::vector <Effects::CPass*> m_passes;
 
+        glm::vec4 m_pos;
+
         double m_animationTime;
 
         bool m_initialized;