CmMaterial.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmResource.h"
  4. #include "CmGpuParam.h"
  5. #include "CmVector2.h"
  6. #include "CmVector3.h"
  7. #include "CmVector4.h"
  8. #include "CmMatrix3.h"
  9. #include "CmMatrix4.h"
  10. #include "CmCommonEnums.h"
  11. namespace CamelotFramework
  12. {
  13. class CM_EXPORT PassParameters
  14. {
  15. public:
  16. GpuParamsPtr mVertParams;
  17. GpuParamsPtr mFragParams;
  18. GpuParamsPtr mGeomParams;
  19. GpuParamsPtr mHullParams;
  20. GpuParamsPtr mDomainParams;
  21. GpuParamsPtr mComputeParams;
  22. // Helper method
  23. GpuParamsPtr& getParamByIdx(UINT32 idx)
  24. {
  25. GpuParamsPtr* paramArray[] = {&mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams};
  26. return *paramArray[idx];
  27. }
  28. // Helper method
  29. UINT32 getNumParams() const { return 6; }
  30. };
  31. class CM_EXPORT Material : public Resource
  32. {
  33. public:
  34. struct StructData
  35. {
  36. StructData()
  37. :size(0), data(nullptr)
  38. { }
  39. StructData(UINT32 _size)
  40. :size(_size)
  41. {
  42. data = std::shared_ptr<void>(cm_alloc<ScratchAlloc>(_size), &cm_free<ScratchAlloc>);
  43. }
  44. void write(void* _data)
  45. {
  46. memcpy(data.get(), _data, size);
  47. }
  48. std::shared_ptr<void> data;
  49. UINT32 size;
  50. };
  51. ~Material();
  52. /**
  53. * @brief Sets a shader that will be used by the material.
  54. * Shaders best technique will be retrieved and used in all subsequent Material
  55. * operations.
  56. * You need to call this method before doing any other operations with this class.
  57. * After setting the shader if change any systems that a shader technique is defendant upon (render system, renderer, ...)
  58. * you will need to call this method again on all your Materials to make sure technique used is updated.
  59. */
  60. void setShader(ShaderPtr shader);
  61. ShaderPtr getShader() const { return mShader; }
  62. void setTexture(const String& name, const HTexture& value) { return getParamTexture(name).set(value); }
  63. void setSamplerState(const String& name, const HSamplerState& value) { return getParamSamplerState(name).set(value); }
  64. void setFloat(const String& name, float value, UINT32 arrayIdx = 0) { return getParamFloat(name).set(value, arrayIdx); }
  65. void setColor(const String& name, const Color& value, UINT32 arrayIdx = 0);
  66. void setVec2(const String& name, const Vector2& value, UINT32 arrayIdx = 0) { return getParamVec2(name).set(value, arrayIdx); }
  67. void setVec3(const String& name, const Vector3& value, UINT32 arrayIdx = 0) { return getParamVec3(name).set(value, arrayIdx); }
  68. void setVec4(const String& name, const Vector4& value, UINT32 arrayIdx = 0) { return getParamVec4(name).set(value, arrayIdx); }
  69. void setMat3(const String& name, const Matrix3& value, UINT32 arrayIdx = 0) { return getParamMat3(name).set(value, arrayIdx); }
  70. void setMat4(const String& name, const Matrix4& value, UINT32 arrayIdx = 0) { return getParamMat4(name).set(value, arrayIdx); }
  71. void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
  72. void setRenderQueue(INT16 renderQueue) { mRenderQueue = renderQueue; }
  73. void setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlock);
  74. HTexture getTexture(const String& name) const { return getParamTexture(name).get(); }
  75. HSamplerState getSamplerState(const String& name) const { return getParamSamplerState(name).get(); }
  76. float getFloat(const String& name, UINT32 arrayIdx = 0) const { return getParamFloat(name).get(arrayIdx); }
  77. Vector2 getVec2(const String& name, UINT32 arrayIdx = 0) const { return getParamVec2(name).get(arrayIdx); }
  78. Vector3 getVec3(const String& name, UINT32 arrayIdx = 0) const { return getParamVec3(name).get(arrayIdx); }
  79. Vector4 getVec4(const String& name, UINT32 arrayIdx = 0) const { return getParamVec4(name).get(arrayIdx); }
  80. Matrix3 getMat3(const String& name, UINT32 arrayIdx = 0) const { return getParamMat3(name).get(arrayIdx); }
  81. Matrix4 getMat4(const String& name, UINT32 arrayIdx = 0) const { return getParamMat4(name).get(arrayIdx); }
  82. StructData getStructData(const String& name, UINT32 arrayIdx = 0) const;
  83. GpuParamFloat getParamFloat(const String& name) const;
  84. GpuParamVec2 getParamVec2(const String& name) const;
  85. GpuParamVec3 getParamVec3(const String& name) const;
  86. GpuParamVec4 getParamVec4(const String& name) const;
  87. GpuParamMat3 getParamMat3(const String& name) const;
  88. GpuParamMat4 getParamMat4(const String& name) const;
  89. GpuParamStruct getParamStruct(const String& name) const;
  90. GpuParamTexture getParamTexture(const String& name) const;
  91. GpuParamSampState getParamSamplerState(const String& name) const;
  92. INT16 getRenderQueue() const { return mRenderQueue; }
  93. UINT32 getNumPasses() const;
  94. PassPtr getPass(UINT32 passIdx) const;
  95. PassParametersPtr getPassParameters(UINT32 passIdx) const;
  96. static HMaterial create();
  97. static HMaterial create(ShaderPtr shader);
  98. protected:
  99. void destroy_internal();
  100. /**
  101. * @brief Allows you to retrieve a handle to a parameter that you can then use for quickly
  102. * setting and retrieving parameter data. This allows you to set/get parameter data
  103. * without all the cost of extra lookups otherwise required.
  104. *
  105. * @note All of these handles will be invalidated if material shader ever changes. It is up to the
  106. * caller to keep track of that.
  107. */
  108. template <typename T>
  109. void getParam(const String& name, GpuDataParamBase<T>& output) const
  110. {
  111. throwIfNotInitialized();
  112. auto iterFind = mValidParams.find(name);
  113. if(iterFind == mValidParams.end())
  114. {
  115. LOGWRN("Material doesn't have a parameter named " + name);
  116. return;
  117. }
  118. const String& gpuVarName = iterFind->second;
  119. GpuParamsPtr params = findParamsWithName(gpuVarName);
  120. params->getParam<T>(gpuVarName, output);
  121. }
  122. private:
  123. friend class MaterialManager;
  124. ShaderPtr mShader;
  125. TechniquePtr mBestTechnique;
  126. INT16 mRenderQueue;
  127. Set<String>::type mValidShareableParamBlocks;
  128. Map<String, String>::type mValidParams; // Also maps Shader param name -> gpu variable name
  129. Vector<PassParametersPtr>::type mParametersPerPass;
  130. Vector<GpuParamBlockBufferPtr>::type mParamBuffers;
  131. Material();
  132. void throwIfNotInitialized() const;
  133. const Map<String, String>::type& getValidParamNames() const { return mValidParams; }
  134. void initBestTechnique();
  135. Map<String, const GpuParamDataDesc*>::type determineValidDataParameters(const Vector<const GpuParamDesc*>::type& paramDescs) const;
  136. Set<String>::type determineValidObjectParameters(const Vector<const GpuParamDesc*>::type& paramDescs) const;
  137. Set<String>::type determineValidShareableParamBlocks(const Vector<const GpuParamDesc*>::type& paramDescs) const;
  138. Map<String, String>::type determineParameterToBlockMapping(const Vector<const GpuParamDesc*>::type& paramDescs);
  139. bool areParamsEqual(const GpuParamDataDesc& paramA, const GpuParamDataDesc& paramB, bool ignoreBufferOffsets = false) const;
  140. void freeParamBuffers();
  141. GpuParamsPtr findParamsWithName(const String& name) const;
  142. GpuParamsPtr findTexWithName(const String& name) const;
  143. GpuParamsPtr findSamplerStateWithName(const String& name) const;
  144. /************************************************************************/
  145. /* RTTI */
  146. /************************************************************************/
  147. public:
  148. friend class MaterialRTTI;
  149. static RTTITypeBase* getRTTIStatic();
  150. virtual RTTITypeBase* getRTTI() const;
  151. };
  152. }