diff --git a/src/WallpaperEngine/Assets/CTexture.cpp b/src/WallpaperEngine/Assets/CTexture.cpp index 893d31d..a24799d 100644 --- a/src/WallpaperEngine/Assets/CTexture.cpp +++ b/src/WallpaperEngine/Assets/CTexture.cpp @@ -249,6 +249,11 @@ const ITexture::TextureFormat CTexture::getFormat () const return this->getHeader ()->format; } +const ITexture::TextureFlags CTexture::getFlags () const +{ + return this->getHeader ()->flags; +} + const CTexture::TextureHeader* CTexture::getHeader () const { return this->m_header; diff --git a/src/WallpaperEngine/Assets/CTexture.h b/src/WallpaperEngine/Assets/CTexture.h index cfcf6cd..8220860 100644 --- a/src/WallpaperEngine/Assets/CTexture.h +++ b/src/WallpaperEngine/Assets/CTexture.h @@ -27,6 +27,7 @@ namespace WallpaperEngine::Assets const uint32_t getRealWidth () const override; const uint32_t getRealHeight () const override; const TextureFormat getFormat () const override; + const TextureFlags getFlags () const override; const glm::vec4* getResolution () const override; const std::vector& getFrames () const override; const bool isAnimated () const override; @@ -75,17 +76,6 @@ namespace WallpaperEngine::Assets void decompressData (); }; - /** - * Configures how the texture will be handled by the background - */ - enum TextureFlags : uint32_t - { - NoFlags = 0, - NoInterpolation = 1, - ClampUVs = 2, - IsGif = 4, - }; - class TextureHeader { public: diff --git a/src/WallpaperEngine/Assets/ITexture.h b/src/WallpaperEngine/Assets/ITexture.h index 6a96aa7..06e6d7e 100644 --- a/src/WallpaperEngine/Assets/ITexture.h +++ b/src/WallpaperEngine/Assets/ITexture.h @@ -31,6 +31,9 @@ namespace WallpaperEngine::Assets float height1; }; + /** + * Configures the data format for the texture + */ enum TextureFormat : uint32_t { ARGB8888 = 0, @@ -41,12 +44,24 @@ namespace WallpaperEngine::Assets R8 = 9, }; + /** + * Configures how the texture will be handled by the background + */ + enum TextureFlags : uint32_t + { + NoFlags = 0, + NoInterpolation = 1, + ClampUVs = 2, + IsGif = 4, + }; + virtual const GLuint getTextureID (uint32_t imageIndex = 0) const = 0; virtual const uint32_t getTextureWidth (uint32_t imageIndex = 0) const = 0; virtual const uint32_t getTextureHeight (uint32_t imageIndex = 0) const = 0; virtual const uint32_t getRealWidth () const = 0; virtual const uint32_t getRealHeight () const = 0; virtual const TextureFormat getFormat () const = 0; + virtual const TextureFlags getFlags () const = 0; virtual const std::vector& getFrames () const = 0; virtual const glm::vec4* getResolution () const = 0; virtual const bool isAnimated () const = 0; diff --git a/src/WallpaperEngine/Core/CObject.cpp b/src/WallpaperEngine/Core/CObject.cpp index a09d306..01c378b 100644 --- a/src/WallpaperEngine/Core/CObject.cpp +++ b/src/WallpaperEngine/Core/CObject.cpp @@ -132,6 +132,22 @@ CObject* CObject::fromJSON (json data, CContainer* container) for (; cur != end; cur ++) { + // check if the effect is visible or not + auto effectVisible_it = (*cur).find ("visible"); + + if (effectVisible_it != (*cur).end ()) + { + if ((*effectVisible_it).is_boolean () && (*effectVisible_it) == false) + continue; + if ((*effectVisible_it).is_object () == true) + { + auto effectVisibleValue_it = (*effectVisible_it).find ("value"); + + if (effectVisibleValue_it != (*effectVisible_it).end () && (*effectVisibleValue_it) == false) + continue; + } + } + object->insertEffect ( Objects::CEffect::fromJSON (*cur, object, container) ); diff --git a/src/WallpaperEngine/Render/CContext.cpp b/src/WallpaperEngine/Render/CContext.cpp index d9810c6..8cad7e7 100644 --- a/src/WallpaperEngine/Render/CContext.cpp +++ b/src/WallpaperEngine/Render/CContext.cpp @@ -136,7 +136,14 @@ void CContext::initializeViewports () XRRFreeScreenResources (screenResources); // create the fbo that will handle the screen - this->m_fbo = new CFBO("_sc_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, fullWidth, fullHeight, fullWidth, fullHeight); + this->m_fbo = new CFBO( + "_sc_FullFrameBuffer", + ITexture::TextureFormat::ARGB8888, + ITexture::TextureFlags::NoInterpolation, + 1.0, + fullWidth, fullHeight, + fullWidth, fullHeight + ); // set the window background so the pixmap is drawn XSetWindowBackgroundPixmap(this->m_display, root, this->m_pixmap); diff --git a/src/WallpaperEngine/Render/CFBO.cpp b/src/WallpaperEngine/Render/CFBO.cpp index b170f06..f1e8d57 100644 --- a/src/WallpaperEngine/Render/CFBO.cpp +++ b/src/WallpaperEngine/Render/CFBO.cpp @@ -2,10 +2,18 @@ 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) : +CFBO::CFBO ( + std::string name, + ITexture::TextureFormat format, + ITexture::TextureFlags flags, + 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) + m_scale (scale), + m_flags (flags) { // create an empty texture that'll be free'd so the FBO is transparent GLenum drawBuffers [1] = {GL_COLOR_ATTACHMENT0}; @@ -18,13 +26,30 @@ CFBO::CFBO (std::string name, ITexture::TextureFormat format, float scale, uint3 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); + if (flags & TextureFlags::ClampUVs) + { + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + else + { + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + + if (flags & TextureFlags::NoInterpolation) + { + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + else + { + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 8.0f); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // set the texture as the colour attachmend #0 glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->m_texture, 0); @@ -73,6 +98,11 @@ const ITexture::TextureFormat CFBO::getFormat () const return this->m_format; } +const ITexture::TextureFlags CFBO::getFlags () const +{ + return this->m_flags; +} + GLuint CFBO::getFramebuffer () const { return this->m_framebuffer; diff --git a/src/WallpaperEngine/Render/CFBO.h b/src/WallpaperEngine/Render/CFBO.h index 1282672..83ccadf 100644 --- a/src/WallpaperEngine/Render/CFBO.h +++ b/src/WallpaperEngine/Render/CFBO.h @@ -11,11 +11,12 @@ 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); + CFBO (std::string name, ITexture::TextureFormat format, ITexture::TextureFlags flags, 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; + const ITexture::TextureFlags getFlags () const override; GLuint getFramebuffer () const; GLuint getDepthbuffer () const; const GLuint getTextureID (uint32_t imageIndex = 0) const override; @@ -36,6 +37,7 @@ namespace WallpaperEngine::Render float m_scale; std::string m_name; ITexture::TextureFormat m_format; + ITexture::TextureFlags m_flags; /** Placeholder for frames, FBOs only have ONE */ std::vector m_frames; }; diff --git a/src/WallpaperEngine/Render/CScene.cpp b/src/WallpaperEngine/Render/CScene.cpp index 1d8ceee..5287806 100644 --- a/src/WallpaperEngine/Render/CScene.cpp +++ b/src/WallpaperEngine/Render/CScene.cpp @@ -33,7 +33,7 @@ CScene::CScene (Core::CScene* scene, CContainer* container, CContext* context) : scene->getOrthogonalProjection ()->setHeight (size.y); } } - + this->m_camera->setOrthogonalProjection ( scene->getOrthogonalProjection ()->getWidth (), scene->getOrthogonalProjection ()->getHeight () diff --git a/src/WallpaperEngine/Render/CWallpaper.cpp b/src/WallpaperEngine/Render/CWallpaper.cpp index a30526a..39abae9 100644 --- a/src/WallpaperEngine/Render/CWallpaper.cpp +++ b/src/WallpaperEngine/Render/CWallpaper.cpp @@ -319,7 +319,14 @@ void CWallpaper::setupFramebuffers () } // create framebuffer for the scene - this->m_sceneFBO = this->createFBO ("_rt_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight); + this->m_sceneFBO = this->createFBO ( + "_rt_FullFrameBuffer", + ITexture::TextureFormat::ARGB8888, + ITexture::TextureFlags::NoInterpolation, + 1.0, + windowWidth, windowHeight, + windowWidth, windowHeight + ); } CContext* CWallpaper::getContext () @@ -327,9 +334,9 @@ CContext* CWallpaper::getContext () return this->m_context; } -CFBO* CWallpaper::createFBO (const std::string& name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight) +CFBO* CWallpaper::createFBO (const std::string& name, ITexture::TextureFormat format, ITexture::TextureFlags flags, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight) { - CFBO* fbo = new CFBO (name, format, scale, realWidth, realHeight, textureWidth, textureHeight); + CFBO* fbo = new CFBO (name, format, flags, scale, realWidth, realHeight, textureWidth, textureHeight); this->m_fbos.insert (std::make_pair (name, fbo)); diff --git a/src/WallpaperEngine/Render/CWallpaper.h b/src/WallpaperEngine/Render/CWallpaper.h index 809e773..ef9d2ea 100644 --- a/src/WallpaperEngine/Render/CWallpaper.h +++ b/src/WallpaperEngine/Render/CWallpaper.h @@ -52,7 +52,7 @@ namespace WallpaperEngine::Render * @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); + CFBO* createFBO (const std::string& name, ITexture::TextureFormat format, ITexture::TextureFlags flags, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight); /** * @return The full FBO list to work with diff --git a/src/WallpaperEngine/Render/Objects/CEffect.cpp b/src/WallpaperEngine/Render/Objects/CEffect.cpp index 2cf078d..c94a472 100644 --- a/src/WallpaperEngine/Render/Objects/CEffect.cpp +++ b/src/WallpaperEngine/Render/Objects/CEffect.cpp @@ -57,6 +57,7 @@ void CEffect::generateFBOs () new CFBO ( (*cur)->getName (), ITexture::TextureFormat::ARGB8888, // TODO: CHANGE + this->m_image->getTexture ()->getFlags (), // TODO: CHANGE (*cur)->getScale (), this->m_image->getSize ().x / (*cur)->getScale (), this->m_image->getSize ().y / (*cur)->getScale (), diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index 6ec01e6..d2b61d6 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -61,7 +61,14 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : 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, 1, realSize.x, realSize.y, realSize.x, realSize.y); + this->m_texture = new CFBO ( + "", + ITexture::TextureFormat::ARGB8888, + ITexture::TextureFlags::NoFlags, + 1, + realSize.x, realSize.y, + realSize.x, realSize.y + ); } // register both FBOs into the scene @@ -70,8 +77,22 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : nameA << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_a"; nameB << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_b"; - this->m_currentMainFBO = this->m_mainFBO = scene->createFBO (nameA.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight (), this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight ()); - this->m_currentSubFBO = this->m_subFBO = scene->createFBO (nameB.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight (), this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight ()); + this->m_currentMainFBO = this->m_mainFBO = scene->createFBO ( + nameA.str (), + ITexture::TextureFormat::ARGB8888, + this->m_texture->getFlags (), + 1, + this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight (), + this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight () + ); + this->m_currentSubFBO = this->m_subFBO = scene->createFBO ( + nameB.str (), + ITexture::TextureFormat::ARGB8888, + this->m_texture->getFlags (), + 1, + this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight (), + this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight () + ); GLfloat realWidth = this->m_texture->getRealWidth () / 2; GLfloat realHeight = this->m_texture->getRealHeight () / 2; @@ -109,7 +130,7 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : if (this->getTexture ()->isAnimated () == true) { - // animated images use different coordinates as they're essentially a texture atlast + // animated images use different coordinates as they're essentially a texture atlas width = static_cast (this->getTexture ()->getRealWidth ()) / static_cast (this->getTexture ()->getTextureWidth ()); height = static_cast (this->getTexture ()->getRealHeight ()) / static_cast (this->getTexture ()->getTextureHeight ()); } diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index 84a64a4..b513ce4 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -369,6 +369,8 @@ void CPass::setupShaders () this->m_pass->getShader (), Shaders::Compiler::Type_Pixel, this->m_pass->getCombos (), + &m_foundCombos, + this->m_pass->getTextures (), this->m_pass->getConstants () ); this->m_fragShader->precompile (); @@ -377,6 +379,8 @@ void CPass::setupShaders () this->m_pass->getShader (), Shaders::Compiler::Type_Vertex, this->m_pass->getCombos (), + &m_foundCombos, + this->m_pass->getTextures (), this->m_pass->getConstants () ); this->m_vertShader->precompile (); diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.h b/src/WallpaperEngine/Render/Objects/Effects/CPass.h index ac32614..b28d307 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.h @@ -90,6 +90,7 @@ namespace WallpaperEngine::Render::Objects::Effects Core::Objects::Images::Materials::CPass* m_pass; std::vector m_textures; std::map m_fbos; + std::map m_foundCombos; std::vector m_attribs; std::map m_uniforms; glm::mat4 m_modelViewProjectionMatrix; diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.cpp b/src/WallpaperEngine/Render/Shaders/Compiler.cpp index d78ec97..d45583a 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.cpp +++ b/src/WallpaperEngine/Render/Shaders/Compiler.cpp @@ -28,10 +28,14 @@ namespace WallpaperEngine::Render::Shaders CContainer* container, std::string filename, Type type, - std::map* combos, + std::map * combos, + std::map * foundCombos, + const std::vector & textures, const std::map& constants, bool recursive) : m_combos (combos), + m_foundCombos (foundCombos), + m_passTextures (textures), m_recursive (recursive), m_type (type), m_file (std::move(filename)), @@ -220,7 +224,7 @@ namespace WallpaperEngine::Render::Shaders { // now compile the new shader // do not include the default header (as it's already included in the parent) - Compiler loader (this->m_container, std::move (filename), Type_Include, this->m_combos, this->m_constants, true); + Compiler loader (this->m_container, std::move (filename), Type_Include, this->m_combos, this->m_foundCombos, this->m_passTextures, this->m_constants, true); loader.precompile (); @@ -479,6 +483,9 @@ namespace WallpaperEngine::Render::Shaders { // add the opengl compatibility at the top finalCode = "#version 130\n" + "// ======================================================\n" + "// Processed shader " + this->m_file + "\n" + "// ======================================================\n" "#define highp\n" "#define mediump\n" "#define lowp\n" @@ -503,13 +510,23 @@ namespace WallpaperEngine::Render::Shaders "#define float3 vec3\n" "#define float4 vec4\n"; + finalCode += "// ======================================================\n" + "// Shader combo parameter definitions\n" + "// ======================================================\n"; + // add combo values - auto cur = this->m_combos->begin (); - auto end = this->m_combos->end (); + auto cur = this->m_foundCombos->begin (); + auto end = this->m_foundCombos->end (); for (; cur != end; cur ++) { - finalCode += "#define " + (*cur).first + " " + std::to_string ((*cur).second) + "\n"; + // find the right value for the combo in the combos map + auto combo = this->m_combos->find ((*cur).first); + + if (combo == this->m_combos->end ()) + continue; + + finalCode += "#define " + (*cur).first + " " + std::to_string ((*combo).second) + "\n"; } } @@ -541,6 +558,9 @@ namespace WallpaperEngine::Render::Shaders // check the combos std::map::const_iterator entry = this->m_combos->find ((*combo).get ()); + // add the combo to the found list + this->m_foundCombos->insert (std::make_pair (*combo, true)); + // if the combo was not found in the predefined values this means that the default value in the JSON data can be used // so only define the ones that are not already defined if (entry == this->m_combos->end ()) @@ -650,17 +670,26 @@ namespace WallpaperEngine::Render::Shaders if (combo != data.end ()) { - // add the new combo to the list - this->m_combos->insert (std::make_pair (*combo, 1)); + // extract the texture number from the name + char value = name.at (std::string("g_Texture").length ()); + // now convert it to integer + int index = value - '0'; + + // if the texture exists, add the combo + if (this->m_passTextures.size () > index) + { + // add the new combo to the list + this->m_combos->insert (std::make_pair (*combo, 1)); + + // textures linked to combos need to be tracked too + if (this->m_foundCombos->find (*combo) == this->m_foundCombos->end ()) + this->m_foundCombos->insert (std::make_pair (*combo, true)); + } if (textureName != data.end ()) { // also ensure that the textureName is loaded and we know about it ITexture* texture = this->m_container->readTexture ((*textureName).get ()); - // extract the texture number from the name - char value = name.at (std::string("g_Texture").length ()); - // now convert it to integer - int index = value - '0'; this->m_textures.insert ( std::make_pair (index, texture) diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.h b/src/WallpaperEngine/Render/Shaders/Compiler.h index 249fa5a..24613bc 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.h +++ b/src/WallpaperEngine/Render/Shaders/Compiler.h @@ -55,6 +55,8 @@ namespace WallpaperEngine::Render::Shaders std::string filename, Type type, std::map* combos, + std::map* foundCombos, + const std::vector & textures, const std::map& constants, bool recursive = false ); @@ -231,6 +233,16 @@ namespace WallpaperEngine::Render::Shaders * The combos the shader should be generated with */ std::map * m_combos; + + /** + * The combos the shader code has defined (shared between fragment and vertex) + */ + std::map * m_foundCombos; + + /** + * The list of textures the pass knows about + */ + const std::vector m_passTextures; /** * The shader constants with values for variables inside the shader */