CmMaterialRTTI.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #include "CmMaterialRTTI.h"
  2. #include "CmMaterialManager.h"
  3. #include "CmGpuParamDesc.h"
  4. namespace CamelotEngine
  5. {
  6. RTTITypeBase* MaterialFloatParam::getRTTIStatic() { return MaterialFloatParamRTTI::instance(); }
  7. RTTITypeBase* MaterialFloatParam::getRTTI() const { return MaterialFloatParam::getRTTIStatic(); }
  8. RTTITypeBase* MaterialVec2Param::getRTTIStatic() { return MaterialVec2ParamRTTI::instance(); }
  9. RTTITypeBase* MaterialVec2Param::getRTTI() const { return MaterialVec2Param::getRTTIStatic(); }
  10. RTTITypeBase* MaterialVec3Param::getRTTIStatic() { return MaterialVec3ParamRTTI::instance(); }
  11. RTTITypeBase* MaterialVec3Param::getRTTI() const { return MaterialVec3Param::getRTTIStatic(); }
  12. RTTITypeBase* MaterialVec4Param::getRTTIStatic() { return MaterialVec4ParamRTTI::instance(); }
  13. RTTITypeBase* MaterialVec4Param::getRTTI() const { return MaterialVec4Param::getRTTIStatic(); }
  14. RTTITypeBase* MaterialMat3Param::getRTTIStatic() { return MaterialMat3ParamRTTI::instance(); }
  15. RTTITypeBase* MaterialMat3Param::getRTTI() const { return MaterialMat3Param::getRTTIStatic(); }
  16. RTTITypeBase* MaterialMat4Param::getRTTIStatic() { return MaterialMat4ParamRTTI::instance(); }
  17. RTTITypeBase* MaterialMat4Param::getRTTI() const { return MaterialMat4Param::getRTTIStatic(); }
  18. RTTITypeBase* MaterialTextureParam::getRTTIStatic() { return MaterialTextureParamRTTI::instance(); }
  19. RTTITypeBase* MaterialTextureParam::getRTTI() const { return MaterialTextureParam::getRTTIStatic(); }
  20. RTTITypeBase* MaterialSamplerStateParam::getRTTIStatic() { return MaterialSamplerStateParamRTTI::instance(); }
  21. RTTITypeBase* MaterialSamplerStateParam::getRTTI() const { return MaterialSamplerStateParam::getRTTIStatic(); }
  22. RTTITypeBase* MaterialParams::getRTTIStatic() { return MaterialParamsRTTI::instance(); }
  23. RTTITypeBase* MaterialParams::getRTTI() const { return MaterialParams::getRTTIStatic(); }
  24. void MaterialRTTI::onSerializationStarted(IReflectable* obj)
  25. {
  26. Material* material = static_cast<Material*>(obj);
  27. std::shared_ptr<MaterialParams> params = std::shared_ptr<MaterialParams>(new MaterialParams());
  28. ShaderPtr shader = material->getShader();
  29. if(shader != nullptr)
  30. {
  31. const map<String, String>::type& validParamNames = material->getValidParamNames();
  32. for(auto iter = validParamNames.begin(); iter != validParamNames.end(); ++iter)
  33. {
  34. GpuParamType type = shader->getParamType(iter->first);
  35. if(type == GPT_DATA)
  36. {
  37. const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(iter->first);
  38. switch(paramDesc.type)
  39. {
  40. case GPDT_FLOAT1:
  41. {
  42. for(UINT32 i = 0; i < paramDesc.arraySize; i++)
  43. {
  44. MaterialFloatParam param;
  45. param.name = iter->first;
  46. param.value = material->getFloat(iter->first, i);
  47. param.arrayIdx = i;
  48. params->floatParams.push_back(param);
  49. }
  50. }
  51. break;
  52. case GPDT_FLOAT2:
  53. {
  54. for(UINT32 i = 0; i < paramDesc.arraySize; i++)
  55. {
  56. MaterialVec2Param param;
  57. param.name = iter->first;
  58. param.value = material->getVec2(iter->first, i);
  59. param.arrayIdx = i;
  60. params->vec2Params.push_back(param);
  61. }
  62. }
  63. break;
  64. case GPDT_FLOAT3:
  65. {
  66. for(UINT32 i = 0; i < paramDesc.arraySize; i++)
  67. {
  68. MaterialVec3Param param;
  69. param.name = iter->first;
  70. param.value = material->getVec3(iter->first, i);
  71. param.arrayIdx = i;
  72. params->vec3Params.push_back(param);
  73. }
  74. }
  75. break;
  76. case GPDT_FLOAT4:
  77. {
  78. for(UINT32 i = 0; i < paramDesc.arraySize; i++)
  79. {
  80. MaterialVec4Param param;
  81. param.name = iter->first;
  82. param.value = material->getVec4(iter->first, i);
  83. param.arrayIdx = i;
  84. params->vec4Params.push_back(param);
  85. }
  86. }
  87. break;
  88. case GPDT_MATRIX_3X3:
  89. {
  90. for(UINT32 i = 0; i < paramDesc.arraySize; i++)
  91. {
  92. MaterialMat3Param param;
  93. param.name = iter->first;
  94. param.value = material->getMat3(iter->first, i);
  95. param.arrayIdx = i;
  96. params->mat3Params.push_back(param);
  97. }
  98. }
  99. break;
  100. case GPDT_MATRIX_4X4:
  101. {
  102. for(UINT32 i = 0; i < paramDesc.arraySize; i++)
  103. {
  104. MaterialMat4Param param;
  105. param.name = iter->first;
  106. param.value = material->getMat4(iter->first, i);
  107. param.arrayIdx = i;
  108. params->mat4Params.push_back(param);
  109. }
  110. }
  111. break;
  112. default:
  113. CM_EXCEPT(InternalErrorException, "Cannot serialize this paramater type: " + toString(paramDesc.type));
  114. }
  115. }
  116. else if(type == GPT_OBJECT)
  117. {
  118. const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getObjectParamDesc(iter->first);
  119. if(Shader::isSampler(paramDesc.type))
  120. {
  121. MaterialSamplerStateParam param;
  122. param.name = iter->first;
  123. param.value = material->getSamplerState(iter->first);
  124. }
  125. else if(Shader::isTexture(paramDesc.type))
  126. {
  127. MaterialTextureParam param;
  128. param.name = iter->first;
  129. param.value = material->getTexture(iter->first);
  130. }
  131. else if(Shader::isBuffer(paramDesc.type))
  132. {
  133. CM_EXCEPT(NotImplementedException, "Buffers can't be serialized yet."); // TODO
  134. }
  135. else
  136. {
  137. CM_EXCEPT(InternalErrorException, "Cannot serialize this paramater type: " + toString(paramDesc.type));
  138. }
  139. }
  140. else
  141. CM_EXCEPT(InternalErrorException, "Invalid parameter type.");
  142. }
  143. }
  144. material->mRTTIData = params;
  145. }
  146. void MaterialRTTI::onSerializationEnded(IReflectable* obj)
  147. {
  148. Material* material = static_cast<Material*>(obj);
  149. material->mRTTIData = nullptr; // This will delete temporary data as it's stored in a unique ptr
  150. }
  151. void MaterialRTTI::onDeserializationStarted(IReflectable* obj)
  152. {
  153. // Do nothing
  154. }
  155. void MaterialRTTI::onDeserializationEnded(IReflectable* obj)
  156. {
  157. Material* material = static_cast<Material*>(obj);
  158. if(material->mRTTIData.empty())
  159. return;
  160. material->initBestTechnique();
  161. std::shared_ptr<MaterialParams> params = boost::any_cast<std::shared_ptr<MaterialParams>>(material->mRTTIData);
  162. ShaderPtr shader = material->getShader();
  163. if(shader != nullptr)
  164. {
  165. for(auto iter = params->floatParams.begin(); iter != params->floatParams.end(); ++iter)
  166. {
  167. if(!shader->hasDataParam(iter->name))
  168. continue;
  169. const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(iter->name);
  170. if(paramDesc.type != GPDT_FLOAT1 || iter->arrayIdx < 0 || iter->arrayIdx >= paramDesc.arraySize)
  171. continue;
  172. material->setFloat(iter->name, iter->value, iter->arrayIdx);
  173. }
  174. for(auto iter = params->vec2Params.begin(); iter != params->vec2Params.end(); ++iter)
  175. {
  176. if(!shader->hasDataParam(iter->name))
  177. continue;
  178. const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(iter->name);
  179. if(paramDesc.type != GPDT_FLOAT2 || iter->arrayIdx < 0 || iter->arrayIdx >= paramDesc.arraySize)
  180. continue;
  181. material->setVec2(iter->name, iter->value, iter->arrayIdx);
  182. }
  183. for(auto iter = params->vec3Params.begin(); iter != params->vec3Params.end(); ++iter)
  184. {
  185. if(!shader->hasDataParam(iter->name))
  186. continue;
  187. const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(iter->name);
  188. if(paramDesc.type != GPDT_FLOAT3 || iter->arrayIdx < 0 || iter->arrayIdx >= paramDesc.arraySize)
  189. continue;
  190. material->setVec3(iter->name, iter->value, iter->arrayIdx);
  191. }
  192. for(auto iter = params->vec4Params.begin(); iter != params->vec4Params.end(); ++iter)
  193. {
  194. if(!shader->hasDataParam(iter->name))
  195. continue;
  196. const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(iter->name);
  197. if(paramDesc.type != GPDT_FLOAT4 || iter->arrayIdx < 0 || iter->arrayIdx >= paramDesc.arraySize)
  198. continue;
  199. material->setVec4(iter->name, iter->value, iter->arrayIdx);
  200. }
  201. for(auto iter = params->mat3Params.begin(); iter != params->mat3Params.end(); ++iter)
  202. {
  203. if(!shader->hasDataParam(iter->name))
  204. continue;
  205. const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(iter->name);
  206. if(paramDesc.type != GPDT_MATRIX_3X3 || iter->arrayIdx < 0 || iter->arrayIdx >= paramDesc.arraySize)
  207. continue;
  208. material->setMat3(iter->name, iter->value, iter->arrayIdx);
  209. }
  210. for(auto iter = params->mat4Params.begin(); iter != params->mat4Params.end(); ++iter)
  211. {
  212. if(!shader->hasDataParam(iter->name))
  213. continue;
  214. const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(iter->name);
  215. if(paramDesc.type != GPDT_MATRIX_4X4 || iter->arrayIdx < 0 || iter->arrayIdx >= paramDesc.arraySize)
  216. continue;
  217. material->setMat4(iter->name, iter->value, iter->arrayIdx);
  218. }
  219. for(auto iter = params->samplerStateParams.begin(); iter != params->samplerStateParams.end(); ++iter)
  220. {
  221. if(!shader->hasObjectParam(iter->name))
  222. continue;
  223. const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getObjectParamDesc(iter->name);
  224. if(!Shader::isSampler(paramDesc.type))
  225. continue;
  226. material->setSamplerState(iter->name, iter->value);
  227. }
  228. for(auto iter = params->textureParams.begin(); iter != params->textureParams.end(); ++iter)
  229. {
  230. if(!shader->hasObjectParam(iter->name))
  231. continue;
  232. const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getObjectParamDesc(iter->name);
  233. if(!Shader::isTexture(paramDesc.type))
  234. continue;
  235. material->setTexture(iter->name, iter->value);
  236. }
  237. }
  238. material->mRTTIData = nullptr; // This will delete temporary data as it's stored in a unique ptr
  239. }
  240. std::shared_ptr<IReflectable> MaterialRTTI::newRTTIObject()
  241. {
  242. return MaterialManager::instance().create();
  243. }
  244. }