BsMaterial.h 31 KB

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