CmMaterialRTTI.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. TextureRef value;
  36. allParams[i]->_readTexture(iter->second.physicalIndex, value);
  37. params->mTextureParams[iter->first] = value;
  38. }
  39. else
  40. {
  41. UINT32 fieldSize = def.getElementSize(def.constType, false);
  42. switch(def.constType)
  43. {
  44. case GCT_FLOAT1:
  45. case GCT_FLOAT2:
  46. case GCT_FLOAT3:
  47. case GCT_FLOAT4:
  48. case GCT_MATRIX_3X3:
  49. case GCT_MATRIX_4X4:
  50. case GCT_SAMPLER2D:
  51. break;
  52. default:
  53. CM_EXCEPT(InternalErrorException, "Material parameter type not supported! Type: " + toString(def.constType));
  54. }
  55. if(fieldSize > 16)
  56. CM_EXCEPT(InternalErrorException, "Field size larger than the supported size.");
  57. allParams[i]->_readRawConstants(iter->second.physicalIndex, fieldSize, tempValue);
  58. auto iterFind = params->mFloatParams.find(iter->first);
  59. if(iterFind == params->mFloatParams.end())
  60. {
  61. params->mFloatParams[iter->first] = FloatParam(params->mFloatBuffer.size(), def.constType, fieldSize);
  62. for(size_t j = 0; j < fieldSize; j++)
  63. params->mFloatBuffer.push_back(tempValue[j]);
  64. }
  65. else
  66. gDebug().logWarning("While saving material found multiple parameters with the same name. Only saving the first.");
  67. }
  68. }
  69. }
  70. material->mRTTIData = params;
  71. }
  72. void MaterialRTTI::onSerializationEnded(IReflectable* obj)
  73. {
  74. Material* material = static_cast<Material*>(obj);
  75. material->mRTTIData = nullptr; // This will delete temporary data as it's stored in a unique ptr
  76. }
  77. void MaterialRTTI::onDeserializationStarted(IReflectable* obj)
  78. {
  79. // Do nothing
  80. }
  81. void MaterialRTTI::onDeserializationEnded(IReflectable* obj)
  82. {
  83. Material* material = static_cast<Material*>(obj);
  84. if(material->mRTTIData.empty())
  85. return;
  86. material->initBestTechnique();
  87. std::shared_ptr<MaterialParams> params = boost::any_cast<std::shared_ptr<MaterialParams>>(material->mRTTIData);
  88. vector<GpuProgramParametersPtr>::type allParams;
  89. for(size_t i = 0; i < material->mParameters.size(); i++)
  90. {
  91. if(material->mParameters[i].mFragParams != nullptr)
  92. allParams.push_back(material->mParameters[i].mFragParams);
  93. if(material->mParameters[i].mVertParams != nullptr)
  94. allParams.push_back(material->mParameters[i].mVertParams);
  95. if(material->mParameters[i].mGeomParams != nullptr)
  96. allParams.push_back(material->mParameters[i].mGeomParams);
  97. }
  98. for(size_t i = 0; i < allParams.size(); i++)
  99. {
  100. const GpuNamedConstants& namedConstants = allParams[i]->getConstantDefinitions();
  101. float tempValue[16];
  102. for(auto iter = namedConstants.map.begin(); iter != namedConstants.map.end(); ++iter)
  103. {
  104. const GpuConstantDefinition& def = iter->second;
  105. if(def.constType == GCT_SAMPLER2D)
  106. {
  107. auto iterFind = params->mTextureParams.find(iter->first);
  108. if(iterFind != params->mTextureParams.end())
  109. allParams[i]->setNamedConstant(iter->first, iterFind->second);
  110. }
  111. else
  112. {
  113. auto iterFind = params->mFloatParams.find(iter->first);
  114. if(iterFind != params->mFloatParams.end() && iterFind->second.mType == def.constType)
  115. {
  116. FloatParam param = iterFind->second;
  117. UINT32 fieldSize = def.getElementSize(def.constType, false);
  118. if(fieldSize != param.mCount)
  119. CM_EXCEPT(InternalErrorException, "Deserializing material parameter but field sizes don't match.");
  120. if(fieldSize > 16)
  121. CM_EXCEPT(InternalErrorException, "Field size larger than the supported size.");
  122. for(size_t j = 0; j < fieldSize; j++)
  123. tempValue[j] = params->mFloatBuffer[param.mBufferIdx + j];
  124. allParams[i]->_writeRawConstants(def.physicalIndex, tempValue, fieldSize);
  125. }
  126. }
  127. }
  128. }
  129. material->mRTTIData = nullptr; // This will delete temporary data as it's stored in a unique ptr
  130. }
  131. }