BsMaterial.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsResource.h"
  4. #include "BsIResourceListener.h"
  5. #include "BsMaterialParam.h"
  6. #include "BsVector2.h"
  7. #include "BsVector3.h"
  8. #include "BsVector4.h"
  9. #include "BsMatrix3.h"
  10. #include "BsMatrix4.h"
  11. namespace BansheeEngine
  12. {
  13. /**
  14. * @brief Helper class containing parameters for all types
  15. * of GPU programs used in a pass.
  16. */
  17. template<bool Core>
  18. class TPassParameters
  19. {
  20. public:
  21. typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
  22. /**
  23. * @brief Returns a set of GPU parameters based on an index.
  24. *
  25. * @note Useful when needing to iterate over all sets of GPU parameters.
  26. */
  27. GpuParamsType& getParamByIdx(UINT32 idx)
  28. {
  29. GpuParamsType* paramArray[] = { &mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams };
  30. return *paramArray[idx];
  31. }
  32. /**
  33. * @brief Sets GPU parameters based on an index.
  34. *
  35. * @note Useful when needing to iterate over all sets of GPU parameters.
  36. */
  37. void setParamByIdx(UINT32 idx, const GpuParamsType& params)
  38. {
  39. GpuParamsType* paramArray[] = { &mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams };
  40. (*paramArray[idx]) = params;
  41. }
  42. GpuParamsType mVertParams;
  43. GpuParamsType mFragParams;
  44. GpuParamsType mGeomParams;
  45. GpuParamsType mHullParams;
  46. GpuParamsType mDomainParams;
  47. GpuParamsType mComputeParams;
  48. };
  49. template<bool Core> struct TGpuParamBlockBufferPtrType { };
  50. template<> struct TGpuParamBlockBufferPtrType<false> { typedef SPtr<GpuParamBlockBuffer> Type; };
  51. template<> struct TGpuParamBlockBufferPtrType<true> { typedef SPtr<GpuParamBlockBufferCore> Type; };
  52. template<bool Core> struct TGpuProgramType { };
  53. template<> struct TGpuProgramType<false> { typedef GpuProgramPtr Type; };
  54. template<> struct TGpuProgramType<true> { typedef SPtr<GpuProgramCore> Type; };
  55. /**
  56. * @brief Contains sim thread pass parameters for each shader stage.
  57. */
  58. class BS_CORE_EXPORT PassParameters : public TPassParameters<false>
  59. {
  60. public:
  61. static const UINT32 NUM_PARAMS;
  62. };
  63. /**
  64. * @brief Contains core thread pass parameters for each shader stage.
  65. */
  66. class BS_CORE_EXPORT PassParametersCore : public TPassParameters<true>
  67. {
  68. public:
  69. static const UINT32 NUM_PARAMS;
  70. };
  71. /**
  72. * @brief Material that controls how objects are rendered. It is represented by a shader and
  73. * parameters used to set up that shader. It provides a simple interface for manipulating the parameters.
  74. */
  75. class BS_CORE_EXPORT MaterialBase
  76. {
  77. public:
  78. /**
  79. * @brief Data used to described a structure defined within a shader.
  80. */
  81. struct StructData
  82. {
  83. StructData()
  84. :size(0), data(nullptr)
  85. { }
  86. StructData(UINT32 _size)
  87. :size(_size)
  88. {
  89. data = std::shared_ptr<void>(bs_alloc(_size), &bs_free);
  90. }
  91. /**
  92. * @brief Writes the specified data to the internal buffer. Caller
  93. * must ensure size of the provided buffer is correct.
  94. */
  95. void write(void* _data)
  96. {
  97. memcpy(data.get(), _data, size);
  98. }
  99. std::shared_ptr<void> data;
  100. UINT32 size;
  101. };
  102. virtual ~MaterialBase() { }
  103. protected:
  104. /**
  105. * @brief Retrieves a list of all shader GPU parameters, and the GPU program variable names they map to.
  106. */
  107. const Map<String, String>& getValidParamNames() const { return mValidParams; }
  108. /**
  109. * @copydoc CoreObject::markCoreDirty
  110. */
  111. virtual void _markCoreDirty() { }
  112. /**
  113. * @copydoc CoreObject::markDependenciesDirty
  114. */
  115. virtual void _markDependenciesDirty() { }
  116. /**
  117. * @copydoc IResourceListener::markResourcesDirty
  118. */
  119. virtual void _markResourcesDirty() { }
  120. /**
  121. * @brief Returns all GPU parameter descriptions in the specified technique.
  122. */
  123. static Vector<GpuParamDescPtr> getAllParamDescs(const SPtr<Technique>& technique);
  124. /**
  125. * @brief Returns all GPU parameter descriptions in the specified technique.
  126. */
  127. static Vector<GpuParamDescPtr> getAllParamDescs(const SPtr<TechniqueCore>& technique);
  128. Set<String> mValidShareableParamBlocks;
  129. Map<String, String> mValidParams; // Also maps Shader param name -> gpu variable name
  130. };
  131. /**
  132. * @copydoc MaterialBase
  133. */
  134. template<bool Core>
  135. class BS_CORE_EXPORT TMaterial : public MaterialBase
  136. {
  137. public:
  138. template<bool Core> struct TPassType {};
  139. template<> struct TPassType < false > { typedef SPtr<Pass> Type; };
  140. template<> struct TPassType < true > { typedef SPtr<PassCore> Type; };
  141. template<bool Core> struct TTechniqueType {};
  142. template<> struct TTechniqueType < false > { typedef SPtr<Technique> Type; };
  143. template<> struct TTechniqueType < true > { typedef SPtr<TechniqueCore> Type; };
  144. template<bool Core> struct TShaderType {};
  145. template<> struct TShaderType < false > { typedef HShader Type; };
  146. template<> struct TShaderType < true > { typedef SPtr<ShaderCore> Type; };
  147. template<bool Core> struct TGpuParamBlockBufferType {};
  148. template<> struct TGpuParamBlockBufferType < false > { typedef GpuParamBlockBuffer Type; };
  149. template<> struct TGpuParamBlockBufferType < true > { typedef GpuParamBlockBufferCore Type; };
  150. template<bool Core> struct TPassParamsType {};
  151. template<> struct TPassParamsType < false > { typedef PassParameters Type; };
  152. template<> struct TPassParamsType < true > { typedef PassParametersCore Type; };
  153. typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
  154. typedef typename TGpuParamTextureType<Core>::Type TextureType;
  155. typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
  156. typedef typename TGpuParamBlockBufferPtrType<Core>::Type ParamBlockPtrType;
  157. typedef typename TGpuParamBlockBufferType<Core>::Type ParamBlockType;
  158. typedef typename TGpuProgramType<Core>::Type GpuProgramType;
  159. typedef typename TPassType<Core>::Type PassType;
  160. typedef typename TTechniqueType<Core>::Type TechniqueType;
  161. typedef typename TShaderType<Core>::Type ShaderType;
  162. typedef typename TPassParamsType<Core>::Type PassParamsType;
  163. virtual ~TMaterial() { }
  164. /**
  165. * @brief Returns the currently active shader.
  166. */
  167. ShaderType getShader() const { return mShader; }
  168. /**
  169. * @brief Returns the number of passes that are used
  170. * by the shader used in the material.
  171. */
  172. UINT32 getNumPasses() const;
  173. /**
  174. * @brief Retrieves a specific shader pass.
  175. */
  176. PassType getPass(UINT32 passIdx) const;
  177. /**
  178. * @brief Assigns a float value to the shader parameter with the specified name.
  179. *
  180. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  181. */
  182. void setFloat(const String& name, float value, UINT32 arrayIdx = 0) { return getParamFloat(name).set(value, arrayIdx); }
  183. /**
  184. * @brief Assigns a color to the shader parameter with the specified name.
  185. *
  186. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  187. */
  188. void setColor(const String& name, const Color& value, UINT32 arrayIdx = 0) { return getParamColor(name).set(value, arrayIdx); }
  189. /**
  190. * @brief Assigns a 2D vector to the shader parameter with the specified name.
  191. *
  192. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  193. */
  194. void setVec2(const String& name, const Vector2& value, UINT32 arrayIdx = 0) { return getParamVec2(name).set(value, arrayIdx); }
  195. /**
  196. * @brief Assigns a 3D vector to the shader parameter with the specified name.
  197. *
  198. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  199. */
  200. void setVec3(const String& name, const Vector3& value, UINT32 arrayIdx = 0) { return getParamVec3(name).set(value, arrayIdx); }
  201. /**
  202. * @brief Assigns a 4D vector to the shader parameter with the specified name.
  203. *
  204. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  205. */
  206. void setVec4(const String& name, const Vector4& value, UINT32 arrayIdx = 0) { return getParamVec4(name).set(value, arrayIdx); }
  207. /**
  208. * @brief Assigns a 3x3 matrix to the shader parameter with the specified name.
  209. *
  210. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  211. */
  212. void setMat3(const String& name, const Matrix3& value, UINT32 arrayIdx = 0) { return getParamMat3(name).set(value, arrayIdx); }
  213. /**
  214. * @brief Assigns a 4x4 matrix to the shader parameter with the specified name.
  215. *
  216. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  217. */
  218. void setMat4(const String& name, const Matrix4& value, UINT32 arrayIdx = 0) { return getParamMat4(name).set(value, arrayIdx); }
  219. /**
  220. * @brief Assigns a structure to the shader parameter with the specified name.
  221. *
  222. * Structure is provided as a raw buffer and caller must ensure structure in buffer
  223. * matches what the shader expects.
  224. *
  225. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  226. */
  227. void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
  228. /** @brief Assigns a texture to the shader parameter with the specified name. */
  229. void setTexture(const String& name, const TextureType& value) { return getParamTexture(name).set(value); }
  230. /**
  231. * @brief Assigns a texture to be used for random load/store operations to the
  232. * shader parameter with the specified name.
  233. */
  234. void setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface)
  235. {
  236. return getParamLoadStoreTexture(name).set(value, surface);
  237. }
  238. /** @brief Assigns a sampler state to the shader parameter with the specified name. */
  239. void setSamplerState(const String& name, const SamplerStateType& value) { return getParamSamplerState(name).set(value); }
  240. /**
  241. * @brief Returns a float value assigned with the parameter with the specified name.
  242. *
  243. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  244. */
  245. float getFloat(const String& name, UINT32 arrayIdx = 0) const { return getParamFloat(name).get(arrayIdx); }
  246. /**
  247. * @brief Returns a color assigned with the parameter with the specified name.
  248. *
  249. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  250. */
  251. Color getColor(const String& name, UINT32 arrayIdx = 0) const { return getParamColor(name).get(arrayIdx); }
  252. /**
  253. * @brief Returns a 2D vector assigned with the parameter with the specified name.
  254. *
  255. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  256. */
  257. Vector2 getVec2(const String& name, UINT32 arrayIdx = 0) const { return getParamVec2(name).get(arrayIdx); }
  258. /**
  259. * @brief Returns a 3D vector assigned with the parameter with the specified name.
  260. *
  261. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  262. */
  263. Vector3 getVec3(const String& name, UINT32 arrayIdx = 0) const { return getParamVec3(name).get(arrayIdx); }
  264. /**
  265. * @brief Returns a 4D vector assigned with the parameter with the specified name.
  266. *
  267. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  268. */
  269. Vector4 getVec4(const String& name, UINT32 arrayIdx = 0) const { return getParamVec4(name).get(arrayIdx); }
  270. /**
  271. * @brief Returns a 3x3 matrix assigned with the parameter with the specified name.
  272. *
  273. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  274. */
  275. Matrix3 getMat3(const String& name, UINT32 arrayIdx = 0) const { return getParamMat3(name).get(arrayIdx); }
  276. /**
  277. * @brief Returns a 4x4 matrix assigned with the parameter with the specified name.
  278. *
  279. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  280. */
  281. Matrix4 getMat4(const String& name, UINT32 arrayIdx = 0) const { return getParamMat4(name).get(arrayIdx); }
  282. /** @brief Returns a texture assigned with the parameter with the specified name. */
  283. TextureType getTexture(const String& name) const { return getParamTexture(name).get(); }
  284. /** @brief Returns a sampler state assigned with the parameter with the specified name. */
  285. SamplerStateType getSamplerState(const String& name) const { return getParamSamplerState(name).get(); }
  286. /**
  287. * @brief Returns a buffer representing a structure assigned to the parameter with the specified name.
  288. *
  289. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  290. */
  291. MaterialBase::StructData getStructData(const String& name, UINT32 arrayIdx = 0) const
  292. {
  293. TMaterialParamStruct<Core> structParam = getParamStruct(name);
  294. MaterialBase::StructData data(structParam.getElementSize());
  295. structParam.get(data.data.get(), structParam.getElementSize(), arrayIdx);
  296. return data;
  297. }
  298. /**
  299. * @brief Returns a float GPU parameter. This parameter may be used for
  300. * more efficiently getting/setting GPU parameter values than calling
  301. * Material::get* / Material::set* methods.
  302. *
  303. * @note Expected behavior is that you would retrieve this parameter when
  304. * initially constructing the material, and then use it throughout material
  305. * lifetime to assign and retrieve parameter values.
  306. *
  307. * If material shader changes this handle will be invalidated.
  308. */
  309. TMaterialDataParam<float, Core> getParamFloat(const String& name) const
  310. {
  311. TMaterialDataParam<float, Core> gpuParam;
  312. getParam(name, gpuParam);
  313. return gpuParam;
  314. }
  315. /**
  316. * @brief Returns a color GPU parameter. This parameter may be used for
  317. * more efficiently getting/setting GPU parameter values than calling
  318. * Material::get* / Material::set* methods.
  319. *
  320. * @note Expected behavior is that you would retrieve this parameter when
  321. * initially constructing the material, and then use it throughout material
  322. * lifetime to assign and retrieve parameter values.
  323. *
  324. * If material shader changes this handle will be invalidated.
  325. */
  326. TMaterialDataParam<Color, Core> getParamColor(const String& name) const
  327. {
  328. TMaterialDataParam<Color, Core> gpuParam;
  329. getParam(name, gpuParam);
  330. return gpuParam;
  331. }
  332. /**
  333. * @brief Returns a 2D vector GPU parameter. This parameter may be used for
  334. * more efficiently getting/setting GPU parameter values than calling
  335. * Material::get* / Material::set* methods.
  336. *
  337. * @note Expected behavior is that you would retrieve this parameter when
  338. * initially constructing the material, and then use it throughout material
  339. * lifetime to assign and retrieve parameter values.
  340. *
  341. * If material shader changes this handle will be invalidated.
  342. */
  343. TMaterialDataParam<Vector2, Core> getParamVec2(const String& name) const
  344. {
  345. TMaterialDataParam<Vector2, Core> gpuParam;
  346. getParam(name, gpuParam);
  347. return gpuParam;
  348. }
  349. /**
  350. * @brief Returns a 3D vector GPU parameter. This parameter may be used for
  351. * more efficiently getting/setting GPU parameter values than calling
  352. * Material::get* / Material::set* methods.
  353. *
  354. * @note Expected behavior is that you would retrieve this parameter when
  355. * initially constructing the material, and then use it throughout material
  356. * lifetime to assign and retrieve parameter values.
  357. *
  358. * If material shader changes this handle will be invalidated.
  359. */
  360. TMaterialDataParam<Vector3, Core> getParamVec3(const String& name) const
  361. {
  362. TMaterialDataParam<Vector3, Core> gpuParam;
  363. getParam(name, gpuParam);
  364. return gpuParam;
  365. }
  366. /**
  367. * @brief Returns a 4D vector GPU parameter. This parameter may be used for
  368. * more efficiently getting/setting GPU parameter values than calling
  369. * Material::get* / Material::set* methods.
  370. *
  371. * @note Expected behavior is that you would retrieve this parameter when
  372. * initially constructing the material, and then use it throughout material
  373. * lifetime to assign and retrieve parameter values.
  374. *
  375. * If material shader changes this handle will be invalidated.
  376. */
  377. TMaterialDataParam<Vector4, Core> getParamVec4(const String& name) const
  378. {
  379. TMaterialDataParam<Vector4, Core> gpuParam;
  380. getParam(name, gpuParam);
  381. return gpuParam;
  382. }
  383. /**
  384. * @brief Returns a 3x3 matrix GPU parameter. This parameter may be used for
  385. * more efficiently getting/setting GPU parameter values than calling
  386. * Material::get* / Material::set* methods.
  387. *
  388. * @note Expected behavior is that you would retrieve this parameter when
  389. * initially constructing the material, and then use it throughout material
  390. * lifetime to assign and retrieve parameter values.
  391. *
  392. * If material shader changes this handle will be invalidated.
  393. */
  394. TMaterialDataParam<Matrix3, Core> getParamMat3(const String& name) const
  395. {
  396. TMaterialDataParam<Matrix3, Core> gpuParam;
  397. getParam(name, gpuParam);
  398. return gpuParam;
  399. }
  400. /**
  401. * @brief Returns a 4x4 matrix GPU parameter. This parameter may be used for
  402. * more efficiently getting/setting GPU parameter values than calling
  403. * Material::get* / Material::set* methods.
  404. *
  405. * @note Expected behavior is that you would retrieve this parameter when
  406. * initially constructing the material, and then use it throughout material
  407. * lifetime to assign and retrieve parameter values.
  408. *
  409. * If material shader changes this handle will be invalidated.
  410. */
  411. TMaterialDataParam<Matrix4, Core> getParamMat4(const String& name) const
  412. {
  413. TMaterialDataParam<Matrix4, Core> gpuParam;
  414. getParam(name, gpuParam);
  415. return gpuParam;
  416. }
  417. /**
  418. * @brief Returns a structure GPU parameter. This parameter may be used for
  419. * more efficiently getting/setting GPU parameter values than calling
  420. * Material::get* / Material::set* methods.
  421. *
  422. * @note Expected behavior is that you would retrieve this parameter when
  423. * initially constructing the material, and then use it throughout material
  424. * lifetime to assign and retrieve parameter values.
  425. *
  426. * If material shader changes this handle will be invalidated.
  427. */
  428. TMaterialParamStruct<Core> getParamStruct(const String& name) const;
  429. /**
  430. * @brief Returns a texture GPU parameter. This parameter may be used for
  431. * more efficiently getting/setting GPU parameter values than calling
  432. * Material::get* / Material::set* methods.
  433. *
  434. * @note Expected behavior is that you would retrieve this parameter when
  435. * initially constructing the material, and then use it throughout material
  436. * lifetime to assign and retrieve parameter values.
  437. *
  438. * If material shader changes this handle will be invalidated.
  439. */
  440. TMaterialParamTexture<Core> getParamTexture(const String& name) const;
  441. /**
  442. * @brief Returns a GPU parameter for binding a load/store texture. This parameter
  443. * may be used for more efficiently getting/setting GPU parameter values
  444. * than calling Material::get* / Material::set* methods.
  445. *
  446. * @note Expected behavior is that you would retrieve this parameter when
  447. * initially constructing the material, and then use it throughout material
  448. * lifetime to assign and retrieve parameter values.
  449. *
  450. * If material shader changes this handle will be invalidated.
  451. */
  452. TMaterialParamLoadStoreTexture<Core> getParamLoadStoreTexture(const String& name) const;
  453. /**
  454. * @brief Returns a sampler state GPU parameter. This parameter may be used for
  455. * more efficiently getting/setting GPU parameter values than calling
  456. * Material::get* / Material::set* methods.
  457. *
  458. * @note Expected behavior is that you would retrieve this parameter when
  459. * initially constructing the material, and then use it throughout material
  460. * lifetime to assign and retrieve parameter values.
  461. *
  462. * If material shader changes this handle will be invalidated.
  463. */
  464. TMaterialParamSampState<Core> getParamSamplerState(const String& name) const;
  465. /**
  466. * @brief Returns a set of parameters for all GPU programs
  467. * in the specified shader pass.
  468. */
  469. SPtr<PassParamsType> getPassParameters(UINT32 passIdx) const { return mParametersPerPass[passIdx]; }
  470. /**
  471. * @brief Assign a parameter block buffer with the specified name.
  472. *
  473. * @note Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or
  474. * potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters
  475. * in the buffers need only be set once and then reused multiple times.
  476. */
  477. void setParamBlockBuffer(const String& name, const ParamBlockPtrType& paramBlock);
  478. protected:
  479. /**
  480. * @brief Allows you to retrieve a handle to a parameter that you can then use for quickly
  481. * setting and retrieving parameter data. This allows you to set/get parameter data
  482. * without all the cost of extra lookups otherwise required.
  483. *
  484. * @note All of these handles will be invalidated if material shader ever changes. It is up to the
  485. * caller to keep track of that.
  486. */
  487. template <typename T>
  488. void getParam(const String& name, TMaterialDataParam<T, Core>& output) const;
  489. /**
  490. * @brief Assigns a value from a raw buffer to the parameter with the specified name.
  491. * Buffer must be of sizeof(T) * numElements size and initialized.
  492. *
  493. * @note Provided parameter must exist, no checking is done.
  494. */
  495. template <typename T>
  496. void setParamValue(const String& name, UINT8* buffer, UINT32 numElements);
  497. /**
  498. * @brief Initializes the material by using the best technique from the currently set shader. Shader
  499. * must contain the technique that matches the current renderer and render system.
  500. */
  501. void initBestTechnique();
  502. /**
  503. * @brief Assigns all the default parameters specified in the shader to the material.
  504. */
  505. void initDefaultParameters();
  506. /**
  507. * @brief Throw an exception if no shader is set, or no acceptable
  508. * technique was found.
  509. */
  510. void throwIfNotInitialized() const;
  511. Vector<SPtr<PassParamsType>> mParametersPerPass;
  512. ShaderType mShader;
  513. TechniqueType mBestTechnique;
  514. };
  515. /**
  516. * @copydoc MaterialBase
  517. */
  518. class BS_CORE_EXPORT MaterialCore : public CoreObjectCore, public TMaterial<true>
  519. {
  520. public:
  521. ~MaterialCore() { }
  522. /**
  523. * @copydoc Material::setShader
  524. */
  525. void setShader(const SPtr<ShaderCore>& shader);
  526. /**
  527. * @brief Creates a new material with the specified shader.
  528. */
  529. static SPtr<MaterialCore> create(const SPtr<ShaderCore>& shader);
  530. private:
  531. friend class Material;
  532. MaterialCore() { }
  533. MaterialCore(const SPtr<ShaderCore>& shader);
  534. MaterialCore(const SPtr<ShaderCore>& shader, const SPtr<TechniqueCore>& bestTechnique,
  535. const Set<String>& validShareableParamBlocks, const Map<String, String>& validParams,
  536. const Vector<SPtr<PassParametersCore>>& passParams);
  537. /**
  538. * @copydoc CoreObjectCore::syncToCore
  539. */
  540. void syncToCore(const CoreSyncData& data) override;
  541. };
  542. /**
  543. * @copydoc MaterialBase
  544. */
  545. class BS_CORE_EXPORT Material : public Resource, public TMaterial<false>, public IResourceListener
  546. {
  547. public:
  548. ~Material() { }
  549. /**
  550. * @brief Sets a shader that will be used by the material. Best technique within the
  551. * provided shader will be used for the material.
  552. *
  553. * @note Shader must be set before doing any other operations with the material.
  554. *
  555. * After setting the shader if change any systems that a shader technique is
  556. * dependent upon (render system, renderer, etc), you will need to call this
  557. * method again on all your Materials to make sure technique used is updated.
  558. */
  559. void setShader(const HShader& shader);
  560. /**
  561. * @brief Retrieves an implementation of a material usable only from the
  562. * core thread.
  563. */
  564. SPtr<MaterialCore> getCore() const;
  565. /**
  566. * @copydoc CoreObject::initialize
  567. */
  568. void initialize() override;
  569. /**
  570. * @brief Creates a deep copy of the material and returns the new object.
  571. */
  572. HMaterial Material::clone();
  573. /**
  574. * @brief Creates a new empty material.
  575. *
  576. * @note Make sure you call Material::setShader before using it.
  577. */
  578. static HMaterial create();
  579. /**
  580. * @brief Creates a new material with the specified shader.
  581. */
  582. static HMaterial create(const HShader& shader);
  583. private:
  584. friend class MaterialManager;
  585. Material();
  586. Material(const HShader& shader);
  587. /**
  588. * @copydoc CoreObject::createCore
  589. */
  590. SPtr<CoreObjectCore> createCore() const override;
  591. /**
  592. * @copydoc CoreObject::syncToCore
  593. */
  594. CoreSyncData syncToCore(FrameAlloc* allocator) override;
  595. /**
  596. * @copydoc CoreObject::getCoreDependencies
  597. */
  598. void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
  599. /**
  600. * @copydoc CoreObject::markCoreDirty
  601. */
  602. void _markCoreDirty() override;
  603. /**
  604. * @copydoc CoreObject::markDependenciesDirty
  605. */
  606. void _markDependenciesDirty() override;
  607. /**
  608. * @copydoc IResourceListener::markResourcesDirty
  609. */
  610. void _markResourcesDirty() override;
  611. /**
  612. * @copydoc IResourceListener::getListenerResources
  613. */
  614. void getListenerResources(Vector<HResource>& resources) override;
  615. /**
  616. * @copydoc IResourceListener::notifyResourceLoaded
  617. */
  618. void notifyResourceLoaded(const HResource& resource) override;
  619. /**
  620. * @copydoc IResourceListener::notifyResourceDestroyed
  621. */
  622. void notifyResourceDestroyed(const HResource& resource) override;
  623. /**
  624. * @copydoc IResourceListener::notifyResourceChanged
  625. */
  626. void notifyResourceChanged(const HResource& resource) override;
  627. /**
  628. * @copydoc Resource::getResourceDependencies
  629. */
  630. void getResourceDependencies(FrameVector<HResource>& dependencies) const override;
  631. /**
  632. * @brief Performs material initialization when all resources are ready.
  633. */
  634. void initializeIfLoaded();
  635. UINT32 mLoadFlags;
  636. /************************************************************************/
  637. /* RTTI */
  638. /************************************************************************/
  639. public:
  640. friend class MaterialRTTI;
  641. static RTTITypeBase* getRTTIStatic();
  642. virtual RTTITypeBase* getRTTI() const override;
  643. };
  644. }