CmShader.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "CmShader.h"
  2. #include "CmTechnique.h"
  3. #include "CmException.h"
  4. #include "CmDebug.h"
  5. #include "CmShaderRTTI.h"
  6. namespace BansheeEngine
  7. {
  8. Shader::Shader(const String& name)
  9. :mName(name)
  10. {
  11. }
  12. TechniquePtr Shader::addTechnique(const String& renderSystem, const String& renderer)
  13. {
  14. TechniquePtr technique = cm_shared_ptr<Technique, PoolAlloc>(renderSystem, renderer);
  15. mTechniques.push_back(technique);
  16. return technique;
  17. }
  18. void Shader::removeTechnique(UINT32 idx)
  19. {
  20. if(idx < 0 || idx >= mTechniques.size())
  21. CM_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx));
  22. int count = 0;
  23. auto iter = mTechniques.begin();
  24. while(count != idx)
  25. {
  26. ++count;
  27. ++iter;
  28. }
  29. mTechniques.erase(iter);
  30. }
  31. void Shader::removeTechnique(TechniquePtr technique)
  32. {
  33. auto iterFind = std::find(mTechniques.begin(), mTechniques.end(), technique);
  34. if(iterFind == mTechniques.end())
  35. CM_EXCEPT(InvalidParametersException, "Cannot remove specified technique because it wasn't found in this shader.");
  36. mTechniques.erase(iterFind);
  37. }
  38. TechniquePtr Shader::getBestTechnique() const
  39. {
  40. for(auto iter = mTechniques.begin(); iter != mTechniques.end(); ++iter)
  41. {
  42. if((*iter)->isSupported())
  43. {
  44. return *iter;
  45. }
  46. }
  47. return nullptr;
  48. // TODO - Low priority. Instead of returning null use an extremely simple technique that will be supported almost everywhere as a fallback.
  49. }
  50. void Shader::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 arraySize, UINT32 elementSize, bool hidden)
  51. {
  52. if(type == GPDT_STRUCT && elementSize <= 0)
  53. CM_EXCEPT(InvalidParametersException, "You need to provide a non-zero element size for a struct parameter.")
  54. SHADER_DATA_PARAM_DESC desc;
  55. desc.name = name;
  56. desc.gpuVariableName = gpuVariableName;
  57. desc.type = type;
  58. desc.arraySize = arraySize;
  59. desc.hidden = hidden;
  60. desc.elementSize = elementSize;
  61. mDataParams[name] = desc;
  62. mObjectParams.erase(name);
  63. }
  64. void Shader::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, bool hidden)
  65. {
  66. SHADER_OBJECT_PARAM_DESC desc;
  67. desc.name = name;
  68. desc.gpuVariableName = gpuVariableName;
  69. desc.type = type;
  70. desc.hidden = hidden;
  71. mObjectParams[name] = desc;
  72. mDataParams.erase(name);
  73. }
  74. GpuParamType Shader::getParamType(const String& name) const
  75. {
  76. auto findIterData = mDataParams.find(name);
  77. if(findIterData != mDataParams.end())
  78. return GPT_DATA;
  79. auto findIterObject = mObjectParams.find(name);
  80. if(findIterObject != mObjectParams.end())
  81. return GPT_OBJECT;
  82. CM_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
  83. }
  84. const SHADER_DATA_PARAM_DESC& Shader::getDataParamDesc(const String& name) const
  85. {
  86. auto findIterData = mDataParams.find(name);
  87. if(findIterData != mDataParams.end())
  88. return findIterData->second;
  89. CM_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
  90. }
  91. const SHADER_OBJECT_PARAM_DESC& Shader::getObjectParamDesc(const String& name) const
  92. {
  93. auto findIterObject = mObjectParams.find(name);
  94. if(findIterObject != mObjectParams.end())
  95. return findIterObject->second;
  96. CM_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
  97. }
  98. bool Shader::hasDataParam(const String& name) const
  99. {
  100. auto findIterData = mDataParams.find(name);
  101. if(findIterData != mDataParams.end())
  102. return true;
  103. return false;
  104. }
  105. bool Shader::hasObjectParam(const String& name) const
  106. {
  107. auto findIterObject = mObjectParams.find(name);
  108. if(findIterObject != mObjectParams.end())
  109. return true;
  110. return false;
  111. }
  112. void Shader::removeParameter(const String& name)
  113. {
  114. mDataParams.erase(name);
  115. mObjectParams.erase(name);
  116. }
  117. void Shader::setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage)
  118. {
  119. SHADER_PARAM_BLOCK_DESC desc;
  120. desc.name = name;
  121. desc.shared = shared;
  122. desc.usage = usage;
  123. mParamBlocks[name] = desc;
  124. }
  125. bool Shader::isSampler(GpuParamObjectType type)
  126. {
  127. switch(type)
  128. {
  129. case GPOT_SAMPLER1D:
  130. case GPOT_SAMPLER2D:
  131. case GPOT_SAMPLER3D:
  132. case GPOT_SAMPLERCUBE:
  133. return true;
  134. }
  135. return false;
  136. }
  137. bool Shader::isTexture(GpuParamObjectType type)
  138. {
  139. switch(type)
  140. {
  141. case GPOT_TEXTURE1D:
  142. case GPOT_TEXTURE2D:
  143. case GPOT_TEXTURE3D:
  144. case GPOT_TEXTURECUBE:
  145. case GPOT_RWTEXTURE1D:
  146. case GPOT_RWTEXTURE2D:
  147. case GPOT_RWTEXTURE3D:
  148. return true;
  149. }
  150. return false;
  151. }
  152. bool Shader::isBuffer(GpuParamObjectType type)
  153. {
  154. switch(type)
  155. {
  156. case GPOT_BYTE_BUFFER:
  157. case GPOT_STRUCTURED_BUFFER:
  158. case GPOT_RWBYTE_BUFFER:
  159. case GPOT_RWAPPEND_BUFFER:
  160. case GPOT_RWCONSUME_BUFFER:
  161. case GPOT_RWSTRUCTURED_BUFFER:
  162. case GPOT_RWSTRUCTURED_BUFFER_WITH_COUNTER:
  163. case GPOT_RWTYPED_BUFFER:
  164. return true;
  165. }
  166. return false;
  167. }
  168. ShaderPtr Shader::create(const String& name)
  169. {
  170. ShaderPtr newShader = cm_core_ptr<Shader, PoolAlloc>(new (cm_alloc<Shader, PoolAlloc>()) Shader(name));
  171. newShader->_setThisPtr(newShader);
  172. newShader->initialize();
  173. return newShader;
  174. }
  175. RTTITypeBase* Shader::getRTTIStatic()
  176. {
  177. return ShaderRTTI::instance();
  178. }
  179. RTTITypeBase* Shader::getRTTI() const
  180. {
  181. return Shader::getRTTIStatic();
  182. }
  183. }