From 9a5913921cf2dcd28e0aabbb4a916b69e46c8c2a Mon Sep 17 00:00:00 2001 From: Alexis Maiquez Date: Thu, 30 Mar 2023 02:01:07 +0200 Subject: [PATCH] Hopefully properly support Fullscreen and Passthrough images Signed-off-by: Alexis Maiquez --- src/WallpaperEngine/Core/CObject.cpp | 3 - src/WallpaperEngine/Core/Objects/CImage.cpp | 33 ++++++- src/WallpaperEngine/Core/Objects/CImage.h | 20 +++- src/WallpaperEngine/Render/Objects/CImage.cpp | 96 ++++++++++++------- 4 files changed, 112 insertions(+), 40 deletions(-) diff --git a/src/WallpaperEngine/Core/CObject.cpp b/src/WallpaperEngine/Core/CObject.cpp index e6549af..562c18c 100644 --- a/src/WallpaperEngine/Core/CObject.cpp +++ b/src/WallpaperEngine/Core/CObject.cpp @@ -58,9 +58,6 @@ CObject* CObject::fromJSON (json data, CScene* scene, CContainer* container) if (image_it != data.end () && !(*image_it).is_null ()) { - if (*image_it == "models/util/composelayer.json") - return nullptr; - object = Objects::CImage::fromJSON ( scene, data, diff --git a/src/WallpaperEngine/Core/Objects/CImage.cpp b/src/WallpaperEngine/Core/Objects/CImage.cpp index 5155bd1..1e8b158 100644 --- a/src/WallpaperEngine/Core/Objects/CImage.cpp +++ b/src/WallpaperEngine/Core/Objects/CImage.cpp @@ -27,7 +27,10 @@ CImage::CImage ( CUserSettingFloat* alpha, float brightness, uint32_t colorBlendMode, - const glm::vec2& parallaxDepth + const glm::vec2& parallaxDepth, + bool fullscreen, + bool passthrough, + bool autosize ) : CObject (scene, visible, id, std::move(name), Type, origin, scale, angles), m_size (size), @@ -37,7 +40,10 @@ CImage::CImage ( m_alpha (alpha), m_brightness (brightness), m_colorBlendMode (colorBlendMode), - m_parallaxDepth(parallaxDepth) + m_parallaxDepth(parallaxDepth), + m_fullscreen (fullscreen), + m_passthrough (passthrough), + m_autosize (autosize) { } @@ -64,6 +70,9 @@ WallpaperEngine::Core::CObject* CImage::fromJSON ( json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get (), container)); auto material_it = jsonFindRequired (content, "material", "Image must have a material"); + auto fullscreen = jsonFindDefault (content, "fullscreen", false); + auto passthrough = jsonFindDefault (content, "passthrough", false); + auto autosize = jsonFindDefault (content, "autosize", false); return new CImage ( scene, @@ -80,7 +89,10 @@ WallpaperEngine::Core::CObject* CImage::fromJSON ( alpha, brightness_val, colorBlendMode_val, - WallpaperEngine::Core::aToVector2 (parallaxDepth_val) + WallpaperEngine::Core::aToVector2 (parallaxDepth_val), + fullscreen, + passthrough, + autosize ); } @@ -125,4 +137,19 @@ const glm::vec2& CImage::getParallaxDepth () const return this->m_parallaxDepth; } +bool CImage::isFullscreen () const +{ + return this->m_fullscreen; +} + +bool CImage::isPassthrough () const +{ + return this->m_passthrough; +} + +bool CImage::isAutosize () const +{ + return this->m_autosize; +} + const std::string CImage::Type = "image"; \ No newline at end of file diff --git a/src/WallpaperEngine/Core/Objects/CImage.h b/src/WallpaperEngine/Core/Objects/CImage.h index f35f8a5..199fb0b 100644 --- a/src/WallpaperEngine/Core/Objects/CImage.h +++ b/src/WallpaperEngine/Core/Objects/CImage.h @@ -66,13 +66,25 @@ namespace WallpaperEngine::Core::Objects * @return Parallax depth of the image */ [[nodiscard]] const glm::vec2& getParallaxDepth () const; + /** + * @return If the image is fullscreen or not + */ + [[nodiscard]] bool isFullscreen () const; + /** + * @return If the image is passthrough or not + */ + [[nodiscard]] bool isPassthrough () const; + /** + * @return If the image is autosized or not + */ + [[nodiscard]] bool isAutosize () const; protected: CImage ( CScene* scene, Images::CMaterial* material, CUserSettingBoolean* visible, uint32_t id, std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles, const glm::vec2& size, std::string alignment, CUserSettingVector3* color, CUserSettingFloat* alpha, float brightness, - uint32_t colorBlendMode, const glm::vec2& parallaxDepth + uint32_t colorBlendMode, const glm::vec2& parallaxDepth, bool fullscreen, bool passthrough, bool autosize ); /** @@ -97,5 +109,11 @@ namespace WallpaperEngine::Core::Objects CUserSettingVector3* m_color; /** The color blending mode used for the image, special value for shaders */ uint32_t m_colorBlendMode; + /** If the image is fullscreen or not */ + bool m_fullscreen; + /** If the image is passthrough or not */ + bool m_passthrough; + /** If the image's size should be automatically determined */ + bool m_autosize; }; } diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index cd671b6..8232a6a 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -31,6 +31,17 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : glm::vec3 origin = this->getImage ()->getOrigin (); glm::vec2 size = this->getSize (); glm::vec3 scale = this->getImage ()->getScale (); + + // fullscreen layers should use the whole projection's size + // TODO: WHAT SHOULD AUTOSIZE DO? + if (this->getImage ()->isFullscreen ()) + { + size = { scene_width, scene_height }; + origin = { scene_width / 2, scene_height / 2, 0 }; + + // TODO: CHANGE ALIGNMENT TOO? + } + glm::vec2 scaledSize = size * glm::vec2 (scale); // calculate the center and shift from there @@ -86,16 +97,14 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : } else { - glm::vec2 realSize = size * glm::vec2 (scale); - // TODO: create a dummy texture of correct size, fbo constructors should be enough, but this should be properly handled this->m_texture = new CFBO ( "", ITexture::TextureFormat::ARGB8888, ITexture::TextureFlags::NoFlags, 1, - realSize.x, realSize.y, - realSize.x, realSize.y + size.x, size.y, + size.x, size.y ); } @@ -123,9 +132,6 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : this->m_texture->getRealWidth (), this->m_texture->getRealHeight () ); - GLfloat realWidth = this->m_texture->getRealWidth (); - GLfloat realHeight = this->m_texture->getRealHeight (); - // build a list of vertices, these might need some change later (or maybe invert the camera) GLfloat sceneSpacePosition [] = { this->m_pos.x, this->m_pos.y, 0.0f, @@ -136,24 +142,6 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : this->m_pos.z, this->m_pos.w, 0.0f }; - GLfloat copySpacePosition [] = { - 0.0, realHeight, 0.0f, - 0.0, 0.0, 0.0f, - realWidth, realHeight, 0.0f, - realWidth, realHeight, 0.0f, - 0.0, 0.0, 0.0f, - realWidth, 0.0, 0.0f - }; - - GLfloat passSpacePosition [] = { - -1.0, 1.0, 0.0f, - -1.0, -1.0, 0.0f, - 1.0, 1.0, 0.0f, - 1.0, 1.0, 0.0f, - -1.0, -1.0, 0.0f, - 1.0, -1.0, 0.0f - }; - float width = 1.0f; float height = 1.0f; @@ -166,9 +154,8 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : // calculate the correct texCoord limits for the texture based on the texture screen size and real size else if (this->getTexture () != nullptr && (this->getTexture ()->getTextureWidth () != this->getTexture ()->getRealWidth () || - this->getTexture ()->getTextureHeight () != this->getTexture ()->getRealHeight ()) - ) - { + this->getTexture ()->getTextureHeight () != this->getTexture ()->getRealHeight ()) + ) { uint32_t x = 1; uint32_t y = 1; @@ -179,6 +166,7 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : height = scaledSize.y / y; } + // TODO: RECALCULATE THESE POSITIONS FOR PASSTHROUGH SO THEY TAKE THE RIGHT PART OF THE TEXTURE float x = 0.0f; float y = 0.0f; @@ -191,6 +179,27 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : height = 1.0f; } + GLfloat realWidth = size.x; + GLfloat realHeight = size.y; + GLfloat realX = 0.0; + GLfloat realY = 0.0; + + if (this->getImage ()->isPassthrough()) + { + x = -((this->m_pos.x + (scene_width / 2)) / size.x); + y = -((this->m_pos.w + (scene_height / 2)) / size.y); + height = (this->m_pos.y + (scene_height / 2)) / size.y; + width = (this->m_pos.z + (scene_width / 2)) / size.x; + + if (this->getImage ()->isFullscreen ()) + { + realX = -1.0; + realY = -1.0; + realWidth = 1.0; + realHeight = 1.0; + } + } + GLfloat texcoordCopy [] = { x, height, x, y, @@ -200,6 +209,15 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : width, y }; + GLfloat copySpacePosition [] = { + realX, realHeight, 0.0f, + realX, realY, 0.0f, + realWidth, realHeight, 0.0f, + realWidth, realHeight, 0.0f, + realX, realY, 0.0f, + realWidth, realY, 0.0f + }; + GLfloat texcoordPass [] = { 0.0f, 1.0f, 0.0f, 0.0f, @@ -209,6 +227,15 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : 1.0f, 0.0f }; + GLfloat passSpacePosition [] = { + -1.0, 1.0, 0.0f, + -1.0, -1.0, 0.0f, + 1.0, 1.0, 0.0f, + 1.0, 1.0, 0.0f, + -1.0, -1.0, 0.0f, + 1.0, -1.0, 0.0f + }; + // bind vertex list to the openGL buffers glGenBuffers (1, &this->m_sceneSpacePosition); glBindBuffer (GL_ARRAY_BUFFER, this->m_sceneSpacePosition); @@ -246,6 +273,10 @@ void CImage::setup () // TODO: SUPPORT PASSTHROUGH (IT'S A SHADER) + // passthrough images without effects are bad, do not draw them + if (this->getImage ()->isPassthrough() && this->getImage ()->getEffects ().empty ()) + return; + { // generate the main material used to render the image this->m_material = new Effects::CMaterial ( @@ -387,13 +418,15 @@ void CImage::pinpongFramebuffer (const CFBO** drawTo, const ITexture** asInput) void CImage::render () { // do not try to render something that did not initialize successfully + // non-visible materials do need to be rendered if (!this->m_initialized) return; glColorMask (true, true, true, true); // update the position if required - if (this->getScene ()->getScene ()->isCameraParallax ()) + // TODO: There's more images that are not affected by parallax, autosize or fullscreen are not affected + if (this->getScene ()->getScene ()->isCameraParallax () && !this->getImage ()->isFullscreen ()) this->updateScreenSpacePosition (); #if !NDEBUG @@ -433,12 +466,9 @@ void CImage::updateScreenSpacePosition () 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 () *