BsBansheeRenderer.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. #include "BsBansheeRenderer.h"
  2. #include "BsCamera.h"
  3. #include "BsSceneObject.h"
  4. #include "BsSceneManager.h"
  5. #include "BsRenderable.h"
  6. #include "BsMaterial.h"
  7. #include "BsMesh.h"
  8. #include "BsPass.h"
  9. #include "BsBlendState.h"
  10. #include "BsRasterizerState.h"
  11. #include "BsDepthStencilState.h"
  12. #include "BsCoreApplication.h"
  13. #include "BsViewport.h"
  14. #include "BsRenderTarget.h"
  15. #include "BsRenderQueue.h"
  16. #include "BsOverlayManager.h"
  17. #include "BsGUIManager.h"
  18. #include "BsCoreThread.h"
  19. #include "BsGpuParams.h"
  20. #include "BsProfilerCPU.h"
  21. #include "BsShader.h"
  22. #include "BsTechnique.h"
  23. #include "BsDrawList.h"
  24. #include "BsHardwareBufferManager.h"
  25. #include "BsGpuParamBlockBuffer.h"
  26. #include "BsShader.h"
  27. #include "BsBansheeLitTexRenderableController.h"
  28. #include "BsTime.h"
  29. #include "BsRenderableElement.h"
  30. #include "BsFrameAlloc.h"
  31. using namespace std::placeholders;
  32. namespace BansheeEngine
  33. {
  34. const String& BansheeRenderer::getName() const
  35. {
  36. static String name = "BansheeRenderer";
  37. return name;
  38. }
  39. void BansheeRenderer::_onActivated()
  40. {
  41. CoreRenderer::_onActivated();
  42. gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::initializeCore, this));
  43. }
  44. void BansheeRenderer::_onDeactivated()
  45. {
  46. CoreRenderer::_onDeactivated();
  47. gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::destroyCore, this));
  48. gCoreAccessor().submitToCoreThread(true);
  49. }
  50. void BansheeRenderer::initializeCore()
  51. {
  52. mLitTexHandler = bs_new<LitTexRenderableController>();
  53. SPtr<ShaderCore> shader = createDefaultShader();
  54. mDummyMaterial = MaterialCore::create(shader);
  55. }
  56. void BansheeRenderer::destroyCore()
  57. {
  58. if (mLitTexHandler != nullptr)
  59. bs_delete(mLitTexHandler);
  60. mRenderTargets.clear();
  61. mCameraData.clear();
  62. mRenderables.clear();
  63. mDummyMaterial = nullptr;
  64. }
  65. void BansheeRenderer::_notifyRenderableAdded(RenderableHandlerCore* renderable)
  66. {
  67. UINT32 renderableId = (UINT32)mRenderables.size();
  68. renderable->setRendererId(renderableId);
  69. mRenderables.push_back(RenderableData());
  70. mWorldTransforms.push_back(renderable->getTransform());
  71. mWorldBounds.push_back(renderable->getBounds());
  72. RenderableData& renderableData = mRenderables.back();
  73. renderableData.renderable = renderable;
  74. if (renderable->getRenderableType() == RenType_LitTextured)
  75. renderableData.controller = mLitTexHandler;
  76. else
  77. renderableData.controller = nullptr;
  78. SPtr<MeshCore> mesh = renderable->getMesh();
  79. if (mesh != nullptr)
  80. {
  81. const MeshProperties& meshProps = mesh->getProperties();
  82. for (UINT32 i = 0; i < meshProps.getNumSubMeshes(); i++)
  83. {
  84. renderableData.elements.push_back(RenderableElement());
  85. RenderableElement& renElement = renderableData.elements.back();
  86. renElement.mesh = mesh;
  87. renElement.subMesh = meshProps.getSubMesh(i);
  88. renElement.material = renderable->getMaterial(i);
  89. if (renElement.material == nullptr)
  90. renElement.material = renderable->getMaterial(0);
  91. if (renElement.material == nullptr)
  92. renElement.material = mDummyMaterial;
  93. if (renderableData.controller != nullptr)
  94. renderableData.controller->initializeRenderElem(renElement);
  95. }
  96. }
  97. }
  98. void BansheeRenderer::_notifyRenderableRemoved(RenderableHandlerCore* renderable)
  99. {
  100. UINT32 renderableId = renderable->getRendererId();
  101. RenderableHandlerCore* lastRenerable = mRenderables.back().renderable;
  102. UINT32 lastRenderableId = lastRenerable->getRendererId();
  103. if (renderableId != lastRenderableId)
  104. {
  105. // Swap current last element with the one we want to erase
  106. std::swap(mRenderables[renderableId], mRenderables[lastRenderableId]);
  107. std::swap(mWorldBounds[renderableId], mWorldBounds[lastRenderableId]);
  108. std::swap(mWorldTransforms[renderableId], mWorldTransforms[lastRenderableId]);
  109. lastRenerable->setRendererId(renderableId);
  110. }
  111. // Last element is the one we want to erase
  112. mRenderables.erase(mRenderables.end() - 1);
  113. mWorldBounds.erase(mWorldBounds.end() - 1);
  114. mWorldTransforms.erase(mWorldTransforms.end() - 1);
  115. }
  116. void BansheeRenderer::_notifyRenderableUpdated(RenderableHandlerCore* renderable)
  117. {
  118. UINT32 renderableId = renderable->getRendererId();
  119. mWorldTransforms[renderableId] = renderable->getTransform();
  120. mWorldBounds[renderableId] = renderable->getBounds();
  121. }
  122. void BansheeRenderer::_notifyCameraAdded(const CameraHandlerCore* camera)
  123. {
  124. CameraData& camData = mCameraData[camera];
  125. camData.renderQueue = bs_shared_ptr<RenderQueue>();
  126. }
  127. void BansheeRenderer::_notifyCameraRemoved(const CameraHandlerCore* camera)
  128. {
  129. mCameraData.erase(camera);
  130. }
  131. void BansheeRenderer::renderAll()
  132. {
  133. // Populate direct draw lists
  134. const Map<CameraHandler*, SceneCameraData>& allCameras = gSceneManager().getAllCameras();
  135. for (auto& cameraData : allCameras)
  136. {
  137. CameraHandlerPtr camera = cameraData.second.camera;
  138. HSceneObject cameraSO = cameraData.second.sceneObject;
  139. DrawListPtr drawList = bs_shared_ptr<DrawList>();
  140. // Get GUI render operations
  141. GUIManager::instance().render(camera->getViewport(), *drawList);
  142. // Get overlay render operations
  143. OverlayManager::instance().render(camera->getViewport(), *drawList);
  144. // Get any operations from hooked up callbacks
  145. const Viewport* viewportRawPtr = camera->getViewport().get();
  146. onRenderViewport(viewportRawPtr, *drawList);
  147. RenderQueuePtr renderQueue = bs_shared_ptr<RenderQueue>();
  148. const Vector<DrawOperation>& drawOps = drawList->getDrawOperations();
  149. for (auto& drawOp : drawOps)
  150. {
  151. SPtr<MaterialCore> materialCore = drawOp.material->getCore();
  152. SPtr<MeshCoreBase> meshCore = drawOp.mesh->getCore();
  153. SubMesh subMesh = meshCore->getProperties().getSubMesh(drawOp.submeshIdx);
  154. float distanceToCamera = (cameraSO->getPosition() - drawOp.worldPosition).length();
  155. renderQueue->add(materialCore, meshCore, subMesh, distanceToCamera);
  156. }
  157. gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addToRenderQueue, this, camera->getCore(), renderQueue));
  158. }
  159. gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::renderAllCore, this, gTime().getTime()));
  160. }
  161. void BansheeRenderer::addToRenderQueue(const SPtr<CameraHandlerCore>& camera, RenderQueuePtr renderQueue)
  162. {
  163. RenderQueuePtr cameraRenderQueue = mCameraData[camera.get()].renderQueue;
  164. cameraRenderQueue->add(*renderQueue);
  165. }
  166. void BansheeRenderer::renderAllCore(float time)
  167. {
  168. THROW_IF_NOT_CORE_THREAD;
  169. // Update global hardware buffers
  170. mLitTexHandler->updateGlobalBuffers(time);
  171. // Sort cameras by render target
  172. for (auto& cameraData : mCameraData)
  173. {
  174. const CameraHandlerCore* camera = cameraData.first;
  175. SPtr<RenderTargetCore> renderTarget = camera->getViewport()->getTarget();
  176. if (renderTarget == nullptr)
  177. continue;
  178. auto findIter = std::find_if(mRenderTargets.begin(), mRenderTargets.end(), [&](const RenderTargetData& x) { return x.target == renderTarget; });
  179. if (findIter != mRenderTargets.end())
  180. {
  181. findIter->cameras.push_back(camera);
  182. }
  183. else
  184. {
  185. mRenderTargets.push_back(RenderTargetData());
  186. RenderTargetData& renderTargetData = mRenderTargets.back();
  187. renderTargetData.target = renderTarget;
  188. renderTargetData.cameras.push_back(camera);
  189. }
  190. }
  191. // Sort everything based on priority
  192. auto cameraComparer = [&](const CameraHandlerCore* a, const CameraHandlerCore* b) { return a->getPriority() > b->getPriority(); };
  193. auto renderTargetInfoComparer = [&](const RenderTargetData& a, const RenderTargetData& b)
  194. { return a.target->getProperties().getPriority() > b.target->getProperties().getPriority(); };
  195. std::sort(begin(mRenderTargets), end(mRenderTargets), renderTargetInfoComparer);
  196. for (auto& camerasPerTarget : mRenderTargets)
  197. {
  198. Vector<const CameraHandlerCore*>& cameras = camerasPerTarget.cameras;
  199. std::sort(begin(cameras), end(cameras), cameraComparer);
  200. }
  201. // Render everything, target by target
  202. for (auto& renderTargetData : mRenderTargets)
  203. {
  204. SPtr<RenderTargetCore> target = renderTargetData.target;
  205. Vector<const CameraHandlerCore*>& cameras = renderTargetData.cameras;
  206. RenderAPICore::instance().beginFrame();
  207. for(auto& camera : cameras)
  208. {
  209. SPtr<ViewportCore> viewport = camera->getViewport();
  210. RenderAPICore::instance().setRenderTarget(target);
  211. RenderAPICore::instance().setViewport(viewport->getNormArea());
  212. UINT32 clearBuffers = 0;
  213. if(viewport->getRequiresColorClear())
  214. clearBuffers |= FBT_COLOR;
  215. if(viewport->getRequiresDepthClear())
  216. clearBuffers |= FBT_DEPTH;
  217. if(viewport->getRequiresStencilClear())
  218. clearBuffers |= FBT_STENCIL;
  219. if(clearBuffers != 0)
  220. RenderAPICore::instance().clearViewport(clearBuffers, viewport->getClearColor(), viewport->getClearDepthValue(), viewport->getClearStencilValue());
  221. render(*camera, mCameraData[camera].renderQueue);
  222. }
  223. RenderAPICore::instance().endFrame();
  224. RenderAPICore::instance().swapBuffers(target);
  225. }
  226. mRenderTargets.clear();
  227. }
  228. void BansheeRenderer::render(const CameraHandlerCore& camera, const RenderQueuePtr& renderQueue)
  229. {
  230. THROW_IF_NOT_CORE_THREAD;
  231. RenderAPICore& rs = RenderAPICore::instance();
  232. Matrix4 projMatrixCstm = camera.getProjectionMatrixRS();
  233. Matrix4 viewMatrixCstm = camera.getViewMatrix();
  234. Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
  235. onCorePreRenderViewport(camera);
  236. if (!camera.getIgnoreSceneRenderables())
  237. {
  238. ConvexVolume worldFrustum = camera.getWorldFrustum();
  239. // Update per-object param buffers and queue render elements
  240. for (auto& renderableData : mRenderables)
  241. {
  242. RenderableHandlerCore* renderable = renderableData.renderable;
  243. RenderableController* controller = renderableData.controller;
  244. UINT32 renderableType = renderable->getRenderableType();
  245. UINT32 rendererId = renderable->getRendererId();
  246. // Update buffers
  247. for (auto& renderElem : renderableData.elements)
  248. {
  249. if (controller != nullptr)
  250. controller->bindPerObjectBuffers(renderElem);
  251. if (renderableType == RenType_LitTextured)
  252. {
  253. Matrix4 worldViewProjMatrix = viewProjMatrix * mWorldTransforms[rendererId];
  254. mLitTexHandler->updatePerObjectBuffers(renderElem, worldViewProjMatrix);
  255. }
  256. UINT32 numPasses = renderElem.material->getNumPasses();
  257. for (UINT32 i = 0; i < numPasses; i++)
  258. {
  259. SPtr<PassParametersCore> passParams = renderElem.material->getPassParameters(i);
  260. for (UINT32 j = 0; j < passParams->getNumParams(); j++)
  261. {
  262. SPtr<GpuParamsCore> params = passParams->getParamByIdx(j);
  263. if (params != nullptr)
  264. params->updateHardwareBuffers();
  265. }
  266. }
  267. }
  268. // Do frustum culling
  269. // TODO - This is bound to be a bottleneck at some point. When it is ensure that intersect
  270. // methods use vector operations, as it is trivial to update them.
  271. const Sphere& boundingSphere = mWorldBounds[rendererId].getSphere();
  272. if (worldFrustum.intersects(boundingSphere))
  273. {
  274. // More precise with the box
  275. const AABox& boundingBox = mWorldBounds[rendererId].getBox();
  276. if (worldFrustum.intersects(boundingBox))
  277. {
  278. float distanceToCamera = (camera.getPosition() - boundingBox.getCenter()).length();
  279. for (auto& renderElem : renderableData.elements)
  280. renderQueue->add(&renderElem, distanceToCamera);
  281. }
  282. }
  283. }
  284. }
  285. renderQueue->sort();
  286. const Vector<RenderQueueElement>& sortedRenderElements = renderQueue->getSortedElements();
  287. for(auto iter = sortedRenderElements.begin(); iter != sortedRenderElements.end(); ++iter)
  288. {
  289. SPtr<MaterialCore> material = iter->material;
  290. setPass(material, iter->passIdx);
  291. draw(iter->mesh, iter->subMesh);
  292. }
  293. renderQueue->clear();
  294. onCorePostRenderViewport(camera);
  295. }
  296. SPtr<ShaderCore> BansheeRenderer::createDefaultShader()
  297. {
  298. String rsName = RenderAPICore::instance().getName();
  299. SPtr<GpuProgramCore> vsProgram;
  300. SPtr<GpuProgramCore> psProgram;
  301. if (rsName == RenderAPIDX11)
  302. {
  303. String vsCode = R"(
  304. cbuffer PerObject
  305. {
  306. float4x4 matWorldViewProj;
  307. }
  308. void vs_main(
  309. in float3 inPos : POSITION,
  310. out float4 oPosition : SV_Position)
  311. {
  312. oPosition = mul(matWorldViewProj, float4(inPos.xyz, 1));
  313. })";
  314. String psCode = R"(
  315. float4 ps_main() : SV_Target
  316. {
  317. return float4(0.3f, 0.9f, 0.3f, 1.0f);
  318. })";
  319. vsProgram = GpuProgramCore::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
  320. psProgram = GpuProgramCore::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_FS_4_0);
  321. }
  322. else if (rsName == RenderAPIDX9)
  323. {
  324. String vsCode = R"(
  325. BS_PARAM_BLOCK PerObject { matWorldViewProj }
  326. float4x4 matWorldViewProj;
  327. void vs_main(
  328. in float3 inPos : POSITION,
  329. out float4 oPosition : POSITION)
  330. {
  331. oPosition = mul(matWorldViewProj, float4(inPos.xyz, 1));
  332. })";
  333. String psCode = R"(
  334. float4 ps_main() : COLOR0
  335. {
  336. return float4(0.3f, 0.9f, 0.3f, 1.0f);
  337. })";
  338. vsProgram = GpuProgramCore::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
  339. psProgram = GpuProgramCore::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_FS_2_0);
  340. }
  341. else if (rsName == RenderAPIOpenGL)
  342. {
  343. String vsCode = R"(#version 400
  344. uniform PerObject
  345. {
  346. mat4 matWorldViewProj;
  347. };
  348. in vec3 bs_position;
  349. void main()
  350. {
  351. gl_Position = matWorldViewProj * vec4(bs_position.xyz, 1);
  352. })";
  353. String psCode = R"(#version 400
  354. out vec4 fragColor;
  355. void main()
  356. {
  357. fragColor = vec4(0.3f, 0.9f, 0.3f, 1.0f);
  358. })";
  359. vsProgram = GpuProgramCore::create(vsCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
  360. psProgram = GpuProgramCore::create(psCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_FS_4_0);
  361. }
  362. PASS_DESC_CORE passDesc;
  363. passDesc.vertexProgram = vsProgram;
  364. passDesc.fragmentProgram = psProgram;
  365. SPtr<PassCore> newPass = PassCore::create(passDesc);
  366. SPtr<TechniqueCore> newTechnique = TechniqueCore::create(rsName, RendererDefault, { newPass });
  367. SHADER_DESC shaderDesc;
  368. shaderDesc.setParamBlockAttribs("PerObject", true, GPBU_DYNAMIC, RBS_PerObject);
  369. shaderDesc.addParameter("matWorldViewProj", "matWorldViewProj", GPDT_MATRIX_4X4, RPS_WorldViewProjTfrm);
  370. SPtr<ShaderCore> defaultShader = ShaderCore::create("DummyShader", shaderDesc, { newTechnique });
  371. return defaultShader;
  372. }
  373. }