BsMaterial.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "BsResource.h"
  6. #include "BsIResourceListener.h"
  7. #include "BsMaterialParam.h"
  8. #include "BsMaterialParams.h"
  9. #include "BsTechnique.h"
  10. #include "BsVector2.h"
  11. #include "BsVector3.h"
  12. #include "BsVector4.h"
  13. #include "BsMatrix3.h"
  14. #include "BsMatrix4.h"
  15. namespace bs
  16. {
  17. /** @addtogroup Implementation
  18. * @{
  19. */
  20. template<bool Core> struct TGpuParamBlockBufferPtrType { };
  21. template<> struct TGpuParamBlockBufferPtrType<false> { typedef SPtr<GpuParamBlockBuffer> Type; };
  22. template<> struct TGpuParamBlockBufferPtrType<true> { typedef SPtr<GpuParamBlockBufferCore> Type; };
  23. template<bool Core> struct TGpuProgramType { };
  24. template<> struct TGpuProgramType<false> { typedef SPtr<GpuProgram> Type; };
  25. template<> struct TGpuProgramType<true> { typedef SPtr<GpuProgramCore> Type; };
  26. template<bool Core> struct TShaderType {};
  27. template<> struct TShaderType < false > { typedef HShader Type; };
  28. template<> struct TShaderType < true > { typedef SPtr<ShaderCore> Type; };
  29. template<bool Core> struct TGpuParamBlockBufferType {};
  30. template<> struct TGpuParamBlockBufferType < false > { typedef GpuParamBlockBuffer Type; };
  31. template<> struct TGpuParamBlockBufferType < true > { typedef GpuParamBlockBufferCore Type; };
  32. template<bool Core> struct TGpuParamsSetType {};
  33. template<> struct TGpuParamsSetType < false > { typedef GpuParamsSet Type; };
  34. template<> struct TGpuParamsSetType < true > { typedef GpuParamsSetCore Type; };
  35. /**
  36. * Material that controls how objects are rendered. It is represented by a shader and parameters used to set up that
  37. * shader. It provides a simple interface for manipulating the parameters.
  38. */
  39. class BS_CORE_EXPORT MaterialBase
  40. {
  41. public:
  42. /** Data used to describe a structure defined within a shader. */
  43. struct StructData
  44. {
  45. StructData()
  46. :data(nullptr), size(0)
  47. { }
  48. StructData(UINT32 _size)
  49. :size(_size)
  50. {
  51. data = std::shared_ptr<void>(bs_alloc(_size), (void(*)(void*))&bs_free);
  52. }
  53. /**
  54. * Writes the specified data to the internal buffer. Caller must ensure size of the provided buffer is correct.
  55. */
  56. void write(void* _data)
  57. {
  58. memcpy(data.get(), _data, size);
  59. }
  60. SPtr<void> data;
  61. UINT32 size;
  62. };
  63. MaterialBase() { }
  64. virtual ~MaterialBase() { }
  65. /** @name Internal
  66. * @{
  67. */
  68. /** Marks the contents of the sim thread object as dirty, causing it to sync with its core thread counterpart. */
  69. virtual void _markCoreDirty() { }
  70. /** @} */
  71. protected:
  72. /** @copydoc CoreObject::markDependenciesDirty */
  73. virtual void _markDependenciesDirty() { }
  74. /** @copydoc IResourceListener::markListenerResourcesDirty */
  75. virtual void _markResourcesDirty() { }
  76. };
  77. /** @copydoc MaterialBase */
  78. template<bool Core>
  79. class BS_CORE_EXPORT TMaterial : public MaterialBase
  80. {
  81. public:
  82. typedef typename TGpuParamTextureType<Core>::Type TextureType;
  83. typedef typename TGpuBufferType<Core>::Type BufferType;
  84. typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
  85. typedef typename TGpuProgramType<Core>::Type GpuProgramType;
  86. typedef typename TPassType<Core>::Type PassType;
  87. typedef typename TTechniqueType<Core>::Type TechniqueType;
  88. typedef typename TShaderType<Core>::Type ShaderType;
  89. typedef typename TGpuParamsSetType<Core>::Type GpuParamsSetType;
  90. typedef typename TMaterialParamsType<Core>::Type MaterialParamsType;
  91. TMaterial() { }
  92. virtual ~TMaterial() { }
  93. /** Returns the currently active shader. */
  94. ShaderType getShader() const { return mShader; }
  95. /** Returns the total number of techniques supported by this material. */
  96. UINT32 getNumTechniques() const { return (UINT32)mTechniques.size(); }
  97. /** Attempts to find a technique with the supported tag. Returns an index of the technique, or -1 if not found. */
  98. UINT32 findTechnique(const StringID& tag) const;
  99. /** Finds the index of the default (primary) technique to use. */
  100. UINT32 getDefaultTechnique() const;
  101. /**
  102. * Returns the number of passes that are used by the technique at the specified index.
  103. *
  104. * @param[in] techniqueIdx Index of the technique to retrieve the number of passes for. 0 is always guaranteed
  105. * to be the default technique.
  106. * @return Number of passes used by the technique.
  107. */
  108. UINT32 getNumPasses(UINT32 techniqueIdx = 0) const;
  109. /**
  110. * Retrieves a specific shader pass from the provided technique.
  111. *
  112. * @param[in] passIdx Sequential index of the pass to retrieve.
  113. * @param[in] techniqueIdx Index of the technique to retrieve the pass for. 0 is always guaranteed to be
  114. * the default technique.
  115. * @return Pass if found, null otherwise.
  116. */
  117. SPtr<PassType> getPass(UINT32 passIdx = 0, UINT32 techniqueIdx = 0) const;
  118. /**
  119. * Creates a set of GpuParams that may be used for binding material parameters to the GPU. The expected behaviour
  120. * is to create a set of GpuParams per-technique once, and then before binding them to the GPU call
  121. * updateParamsSet() to ensure any dirty parameters are transfered from the material to GpuParams. You may also
  122. * use the parameter set to manually modify parameters on a per-program basis, in which case no further updates from
  123. * the material are necessary.
  124. */
  125. SPtr<GpuParamsSetType> createParamsSet(UINT32 techniqueIdx = 0);
  126. /**
  127. * Copies internal material parameter data to the provided params set.
  128. *
  129. * @param[in] paramsSet Parameter set to update.
  130. * @param[in] updateAll Normally the system will track dirty parameters since the last call to this method
  131. * (on a per-set basis), and only update the dirty ones. Set this to true if you want
  132. * to force all parameters to update, regardless of their dirty state.
  133. */
  134. void updateParamsSet(const SPtr<GpuParamsSetType>& paramsSet, bool updateAll = false);
  135. /**
  136. * Assigns a float value to the shader parameter with the specified name.
  137. *
  138. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  139. */
  140. void setFloat(const String& name, float value, UINT32 arrayIdx = 0) { return getParamFloat(name).set(value, arrayIdx); }
  141. /**
  142. * Assigns a color to the shader parameter with the specified name.
  143. *
  144. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  145. */
  146. void setColor(const String& name, const Color& value, UINT32 arrayIdx = 0) { return getParamColor(name).set(value, arrayIdx); }
  147. /**
  148. * Assigns a 2D vector to the shader parameter with the specified name.
  149. *
  150. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  151. */
  152. void setVec2(const String& name, const Vector2& value, UINT32 arrayIdx = 0) { return getParamVec2(name).set(value, arrayIdx); }
  153. /**
  154. * Assigns a 3D vector to the shader parameter with the specified name.
  155. *
  156. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  157. */
  158. void setVec3(const String& name, const Vector3& value, UINT32 arrayIdx = 0) { return getParamVec3(name).set(value, arrayIdx); }
  159. /**
  160. * Assigns a 4D vector to the shader parameter with the specified name.
  161. *
  162. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  163. */
  164. void setVec4(const String& name, const Vector4& value, UINT32 arrayIdx = 0) { return getParamVec4(name).set(value, arrayIdx); }
  165. /**
  166. * Assigns a 3x3 matrix to the shader parameter with the specified name.
  167. *
  168. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  169. */
  170. void setMat3(const String& name, const Matrix3& value, UINT32 arrayIdx = 0) { return getParamMat3(name).set(value, arrayIdx); }
  171. /**
  172. * Assigns a 4x4 matrix to the shader parameter with the specified name.
  173. *
  174. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  175. */
  176. void setMat4(const String& name, const Matrix4& value, UINT32 arrayIdx = 0) { return getParamMat4(name).set(value, arrayIdx); }
  177. /**
  178. * Assigns a structure to the shader parameter with the specified name.
  179. *
  180. * Structure is provided as a raw buffer and caller must ensure structure in buffer matches what the shader expects.
  181. *
  182. * Optionally if the parameter is an array you may provide an array index to assign the value to.
  183. */
  184. void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
  185. /** Assigns a texture to the shader parameter with the specified name. */
  186. void setTexture(const String& name, const TextureType& value) { return getParamTexture(name).set(value); }
  187. /** Assigns a texture to be used for random load/store operations to the shader parameter with the specified name. */
  188. void setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface)
  189. {
  190. return getParamLoadStoreTexture(name).set(value, surface);
  191. }
  192. /** Assigns a buffer to the shader parameter with the specified name. */
  193. void setBuffer(const String& name, const BufferType& value) { return getParamBuffer(name).set(value); }
  194. /** Assigns a sampler state to the shader parameter with the specified name. */
  195. void setSamplerState(const String& name, const SamplerStateType& value) { return getParamSamplerState(name).set(value); }
  196. /**
  197. * Returns a float value assigned with the parameter with the specified name.
  198. *
  199. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  200. */
  201. float getFloat(const String& name, UINT32 arrayIdx = 0) const { return getParamFloat(name).get(arrayIdx); }
  202. /**
  203. * Returns a color assigned with the parameter with the specified name.
  204. *
  205. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  206. */
  207. Color getColor(const String& name, UINT32 arrayIdx = 0) const { return getParamColor(name).get(arrayIdx); }
  208. /**
  209. * Returns a 2D vector assigned with the parameter with the specified name.
  210. *
  211. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  212. */
  213. Vector2 getVec2(const String& name, UINT32 arrayIdx = 0) const { return getParamVec2(name).get(arrayIdx); }
  214. /**
  215. * Returns a 3D vector assigned with the parameter with the specified name.
  216. *
  217. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  218. */
  219. Vector3 getVec3(const String& name, UINT32 arrayIdx = 0) const { return getParamVec3(name).get(arrayIdx); }
  220. /**
  221. * Returns a 4D vector assigned with the parameter with the specified name.
  222. *
  223. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  224. */
  225. Vector4 getVec4(const String& name, UINT32 arrayIdx = 0) const { return getParamVec4(name).get(arrayIdx); }
  226. /**
  227. * Returns a 3x3 matrix assigned with the parameter with the specified name.
  228. *
  229. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  230. */
  231. Matrix3 getMat3(const String& name, UINT32 arrayIdx = 0) const { return getParamMat3(name).get(arrayIdx); }
  232. /**
  233. * Returns a 4x4 matrix assigned with the parameter with the specified name.
  234. *
  235. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  236. */
  237. Matrix4 getMat4(const String& name, UINT32 arrayIdx = 0) const { return getParamMat4(name).get(arrayIdx); }
  238. /** Returns a texture assigned with the parameter with the specified name. */
  239. TextureType getTexture(const String& name) const { return getParamTexture(name).get(); }
  240. /** Returns a sampler state assigned with the parameter with the specified name. */
  241. SamplerStateType getSamplerState(const String& name) const { return getParamSamplerState(name).get(); }
  242. /**
  243. * Returns a buffer representing a structure assigned to the parameter with the specified name.
  244. *
  245. * Optionally if the parameter is an array you may provide an array index you which to retrieve.
  246. */
  247. MaterialBase::StructData getStructData(const String& name, UINT32 arrayIdx = 0) const
  248. {
  249. TMaterialParamStruct<Core> structParam = getParamStruct(name);
  250. MaterialBase::StructData data(structParam.getElementSize());
  251. structParam.get(data.data.get(), structParam.getElementSize(), arrayIdx);
  252. return data;
  253. }
  254. /**
  255. * Returns a float GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  256. * values than calling Material::get* / Material::set* methods.
  257. *
  258. * @note
  259. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  260. * use it throughout material lifetime to assign and retrieve parameter values.
  261. * @note
  262. * If material shader changes this handle will be invalidated.
  263. */
  264. TMaterialDataParam<float, Core> getParamFloat(const String& name) const
  265. {
  266. TMaterialDataParam<float, Core> gpuParam;
  267. getParam(name, gpuParam);
  268. return gpuParam;
  269. }
  270. /**
  271. * Returns a color GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  272. * values than calling Material::get* / Material::set* methods.
  273. *
  274. * @note
  275. * Expected behavior is that you would retrieve this parameter when initially constructing the material,
  276. * and then use it throughout material lifetime to assign and retrieve parameter values.
  277. * @note
  278. * If material shader changes this handle will be invalidated.
  279. */
  280. TMaterialDataParam<Color, Core> getParamColor(const String& name) const
  281. {
  282. TMaterialDataParam<Color, Core> gpuParam;
  283. getParam(name, gpuParam);
  284. return gpuParam;
  285. }
  286. /**
  287. * Returns a 2D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  288. * values than calling Material::get* / Material::set* methods.
  289. *
  290. * @note
  291. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  292. * use it throughout material lifetime to assign and retrieve parameter values.
  293. * @note
  294. * If material shader changes this handle will be invalidated.
  295. */
  296. TMaterialDataParam<Vector2, Core> getParamVec2(const String& name) const
  297. {
  298. TMaterialDataParam<Vector2, Core> gpuParam;
  299. getParam(name, gpuParam);
  300. return gpuParam;
  301. }
  302. /**
  303. * Returns a 3D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  304. * values than calling Material::get* / Material::set* methods.
  305. *
  306. * @note
  307. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  308. * use it throughout material lifetime to assign and retrieve parameter values.
  309. * @note
  310. * If material shader changes this handle will be invalidated.
  311. */
  312. TMaterialDataParam<Vector3, Core> getParamVec3(const String& name) const
  313. {
  314. TMaterialDataParam<Vector3, Core> gpuParam;
  315. getParam(name, gpuParam);
  316. return gpuParam;
  317. }
  318. /**
  319. * Returns a 4D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  320. * values than calling Material::get* / Material::set* methods.
  321. *
  322. * @note
  323. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  324. * use it throughout material lifetime to assign and retrieve parameter values.
  325. * @note
  326. * If material shader changes this handle will be invalidated.
  327. */
  328. TMaterialDataParam<Vector4, Core> getParamVec4(const String& name) const
  329. {
  330. TMaterialDataParam<Vector4, Core> gpuParam;
  331. getParam(name, gpuParam);
  332. return gpuParam;
  333. }
  334. /**
  335. * Returns a 3x3 matrix GPU parameter. This parameter may be used for more efficiently getting/setting GPU
  336. * parameter values than calling Material::get* / Material::set* methods.
  337. *
  338. * @note
  339. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  340. * use it throughout material lifetime to assign and retrieve parameter values.
  341. * @note
  342. * If material shader changes this handle will be invalidated.
  343. */
  344. TMaterialDataParam<Matrix3, Core> getParamMat3(const String& name) const
  345. {
  346. TMaterialDataParam<Matrix3, Core> gpuParam;
  347. getParam(name, gpuParam);
  348. return gpuParam;
  349. }
  350. /**
  351. * Returns a 4x4 matrix GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  352. * values than calling Material::get* / Material::set* methods.
  353. *
  354. * @note
  355. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  356. * use it throughout material lifetime to assign and retrieve parameter values.
  357. * @note
  358. * If material shader changes this handle will be invalidated.
  359. */
  360. TMaterialDataParam<Matrix4, Core> getParamMat4(const String& name) const
  361. {
  362. TMaterialDataParam<Matrix4, Core> gpuParam;
  363. getParam(name, gpuParam);
  364. return gpuParam;
  365. }
  366. /**
  367. * Returns a structure GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  368. * values than calling Material::get* / Material::set* methods.
  369. *
  370. * @note
  371. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  372. * use it throughout material lifetime to assign and retrieve parameter values.
  373. * @note
  374. * If material shader changes this handle will be invalidated.
  375. */
  376. TMaterialParamStruct<Core> getParamStruct(const String& name) const;
  377. /**
  378. * Returns a texture GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  379. * values than calling Material::get* / Material::set* methods.
  380. *
  381. * @note
  382. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  383. * use it throughout material lifetime to assign and retrieve parameter values.
  384. * @note
  385. * If material shader changes this handle will be invalidated.
  386. */
  387. TMaterialParamTexture<Core> getParamTexture(const String& name) const;
  388. /**
  389. * Returns a GPU parameter for binding a load/store texture. This parameter may be used for more efficiently
  390. * getting/setting GPU parameter values than calling Material::get* / Material::set* methods.
  391. *
  392. * @note
  393. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  394. * use it throughout material lifetime to assign and retrieve parameter values.
  395. * @note
  396. * If material shader changes this handle will be invalidated.
  397. */
  398. TMaterialParamLoadStoreTexture<Core> getParamLoadStoreTexture(const String& name) const;
  399. /**
  400. * Returns a buffer GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
  401. * values than calling Material::get* / Material::set* methods.
  402. *
  403. * @note
  404. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  405. * use it throughout material lifetime to assign and retrieve parameter values.
  406. * @note
  407. * If material shader changes this handle will be invalidated.
  408. */
  409. TMaterialParamBuffer<Core> getParamBuffer(const String& name) const;
  410. /**
  411. * Returns a sampler state GPU parameter. This parameter may be used for more efficiently getting/setting GPU
  412. * parameter values than calling Material::get* / Material::set* methods.
  413. *
  414. * @note
  415. * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
  416. * use it throughout material lifetime to assign and retrieve parameter values.
  417. * @note
  418. * If material shader changes this handle will be invalidated.
  419. */
  420. TMaterialParamSampState<Core> getParamSamplerState(const String& name) const;
  421. /**
  422. * Allows you to retrieve a handle to a parameter that you can then use for quickly setting and retrieving parameter
  423. * data. This allows you to set/get parameter data without all the cost of extra lookups otherwise required.
  424. *
  425. * @note
  426. * All of these handles will be invalidated if material shader ever changes. It is up to the caller to keep track
  427. * of that.
  428. */
  429. template <typename T>
  430. void getParam(const String& name, TMaterialDataParam<T, Core>& output) const;
  431. /**
  432. * @name Internal
  433. * @{
  434. */
  435. /**
  436. * Returns an object containg all of material's parameters. Allows the caller to manipulate the parameters more
  437. * directly.
  438. */
  439. SPtr<MaterialParamsType> _getInternalParams() const { return mParams; }
  440. /** @} */
  441. protected:
  442. /**
  443. * Assigns a value from a raw buffer to the parameter with the specified name. Buffer must be of sizeof(T) *
  444. * numElements size and initialized.
  445. *
  446. * @note Provided parameter must exist, no checking is done.
  447. */
  448. template <typename T>
  449. void setParamValue(const String& name, UINT8* buffer, UINT32 numElements);
  450. /**
  451. * Initializes the material by using the compatible techniques from the currently set shader. Shader must contain
  452. * the techniques that matches the current renderer and render system.
  453. */
  454. void initializeTechniques();
  455. /** Assigns all the default parameters specified in the shader to the material. */
  456. void initDefaultParameters();
  457. /** Throw an exception if no shader is set, or no acceptable technique was found. */
  458. void throwIfNotInitialized() const;
  459. ShaderType mShader;
  460. SPtr<MaterialParamsType> mParams;
  461. Vector<SPtr<TechniqueType>> mTechniques;
  462. };
  463. /** @} */
  464. /** @addtogroup Material-Internal
  465. * @{
  466. */
  467. /** @copydoc MaterialBase */
  468. class BS_CORE_EXPORT MaterialCore : public CoreObjectCore, public TMaterial<true>
  469. {
  470. public:
  471. ~MaterialCore() { }
  472. /** @copydoc Material::setShader */
  473. void setShader(const SPtr<ShaderCore>& shader);
  474. /** Creates a new material with the specified shader. */
  475. static SPtr<MaterialCore> create(const SPtr<ShaderCore>& shader);
  476. private:
  477. friend class Material;
  478. MaterialCore() { }
  479. MaterialCore(const SPtr<ShaderCore>& shader);
  480. MaterialCore(const SPtr<ShaderCore>& shader, const Vector<SPtr<TechniqueCore>>& techniques,
  481. const SPtr<MaterialParamsCore>& materialParams);
  482. /** @copydoc CoreObjectCore::syncToCore */
  483. void syncToCore(const CoreSyncData& data) override;
  484. };
  485. /** @} */
  486. /** @addtogroup Material
  487. * @{
  488. */
  489. /** @copydoc MaterialBase */
  490. class BS_CORE_EXPORT Material : public Resource, public TMaterial<false>, public IResourceListener
  491. {
  492. public:
  493. ~Material() { }
  494. /**
  495. * Sets a shader that will be used by the material. Best technique within the provided shader will be used for the
  496. * material.
  497. *
  498. * @note
  499. * Shader must be set before doing any other operations with the material.
  500. * @note
  501. * After setting the shader if you change the implementation of systems that a shader technique is dependent upon
  502. * (render system, renderer, etc), you will need to call this method again on all your Materials to make sure
  503. * technique used is updated.
  504. */
  505. void setShader(const HShader& shader);
  506. /** Retrieves an implementation of a material usable only from the core thread. */
  507. SPtr<MaterialCore> getCore() const;
  508. /** @copydoc CoreObject::initialize */
  509. void initialize() override;
  510. /** Creates a deep copy of the material and returns the new object. */
  511. HMaterial clone();
  512. /**
  513. * Creates a new empty material.
  514. *
  515. * @note Make sure you call Material::setShader before using it.
  516. */
  517. static HMaterial create();
  518. /** Creates a new material with the specified shader. */
  519. static HMaterial create(const HShader& shader);
  520. /** @name Internal
  521. * @{
  522. */
  523. /**
  524. * Marks the core data as dirty. This causes the syncToCore() method to trigger the next time objects are synced
  525. * between core and sim threads.
  526. */
  527. void _markCoreDirty() override;
  528. /** @} */
  529. private:
  530. friend class MaterialManager;
  531. Material();
  532. Material(const HShader& shader);
  533. /** @copydoc CoreObject::createCore */
  534. SPtr<CoreObjectCore> createCore() const override;
  535. /** @copydoc CoreObject::syncToCore */
  536. CoreSyncData syncToCore(FrameAlloc* allocator) override;
  537. /** @copydoc CoreObject::getCoreDependencies */
  538. void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
  539. /** @copydoc CoreObject::markDependenciesDirty */
  540. void _markDependenciesDirty() override;
  541. /** @copydoc IResourceListener::markResourcesDirty */
  542. void _markResourcesDirty() override;
  543. /** @copydoc IResourceListener::getListenerResources */
  544. void getListenerResources(Vector<HResource>& resources) override;
  545. /** @copydoc IResourceListener::notifyResourceLoaded */
  546. void notifyResourceLoaded(const HResource& resource) override;
  547. /** @copydoc IResourceListener::notifyResourceChanged */
  548. void notifyResourceChanged(const HResource& resource) override;
  549. /** @copydoc Resource::getResourceDependencies */
  550. void getResourceDependencies(FrameVector<HResource>& dependencies) const override;
  551. /** Performs material initialization when all resources are ready. */
  552. void initializeIfLoaded();
  553. /**
  554. * Uses the provided list of parameters to try to set every parameter in this material. Parameter whose name, type
  555. * or size don't match are ignored and will not be set.
  556. */
  557. void setParams(const SPtr<MaterialParams>& params);
  558. UINT32 mLoadFlags;
  559. /************************************************************************/
  560. /* RTTI */
  561. /************************************************************************/
  562. public:
  563. friend class MaterialRTTI;
  564. static RTTITypeBase* getRTTIStatic();
  565. RTTITypeBase* getRTTI() const override;
  566. };
  567. /** @} */
  568. }