CmMaterialRTTI.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include "CmMaterialRTTI.h"
  2. namespace CamelotEngine
  3. {
  4. RTTITypeBase* MaterialRTTI::MaterialParams::getRTTIStatic()
  5. {
  6. return MaterialParamsRTTI::instance();
  7. }
  8. RTTITypeBase* MaterialRTTI::MaterialParams::getRTTI() const
  9. {
  10. return MaterialParams::getRTTIStatic();
  11. }
  12. void MaterialRTTI::onSerializationStarted(IReflectable* obj)
  13. {
  14. Material* material = static_cast<Material*>(obj);
  15. std::shared_ptr<MaterialParams> params = std::shared_ptr<MaterialParams>(new MaterialParams());
  16. vector<GpuProgramParametersPtr>::type allParams;
  17. for(size_t i = 0; i < material->mParameters.size(); i++)
  18. {
  19. if(material->mParameters[i]->mFragParams != nullptr)
  20. allParams.push_back(material->mParameters[i]->mFragParams);
  21. if(material->mParameters[i]->mVertParams != nullptr)
  22. allParams.push_back(material->mParameters[i]->mVertParams);
  23. if(material->mParameters[i]->mGeomParams != nullptr)
  24. allParams.push_back(material->mParameters[i]->mGeomParams);
  25. }
  26. for(size_t i = 0; i < allParams.size(); i++)
  27. {
  28. const GpuNamedConstants& namedConstants = allParams[i]->getConstantDefinitions();
  29. float tempValue[16];
  30. for(auto iter = namedConstants.map.begin(); iter != namedConstants.map.end(); ++iter)
  31. {
  32. const GpuConstantDefinition& def = iter->second;
  33. if(def.constType == GCT_SAMPLER2D)
  34. {
  35. TextureHandle texture;
  36. allParams[i]->_readTexture(iter->second.physicalIndex, texture);
  37. params->mTextureParams[iter->first] = texture;
  38. SamplerState samplerState = allParams[i]->getSamplerState(iter->second.physicalIndex);
  39. params->mSamplerStateParams[iter->first] = samplerState;
  40. }
  41. else
  42. {
  43. UINT32 fieldSize = def.getElementSize(def.constType, false);
  44. switch(def.constType)
  45. {
  46. case GCT_FLOAT1:
  47. case GCT_FLOAT2:
  48. case GCT_FLOAT3:
  49. case GCT_FLOAT4:
  50. case GCT_MATRIX_3X3:
  51. case GCT_MATRIX_4X4:
  52. case GCT_SAMPLER2D:
  53. break;
  54. default:
  55. CM_EXCEPT(InternalErrorException, "Material parameter type not supported! Type: " + toString(def.constType));
  56. }
  57. if(fieldSize > 16)
  58. CM_EXCEPT(InternalErrorException, "Field size larger than the supported size.");
  59. allParams[i]->_readRawConstants(iter->second.physicalIndex, fieldSize, tempValue);
  60. auto iterFind = params->mFloatParams.find(iter->first);
  61. if(iterFind == params->mFloatParams.end())
  62. {
  63. params->mFloatParams[iter->first] = FloatParam((UINT32)params->mFloatBuffer.size(), def.constType, fieldSize);
  64. for(UINT32 j = 0; j < fieldSize; j++)
  65. params->mFloatBuffer.push_back(tempValue[j]);
  66. }
  67. else
  68. gDebug().logWarning("While saving material found multiple parameters with the same name. Only saving the first.");
  69. }
  70. }
  71. }
  72. material->mRTTIData = params;
  73. }
  74. void MaterialRTTI::onSerializationEnded(IReflectable* obj)
  75. {
  76. Material* material = static_cast<Material*>(obj);
  77. material->mRTTIData = nullptr; // This will delete temporary data as it's stored in a unique ptr
  78. }
  79. void MaterialRTTI::onDeserializationStarted(IReflectable* obj)
  80. {
  81. // Do nothing
  82. }
  83. void MaterialRTTI::onDeserializationEnded(IReflectable* obj)
  84. {
  85. Material* material = static_cast<Material*>(obj);
  86. if(material->mRTTIData.empty())
  87. return;
  88. material->initBestTechnique();
  89. std::shared_ptr<MaterialParams> params = boost::any_cast<std::shared_ptr<MaterialParams>>(material->mRTTIData);
  90. vector<GpuProgramParametersPtr>::type allParams;
  91. for(size_t i = 0; i < material->mParameters.size(); i++)
  92. {
  93. if(material->mParameters[i]->mFragParams != nullptr)
  94. allParams.push_back(material->mParameters[i]->mFragParams);
  95. if(material->mParameters[i]->mVertParams != nullptr)
  96. allParams.push_back(material->mParameters[i]->mVertParams);
  97. if(material->mParameters[i]->mGeomParams != nullptr)
  98. allParams.push_back(material->mParameters[i]->mGeomParams);
  99. }
  100. for(size_t i = 0; i < allParams.size(); i++)
  101. {
  102. const GpuNamedConstants& namedConstants = allParams[i]->getConstantDefinitions();
  103. float tempValue[16];
  104. for(auto iter = namedConstants.map.begin(); iter != namedConstants.map.end(); ++iter)
  105. {
  106. const GpuConstantDefinition& def = iter->second;
  107. if(def.constType == GCT_SAMPLER2D)
  108. {
  109. auto iterFind = params->mTextureParams.find(iter->first);
  110. if(iterFind != params->mTextureParams.end())
  111. allParams[i]->setNamedConstant(iter->first, iterFind->second);
  112. auto iterFind2 = params->mSamplerStateParams.find(iter->first);
  113. if(iterFind2 != params->mSamplerStateParams.end())
  114. allParams[i]->setNamedConstant(iter->first, iterFind2->second);
  115. }
  116. else
  117. {
  118. auto iterFind = params->mFloatParams.find(iter->first);
  119. if(iterFind != params->mFloatParams.end() && iterFind->second.mType == def.constType)
  120. {
  121. FloatParam param = iterFind->second;
  122. UINT32 fieldSize = def.getElementSize(def.constType, false);
  123. if(fieldSize != param.mCount)
  124. CM_EXCEPT(InternalErrorException, "Deserializing material parameter but field sizes don't match.");
  125. if(fieldSize > 16)
  126. CM_EXCEPT(InternalErrorException, "Field size larger than the supported size.");
  127. for(size_t j = 0; j < fieldSize; j++)
  128. tempValue[j] = params->mFloatBuffer[param.mBufferIdx + j];
  129. allParams[i]->_writeRawConstants(def.physicalIndex, tempValue, fieldSize);
  130. }
  131. }
  132. }
  133. }
  134. material->mRTTIData = nullptr; // This will delete temporary data as it's stored in a unique ptr
  135. }
  136. }