BsRenderTargets.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include "BsRenderTargets.h"
  2. #include "BsRenderTexturePool.h"
  3. #include "BsViewport.h"
  4. #include "BsRenderAPI.h"
  5. #include "BsTextureManager.h"
  6. namespace BansheeEngine
  7. {
  8. RenderTargets::RenderTargets(const SPtr<ViewportCore>& viewport, bool hdr, UINT32 numSamples)
  9. :mNumSamples(numSamples), mHDR(hdr), mViewport(viewport)
  10. {
  11. if (hdr)
  12. mDiffuseFormat = PF_FLOAT_R11G11B10;
  13. else
  14. mDiffuseFormat = PF_B8G8R8X8;
  15. mNormalFormat = PF_UNORM_R10G10B10A2;
  16. }
  17. SPtr<RenderTargets> RenderTargets::create(const SPtr<ViewportCore>& viewport, bool hdr, UINT32 numSamples)
  18. {
  19. return bs_shared_ptr<RenderTargets>(new (bs_alloc<RenderTargets>()) RenderTargets(viewport, hdr, numSamples));
  20. }
  21. void RenderTargets::allocate()
  22. {
  23. RenderTexturePool& texPool = RenderTexturePool::instance();
  24. UINT32 width = getWidth();
  25. UINT32 height = getHeight();
  26. SPtr<PooledRenderTexture> newAlbedoRT = texPool.get(mDiffuseFormat, width, height, false, mNumSamples);
  27. SPtr<PooledRenderTexture> newNormalRT = texPool.get(mNormalFormat, width, height, false, mNumSamples);
  28. SPtr<PooledRenderTexture> newDepthRT = texPool.get(PF_D24S8, width, height, false, mNumSamples);
  29. SPtr<PooledRenderTexture> newColorRT = nullptr;
  30. // See if I can use the final output color target for gbuffer rendering, this saves a little memory
  31. SPtr<RenderTargetCore> resolvedRT = mViewport->getTarget();
  32. const RenderTargetProperties& resolvedRTProps = resolvedRT->getProperties();
  33. bool useResolvedColor = !resolvedRTProps.isWindow() &&
  34. mViewport->getWidth() == getWidth() &&
  35. mViewport->getHeight() == getHeight() &&
  36. ((resolvedRTProps.getMultisampleCount() <= 1) == (mNumSamples <= 1) ||
  37. resolvedRTProps.getMultisampleCount() == mNumSamples);
  38. if (!useResolvedColor)
  39. newColorRT = texPool.get(PF_B8G8R8X8, width, height, false, mNumSamples);
  40. bool rebuildTargets = newColorRT != mSceneColorTex || newAlbedoRT != mAlbedoTex || newNormalRT != mNormalTex || newDepthRT != mDepthTex;
  41. mSceneColorTex = newColorRT;
  42. mAlbedoTex = newAlbedoRT;
  43. mNormalTex = newNormalRT;
  44. mDepthTex = newDepthRT;
  45. if (mGBufferRT == nullptr || mSceneColorRT == nullptr || rebuildTargets)
  46. {
  47. MULTI_RENDER_TEXTURE_CORE_DESC gbufferDesc;
  48. gbufferDesc.colorSurfaces.resize(3);
  49. SPtr<TextureCore> sceneColorTex = nullptr;
  50. if (newColorRT != nullptr)
  51. sceneColorTex = newColorRT->texture;
  52. else // Re-using output scene color texture
  53. {
  54. SPtr<RenderTextureCore> resolvedRTex = std::static_pointer_cast<RenderTextureCore>(resolvedRT);
  55. sceneColorTex = resolvedRTex->getBindableColorTexture();
  56. }
  57. gbufferDesc.colorSurfaces[0].texture = sceneColorTex;
  58. gbufferDesc.colorSurfaces[0].face = 0;
  59. gbufferDesc.colorSurfaces[0].mipLevel = 0;
  60. gbufferDesc.colorSurfaces[1].texture = mAlbedoTex->texture;
  61. gbufferDesc.colorSurfaces[1].face = 0;
  62. gbufferDesc.colorSurfaces[1].mipLevel = 0;
  63. gbufferDesc.colorSurfaces[2].texture = mNormalTex->texture;
  64. gbufferDesc.colorSurfaces[2].face = 0;
  65. gbufferDesc.colorSurfaces[2].mipLevel = 0;
  66. gbufferDesc.depthStencilSurface.texture = mDepthTex->texture;
  67. gbufferDesc.depthStencilSurface.face = 0;
  68. gbufferDesc.depthStencilSurface.mipLevel = 0;
  69. mGBufferRT = TextureCoreManager::instance().createMultiRenderTexture(gbufferDesc);
  70. RENDER_TEXTURE_CORE_DESC sceneColorDesc;
  71. sceneColorDesc.colorSurface.texture = sceneColorTex;
  72. sceneColorDesc.colorSurface.face = 0;
  73. sceneColorDesc.colorSurface.mipLevel = 0;
  74. sceneColorDesc.depthStencilSurface.texture = mDepthTex->texture;
  75. sceneColorDesc.depthStencilSurface.face = 0;
  76. sceneColorDesc.depthStencilSurface.mipLevel = 0;
  77. mSceneColorRT = TextureCoreManager::instance().createRenderTexture(sceneColorDesc);
  78. }
  79. }
  80. void RenderTargets::release()
  81. {
  82. RenderAPICore& rapi = RenderAPICore::instance();
  83. rapi.setRenderTarget(nullptr);
  84. RenderTexturePool& texPool = RenderTexturePool::instance();
  85. if (mSceneColorTex != nullptr)
  86. texPool.release(mSceneColorTex);
  87. texPool.release(mAlbedoTex);
  88. texPool.release(mNormalTex);
  89. texPool.release(mDepthTex);
  90. }
  91. void RenderTargets::bindGBuffer()
  92. {
  93. RenderAPICore& rapi = RenderAPICore::instance();
  94. rapi.setRenderTarget(mGBufferRT);
  95. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  96. rapi.setViewport(area);
  97. UINT32 clearBuffers = FBT_COLOR | FBT_DEPTH | FBT_STENCIL;
  98. RenderAPICore::instance().clearViewport(clearBuffers, Color::ZERO, 1.0f, 0);
  99. }
  100. void RenderTargets::bindSceneColor()
  101. {
  102. RenderAPICore& rapi = RenderAPICore::instance();
  103. rapi.setRenderTarget(mSceneColorRT, true);
  104. Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
  105. rapi.setViewport(area);
  106. }
  107. void RenderTargets::resolve()
  108. {
  109. // Prepare final render target
  110. SPtr<RenderTargetCore> target = mViewport->getTarget();
  111. RenderAPICore::instance().setRenderTarget(target);
  112. RenderAPICore::instance().setViewport(mViewport->getNormArea());
  113. // If using a separate scene color texture clear the final render target
  114. if (mSceneColorTex == nullptr)
  115. {
  116. // Do nothing as final render target is already our scene color target
  117. }
  118. else
  119. {
  120. UINT32 clearBuffers = 0;
  121. if (mViewport->getRequiresColorClear())
  122. clearBuffers |= FBT_COLOR;
  123. if (mViewport->getRequiresDepthClear())
  124. clearBuffers |= FBT_DEPTH;
  125. if (mViewport->getRequiresStencilClear())
  126. clearBuffers |= FBT_STENCIL;
  127. if (clearBuffers != 0)
  128. {
  129. RenderAPICore::instance().clearViewport(clearBuffers, mViewport->getClearColor(),
  130. mViewport->getClearDepthValue(), mViewport->getClearStencilValue());
  131. }
  132. // TODO - Copy from internal scene color to final scene color
  133. }
  134. }
  135. SPtr<TextureCore> RenderTargets::getTextureA() const
  136. {
  137. return mAlbedoTex->texture;
  138. }
  139. SPtr<TextureCore> RenderTargets::getTextureB() const
  140. {
  141. return mNormalTex->texture;
  142. }
  143. SPtr<TextureCore> RenderTargets::getTextureDepth() const
  144. {
  145. return mDepthTex->texture;
  146. }
  147. UINT32 RenderTargets::getWidth() const
  148. {
  149. return (UINT32)mViewport->getWidth();
  150. }
  151. UINT32 RenderTargets::getHeight() const
  152. {
  153. return (UINT32)mViewport->getHeight();
  154. }
  155. }