From d6831ad40f1f563ed6869b57e6a6f65d863da159 Mon Sep 17 00:00:00 2001 From: Almamu Date: Tue, 19 Aug 2025 21:44:25 +0200 Subject: [PATCH] chore: bring back support for pass commands --- .../Data/Dumpers/StringPrinter.cpp | 64 +++++++++-------- src/WallpaperEngine/Data/Model/Effect.h | 16 ++--- .../Data/Parsers/EffectParser.cpp | 25 +++---- src/WallpaperEngine/Render/Objects/CImage.cpp | 70 ++++++++++++++----- src/WallpaperEngine/Render/Objects/CImage.h | 1 + .../Render/Objects/Effects/CPass.cpp | 2 +- .../Render/Objects/Effects/CPass.h | 2 +- 7 files changed, 106 insertions(+), 74 deletions(-) diff --git a/src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp b/src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp index 3a52b04..462f25d 100644 --- a/src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp +++ b/src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp @@ -265,39 +265,47 @@ void StringPrinter::printEffect (const Effect& effect) { void StringPrinter::printEffectPass (const EffectPass& effectPass) { if (effectPass.command.has_value ()) { - const auto& command = effectPass.command.value (); + this->m_out << "Command: " << (*effectPass.command == Command_Copy ? "copy" : "swap"); - this->m_out << "Command: " << (command.command == Command_Copy ? "copy" : "swap"); - this->lineEnd (); - this->m_out << "Source: " << command.source; - this->lineEnd (); - this->m_out << "Target: " << command.target; - } else { + if (effectPass.target.has_value () || effectPass.source.has_value ()) { + this->lineEnd (); + } + } + + if (effectPass.target.has_value ()) { + this->m_out << "Target: " << effectPass.target.value (); + + if (effectPass.source.has_value ()) { + this->lineEnd (); + } + } + + if (effectPass.source.has_value ()) { + this->m_out << "Source: " << effectPass.source.value (); + } + + if (!effectPass.binds.empty ()) { if (effectPass.target.has_value ()) { - this->m_out << "Target: " << effectPass.target.value (); - } - - if (!effectPass.binds.empty ()) { - if (effectPass.target.has_value ()) { - this->lineEnd (); - } - - this->m_out << "Binds count: " << effectPass.binds.size (); - this->increaseIndentation (); - - for (const auto& bind : effectPass.binds) { - this->lineEnd (); - this->m_out << "Bind " << bind.first << ": " << bind.second; - } - - this->decreaseIndentation (); - } - - if (effectPass.target.has_value () || !effectPass.binds.empty ()) { this->lineEnd (); } - this->printMaterial (*effectPass.material); + this->m_out << "Binds count: " << effectPass.binds.size (); + this->increaseIndentation (); + + for (const auto& bind : effectPass.binds) { + this->lineEnd (); + this->m_out << "Bind " << bind.first << ": " << bind.second; + } + + this->decreaseIndentation (); + } + + if (effectPass.target.has_value () || !effectPass.binds.empty ()) { + this->lineEnd (); + } + + if (effectPass.material.has_value ()) { + this->printMaterial (**effectPass.material); } } diff --git a/src/WallpaperEngine/Data/Model/Effect.h b/src/WallpaperEngine/Data/Model/Effect.h index 54b76e8..217ec97 100644 --- a/src/WallpaperEngine/Data/Model/Effect.h +++ b/src/WallpaperEngine/Data/Model/Effect.h @@ -14,24 +14,18 @@ struct FBO { std::string name; std::string format; float scale; -}; - -struct PassCommand { - /** The type of command to execute */ - PassCommandType command; - /** The target of the command (where to draw to) */ - std::string target; - /** The source of the command (where to draw from) */ - std::string source; + bool unique; }; struct EffectPass { /** The material to use for this effect's pass */ - MaterialUniquePtr material; + std::optional material; /** Texture bindings for this effect's pass */ TextureMap binds; /** The command this material executes (if specified) */ - std::optional command; + std::optional command; + /** The source this material renders from (if specified) */ + std::optional source; /** The target this material renders to (if specified) */ std::optional target; }; diff --git a/src/WallpaperEngine/Data/Parsers/EffectParser.cpp b/src/WallpaperEngine/Data/Parsers/EffectParser.cpp index 98709d0..7ed6ec6 100644 --- a/src/WallpaperEngine/Data/Parsers/EffectParser.cpp +++ b/src/WallpaperEngine/Data/Parsers/EffectParser.cpp @@ -52,27 +52,17 @@ std::vector EffectParser::parseEffectPasses (const JSON& i for (const auto& cur : it) { const auto binds = cur.optional ("bind"); - std::optional command = std::nullopt; + const auto command = cur.optional ("command"); + const auto material = cur.optional ("material"); - if (cur.contains ("command")) { - command = { - .command = cur.require ("command", "Material command must have a command") == "copy" - ? Command_Copy - : Command_Swap, - .target = cur.require ("target", "Material command must have a target"), - .source = cur.require ("source", "Material command must have a source"), - }; - } + // TODO: CAN TARGET BE SET IF MATERIAL IS SET? result.push_back (std::make_unique (EffectPass { - .material = MaterialParser::load (project, cur.require ("material", "Effect pass must have a material")), + .material = material.has_value () ? MaterialParser::load (project, *material) : std::optional {}, .binds = binds.has_value () ? parseBinds (binds.value ()) : std::map {}, - .command = command, - // target is a bit special: if the material is a command this will be nullopt - // and the actual target will be set in the command itself, otherwise it will - // be set to whatever is in the json, which is not required to be present for - // normal materials - .target = command.has_value () ? std::nullopt : cur.optional ("target"), + .command = command.has_value () ? (command.value () == "copy" ? Command_Copy : Command_Swap) : std::optional {}, + .source = command.has_value () ? cur.require ("source", "Effect command must have a source") : cur.optional ("source"), + .target = command.has_value () ? cur.require ("target", "Effect command must have a target") : cur.optional ("target"), })); } @@ -108,6 +98,7 @@ std::vector EffectParser::parseFBOs (const JSON& it) { .name = cur.require ("name", "FBO must have a name"), .format = cur.optional ("format", "rgba8888"), .scale = cur.optional ("scale", 1.0f), + .unique = cur.optional ("unique", false), })); } diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index d0ca2b0..86c23a2 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -2,7 +2,6 @@ #include #include "WallpaperEngine/Data/Parsers/MaterialParser.h" -#include "WallpaperEngine/Data/Builders/UserSettingBuilder.h" #include "WallpaperEngine/Data/Model/Object.h" #include "WallpaperEngine/Data/Model/Material.h" @@ -245,7 +244,6 @@ void CImage::setup () { new CPass (*this, std::make_shared(this), *cur, std::nullopt, std::nullopt, std::nullopt) ); - // TODO: MAYBE GET RID OF THE WHOLE EFFECT CLASS AND PROCESS THE EFFECTS DIRECTLY TO SIMPLIFY RENDERING CODE? // prepare the passes list if (!this->getImage ().effects.empty ()) { // generate the effects used by this material @@ -265,23 +263,63 @@ void CImage::setup () { auto endOverride = cur->passOverrides.end (); for (; curEffect != endEffect; curEffect++) { - auto curPass = (*curEffect)->material->passes.begin (); - auto endPass = (*curEffect)->material->passes.end (); + if (!(*curEffect)->material.has_value ()) { + if (!(*curEffect)->command.has_value ()) { + sLog.error ("Pass without material and command not supported"); + continue; + } - const auto override = curOverride != endOverride - ? **curOverride - : std::optional> (std::nullopt); - const auto target = (*curEffect)->target.has_value () - ? *(*curEffect)->target - : std::optional> (std::nullopt); + if (!(*curEffect)->source.has_value ()) { + sLog.error ("Pass without material and source not supported"); + continue; + } - this->m_passes.push_back ( - new CPass ( - *this, fboProvider, **curPass, override, (*curEffect)->binds, target) - ); + if (!(*curEffect)->target.has_value ()) { + sLog.error ("Pass without material and target not supported"); + continue; + } - if (curOverride != endOverride) { - curOverride ++; + if ((*curEffect)->command != Command_Copy) { + sLog.error ("Only copy command is supported for pass without material"); + continue; + } + + const auto virtualPass = MaterialPass { + .blending = "normal", + .cullmode = "nocull", + .depthtest = "disabled", + .depthwrite = "disabled", + .shader = "commands/copy", + .textures = { + {0, *(*curEffect)->source} + }, + .combos = {} + }; + + const auto& config = this->m_virtualPassess.emplace_back (virtualPass); + + // build a pass for a copy shader + this->m_passes.push_back ( + new CPass (*this, fboProvider, config, std::nullopt, std::nullopt, (*curEffect)->target.value ()) + ); + } else { + auto curPass = (*curEffect)->material.value ()->passes.begin (); + auto endPass = (*curEffect)->material.value ()->passes.end (); + + const auto override = + curOverride != endOverride + ? **curOverride + : std::optional> (std::nullopt); + const auto target = (*curEffect)->target.has_value () + ? *(*curEffect)->target + : std::optional> (std::nullopt); + + this->m_passes.push_back ( + new CPass (*this, fboProvider, **curPass, override, (*curEffect)->binds, target)); + + if (curOverride != endOverride) { + curOverride++; + } } } } diff --git a/src/WallpaperEngine/Render/Objects/CImage.h b/src/WallpaperEngine/Render/Objects/CImage.h index 877a8bb..39a5c18 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.h +++ b/src/WallpaperEngine/Render/Objects/CImage.h @@ -85,6 +85,7 @@ class CImage final : public CObject, public CFBOProvider { Effects::CMaterial* m_material = nullptr; Effects::CMaterial* m_colorBlendMaterial = nullptr; std::vector m_passes = {}; + std::vector m_virtualPassess = {}; glm::vec4 m_pos = {}; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index b367381..a5443da 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -349,7 +349,7 @@ const MaterialPass& CPass::getPass () const { return this->m_pass; } -const std::optional> CPass::getTarget () const { +std::optional> CPass::getTarget () const { return this->m_target; } diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.h b/src/WallpaperEngine/Render/Objects/Effects/CPass.h index 28c6a4e..553617c 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.h @@ -45,7 +45,7 @@ class CPass final : public Helpers::CContextAware { [[nodiscard]] std::shared_ptr getFBOProvider () const; [[nodiscard]] const CImage& getImage () const; [[nodiscard]] const MaterialPass& getPass () const; - [[nodiscard]] const std::optional> getTarget () const; + [[nodiscard]] std::optional> getTarget () const; [[nodiscard]] Render::Shaders::CShader* getShader () const; private: