effect.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. #include <wallpaperengine/fs/utils.h>
  2. #include "shaders/compiler.h"
  3. #include "effect.h"
  4. #include "irrlicht.h"
  5. #include "core.h"
  6. extern irr::f32 g_Time;
  7. namespace wp
  8. {
  9. effect::effect (json json_data)
  10. {
  11. json::const_iterator file = json_data.find ("file");
  12. json::const_iterator pass = json_data.find ("passes");
  13. if (file != json_data.end () && (*file).is_string () == true)
  14. {
  15. this->m_file = (*file).get <std::string> ().c_str ();
  16. }
  17. // passes list is optional
  18. if (pass == json_data.end () || (*pass).is_array () == false)
  19. return;
  20. json::const_iterator curpass = (*pass).begin ();
  21. json::const_iterator endpass = (*pass).end ();
  22. if (curpass == endpass)
  23. return;
  24. json::const_iterator textures = (*curpass).find ("textures");
  25. json::const_iterator combos = (*curpass).find ("combos");
  26. if (textures == (*curpass).end () || (*textures).is_array () == false)
  27. return;
  28. if (combos != (*curpass).end ())
  29. this->parseCombos (*combos);
  30. json::const_iterator curtex = (*textures).begin ();
  31. json::const_iterator endtex = (*textures).end ();
  32. for (; curtex != endtex; curtex ++)
  33. {
  34. if ((*curtex).is_null () == true)
  35. {
  36. this->m_textures.push_back (nullptr);
  37. }
  38. else if ((*curtex).is_string () == true)
  39. {
  40. irr::io::path texturepath = ("materials/" + (*curtex).get <std::string> () + ".tex").c_str ();
  41. this->m_textures.push_back (new wp::texture (texturepath));
  42. }
  43. }
  44. this->m_content = wp::fs::utils::loadFullFile (this->m_file);
  45. this->m_json = json::parse (this->m_content);
  46. json::const_iterator passes = this->m_json.find ("passes");
  47. if (passes == this->m_json.end () || (*passes).is_array () == false)
  48. return;
  49. json::const_iterator curpassmaterial = (*passes).begin ();
  50. json::const_iterator endpassmaterial = (*passes).end ();
  51. for (; curpassmaterial != endpassmaterial; curpassmaterial ++)
  52. {
  53. json::const_iterator material_it = (*curpassmaterial).find ("material");
  54. if (material_it == (*curpassmaterial).end () || (*material_it).is_string () == false)
  55. continue;
  56. irr::io::path material = (*material_it).get <std::string> ().c_str ();
  57. std::string content = wp::fs::utils::loadFullFile (material);
  58. json material_json = json::parse (content);
  59. json::const_iterator shader_passes = material_json.find ("passes");
  60. if (shader_passes == material_json.end () || (*shader_passes).is_array () == false)
  61. continue;
  62. json::const_iterator shaderpasscur = (*shader_passes).begin ();
  63. json::const_iterator shader = (*shaderpasscur).find ("shader");
  64. if (shader == (*shaderpasscur).end () || (*shader).is_string () == false)
  65. continue;
  66. irr::io::path shaderpath = ("shaders/" + (*shader).get <std::string> ()).c_str ();
  67. irr::io::path fragpath = shaderpath + ".frag";
  68. irr::io::path vertpath = shaderpath + ".vert";
  69. this->m_fragShader = new wp::shaders::compiler (fragpath, wp::shaders::compiler::Type::Type_Pixel, &this->m_combos, false);
  70. this->m_vertShader = new wp::shaders::compiler (vertpath, wp::shaders::compiler::Type::Type_Vertex, &this->m_combos, false);
  71. this->m_materialType = wp::irrlicht::driver->getGPUProgrammingServices ()
  72. ->addHighLevelShaderMaterial (
  73. this->m_vertShader->precompile ().c_str (), "main", irr::video::EVST_VS_2_0,
  74. this->m_fragShader->precompile ().c_str (), "main", irr::video::EPST_PS_2_0,
  75. this, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0, irr::video::EGSL_DEFAULT
  76. );
  77. }
  78. json::const_iterator constantvalues = (*curpass).find ("constantshadervalues");
  79. if (constantvalues != (*curpass).end () && (*constantvalues).is_object () == true)
  80. this->parseConstantValues ((*constantvalues));
  81. // last step is creating the actual variables for the shaders
  82. std::vector <shaders::compiler::ShaderParameter*>::const_iterator cur;
  83. std::vector <shaders::compiler::ShaderParameter*>::const_iterator end;
  84. cur = this->m_fragShader->getParameters ().begin ();
  85. end = this->m_fragShader->getParameters ().end ();
  86. // first do fragment shaders
  87. for (; cur != end; cur ++)
  88. {
  89. wp::shaders::compiler::ShaderParameter* param = (*cur);
  90. ShaderParameter* parameter = new ShaderParameter;
  91. void* defaultValue = param->defaultValue;
  92. std::map<std::string,void*>::const_iterator constant = this->m_constants.find (param->identifierName);
  93. if (constant != this->m_constants.end ())
  94. defaultValue = (*constant).second;
  95. parameter->value = nullptr;
  96. if (param->type == "vec4")
  97. {
  98. irr::core::vector3df* vec = (irr::core::vector3df*) defaultValue;
  99. irr::f32* val = new irr::f32 [4];
  100. val [0] = vec->X;
  101. val [1] = vec->Y;
  102. val [2] = vec->Z;
  103. val [3] = 0.0f;
  104. parameter->value = val;
  105. parameter->type = ParameterType::TYPE_VEC4;
  106. }
  107. else if (param->type == "vec3")
  108. {
  109. irr::core::vector3df* vec = (irr::core::vector3df*) defaultValue;
  110. irr::f32* val = new irr::f32 [3];
  111. val [0] = vec->X;
  112. val [1] = vec->Y;
  113. val [2] = vec->Z;
  114. parameter->value = val;
  115. parameter->type = ParameterType::TYPE_VEC3;
  116. }
  117. else if (param->type == "vec2")
  118. {
  119. irr::core::vector2df* vec = (irr::core::vector2df*) defaultValue;
  120. irr::f32* val = new irr::f32 [2];
  121. val [0] = vec->X;
  122. val [1] = vec->Y;
  123. parameter->value = val;
  124. parameter->type = ParameterType::TYPE_VEC2;
  125. }
  126. else if (param->type == "float")
  127. {
  128. irr::f32* org = (irr::f32*) defaultValue;
  129. irr::f32* val = new irr::f32;
  130. *val = *org;
  131. parameter->value = val;
  132. parameter->type = ParameterType::TYPE_FLOAT;
  133. }
  134. else if (param->type == "int")
  135. {
  136. irr::s32* org = (irr::s32*) defaultValue;
  137. irr::s32* val = new irr::s32;
  138. *val = *org;
  139. parameter->value = val;
  140. parameter->type = ParameterType::TYPE_INT;
  141. }
  142. else if (param->type == "sampler2D")
  143. {
  144. // sampler2D are textures from wallpaper engine
  145. // so these can be ignored as they are later on defined
  146. continue;
  147. }
  148. this->m_pixelVariables.insert (std::pair <std::string, ShaderParameter*> (param->variableName, parameter));
  149. }
  150. cur = this->m_vertShader->getParameters ().begin ();
  151. end = this->m_vertShader->getParameters ().end ();
  152. // second do vertex shaders
  153. for (;cur != end; cur ++)
  154. {
  155. wp::shaders::compiler::ShaderParameter* param = (*cur);
  156. if (param == nullptr)
  157. continue;
  158. void* defaultValue = param->defaultValue;
  159. std::map<std::string,void*>::const_iterator constant = this->m_constants.find (param->identifierName);
  160. if (constant != this->m_constants.end ())
  161. defaultValue = (*constant).second;
  162. ShaderParameter* parameter = new ShaderParameter;
  163. parameter->value = nullptr;
  164. if (param->type == "vec4")
  165. {
  166. irr::core::vector3df* vec = (irr::core::vector3df*) defaultValue;
  167. irr::f32* val = new irr::f32 [4];
  168. val [0] = vec->X;
  169. val [1] = vec->Y;
  170. val [2] = vec->Z;
  171. val [3] = 0.0f;
  172. parameter->value = val;
  173. parameter->type = ParameterType::TYPE_VEC4;
  174. }
  175. else if (param->type == "vec3")
  176. {
  177. irr::core::vector3df* vec = (irr::core::vector3df*) defaultValue;
  178. irr::f32* val = new irr::f32 [3];
  179. val [0] = vec->X;
  180. val [1] = vec->Y;
  181. val [2] = vec->Z;
  182. parameter->value = val;
  183. parameter->type = ParameterType::TYPE_VEC3;
  184. }
  185. else if (param->type == "vec2")
  186. {
  187. irr::core::vector2df* vec = (irr::core::vector2df*) defaultValue;
  188. irr::f32* val = new irr::f32 [2];
  189. val [0] = vec->X;
  190. val [1] = vec->Y;
  191. parameter->value = val;
  192. parameter->type = ParameterType::TYPE_VEC2;
  193. }
  194. else if (param->type == "float")
  195. {
  196. irr::f32* org = (irr::f32*) defaultValue;
  197. irr::f32* val = new irr::f32;
  198. *val = *org;
  199. parameter->value = val;
  200. parameter->type = ParameterType::TYPE_FLOAT;
  201. }
  202. else if (param->type == "int")
  203. {
  204. irr::s32* org = (irr::s32*) defaultValue;
  205. irr::s32* val = new irr::s32;
  206. *val = *org;
  207. parameter->value = val;
  208. parameter->type = ParameterType::TYPE_INT;
  209. }
  210. else if (param->type == "sampler2D")
  211. {
  212. // sampler2D are textures from wallpaper engine
  213. // so these can be ignored as they are later on defined
  214. continue;
  215. }
  216. this->m_vertexVariables.insert (std::pair <std::string, ShaderParameter*> (param->variableName, parameter));
  217. }
  218. }
  219. void effect::parseConstantValues (json data)
  220. {
  221. /*
  222. "ui_editor_properties_animation_speed" : 0.10000000149011612,
  223. "ui_editor_properties_ripple_scale" : 2.5,
  224. "ui_editor_properties_ripple_strength" : 0.070000000298023224
  225. */
  226. json::const_iterator cur = data.begin ();
  227. json::const_iterator end = data.end ();
  228. for (; cur != end; cur ++)
  229. {
  230. std::string name = cur.key ();
  231. void* value = nullptr;
  232. if ((*cur).is_number_float () == true)
  233. {
  234. value = new irr::f32;
  235. *(irr::f32*) value = (*cur).get <irr::f32> ();
  236. }
  237. else if ((*cur).is_number_integer () == true)
  238. {
  239. value = new irr::s32;
  240. *(irr::s32*) value = (*cur).get <irr::s32> ();
  241. }
  242. else if ((*cur).is_string () == true)
  243. {
  244. value = new irr::core::vector3df;
  245. *(irr::core::vector3df*) value = core::ato3vf ((*cur).get <std::string> ().c_str ());
  246. }
  247. this->m_constants.insert (std::pair <std::string, void*> (name, value));
  248. }
  249. }
  250. void effect::parseCombos (json data)
  251. {
  252. json::const_iterator cur = data.begin ();
  253. json::const_iterator end = data.end ();
  254. for (; cur != end; cur ++)
  255. {
  256. std::string name = cur.key ();
  257. if ((*cur).is_number_integer () == true)
  258. {
  259. this->m_combos.insert (std::pair <std::string, int> (name, (*cur).get <int> ()));
  260. }
  261. else
  262. {
  263. wp::irrlicht::device->getLogger ()->log ("Unknown type for combo value", name.c_str (), irr::ELL_ERROR);
  264. }
  265. }
  266. }
  267. std::vector<wp::texture*>& effect::getTextureList ()
  268. {
  269. return this->m_textures;
  270. }
  271. irr::s32 effect::getMaterialType ()
  272. {
  273. return this->m_materialType;
  274. }
  275. void effect::OnSetConstants (irr::video::IMaterialRendererServices* services, int32_t userData)
  276. {
  277. // TODO: IMPLEMENT PROPER SHADER CODE
  278. irr::f32 g_AnimationSpeed = 0.1f;
  279. irr::f32 g_Scale = 2.5f;
  280. irr::f32 g_ScrollSpeed = 0.0f;
  281. irr::f32 g_Direction = 0.0f;
  282. irr::f32 g_Strength = 0.07f;
  283. irr::f32 g_SpecularPower = 1.0f;
  284. irr::f32 g_SpecularStrength = 1.0f;
  285. irr::f32 g_SpecularColor [3] = {1.0f, 1.0f, 1.0f};
  286. irr::f32 g_Texture1Resolution [4] = {1.0f, 1.0f, 1.0f, 1.0f};
  287. irr::f32 g_Texture0 = 0;
  288. irr::f32 g_Texture1 = 1;
  289. irr::f32 g_Texture2 = 2;
  290. irr::video::IVideoDriver* driver = services->getVideoDriver ();
  291. irr::core::matrix4 worldViewProj;
  292. worldViewProj = driver->getTransform(irr::video::ETS_PROJECTION);
  293. worldViewProj *= driver->getTransform(irr::video::ETS_VIEW);
  294. worldViewProj *= driver->getTransform(irr::video::ETS_WORLD);
  295. /*
  296. THESE ARE THE VARIABLES AVAILABLE ON SHADERS
  297. uniform float g_Alpha;
  298. uniform vec3 g_Color;
  299. // Application time, starts with 0
  300. uniform float g_Time;
  301. // Maps 24 hrs to [0, 1]
  302. uniform float g_Daytime;
  303. uniform vec2 g_TexelSize;
  304. uniform vec2 g_TexelSizeHalf;
  305. uniform mat4 g_ModelMatrix;
  306. uniform mat4 g_ViewProjectionMatrix;
  307. uniform mat4 g_ModelViewProjectionMatrix;
  308. uniform mat4 g_ModelViewProjectionMatrixInverse;
  309. uniform vec3 g_EyePosition;
  310. uniform vec3 g_ViewUp;
  311. uniform vec3 g_ViewRight;
  312. // Samplers that map to the textures[] array in the material
  313. uniform sampler2D g_Texture0;
  314. uniform sampler2D g_Texture1;
  315. uniform sampler2D g_Texture2;
  316. uniform sampler2D g_Texture3;
  317. uniform sampler2D g_Texture4;
  318. uniform sampler2D g_Texture5;
  319. uniform sampler2D g_Texture6;
  320. uniform sampler2D g_Texture7;
  321. // For sprite sheets (GIFs)
  322. uniform vec4 g_Texture0Rotation;
  323. uniform vec4 g_Texture1Rotation;
  324. uniform vec4 g_Texture2Rotation;
  325. uniform vec4 g_Texture3Rotation;
  326. uniform vec4 g_Texture4Rotation;
  327. uniform vec4 g_Texture5Rotation;
  328. uniform vec4 g_Texture6Rotation;
  329. uniform vec4 g_Texture7Rotation;
  330. uniform vec2 g_Texture0Translation;
  331. uniform vec2 g_Texture1Translation;
  332. uniform vec2 g_Texture2Translation;
  333. uniform vec2 g_Texture3Translation;
  334. uniform vec2 g_Texture4Translation;
  335. uniform vec2 g_Texture5Translation;
  336. uniform vec2 g_Texture6Translation;
  337. uniform vec2 g_Texture7Translation;
  338. uniform vec4 g_LightsColorRadius[4]; // color in XYZ, radius in W
  339. uniform vec3 g_LightsPosition[4];
  340. uniform vec3 g_LightAmbientColor;
  341. uniform vec3 g_LightSkylightColor;
  342. // lower frequencies at lower indices
  343. uniform float g_AudioSpectrum16Left[16];
  344. uniform float g_AudioSpectrum16Right[16];
  345. uniform float g_AudioSpectrum32Left[32];
  346. uniform float g_AudioSpectrum32Right[32];
  347. uniform float g_AudioSpectrum64Left[64];
  348. uniform float g_AudioSpectrum64Right[64];
  349. // Normalized in UV space [0, 1]
  350. uniform vec2 g_PointerPosition;
  351. */
  352. services->setVertexShaderConstant ("g_Time", &g_Time, 1);
  353. services->setPixelShaderConstant ("g_Time", &g_Time, 1);
  354. std::map<std::string, ShaderParameter*>::const_iterator vertcur = this->m_vertexVariables.begin ();
  355. std::map<std::string, ShaderParameter*>::const_iterator vertend = this->m_vertexVariables.end ();
  356. for (; vertcur != vertend; vertcur ++)
  357. {
  358. switch ((*vertcur).second->type)
  359. {
  360. case ParameterType::TYPE_FLOAT:
  361. services->setVertexShaderConstant ((*vertcur).first.c_str (), (irr::f32*) (*vertcur).second->value, 1);
  362. break;
  363. case ParameterType::TYPE_VEC2:
  364. services->setVertexShaderConstant ((*vertcur).first.c_str (), (irr::f32*) (*vertcur).second->value, 2);
  365. break;
  366. case ParameterType::TYPE_VEC3:
  367. services->setVertexShaderConstant ((*vertcur).first.c_str (), (irr::f32*) (*vertcur).second->value, 3);
  368. break;
  369. case ParameterType::TYPE_VEC4:
  370. services->setVertexShaderConstant ((*vertcur).first.c_str (), (irr::f32*) (*vertcur).second->value, 4);
  371. break;
  372. case ParameterType::TYPE_INT:
  373. services->setVertexShaderConstant ((*vertcur).first.c_str (), (irr::s32*) (*vertcur).second->value, 1);
  374. break;
  375. }
  376. }
  377. std::map<std::string, ShaderParameter*>::const_iterator pixelcur = this->m_pixelVariables.begin ();
  378. std::map<std::string, ShaderParameter*>::const_iterator pixelend = this->m_pixelVariables.end ();
  379. for (; pixelcur != pixelend; pixelcur ++)
  380. {
  381. switch ((*pixelcur).second->type)
  382. {
  383. case ParameterType::TYPE_FLOAT:
  384. services->setPixelShaderConstant ((*pixelcur).first.c_str (), (irr::f32*) (*pixelcur).second->value, 1);
  385. break;
  386. case ParameterType::TYPE_VEC2:
  387. services->setPixelShaderConstant ((*pixelcur).first.c_str (), (irr::f32*) (*pixelcur).second->value, 2);
  388. break;
  389. case ParameterType::TYPE_VEC3:
  390. services->setPixelShaderConstant ((*pixelcur).first.c_str (), (irr::f32*) (*pixelcur).second->value, 3);
  391. break;
  392. case ParameterType::TYPE_VEC4:
  393. services->setPixelShaderConstant ((*pixelcur).first.c_str (), (irr::f32*) (*pixelcur).second->value, 4);
  394. break;
  395. case ParameterType::TYPE_INT:
  396. services->setPixelShaderConstant ((*pixelcur).first.c_str (), (irr::s32*) (*pixelcur).second->value, 1);
  397. break;
  398. }
  399. }
  400. /*services->setVertexShaderConstant ("g_AnimationSpeed", &g_AnimationSpeed, 1);
  401. services->setVertexShaderConstant ("g_Scale", &g_Scale, 1);
  402. services->setVertexShaderConstant ("g_ScrollSpeed", &g_ScrollSpeed, 1);
  403. services->setVertexShaderConstant ("g_Direction", &g_Direction, 1);*/
  404. services->setVertexShaderConstant ("g_ModelViewProjectionMatrix", worldViewProj.pointer(), 16);
  405. services->setVertexShaderConstant ("g_Texture0Resolution", g_Texture1Resolution, 4);
  406. services->setVertexShaderConstant ("g_Texture1Resolution", g_Texture1Resolution, 4);
  407. services->setVertexShaderConstant ("g_Texture2Resolution", g_Texture1Resolution, 4);
  408. // TODO: Support up to 7 materials (as wallpaper engine)
  409. /*services->setPixelShaderConstant ("g_Strength", &g_Strength, 1);
  410. services->setPixelShaderConstant ("g_SpecularPower", &g_SpecularPower, 1);
  411. services->setPixelShaderConstant ("g_SpecularStrength", &g_SpecularStrength, 1);
  412. services->setPixelShaderConstant ("g_SpecularColor", g_SpecularColor, 3);*/
  413. services->setPixelShaderConstant ("g_Texture0", &g_Texture0, 1);
  414. services->setPixelShaderConstant ("g_Texture1", &g_Texture1, 1);
  415. services->setPixelShaderConstant ("g_Texture2", &g_Texture2, 1);
  416. }
  417. };