BsRenderQueue.cpp 3.0 KB

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