| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "BsRenderTargets.h"
- #include "BsRenderTexturePool.h"
- #include "BsViewport.h"
- #include "BsRenderAPI.h"
- #include "BsTextureManager.h"
- #include "BsRendererUtility.h"
- namespace BansheeEngine
- {
- RenderTargets::RenderTargets(const SPtr<ViewportCore>& viewport, bool hdr, UINT32 numSamples)
- :mViewport(viewport), mNumSamples(numSamples), mHDR(hdr)
- {
- // Note: Consider customizable HDR format via options? e.g. smaller PF_FLOAT_R11G11B10 or larger 32-bit format
- mSceneColorFormat = hdr ? PF_FLOAT16_RGBA : PF_B8G8R8A8;
- mAlbedoFormat = PF_B8G8R8X8; // Note: Also consider customizable format (e.g. 16-bit float?)
- mNormalFormat = PF_UNORM_R10G10B10A2; // Note: Also consider customizable format (e.g. 16-bit float?)
- }
- SPtr<RenderTargets> RenderTargets::create(const SPtr<ViewportCore>& viewport, bool hdr, UINT32 numSamples)
- {
- return bs_shared_ptr<RenderTargets>(new (bs_alloc<RenderTargets>()) RenderTargets(viewport, hdr, numSamples));
- }
- void RenderTargets::allocate()
- {
- RenderTexturePool& texPool = RenderTexturePool::instance();
- UINT32 width = getWidth();
- UINT32 height = getHeight();
- // Note: Albedo is allocated as SRGB, meaning when reading from textures during depth pass we decode from sRGB into linear,
- // then back into sRGB when writing to albedo, and back to linear when reading from albedo during light pass. This /might/ have
- // a performance impact. In which case we could just use a higher precision albedo buffer, which can then store linear color
- // directly (storing linear in 8bit buffer causes too much detail to be lost in the blacks).
- SPtr<PooledRenderTexture> newColorRT = texPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(mSceneColorFormat, width, height, TU_RENDERTARGET,
- mNumSamples, false));
- SPtr<PooledRenderTexture> newAlbedoRT = texPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(mAlbedoFormat, width,
- height, TU_RENDERTARGET, mNumSamples, true));
- SPtr<PooledRenderTexture> newNormalRT = texPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(mNormalFormat, width,
- height, TU_RENDERTARGET, mNumSamples, false));
- SPtr<PooledRenderTexture> newDepthRT = texPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_D24S8, width, height,
- TU_DEPTHSTENCIL, mNumSamples, false));
- bool rebuildTargets = newColorRT != mSceneColorTex || newAlbedoRT != mAlbedoTex || newNormalRT != mNormalTex || newDepthRT != mDepthTex;
- mSceneColorTex = newColorRT;
- mAlbedoTex = newAlbedoRT;
- mNormalTex = newNormalRT;
- mDepthTex = newDepthRT;
- if (mGBufferRT == nullptr || mSceneColorRT == nullptr || rebuildTargets)
- {
- RENDER_TEXTURE_DESC_CORE gbufferDesc;
- gbufferDesc.colorSurfaces[0].texture = mSceneColorTex->texture;
- gbufferDesc.colorSurfaces[0].face = 0;
- gbufferDesc.colorSurfaces[0].numFaces = 1;
- gbufferDesc.colorSurfaces[0].mipLevel = 0;
- gbufferDesc.colorSurfaces[1].texture = mAlbedoTex->texture;
- gbufferDesc.colorSurfaces[1].face = 0;
- gbufferDesc.colorSurfaces[1].numFaces = 1;
- gbufferDesc.colorSurfaces[1].mipLevel = 0;
- gbufferDesc.colorSurfaces[2].texture = mNormalTex->texture;
- gbufferDesc.colorSurfaces[2].face = 0;
- gbufferDesc.colorSurfaces[2].numFaces = 1;
- gbufferDesc.colorSurfaces[2].mipLevel = 0;
- gbufferDesc.depthStencilSurface.texture = mDepthTex->texture;
- gbufferDesc.depthStencilSurface.face = 0;
- gbufferDesc.depthStencilSurface.mipLevel = 0;
- mGBufferRT = RenderTextureCore::create(gbufferDesc);
- RENDER_TEXTURE_DESC_CORE sceneColorDesc;
- sceneColorDesc.colorSurfaces[0].texture = mSceneColorTex->texture;
- sceneColorDesc.colorSurfaces[0].face = 0;
- sceneColorDesc.colorSurfaces[0].numFaces = 1;
- sceneColorDesc.colorSurfaces[0].mipLevel = 0;
- sceneColorDesc.depthStencilSurface.texture = mDepthTex->texture;
- sceneColorDesc.depthStencilSurface.face = 0;
- sceneColorDesc.depthStencilSurface.numFaces = 1;
- sceneColorDesc.depthStencilSurface.mipLevel = 0;
- mSceneColorRT = TextureCoreManager::instance().createRenderTexture(sceneColorDesc);
- }
- }
- void RenderTargets::release()
- {
- RenderAPICore& rapi = RenderAPICore::instance();
- rapi.setRenderTarget(nullptr);
- RenderTexturePool& texPool = RenderTexturePool::instance();
- texPool.release(mSceneColorTex);
- texPool.release(mAlbedoTex);
- texPool.release(mNormalTex);
- texPool.release(mDepthTex);
- }
- void RenderTargets::bindGBuffer()
- {
- RenderAPICore& rapi = RenderAPICore::instance();
- rapi.setRenderTarget(mGBufferRT);
- Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
- rapi.setViewport(area);
- UINT32 clearBuffers = 0;
- if (mViewport->getRequiresColorClear())
- clearBuffers |= FBT_COLOR;
- if (mViewport->getRequiresDepthClear())
- clearBuffers |= FBT_DEPTH;
- if (mViewport->getRequiresStencilClear())
- clearBuffers |= FBT_STENCIL;
- // Clear scene color, depth, stencil according to user defined values
- if (clearBuffers != 0)
- {
- RenderAPICore::instance().clearViewport(clearBuffers, mViewport->getClearColor(),
- mViewport->getClearDepthValue(), mViewport->getClearStencilValue(), 0x01);
- }
- // Clear all others
- RenderAPICore::instance().clearViewport(FBT_COLOR, Color::ZERO, 1.0f, 0, 0xFF & ~0x01);
- }
- void RenderTargets::bindSceneColor(bool readOnlyDepthStencil)
- {
- RenderAPICore& rapi = RenderAPICore::instance();
- rapi.setRenderTarget(mSceneColorRT, readOnlyDepthStencil);
- Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
- rapi.setViewport(area);
- }
- SPtr<TextureCore> RenderTargets::getTextureA() const
- {
- return mAlbedoTex->texture;
- }
- SPtr<TextureCore> RenderTargets::getTextureB() const
- {
- return mNormalTex->texture;
- }
- SPtr<TextureCore> RenderTargets::getTextureDepth() const
- {
- return mDepthTex->texture;
- }
- UINT32 RenderTargets::getWidth() const
- {
- return (UINT32)mViewport->getWidth();
- }
- UINT32 RenderTargets::getHeight() const
- {
- return (UINT32)mViewport->getHeight();
- }
- }
|