CImage.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #include "CImage.h"
  2. #include "WallpaperEngine/Render/Shaders/Compiler.h"
  3. #include "WallpaperEngine/Render/Shaders/Parameters/CShaderParameter.h"
  4. #include "WallpaperEngine/Render/Shaders/Parameters/CShaderParameterFloat.h"
  5. #include "WallpaperEngine/Render/Shaders/Parameters/CShaderParameterInteger.h"
  6. #include "WallpaperEngine/Render/Shaders/Parameters/CShaderParameterVector2.h"
  7. #include "WallpaperEngine/Render/Shaders/Parameters/CShaderParameterVector3.h"
  8. #include "WallpaperEngine/Render/Shaders/Parameters/CShaderParameterVector4.h"
  9. using namespace WallpaperEngine;
  10. using namespace WallpaperEngine::Render::Objects;
  11. using namespace WallpaperEngine::Render::Shaders::Parameters;
  12. extern irr::f32 g_Time;
  13. CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
  14. Render::CObject (scene, Type, image),
  15. m_image (image),
  16. m_passes (0)
  17. {
  18. // TODO: INITIALIZE NEEDED EFFECTS AND PROPERLY CALCULATE THESE?
  19. irr::f32 xright = this->m_image->getOrigin ().X;
  20. irr::f32 xleft = -this->m_image->getOrigin ().X;
  21. irr::f32 ztop = this->m_image->getOrigin ().Y;
  22. irr::f32 zbottom = -this->m_image->getOrigin ().Y;
  23. irr::f32 z = this->m_image->getOrigin ().Z;
  24. // top left
  25. this->m_vertex [0].Pos = irr::core::vector3df (xleft, ztop, z);
  26. // top right
  27. this->m_vertex [1].Pos = irr::core::vector3df (xright, ztop, z);
  28. // bottom right
  29. this->m_vertex [2].Pos = irr::core::vector3df (xright, zbottom, z);
  30. // bottom left
  31. this->m_vertex [3].Pos = irr::core::vector3df (xleft, zbottom, z);
  32. this->m_vertex [0].TCoords = irr::core::vector2df (1.0f, 0.0f);
  33. this->m_vertex [1].TCoords = irr::core::vector2df (0.0f, 0.0f);
  34. this->m_vertex [2].TCoords = irr::core::vector2df (0.0f, 1.0f);
  35. this->m_vertex [3].TCoords = irr::core::vector2df (1.0f, 1.0f);
  36. this->m_vertex [0].Color = irr::video::SColor (255, 255, 255, 255);
  37. this->m_vertex [1].Color = irr::video::SColor (255, 255, 255, 255);
  38. this->m_vertex [2].Color = irr::video::SColor (255, 255, 255, 255);
  39. this->m_vertex [3].Color = irr::video::SColor (255, 255, 255, 255);
  40. this->generateMaterial ();
  41. this->setAutomaticCulling (irr::scene::EAC_OFF);
  42. this->m_boundingBox = irr::core::aabbox3d<irr::f32>(0, 0, 0, 0, 0, 0);
  43. }
  44. void CImage::render()
  45. {
  46. uint16_t indices [] =
  47. {
  48. 3, 2, 1, 0
  49. };
  50. irr::video::IVideoDriver* driver = SceneManager->getVideoDriver ();
  51. auto cur = this->m_materials.begin ();
  52. auto end = this->m_materials.end ();
  53. auto textureCur = this->m_renderTextures.begin ();
  54. auto textureEnd = this->m_renderTextures.end ();
  55. for (; cur != end; cur ++)
  56. {
  57. if (textureCur == textureEnd)
  58. {
  59. driver->setRenderTarget (irr::video::ERT_FRAME_BUFFER, false, false);
  60. }
  61. else
  62. {
  63. driver->setRenderTarget (*textureCur, true, true, irr::video::SColor (0, 0, 0, 0));
  64. textureCur ++;
  65. }
  66. driver->setMaterial (*cur);
  67. driver->drawVertexPrimitiveList (
  68. this->m_vertex, 4, indices, 1,
  69. irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT
  70. );
  71. }
  72. }
  73. void CImage::generateMaterial ()
  74. {
  75. auto cur = this->m_image->getMaterial ()->getPasses ().begin ();
  76. auto end = this->m_image->getMaterial ()->getPasses ().end ();
  77. for (; cur != end; cur++)
  78. {
  79. this->generatePass (*cur);
  80. }
  81. auto effectCur = this->m_image->getEffects ().begin ();
  82. auto effectEnd = this->m_image->getEffects ().end ();
  83. for (; effectCur != effectEnd; effectCur++)
  84. {
  85. auto materialCur = (*effectCur)->getMaterials ().begin ();
  86. auto materialEnd = (*effectCur)->getMaterials ().end ();
  87. for (; materialCur != materialEnd; materialCur++)
  88. {
  89. cur = (*materialCur)->getPasses ().begin ();
  90. end = (*materialCur)->getPasses ().end ();
  91. for (; cur != end; cur++)
  92. {
  93. this->generatePass (*cur);
  94. }
  95. }
  96. }
  97. }
  98. void CImage::generatePass (Core::Objects::Images::Materials::CPassess* pass)
  99. {
  100. std::vector<std::string>* textures = pass->getTextures ();
  101. irr::video::SMaterial material;
  102. auto texturesCur = textures->begin ();
  103. auto texturesEnd = textures->end ();
  104. for (int textureNumber = 0; texturesCur != texturesEnd; texturesCur ++, textureNumber ++)
  105. {
  106. irr::io::path texturepath = this->getScene ()->getContext ()->resolveMaterials (*texturesCur);
  107. irr::video::ITexture* texture = nullptr;
  108. if (textureNumber == 0 && this->m_passes > 0)
  109. {
  110. irr::video::ITexture* originalTexture = this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->getTexture (texturepath);
  111. texture = this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->addRenderTargetTexture (
  112. irr::core::dimension2d<irr::u32> (
  113. originalTexture->getSize ().Width,
  114. originalTexture->getSize ().Height
  115. ), ("_RT_" + this->m_image->getName () + std::to_string (textureNumber) + "_" + std::to_string (this->m_passes)).c_str ()
  116. );
  117. this->m_renderTextures.push_back (texture);
  118. }
  119. else
  120. {
  121. texture = this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->getTexture (texturepath);
  122. }
  123. material.setTexture (textureNumber, texture);
  124. }
  125. // TODO: MOVE SHADER INITIALIZATION ELSEWHERE
  126. irr::io::path vertpath = this->getScene ()->getContext ()->resolveVertexShader (pass->getShader ());
  127. irr::io::path fragpath = this->getScene ()->getContext ()->resolveFragmentShader (pass->getShader ());
  128. auto vertexShader = new Render::Shaders::Compiler (this->getScene ()->getContext (), vertpath, Render::Shaders::Compiler::Type::Type_Vertex, pass->getCombos (), false);
  129. auto pixelShader = new Render::Shaders::Compiler (this->getScene ()->getContext (), fragpath, Render::Shaders::Compiler::Type::Type_Pixel, pass->getCombos (), false);
  130. material.MaterialType = (irr::video::E_MATERIAL_TYPE)
  131. this->getScene ()->getContext ()->getDevice ()->getVideoDriver ()->getGPUProgrammingServices ()->addHighLevelShaderMaterial (
  132. vertexShader->precompile ().c_str (), "main", irr::video::EVST_VS_2_0,
  133. pixelShader->precompile ().c_str (), "main", irr::video::EPST_PS_2_0,
  134. this, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, this->m_passes, irr::video::EGSL_DEFAULT
  135. );
  136. // TODO: TAKE INTO ACCOUNT BLENDING AND CULLING METHODS FROM THE JSON
  137. material.setFlag (irr::video::EMF_LIGHTING, false);
  138. material.setFlag (irr::video::EMF_BLEND_OPERATION, true);
  139. material.Wireframe = false;
  140. material.Lighting = false;
  141. this->m_vertexShaders.push_back (vertexShader);
  142. this->m_pixelShaders.push_back (pixelShader);
  143. this->m_materials.push_back (material);
  144. this->m_passes ++;
  145. }
  146. const irr::core::aabbox3d<irr::f32>& CImage::getBoundingBox() const
  147. {
  148. return this->m_boundingBox;
  149. }
  150. void CImage::OnSetConstants (irr::video::IMaterialRendererServices *services, int32_t userData)
  151. {
  152. irr::f32 g_Texture0 = 0;
  153. irr::f32 g_Texture1 = 1;
  154. irr::f32 g_Texture2 = 2;
  155. irr::f32 g_Texture3 = 3;
  156. irr::f32 g_Texture4 = 4;
  157. irr::f32 g_Texture5 = 5;
  158. irr::f32 g_Texture6 = 6;
  159. irr::f32 g_Texture7 = 7;
  160. irr::f32 g_Texture0Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
  161. irr::f32 g_Texture1Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
  162. irr::f32 g_Texture2Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
  163. irr::f32 g_Texture3Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
  164. irr::f32 g_Texture4Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
  165. irr::f32 g_Texture5Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
  166. irr::f32 g_Texture6Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
  167. irr::f32 g_Texture7Rotation [4] = { this->m_image->getAngles ().X, this->m_image->getAngles ().Y, this->m_image->getAngles ().Z, this->m_image->getAngles ().Z };
  168. irr::f32 g_Texture0Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
  169. irr::f32 g_Texture1Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
  170. irr::f32 g_Texture2Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
  171. irr::f32 g_Texture3Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
  172. irr::f32 g_Texture4Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
  173. irr::f32 g_Texture5Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
  174. irr::f32 g_Texture6Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
  175. irr::f32 g_Texture7Resolution [4] = { this->m_image->getSize ().X, this->m_image->getSize ().Y, this->m_image->getSize ().X, this->m_image->getSize ().Y };
  176. irr::video::IVideoDriver* driver = services->getVideoDriver ();
  177. irr::core::matrix4 worldViewProj;
  178. worldViewProj = driver->getTransform (irr::video::ETS_PROJECTION);
  179. worldViewProj *= driver->getTransform (irr::video::ETS_VIEW);
  180. worldViewProj *= driver->getTransform (irr::video::ETS_WORLD);
  181. Render::Shaders::Compiler* vertexShader = this->m_vertexShaders.at (userData);
  182. Render::Shaders::Compiler* pixelShader = this->m_pixelShaders.at (userData);
  183. auto cur = vertexShader->getParameters ().begin ();
  184. auto end = vertexShader->getParameters ().end ();
  185. for (; cur != end; cur ++)
  186. {
  187. if ((*cur)->is <CShaderParameterInteger> () == true)
  188. {
  189. services->setVertexShaderConstant (
  190. (*cur)->getName ().c_str (),
  191. (irr::s32*) (*cur)->getValue (),
  192. (*cur)->getSize ()
  193. );
  194. }
  195. else if (
  196. (*cur)->is <CShaderParameterFloat> () == true ||
  197. (*cur)->is <CShaderParameterVector2> () == true ||
  198. (*cur)->is <CShaderParameterVector3> () == true ||
  199. (*cur)->is <CShaderParameterVector4> () == true)
  200. {
  201. services->setVertexShaderConstant (
  202. (*cur)->getName ().c_str (),
  203. (irr::f32*) (*cur)->getValue (),
  204. (*cur)->getSize ()
  205. );
  206. }
  207. }
  208. cur = pixelShader->getParameters ().begin ();
  209. end = pixelShader->getParameters ().end ();
  210. for (; cur != end; cur ++)
  211. {
  212. if ((*cur)->is <CShaderParameterInteger> () == true)
  213. {
  214. services->setPixelShaderConstant (
  215. (*cur)->getName ().c_str (),
  216. (irr::s32*) (*cur)->getValue (),
  217. (*cur)->getSize ()
  218. );
  219. }
  220. else if (
  221. (*cur)->is <CShaderParameterFloat> () == true ||
  222. (*cur)->is <CShaderParameterVector2> () == true ||
  223. (*cur)->is <CShaderParameterVector3> () == true ||
  224. (*cur)->is <CShaderParameterVector4> () == true)
  225. {
  226. services->setPixelShaderConstant (
  227. (*cur)->getName ().c_str (),
  228. (irr::f32*) (*cur)->getValue (),
  229. (*cur)->getSize ()
  230. );
  231. }
  232. }
  233. services->setVertexShaderConstant ("g_Time", &g_Time, 1);
  234. services->setPixelShaderConstant ("g_Time", &g_Time, 1);
  235. services->setVertexShaderConstant ("g_ModelViewProjectionMatrix", worldViewProj.pointer(), 16);
  236. services->setVertexShaderConstant ("g_Texture0Resolution", g_Texture0Resolution, 4);
  237. services->setVertexShaderConstant ("g_Texture1Resolution", g_Texture1Resolution, 4);
  238. services->setVertexShaderConstant ("g_Texture2Resolution", g_Texture2Resolution, 4);
  239. services->setVertexShaderConstant ("g_Texture3Resolution", g_Texture3Resolution, 4);
  240. services->setVertexShaderConstant ("g_Texture4Resolution", g_Texture4Resolution, 4);
  241. services->setVertexShaderConstant ("g_Texture5Resolution", g_Texture5Resolution, 4);
  242. services->setVertexShaderConstant ("g_Texture6Resolution", g_Texture6Resolution, 4);
  243. services->setVertexShaderConstant ("g_Texture7Resolution", g_Texture7Resolution, 4);
  244. services->setVertexShaderConstant ("g_Texture0Rotation", g_Texture0Rotation, 4);
  245. services->setVertexShaderConstant ("g_Texture1Rotation", g_Texture1Rotation, 4);
  246. services->setVertexShaderConstant ("g_Texture2Rotation", g_Texture2Rotation, 4);
  247. services->setVertexShaderConstant ("g_Texture3Rotation", g_Texture3Rotation, 4);
  248. services->setVertexShaderConstant ("g_Texture4Rotation", g_Texture4Rotation, 4);
  249. services->setVertexShaderConstant ("g_Texture5Rotation", g_Texture5Rotation, 4);
  250. services->setVertexShaderConstant ("g_Texture6Rotation", g_Texture6Rotation, 4);
  251. services->setVertexShaderConstant ("g_Texture7Rotation", g_Texture7Rotation, 4);
  252. services->setPixelShaderConstant ("g_Texture0", &g_Texture0, 1);
  253. services->setPixelShaderConstant ("g_Texture1", &g_Texture1, 1);
  254. services->setPixelShaderConstant ("g_Texture2", &g_Texture2, 1);
  255. services->setPixelShaderConstant ("g_Texture3", &g_Texture3, 1);
  256. services->setPixelShaderConstant ("g_Texture4", &g_Texture4, 1);
  257. services->setPixelShaderConstant ("g_Texture5", &g_Texture5, 1);
  258. services->setPixelShaderConstant ("g_Texture6", &g_Texture6, 1);
  259. services->setPixelShaderConstant ("g_Texture7", &g_Texture7, 1);
  260. }
  261. const std::string CImage::Type = "image";