BsRenderableHandler.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "BsRenderableHandler.h"
  2. #include "BsRenderableHandlerRTTI.h"
  3. #include "BsSceneObject.h"
  4. #include "BsBuiltinResources.h"
  5. #include "BsMesh.h"
  6. #include "BsMaterial.h"
  7. #include "BsRenderQueue.h"
  8. #include "BsBounds.h"
  9. namespace BansheeEngine
  10. {
  11. RenderableHandler::MeshData::MeshData(const HMesh& mesh)
  12. {
  13. this->mesh = mesh;
  14. isLoaded = mesh.isLoaded();
  15. }
  16. RenderableHandler::MaterialData::MaterialData(const HMaterial& material)
  17. {
  18. this->material = material;
  19. isLoaded = material.isLoaded();
  20. }
  21. RenderableHandler::RenderableHandler()
  22. :mLayer(1), mCoreDirtyFlags(0xFFFFFFFF), mActiveProxy(nullptr)
  23. {
  24. mMaterialData.resize(1);
  25. }
  26. void RenderableHandler::setMesh(HMesh mesh)
  27. {
  28. mMeshData = mesh;
  29. mMaterialData.resize(mesh->getProperties().getNumSubMeshes());
  30. _markCoreDirty();
  31. }
  32. void RenderableHandler::setMaterial(UINT32 idx, HMaterial material)
  33. {
  34. mMaterialData[idx] = material;
  35. _markCoreDirty();
  36. }
  37. void RenderableHandler::setMaterial(HMaterial material)
  38. {
  39. setMaterial(0, material);
  40. }
  41. HMaterial RenderableHandler::getMaterial(UINT32 idx) const
  42. {
  43. if (mMaterialData[idx].material != nullptr)
  44. return mMaterialData[idx].material;
  45. else
  46. return mMaterialData[0].material;
  47. }
  48. void RenderableHandler::setLayer(UINT64 layer)
  49. {
  50. bool isPow2 = layer && !((layer - 1) & layer);
  51. if (!isPow2)
  52. BS_EXCEPT(InvalidParametersException, "Invalid layer provided. Only one layer bit may be set.");
  53. mLayer = layer;
  54. _markCoreDirty();
  55. }
  56. bool RenderableHandler::_isCoreDirty() const
  57. {
  58. updateResourceLoadStates();
  59. for (auto& materialData : mMaterialData)
  60. {
  61. if (materialData.material != nullptr && materialData.material.isLoaded() && materialData.material->_isCoreDirty(MaterialDirtyFlag::Material))
  62. return true;
  63. }
  64. return mCoreDirtyFlags != 0;
  65. }
  66. void RenderableHandler::_markCoreClean()
  67. {
  68. for (auto& materialData : mMaterialData)
  69. {
  70. if (materialData.material != nullptr && materialData.material.isLoaded())
  71. materialData.material->_markCoreClean(MaterialDirtyFlag::Material);
  72. }
  73. mCoreDirtyFlags = 0;
  74. }
  75. void RenderableHandler::updateResourceLoadStates() const
  76. {
  77. if (!mMeshData.isLoaded && mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded())
  78. {
  79. mMeshData.isLoaded = true;
  80. _markCoreDirty();
  81. }
  82. for (auto& materialData : mMaterialData)
  83. {
  84. if (!materialData.isLoaded && materialData.material != nullptr && materialData.material.isLoaded())
  85. {
  86. materialData.isLoaded = true;
  87. _markCoreDirty();
  88. }
  89. }
  90. }
  91. RenderableProxyPtr RenderableHandler::_createProxy(const Matrix4& worldTransform) const
  92. {
  93. if (mMeshData.mesh == nullptr || !mMeshData.mesh.isLoaded())
  94. return nullptr;
  95. RenderableProxyPtr proxy = bs_shared_ptr<RenderableProxy>();
  96. for (UINT32 i = 0; i < mMeshData.mesh->getProperties().getNumSubMeshes(); i++)
  97. {
  98. RenderableElement* renElement = bs_new<RenderableElement>();
  99. renElement->layer = mLayer;
  100. renElement->worldTransform = worldTransform;
  101. renElement->mesh = mMeshData.mesh->getCore();
  102. renElement->subMesh = mMeshData.mesh->getProperties().getSubMesh(i);
  103. HMaterial material;
  104. if (mMaterialData[i].material != nullptr)
  105. material = mMaterialData[i].material;
  106. else
  107. material = mMaterialData[0].material;
  108. if (material == nullptr || !material.isLoaded())
  109. material = BuiltinResources::instance().createDummyMaterial();
  110. if (material->_isCoreDirty(MaterialDirtyFlag::Proxy))
  111. {
  112. material->_setActiveProxy(material->_createProxy());
  113. material->_markCoreClean(MaterialDirtyFlag::Proxy);
  114. }
  115. renElement->material = material->_getActiveProxy();
  116. proxy->renderableElements.push_back(renElement);
  117. }
  118. proxy->renderableType = RenType_LitTextured;
  119. return proxy;
  120. }
  121. RTTITypeBase* RenderableHandler::getRTTIStatic()
  122. {
  123. return RenderableHandlerRTTI::instance();
  124. }
  125. RTTITypeBase* RenderableHandler::getRTTI() const
  126. {
  127. return RenderableHandler::getRTTIStatic();
  128. }
  129. }