BsRenderQueue.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "BsRenderQueue.h"
  2. #include "BsSubMesh.h"
  3. #include "BsShader.h"
  4. #include "BsMesh.h"
  5. #include "BsMaterial.h"
  6. #include "BsRenderableElement.h"
  7. namespace BansheeEngine
  8. {
  9. RenderQueue::RenderQueue()
  10. :mRenderElements(&elementSorter)
  11. {
  12. }
  13. void RenderQueue::clear()
  14. {
  15. mRenderElements.clear();
  16. mSortedRenderElements.clear();
  17. }
  18. void RenderQueue::add(RenderableElement* element, float distFromCamera)
  19. {
  20. SortData sortData;
  21. RenderQueueElement& renderOp = sortData.element;
  22. renderOp.renderElem = element;
  23. renderOp.material = element->material;
  24. renderOp.mesh = element->mesh;
  25. renderOp.subMesh = element->subMesh;
  26. sortData.distFromCamera = distFromCamera;
  27. sortData.priority = element->material->getShader()->getQueuePriority();
  28. sortData.sortType = element->material->getShader()->getQueueSortType();
  29. sortData.seqIdx = (UINT32)mRenderElements.size();
  30. // TODO - Make sure elements are cached so we dont allocate memory for them every frame
  31. mRenderElements.insert(sortData);
  32. }
  33. void RenderQueue::add(const SPtr<MaterialCore>& material, const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh, float distFromCamera)
  34. {
  35. SortData sortData;
  36. RenderQueueElement& renderOp = sortData.element;
  37. renderOp.renderElem = nullptr;
  38. renderOp.material = material;
  39. renderOp.mesh = mesh;
  40. renderOp.subMesh = subMesh;
  41. sortData.distFromCamera = distFromCamera;
  42. sortData.priority = material->getShader()->getQueuePriority();
  43. sortData.sortType = material->getShader()->getQueueSortType();
  44. sortData.seqIdx = (UINT32)mRenderElements.size();
  45. // TODO - Make sure elements are cached so we dont allocate memory for them every frame
  46. mRenderElements.insert(sortData);
  47. }
  48. void RenderQueue::add(const RenderQueue& renderQueue)
  49. {
  50. for (auto& elem : renderQueue.mRenderElements)
  51. {
  52. if (elem.element.renderElem != nullptr)
  53. add(elem.element.renderElem, elem.distFromCamera);
  54. else
  55. add(elem.element.material, elem.element.mesh, elem.element.subMesh, elem.distFromCamera);
  56. }
  57. }
  58. void RenderQueue::sort()
  59. {
  60. // TODO - I'm ignoring "separate pass" material parameter.
  61. for (auto& sortData : mRenderElements)
  62. {
  63. const RenderQueueElement& renderElem = sortData.element;
  64. UINT32 numPasses = (UINT32)renderElem.material->getNumPasses();
  65. for (UINT32 i = 0; i < numPasses; i++)
  66. {
  67. mSortedRenderElements.push_back(RenderQueueElement());
  68. RenderQueueElement& sortedElem = mSortedRenderElements.back();
  69. sortedElem.renderElem = renderElem.renderElem;
  70. sortedElem.material = renderElem.material;
  71. sortedElem.mesh = renderElem.mesh;
  72. sortedElem.subMesh = renderElem.subMesh;
  73. sortedElem.passIdx = i;
  74. }
  75. }
  76. }
  77. bool RenderQueue::elementSorter(const SortData& a, const SortData& b)
  78. {
  79. if (a.priority == b.priority)
  80. {
  81. if (a.sortType == QueueSortType::None || a.sortType != b.sortType)
  82. return a.seqIdx < b.seqIdx;
  83. if (a.distFromCamera == b.distFromCamera)
  84. return a.seqIdx < b.seqIdx;
  85. if (a.sortType == QueueSortType::FrontToBack)
  86. return a.distFromCamera < b.distFromCamera;
  87. else
  88. return a.distFromCamera > b.distFromCamera;
  89. }
  90. return a.priority > b.priority;
  91. }
  92. const Vector<RenderQueueElement>& RenderQueue::getSortedElements() const
  93. {
  94. return mSortedRenderElements;
  95. }
  96. }