CmMaterialRTTI.cpp 9.7 KB

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