mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-16 14:22:24 +08:00
feat: added material command copy support
This commit is contained in:
parent
d648964ae2
commit
58f6a5c2e5
@ -187,6 +187,25 @@ void CWallpaperApplication::setupContainer (CCombinedContainer& container, const
|
||||
)}}
|
||||
);
|
||||
|
||||
virtualContainer->add(
|
||||
"shaders/commands/copy.frag",
|
||||
"uniform sampler2D g_Texture0;\n"
|
||||
"in vec2 v_TexCoord;\n"
|
||||
"void main () {\n"
|
||||
"out_FragColor = texture (g_Texture0, v_TexCoord);\n"
|
||||
"}"
|
||||
);
|
||||
virtualContainer->add(
|
||||
"shaders/commands/copy.vert",
|
||||
"in vec3 a_Position;\n"
|
||||
"in vec2 a_TexCoord;\n"
|
||||
"out vec2 v_TexCoord;\n"
|
||||
"void main () {\n"
|
||||
"gl_Position = vec4 (a_Position, 1.0);\n"
|
||||
"v_TexCoord = a_TexCoord;\n"
|
||||
"}"
|
||||
);
|
||||
|
||||
container.add (virtualContainer);
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,10 @@ void CVirtualContainer::add (const std::filesystem::path& filename, const std::s
|
||||
this->add (filename, copy, contents.length () + 1);
|
||||
}
|
||||
|
||||
void CVirtualContainer::add (const std::filesystem::path& filename, const char* contents) {
|
||||
this->add (filename, std::string (contents));
|
||||
}
|
||||
|
||||
void CVirtualContainer::add (const std::filesystem::path& filename, const json& contents) {
|
||||
this->add (filename, contents.dump ());
|
||||
}
|
||||
|
@ -31,6 +31,14 @@ class CVirtualContainer final : public CContainer {
|
||||
* @param contents
|
||||
*/
|
||||
void add (const std::filesystem::path& filename, const std::string& contents);
|
||||
|
||||
/**
|
||||
* Adds a new file to the virtual container
|
||||
*
|
||||
* @param filename
|
||||
* @param contents
|
||||
*/
|
||||
void add (const std::filesystem::path& filename, const char* contents);
|
||||
/**
|
||||
* Adds a new file to the virtual container from a json object
|
||||
* @param filename
|
||||
|
@ -187,12 +187,17 @@ std::vector<const Images::CMaterial*> CEffect::materialsFromJSON (
|
||||
for (const auto& cur : (*passes_it)) {
|
||||
++materialNumber;
|
||||
const auto materialfile = cur.find ("material");
|
||||
const auto target = cur.find ("target");
|
||||
const auto target_it = cur.find ("target");
|
||||
const auto bind_it = cur.find ("bind");
|
||||
const auto command_it = cur.find ("command");
|
||||
const auto compose_it = cur.find ("compose");
|
||||
const Images::CMaterial* material;
|
||||
|
||||
if (materialfile == cur.end ())
|
||||
sLog.exception ("Found an effect ", name, " without material");
|
||||
if (compose_it != cur.end ()) {
|
||||
sLog.error ("Composing materials is not supported yet...");
|
||||
}
|
||||
|
||||
if (materialfile != cur.end ()) {
|
||||
std::map<int, const Effects::CBind*> textureBindings;
|
||||
|
||||
if (bind_it != cur.end ()) {
|
||||
@ -202,7 +207,6 @@ std::vector<const Images::CMaterial*> CEffect::materialsFromJSON (
|
||||
}
|
||||
}
|
||||
|
||||
const Images::CMaterial* material;
|
||||
const Images::CMaterial::OverrideInfo* overrideInfo;
|
||||
const auto overrideIt = overrides.find (materialNumber);
|
||||
|
||||
@ -210,10 +214,18 @@ std::vector<const Images::CMaterial*> CEffect::materialsFromJSON (
|
||||
overrideInfo = &overrideIt->second;
|
||||
}
|
||||
|
||||
if (target == cur.end ())
|
||||
material = Images::CMaterial::fromFile (materialfile->get<std::string> (), container, textureBindings, overrideInfo);
|
||||
else
|
||||
material = Images::CMaterial::fromFile (materialfile->get<std::string> (), *target, container, textureBindings, overrideInfo);
|
||||
if (target_it == cur.end ()) {
|
||||
material = Images::CMaterial::fromFile (
|
||||
materialfile->get<std::string> (), container, false, textureBindings, overrideInfo);
|
||||
} else {
|
||||
material = Images::CMaterial::fromFile (
|
||||
materialfile->get<std::string> (), *target_it, container, false, textureBindings, overrideInfo);
|
||||
}
|
||||
} else if (command_it != cur.end ()) {
|
||||
material = Images::CMaterial::fromCommand (cur);
|
||||
} else {
|
||||
sLog.exception ("Material without command nor material file: ", name, " (", materialNumber,")");
|
||||
}
|
||||
|
||||
materials.push_back (material);
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ const WallpaperEngine::Core::CObject* CImage::fromJSON (
|
||||
|
||||
const auto material = Images::CMaterial::fromFile (
|
||||
jsonFindRequired<std::string> (content, "material", "Image must have a material"),
|
||||
container
|
||||
container,
|
||||
jsonFindDefault (content, "solidlayer", false)
|
||||
);
|
||||
|
||||
if (effects_it != data.end () && effects_it->is_array ()) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "CMaterial.h"
|
||||
|
||||
#include "WallpaperEngine/Core/Objects/Images/Materials/CPass.h"
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <utility>
|
||||
|
||||
@ -10,37 +11,39 @@ using namespace WallpaperEngine::Core::Objects;
|
||||
using namespace WallpaperEngine::Core::Objects::Images;
|
||||
|
||||
CMaterial::CMaterial (
|
||||
std::string name, std::map<int, const Effects::CBind*> textureBindings,
|
||||
std::string name, bool solidlayer, std::map<int, const Effects::CBind*> textureBindings,
|
||||
std::vector<const Materials::CPass*> passes
|
||||
) :
|
||||
m_name (std::move(name)),
|
||||
m_textureBindings (std::move(textureBindings)),
|
||||
m_passes (std::move(passes)) {}
|
||||
m_passes (std::move(passes)),
|
||||
m_solidlayer (solidlayer) {}
|
||||
CMaterial::CMaterial (
|
||||
std::string name, std::string target,
|
||||
std::string name, std::string target, bool solidlayer,
|
||||
std::map<int, const Effects::CBind*> textureBindings, std::vector<const Materials::CPass*> passes
|
||||
) :
|
||||
m_name (std::move(name)),
|
||||
m_target (std::move(target)),
|
||||
m_textureBindings (std::move(textureBindings)),
|
||||
m_passes (std::move(passes)) {}
|
||||
m_passes (std::move(passes)),
|
||||
m_solidlayer (solidlayer) {}
|
||||
|
||||
const CMaterial* CMaterial::fromFile (
|
||||
const std::filesystem::path& filename, const CContainer* container,
|
||||
const std::filesystem::path& filename, const CContainer* container, bool solidlayer,
|
||||
std::map<int, const Effects::CBind*> textureBindings, const OverrideInfo* overrides
|
||||
) {
|
||||
return fromJSON (filename, json::parse (container->readFileAsString (filename)), std::move(textureBindings), overrides);
|
||||
return fromJSON (filename, json::parse (container->readFileAsString (filename)), solidlayer, std::move(textureBindings), overrides);
|
||||
}
|
||||
|
||||
const CMaterial* CMaterial::fromFile (
|
||||
const std::filesystem::path& filename, const std::string& target,
|
||||
const CContainer* container, std::map<int, const Effects::CBind*> textureBindings, const OverrideInfo* overrides
|
||||
const std::filesystem::path& filename, const std::string& target, const CContainer* container, bool solidlayer,
|
||||
std::map<int, const Effects::CBind*> textureBindings, const OverrideInfo* overrides
|
||||
) {
|
||||
return fromJSON (filename, json::parse (container->readFileAsString (filename)), target, std::move(textureBindings), overrides);
|
||||
return fromJSON (filename, json::parse (container->readFileAsString (filename)), target, solidlayer, std::move(textureBindings), overrides);
|
||||
}
|
||||
|
||||
const CMaterial* CMaterial::fromJSON (
|
||||
const std::string& name, const json& data, const std::string& target,
|
||||
const std::string& name, const json& data, const std::string& target, bool solidlayer,
|
||||
std::map<int, const Effects::CBind*> textureBindings, const OverrideInfo* overrides
|
||||
) {
|
||||
const auto passes_it = jsonFindRequired (data, "passes", "Material must have at least one pass");
|
||||
@ -49,11 +52,11 @@ const CMaterial* CMaterial::fromJSON (
|
||||
for (const auto& cur : (*passes_it))
|
||||
passes.push_back (Materials::CPass::fromJSON (cur, overrides));
|
||||
|
||||
return new CMaterial (name, target, std::move(textureBindings), passes);
|
||||
return new CMaterial (name, target, solidlayer, std::move(textureBindings), passes);
|
||||
}
|
||||
|
||||
const CMaterial* CMaterial::fromJSON (
|
||||
const std::string& name, const json& data, std::map<int, const Effects::CBind*> textureBindings,
|
||||
const std::string& name, const json& data, bool solidlayer, std::map<int, const Effects::CBind*> textureBindings,
|
||||
const OverrideInfo* overrides
|
||||
) {
|
||||
const auto passes_it = jsonFindRequired (data, "passes", "Material must have at least one pass");
|
||||
@ -62,7 +65,34 @@ const CMaterial* CMaterial::fromJSON (
|
||||
for (const auto& cur : (*passes_it))
|
||||
passes.push_back (Materials::CPass::fromJSON (cur, overrides));
|
||||
|
||||
return new CMaterial (name, std::move(textureBindings), passes);
|
||||
return new CMaterial (name, solidlayer, std::move(textureBindings), passes);
|
||||
}
|
||||
|
||||
const CMaterial* CMaterial::fromCommand (const json& data) {
|
||||
const std::string& command = jsonFindRequired <std::string> (data, "command", "Command material must have a command");
|
||||
const std::string& target = jsonFindRequired <std::string> (data, "target", "Command material must have a target");
|
||||
const std::string& source = jsonFindRequired <std::string> (data, "source", "Command material must have a source");
|
||||
std::vector<const Materials::CPass*> passes;
|
||||
|
||||
if (command == "copy") {
|
||||
passes.push_back (
|
||||
Materials::CPass::fromJSON ({
|
||||
{"blending", "normal"},
|
||||
{"cullmode", "nocull"},
|
||||
{"depthtest", "disabled"},
|
||||
{"depthwrite", "disabled"},
|
||||
{"shader", "commands/copy"},
|
||||
{"textures", json::array ({source, target})}
|
||||
}, nullptr)
|
||||
);
|
||||
} else if (command == "swap") {
|
||||
// TODO: HOW TO IMPLEMENT THIS ONE?
|
||||
sLog.exception ("Command material swap not implemented yet");
|
||||
} else {
|
||||
sLog.exception ("Unknown command: ", command);
|
||||
}
|
||||
|
||||
return new CMaterial (command, false, {}, passes);
|
||||
}
|
||||
|
||||
const std::vector<const Materials::CPass*>& CMaterial::getPasses () const {
|
||||
@ -84,3 +114,7 @@ const std::string& CMaterial::getName () const {
|
||||
bool CMaterial::hasTarget () const {
|
||||
return !this->m_target.empty ();
|
||||
}
|
||||
|
||||
bool CMaterial::isSolidLayer () const {
|
||||
return this->m_solidlayer;
|
||||
}
|
@ -26,18 +26,20 @@ class CMaterial {
|
||||
};
|
||||
|
||||
static const CMaterial* fromFile (
|
||||
const std::filesystem::path& filename, const Assets::CContainer* container,
|
||||
const std::filesystem::path& filename, const Assets::CContainer* container, bool solidlayer = false,
|
||||
std::map<int, const Effects::CBind*> textureBindings = {}, const OverrideInfo* overrides = nullptr);
|
||||
static const CMaterial* fromFile (
|
||||
const std::filesystem::path& filename, const std::string& target,
|
||||
const Assets::CContainer* container, std::map<int, const Effects::CBind*> textureBindings = {},
|
||||
const std::filesystem::path& filename, const std::string& target, const Assets::CContainer* container,
|
||||
bool solidlayer = false, std::map<int, const Effects::CBind*> textureBindings = {},
|
||||
const OverrideInfo* overrides = nullptr);
|
||||
static const CMaterial* fromJSON (
|
||||
const std::string& name, const json& data,
|
||||
const std::string& name, const json& data, bool solidlayer = false,
|
||||
std::map<int, const Effects::CBind*> textureBindings = {}, const OverrideInfo* overrides = nullptr);
|
||||
static const CMaterial* fromJSON (
|
||||
const std::string& name, const json& data, const std::string& target,
|
||||
const std::string& name, const json& data, const std::string& target, bool solidlayer = false,
|
||||
std::map<int, const Effects::CBind*> textureBindings = {}, const OverrideInfo* overrides = nullptr);
|
||||
static const CMaterial* fromCommand (const json& data);
|
||||
|
||||
/**
|
||||
* @return All the rendering passes that happen for this material
|
||||
*/
|
||||
@ -59,13 +61,17 @@ class CMaterial {
|
||||
* @return The name of the material
|
||||
*/
|
||||
[[nodiscard]] const std::string& getName () const;
|
||||
/**
|
||||
* @return If this material is a solidlayer or not
|
||||
*/
|
||||
[[nodiscard]] bool isSolidLayer () const;
|
||||
|
||||
protected:
|
||||
CMaterial (
|
||||
std::string name, std::map<int, const Effects::CBind*> textureBindings,
|
||||
std::string name, bool solidlayer, std::map<int, const Effects::CBind*> textureBindings,
|
||||
std::vector<const Materials::CPass*> passes);
|
||||
CMaterial (
|
||||
std::string name, std::string target, std::map<int, const Effects::CBind*> textureBindings,
|
||||
std::string name, std::string target, bool solidlayer, std::map<int, const Effects::CBind*> textureBindings,
|
||||
std::vector<const Materials::CPass*> passes);
|
||||
|
||||
private:
|
||||
@ -77,5 +83,7 @@ class CMaterial {
|
||||
const std::string m_target;
|
||||
/** The material's name */
|
||||
const std::string m_name;
|
||||
/** If this material is a solid layer or not */
|
||||
const bool m_solidlayer;
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Images
|
||||
|
@ -88,9 +88,16 @@ CImage::CImage (Wallpapers::CScene* scene, const Core::Objects::CImage* image) :
|
||||
this->m_texture = this->getContext ().resolveTexture (textureName);
|
||||
}
|
||||
} else {
|
||||
if (this->m_image->getMaterial ()->isSolidLayer()) {
|
||||
size.x = scene_width;
|
||||
size.y = scene_height;
|
||||
}
|
||||
// if (this->m_image->isSolid ()) // layer receives cursor events: https://docs.wallpaperengine.io/en/scene/scenescript/reference/event/cursor.html
|
||||
// same applies to effects
|
||||
// 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, size.x,
|
||||
this->m_texture = new CFBO (
|
||||
"", ITexture::TextureFormat::ARGB8888, ITexture::TextureFlags::NoFlags, 1, size.x,
|
||||
size.y, size.x, size.y);
|
||||
}
|
||||
|
||||
@ -258,7 +265,7 @@ void CImage::setup () {
|
||||
|
||||
overrides.combos.insert (std::pair ("BLENDMODE", this->m_image->getColorBlendMode ()));
|
||||
const auto material =
|
||||
Core::Objects::Images::CMaterial::fromFile ("materials/util/effectpassthrough.json", this->getContainer (), {}, &overrides);
|
||||
Core::Objects::Images::CMaterial::fromFile ("materials/util/effectpassthrough.json", this->getContainer (), false, {}, &overrides);
|
||||
|
||||
// generate the main material used to render the image
|
||||
this->m_colorBlendMaterial = new Effects::CMaterial (
|
||||
|
Loading…
Reference in New Issue
Block a user