| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- #include "CEffect.h"
- #include <utility>
- #include <iostream>
- #include "WallpaperEngine/Core/CScene.h"
- #include "WallpaperEngine/Core/CProject.h"
- #include "WallpaperEngine/Core/Objects/CImage.h"
- #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
- #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h"
- #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h"
- #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h"
- #include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
- #include "WallpaperEngine/FileSystem/FileSystem.h"
- using namespace WallpaperEngine;
- using namespace WallpaperEngine::Core::Objects;
- using namespace WallpaperEngine::Core::UserSettings;
- CEffect::CEffect (
- std::string name,
- std::string description,
- std::string group,
- std::string preview,
- Core::CObject* object,
- CUserSettingBoolean* visible):
- m_name (std::move(name)),
- m_description (std::move(description)),
- m_group (std::move(group)),
- m_preview (std::move(preview)),
- m_object (object),
- m_visible (visible)
- {
- }
- CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, const CContainer* container)
- {
- auto file_it = jsonFindRequired (data, "file", "Object effect must have a file");
- auto effectpasses_it = data.find ("passes");
- json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*file_it).get <std::string> (), container));
- auto name_it = jsonFindRequired (content, "name", "Effect must have a name");
- auto description = jsonFindDefault <std::string> (content, "description", "");
- auto group_it = jsonFindRequired (content, "group", "Effect must have a group");
- auto preview = jsonFindDefault <std::string> (content, "preview", "");
- auto passes_it = jsonFindRequired (content, "passes", "Effect must have a pass list");
- auto dependencies_it = jsonFindRequired (content, "dependencies", "");
- auto fbos_it = content.find ("fbos");
- CEffect* effect = new CEffect (
- *name_it,
- description,
- *group_it,
- preview,
- object,
- visible
- );
- CEffect::materialsFromJSON (passes_it, effect, container);
- CEffect::dependencyFromJSON (dependencies_it, effect);
- if (fbos_it != content.end ())
- {
- CEffect::fbosFromJSON (fbos_it, effect);
- }
- if (effectpasses_it != data.end ())
- {
- auto cur = (*effectpasses_it).begin ();
- auto end = (*effectpasses_it).end ();
- for (int passNumber = 0; cur != end; cur ++, passNumber ++)
- {
- auto constants_it = (*cur).find ("constantshadervalues");
- auto combos_it = (*cur).find ("combos");
- auto textures_it = (*cur).find ("textures");
- if (constants_it == (*cur).end () && combos_it == (*cur).end () && textures_it == (*cur).end ())
- continue;
- Images::CMaterial* material = effect->getMaterials ().at (passNumber);
- auto passCur = material->getPasses ().begin ();
- auto passEnd = material->getPasses ().end ();
- for (; passCur != passEnd; passCur ++)
- {
- if (textures_it != (*cur).end ())
- {
- auto texturesCur = (*textures_it).begin ();
- auto texturesEnd = (*textures_it).end ();
- for (int textureNumber = 0; texturesCur != texturesEnd; texturesCur ++)
- {
- std::string texture;
- if ((*texturesCur).is_null () == true)
- {
- if (textureNumber == 0)
- {
- CImage* image = object->as <CImage> ();
- texture = (*(*image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ());
- }
- else
- {
- texture = "";
- }
- }
- else
- {
- texture = *texturesCur;
- }
- std::vector<std::string> passTextures = (*passCur)->getTextures ();
- if (textureNumber < passTextures.size ())
- (*passCur)->setTexture (textureNumber, texture);
- else
- (*passCur)->insertTexture (texture);
- textureNumber ++;
- }
- }
- if (combos_it != (*cur).end ())
- {
- CEffect::combosFromJSON (combos_it, *passCur);
- }
- if (constants_it != (*cur).end ())
- {
- CEffect::constantsFromJSON (constants_it, *passCur);
- }
- }
- }
- }
- return effect;
- }
- void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass)
- {
- auto cur = (*combos_it).begin ();
- auto end = (*combos_it).end ();
- for (; cur != end; cur ++)
- {
- pass->insertCombo (cur.key (), *cur);
- }
- }
- void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass)
- {
- auto cur = (*constants_it).begin ();
- auto end = (*constants_it).end ();
- for (; cur != end; cur ++)
- {
- json::const_iterator val = cur;
- Effects::Constants::CShaderConstant* constant = nullptr;
- // if the constant is an object, that means the constant has some extra information
- // for the UI, take the value, which is what we need
- if ((*cur).is_object () == true)
- {
- val = (*cur).find ("value");
- if (val == (*cur).end ())
- {
- std::cerr << "Found object for shader constant without \"value\" member" << std::endl;
- continue;
- }
- }
- if ((*val).is_number_float () == true)
- {
- constant = new Effects::Constants::CShaderConstantFloat ((*val).get <float> ());
- }
- else if ((*val).is_number_integer () == true)
- {
- constant = new Effects::Constants::CShaderConstantInteger ((*val).get <int> ());
- }
- else if ((*val).is_string () == true)
- {
- // try a vector 4 first, then a vector3 and then a vector 2
- constant = new Effects::Constants::CShaderConstantVector4 (WallpaperEngine::Core::aToVector4 (*val));
- }
- else
- {
- throw std::runtime_error ("unknown shader constant type");
- }
- pass->insertConstant (cur.key (), constant);
- }
- }
- void CEffect::fbosFromJSON (json::const_iterator fbos_it, CEffect* effect)
- {
- auto cur = (*fbos_it).begin ();
- auto end = (*fbos_it).end ();
- for (; cur != end; cur ++)
- {
- effect->insertFBO (
- Effects::CFBO::fromJSON (*cur)
- );
- }
- }
- void CEffect::dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect)
- {
- auto cur = (*dependencies_it).begin ();
- auto end = (*dependencies_it).end ();
- for (; cur != end; cur ++)
- {
- effect->insertDependency (*cur);
- }
- }
- void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, const CContainer* container)
- {
- auto cur = (*passes_it).begin ();
- auto end = (*passes_it).end ();
- for (; cur != end; cur ++)
- {
- auto materialfile = (*cur).find ("material");
- auto target = (*cur).find ("target");
- auto bind = (*cur).find ("bind");
- if (materialfile == (*cur).end ())
- {
- throw std::runtime_error ("Effect pass must have a material file");
- }
- Images::CMaterial* material = nullptr;
- if (target == (*cur).end ())
- {
- material = Images::CMaterial::fromFile ((*materialfile).get <std::string> (), container);
- }
- else
- {
- material = Images::CMaterial::fromFile ((*materialfile).get <std::string> (), *target, container);
- }
- if (bind != (*cur).end ())
- {
- auto bindCur = (*bind).begin ();
- auto bindEnd = (*bind).end ();
- for (; bindCur != bindEnd; bindCur ++)
- {
- material->insertTextureBind (
- Effects::CBind::fromJSON (*bindCur)
- );
- }
- }
- effect->insertMaterial (material);
- }
- }
- const std::vector<std::string>& CEffect::getDependencies () const
- {
- return this->m_dependencies;
- }
- const std::vector<Images::CMaterial*>& CEffect::getMaterials () const
- {
- return this->m_materials;
- }
- const std::vector<Effects::CFBO*>& CEffect::getFbos () const
- {
- return this->m_fbos;
- }
- bool CEffect::isVisible () const
- {
- return this->m_visible->processValue (this->m_object->getScene ()->getProject ()->getProperties ());
- }
- Effects::CFBO* CEffect::findFBO (const std::string& name)
- {
- auto cur = this->m_fbos.begin ();
- auto end = this->m_fbos.end ();
- for (; cur != end; cur ++)
- {
- if ((*cur)->getName () == name)
- {
- return (*cur);
- }
- }
- throw std::runtime_error ("cannot find fbo named " + name);
- }
- void CEffect::insertDependency (const std::string& dep)
- {
- this->m_dependencies.push_back (dep);
- }
- void CEffect::insertMaterial (Images::CMaterial* material)
- {
- this->m_materials.push_back (material);
- }
- void CEffect::insertFBO (Effects::CFBO* fbo)
- {
- this->m_fbos.push_back (fbo);
- }
|