CEffect.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include "CEffect.h"
  2. #include <utility>
  3. #include "WallpaperEngine/Core/Objects/CImage.h"
  4. #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
  5. #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h"
  6. #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h"
  7. #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h"
  8. #include "WallpaperEngine/FileSystem/FileSystem.h"
  9. using namespace WallpaperEngine;
  10. using namespace WallpaperEngine::Core::Objects;
  11. CEffect::CEffect (
  12. std::string name,
  13. std::string description,
  14. std::string group,
  15. std::string preview,
  16. Core::CObject* object):
  17. m_name (std::move(name)),
  18. m_description (std::move(description)),
  19. m_group (std::move(group)),
  20. m_preview (std::move(preview)),
  21. m_object (object)
  22. {
  23. }
  24. CEffect* CEffect::fromJSON (json data, Core::CObject* object, CContainer* container)
  25. {
  26. auto file_it = jsonFindRequired (data, "file", "Object effect must have a file");
  27. auto effectpasses_it = data.find ("passes");
  28. json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*file_it).get <std::string> (), container));
  29. auto name_it = jsonFindRequired (content, "name", "Effect must have a name");
  30. auto description_it = jsonFindRequired (content, "description", "Effect must have a description");
  31. auto group_it = jsonFindRequired (content, "group", "Effect must have a group");
  32. auto preview_it = jsonFindRequired (content, "preview", "Effect must have a preview");
  33. auto passes_it = jsonFindRequired (content, "passes", "Effect must have a pass list");
  34. auto dependencies_it = jsonFindRequired (content, "dependencies", "");
  35. auto fbos_it = content.find ("fbos");
  36. CEffect* effect = new CEffect (
  37. *name_it,
  38. *description_it,
  39. *group_it,
  40. *preview_it,
  41. object
  42. );
  43. CEffect::materialsFromJSON (passes_it, effect, container);
  44. CEffect::dependencyFromJSON (dependencies_it, effect);
  45. if (fbos_it != content.end ())
  46. {
  47. CEffect::fbosFromJSON (fbos_it, effect);
  48. }
  49. if (effectpasses_it != data.end ())
  50. {
  51. auto cur = (*effectpasses_it).begin ();
  52. auto end = (*effectpasses_it).end ();
  53. for (int passNumber = 0; cur != end; cur ++, passNumber ++)
  54. {
  55. auto constants_it = (*cur).find ("constantshadervalues");
  56. auto combos_it = (*cur).find ("combos");
  57. auto textures_it = (*cur).find ("textures");
  58. if (constants_it == (*cur).end () && combos_it == (*cur).end () && textures_it == (*cur).end ())
  59. continue;
  60. Images::CMaterial* material = effect->getMaterials ().at (passNumber);
  61. auto passCur = material->getPasses ().begin ();
  62. auto passEnd = material->getPasses ().end ();
  63. for (; passCur != passEnd; passCur ++)
  64. {
  65. if (textures_it != (*cur).end ())
  66. {
  67. auto texturesCur = (*textures_it).begin ();
  68. auto texturesEnd = (*textures_it).end ();
  69. for (int textureNumber = 0; texturesCur != texturesEnd; texturesCur ++)
  70. {
  71. std::string texture;
  72. if ((*texturesCur).is_null () == true)
  73. {
  74. if (object->is <CImage> () == false)
  75. {
  76. throw std::runtime_error ("unexpected null texture for non-image object");
  77. }
  78. CImage* image = object->as <CImage> ();
  79. texture = (*(*image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ());
  80. }
  81. else
  82. {
  83. texture = *texturesCur;
  84. }
  85. std::vector<std::string> passTextures = (*passCur)->getTextures ();
  86. if (textureNumber < passTextures.size ())
  87. (*passCur)->setTexture (textureNumber, texture);
  88. else
  89. (*passCur)->insertTexture (texture);
  90. textureNumber ++;
  91. }
  92. }
  93. if (combos_it != (*cur).end ())
  94. {
  95. CEffect::combosFromJSON (combos_it, *passCur);
  96. }
  97. if (constants_it != (*cur).end ())
  98. {
  99. CEffect::constantsFromJSON (constants_it, *passCur);
  100. }
  101. }
  102. }
  103. }
  104. return effect;
  105. }
  106. void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass)
  107. {
  108. auto cur = (*combos_it).begin ();
  109. auto end = (*combos_it).end ();
  110. for (; cur != end; cur ++)
  111. {
  112. pass->insertCombo (cur.key (), *cur);
  113. }
  114. }
  115. void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass)
  116. {
  117. auto cur = (*constants_it).begin ();
  118. auto end = (*constants_it).end ();
  119. for (; cur != end; cur ++)
  120. {
  121. Effects::Constants::CShaderConstant* constant = nullptr;
  122. if ((*cur).is_number_float () == true)
  123. {
  124. constant = new Effects::Constants::CShaderConstantFloat ((*cur).get <float> ());
  125. }
  126. else if ((*cur).is_number_integer () == true)
  127. {
  128. constant = new Effects::Constants::CShaderConstantInteger ((*cur).get <irr::s32> ());
  129. }
  130. else if ((*cur).is_string () == true)
  131. {
  132. constant = new Effects::Constants::CShaderConstantVector3 (WallpaperEngine::Core::aToVector3 (*cur));
  133. }
  134. else
  135. {
  136. throw std::runtime_error ("unknown shader constant type");
  137. }
  138. pass->insertConstant (cur.key (), constant);
  139. }
  140. }
  141. void CEffect::fbosFromJSON (json::const_iterator fbos_it, CEffect* effect)
  142. {
  143. auto cur = (*fbos_it).begin ();
  144. auto end = (*fbos_it).end ();
  145. for (; cur != end; cur ++)
  146. {
  147. effect->insertFBO (
  148. Effects::CFBO::fromJSON (*cur)
  149. );
  150. }
  151. }
  152. void CEffect::dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect)
  153. {
  154. auto cur = (*dependencies_it).begin ();
  155. auto end = (*dependencies_it).end ();
  156. for (; cur != end; cur ++)
  157. {
  158. effect->insertDependency (*cur);
  159. }
  160. }
  161. void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container)
  162. {
  163. auto cur = (*passes_it).begin ();
  164. auto end = (*passes_it).end ();
  165. for (; cur != end; cur ++)
  166. {
  167. auto materialfile = (*cur).find ("material");
  168. auto target = (*cur).find ("target");
  169. auto bind = (*cur).find ("bind");
  170. if (materialfile == (*cur).end ())
  171. {
  172. throw std::runtime_error ("Effect pass must have a material file");
  173. }
  174. Images::CMaterial* material = nullptr;
  175. if (target == (*cur).end ())
  176. {
  177. material = Images::CMaterial::fromFile ((*materialfile).get <std::string> (), container);
  178. }
  179. else
  180. {
  181. material = Images::CMaterial::fromFile ((*materialfile).get <std::string> (), *target, container);
  182. }
  183. if (bind != (*cur).end ())
  184. {
  185. auto bindCur = (*bind).begin ();
  186. auto bindEnd = (*bind).end ();
  187. for (; bindCur != bindEnd; bindCur ++)
  188. {
  189. material->insertTextureBind (
  190. Effects::CBind::fromJSON (*bindCur)
  191. );
  192. }
  193. }
  194. effect->insertMaterial (material);
  195. }
  196. }
  197. const std::vector<std::string>& CEffect::getDependencies () const
  198. {
  199. return this->m_dependencies;
  200. }
  201. const std::vector<Images::CMaterial*>& CEffect::getMaterials () const
  202. {
  203. return this->m_materials;
  204. }
  205. const std::vector<Effects::CFBO*>& CEffect::getFbos () const
  206. {
  207. return this->m_fbos;
  208. }
  209. Effects::CFBO* CEffect::findFBO (const std::string& name)
  210. {
  211. auto cur = this->m_fbos.begin ();
  212. auto end = this->m_fbos.end ();
  213. for (; cur != end; cur ++)
  214. {
  215. if ((*cur)->getName () == name)
  216. {
  217. return (*cur);
  218. }
  219. }
  220. throw std::runtime_error ("cannot find fbo named " + name);
  221. }
  222. void CEffect::insertDependency (const std::string& dep)
  223. {
  224. this->m_dependencies.push_back (dep);
  225. }
  226. void CEffect::insertMaterial (Images::CMaterial* material)
  227. {
  228. this->m_materials.push_back (material);
  229. }
  230. void CEffect::insertFBO (Effects::CFBO* fbo)
  231. {
  232. this->m_fbos.push_back (fbo);
  233. }