BsForwardRenderer.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include "BsForwardRenderer.h"
  2. #include "BsCamera.h"
  3. #include "BsSceneManager.h"
  4. #include "BsRenderable.h"
  5. #include "CmMaterial.h"
  6. #include "CmMesh.h"
  7. #include "CmPass.h"
  8. #include "CmBlendState.h"
  9. #include "CmRasterizerState.h"
  10. #include "CmDepthStencilState.h"
  11. #include "CmApplication.h"
  12. #include "CmViewport.h"
  13. #include "CmRenderTarget.h"
  14. #include "CmRenderOperation.h"
  15. #include "CmDefaultRenderQueue.h"
  16. #include "BsOverlayManager.h"
  17. #include "BsDrawHelper2D.h"
  18. #include "BsDrawHelper3D.h"
  19. #include "BsGUIManager.h"
  20. using namespace CamelotFramework;
  21. namespace BansheeEngine
  22. {
  23. ForwardRenderer::ForwardRenderer()
  24. {
  25. mRenderQueue = cm_new<DefaultRenderQueue>();
  26. }
  27. ForwardRenderer::~ForwardRenderer()
  28. {
  29. cm_delete(mRenderQueue);
  30. }
  31. const String& ForwardRenderer::getName() const
  32. {
  33. static String name = "ForwardRenderer";
  34. return name;
  35. }
  36. void ForwardRenderer::renderAll()
  37. {
  38. gSceneManager().updateRenderableBounds();
  39. CoreAccessor& coreAccessor = gMainCA();
  40. const Vector<HCamera>::type& allCameras = gSceneManager().getAllCameras();
  41. struct RenderTargetRenderInfo
  42. {
  43. RenderTargetPtr target;
  44. Vector<HCamera>::type cameras;
  45. };
  46. // Find all unique render targets
  47. Vector<RenderTargetRenderInfo>::type camerasPerRenderTarget;
  48. for(auto& camera : allCameras)
  49. {
  50. RenderTargetPtr target = camera->getViewport()->getTarget();
  51. auto findIter = std::find_if(begin(camerasPerRenderTarget), end(camerasPerRenderTarget), [&target] (const RenderTargetRenderInfo& x) { return x.target == target; });
  52. if(findIter == camerasPerRenderTarget.end())
  53. {
  54. camerasPerRenderTarget.push_back(RenderTargetRenderInfo());
  55. camerasPerRenderTarget[camerasPerRenderTarget.size() - 1].target = target;
  56. camerasPerRenderTarget[camerasPerRenderTarget.size() - 1].cameras.push_back(camera);
  57. }
  58. else
  59. findIter->cameras.push_back(camera);
  60. }
  61. // Sort everything based on priority
  62. auto cameraComparer = [&] (const HCamera& a, const HCamera& b) { return a->getPriority() > b->getPriority(); };
  63. auto renderTargetInfoComparer = [&] (const RenderTargetRenderInfo& a, const RenderTargetRenderInfo& b) { return a.target->getPriority() > b.target->getPriority(); };
  64. std::sort(begin(camerasPerRenderTarget), end(camerasPerRenderTarget), renderTargetInfoComparer);
  65. for(auto& camerasPerTarget : camerasPerRenderTarget)
  66. {
  67. Vector<HCamera>::type& cameras = camerasPerTarget.cameras;
  68. std::sort(begin(cameras), end(cameras), cameraComparer);
  69. }
  70. // Render everything, target by target
  71. for(auto& camerasPerTarget : camerasPerRenderTarget)
  72. {
  73. RenderTargetPtr target = camerasPerTarget.target;
  74. const Vector<HCamera>::type& cameras = camerasPerTarget.cameras;
  75. coreAccessor.beginFrame();
  76. for(auto& camera : cameras)
  77. {
  78. ViewportPtr viewport = camera->getViewport();
  79. coreAccessor.setViewport(viewport);
  80. UINT32 clearBuffers = 0;
  81. if(viewport->getRequiresColorClear())
  82. clearBuffers |= FBT_COLOR;
  83. if(viewport->getRequiresDepthClear())
  84. clearBuffers |= FBT_DEPTH;
  85. if(viewport->getRequiresStencilClear())
  86. clearBuffers |= FBT_STENCIL;
  87. if(clearBuffers != 0)
  88. coreAccessor.clearViewport(clearBuffers, viewport->getClearColor(), viewport->getClearDepthValue(), viewport->getClearStencilValue());
  89. render(camera);
  90. }
  91. coreAccessor.endFrame();
  92. coreAccessor.swapBuffers(target);
  93. }
  94. }
  95. void ForwardRenderer::render(const HCamera& camera)
  96. {
  97. Vector<HRenderable>::type allRenderables;
  98. if(!camera->getIgnoreSceneRenderables())
  99. allRenderables = gSceneManager().getVisibleRenderables(camera);
  100. CoreAccessor& coreAccessor = gMainCA();
  101. coreAccessor.setViewport(camera->getViewport());
  102. Matrix4 projMatrixCstm = camera->getProjectionMatrix();
  103. Matrix4 viewMatrixCstm = camera->getViewMatrix();
  104. Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
  105. mRenderQueue->clear();
  106. // Get scene render operations
  107. for(auto iter = allRenderables.begin(); iter != allRenderables.end(); ++iter)
  108. {
  109. UINT32 numMaterials = (*iter)->getNumMaterials();
  110. for(UINT32 i = 0; i < numMaterials; i++)
  111. {
  112. // TODO - Do different things depending on material and renderable settings
  113. // TODO - Renderer should ensure shader is compatible with it, and it contains all the needed parameters
  114. // (probably at an earlier stage). e.g. I want the user to be warned if the shader doesn't contain matViewProjection param
  115. // (or should we just ignore such missing parameters?)
  116. HMaterial& material = (*iter)->getMaterial(i);
  117. material->setMat4("matViewProjection", viewProjMatrix);
  118. }
  119. (*iter)->render(*mRenderQueue);
  120. }
  121. // Get GUI render operations
  122. GUIManager::instance().render(camera->getViewport(), *mRenderQueue);
  123. // Get overlay render operations
  124. OverlayManager::instance().render(camera->getViewport(), *mRenderQueue);
  125. // Get debug render operations
  126. DrawHelper3D::instance().render(camera, *mRenderQueue);
  127. DrawHelper2D::instance().render(camera, *mRenderQueue);
  128. // Get any operations from hooked up callbacks
  129. const Viewport* viewportRawPtr = camera->getViewport().get();
  130. auto callbacksForViewport = mRenderCallbacks[viewportRawPtr];
  131. for(auto& callback : callbacksForViewport)
  132. callback(viewportRawPtr, *mRenderQueue);
  133. // TODO - Material queue is completely ignored
  134. mRenderQueue->sort();
  135. const Vector<SortedRenderOp>::type& sortedROps = mRenderQueue->getSortedRenderOps();
  136. for(auto iter = sortedROps.begin(); iter != sortedROps.end(); ++iter)
  137. {
  138. const RenderOperation& renderOp = *iter->baseOperation;
  139. HMaterial material = renderOp.material;
  140. PassPtr pass = material->getPass(iter->passIdx);
  141. pass->activate(coreAccessor);
  142. PassParametersPtr paramsPtr = material->getPassParameters(iter->passIdx);
  143. pass->bindParameters(coreAccessor, paramsPtr);
  144. coreAccessor.render(renderOp.meshData);
  145. }
  146. }
  147. }