Files
WickedEngine/WickedEngine/wiRenderTarget.cpp
T
2019-02-06 22:52:46 +00:00

275 lines
7.9 KiB
C++

#include "wiRenderTarget.h"
#include "wiRenderer.h"
#include "wiDepthTarget.h"
using namespace wiGraphicsTypes;
wiRenderTarget::wiRenderTarget()
{
numViews = 0;
depth = nullptr;
}
wiRenderTarget::wiRenderTarget(UINT width, UINT height, bool hasDepth, FORMAT format, UINT mipMapLevelCount, UINT MSAAC, bool depthOnly)
{
numViews = 0;
depth = nullptr;
Initialize(width, height, hasDepth, format, mipMapLevelCount, MSAAC);
}
wiRenderTarget::~wiRenderTarget()
{
CleanUp();
}
void wiRenderTarget::CleanUp() {
for (size_t i = 0; i < renderTargets.size(); ++i)
{
SAFE_DELETE(renderTargets[i]);
}
for (size_t i = 0; i < renderTargets_resolvedMSAA.size(); ++i)
{
SAFE_DELETE(renderTargets_resolvedMSAA[i]);
}
renderTargets.clear();
renderTargets_resolvedMSAA.clear();
SAFE_DELETE(depth);
resolvedMSAAUptodate.clear();
}
void wiRenderTarget::Initialize(UINT width, UINT height, bool hasDepth
, FORMAT format, UINT mipMapLevelCount, UINT MSAAC, bool depthOnly)
{
CleanUp();
if (!depthOnly)
{
TextureDesc textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = width;
textureDesc.Height = height;
textureDesc.MipLevels = mipMapLevelCount;
textureDesc.ArraySize = 1;
textureDesc.Format = format;
textureDesc.SampleDesc.Count = MSAAC;
//textureDesc.SampleDesc.Quality = 0; // auto-fill in device to maximum
textureDesc.Usage = USAGE_DEFAULT;
textureDesc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
numViews = 1;
Texture2D* texture = new Texture2D;
if (mipMapLevelCount != 1)
{
texture->RequestIndependentShaderResourcesForMIPs(true);
texture->RequestIndependentUnorderedAccessResourcesForMIPs(true);
textureDesc.BindFlags |= BIND_UNORDERED_ACCESS;
}
renderTargets.push_back(texture);
wiRenderer::GetDevice()->CreateTexture2D(&textureDesc, nullptr, renderTargets[0]);
if (MSAAC > 1)
{
textureDesc.SampleDesc.Count = 1;
renderTargets_resolvedMSAA.push_back(new Texture2D);
wiRenderer::GetDevice()->CreateTexture2D(&textureDesc, nullptr, renderTargets_resolvedMSAA[0]);
resolvedMSAAUptodate.push_back(false);
}
else
{
resolvedMSAAUptodate.push_back(true);
}
}
viewPort.Width = (FLOAT)width;
viewPort.Height = (FLOAT)height;
viewPort.MinDepth = 0.0f;
viewPort.MaxDepth = 1.0f;
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
if(hasDepth) {
depth = new wiDepthTarget();
depth->Initialize(width,height,MSAAC);
}
}
void wiRenderTarget::InitializeCube(UINT size, bool hasDepth, FORMAT format, UINT mipMapLevelCount, bool depthOnly)
{
CleanUp();
if (!depthOnly)
{
TextureDesc textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = size;
textureDesc.Height = size;
textureDesc.MipLevels = mipMapLevelCount;
textureDesc.ArraySize = 6;
textureDesc.Format = format;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = USAGE_DEFAULT;
textureDesc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = RESOURCE_MISC_TEXTURECUBE;
Texture2D* texture = new Texture2D;
if (mipMapLevelCount != 1)
{
texture->RequestIndependentShaderResourcesForMIPs(true);
texture->RequestIndependentUnorderedAccessResourcesForMIPs(true);
textureDesc.BindFlags |= BIND_UNORDERED_ACCESS;
//textureDesc.MiscFlags |= RESOURCE_MISC_GENERATE_MIPS;
}
numViews = 1;
renderTargets.push_back(texture);
wiRenderer::GetDevice()->CreateTexture2D(&textureDesc, nullptr, renderTargets[0]);
resolvedMSAAUptodate.push_back(true);
}
viewPort.Width = (FLOAT)size;
viewPort.Height = (FLOAT)size;
viewPort.MinDepth = 0.0f;
viewPort.MaxDepth = 1.0f;
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
if(hasDepth) {
depth = new wiDepthTarget();
depth->InitializeCube(size);
}
}
void wiRenderTarget::Add(FORMAT format)
{
TextureDesc desc = GetTexture(0)->GetDesc();
desc.Format = format;
if (!renderTargets.empty())
{
numViews++;
renderTargets.push_back(new Texture2D);
wiRenderer::GetDevice()->CreateTexture2D(&desc, nullptr, renderTargets.back());
if (desc.SampleDesc.Count > 1)
{
desc.SampleDesc.Count = 1;
renderTargets_resolvedMSAA.push_back(new Texture2D);
wiRenderer::GetDevice()->CreateTexture2D(&desc, nullptr, renderTargets_resolvedMSAA.back());
resolvedMSAAUptodate.push_back(false);
}
else
{
resolvedMSAAUptodate.push_back(true);
}
}
else
{
assert(0 && "Rendertarget Add failed because it is not properly initilaized!");
}
}
void wiRenderTarget::Activate(GRAPHICSTHREAD threadID, bool disableColor, int viewID)
{
Activate(threadID,0,0,0,0,disableColor, viewID);
}
void wiRenderTarget::Activate(GRAPHICSTHREAD threadID, float r, float g, float b, float a, bool disableColor, int viewID)
{
Set(threadID, disableColor, viewID);
float ClearColor[4] = { r, g, b, a };
if (viewID >= 0)
{
wiRenderer::GetDevice()->ClearRenderTarget(GetTexture(viewID), ClearColor, threadID);
}
else
{
for (int i = 0; i<numViews; ++i)
wiRenderer::GetDevice()->ClearRenderTarget(GetTexture(i), ClearColor, threadID);
}
if(depth) depth->Clear(threadID);
}
void wiRenderTarget::Activate(GRAPHICSTHREAD threadID, wiDepthTarget* getDepth, float r, float g, float b, float a, bool disableColor, int viewID)
{
Set(threadID,getDepth, disableColor, viewID);
float ClearColor[4] = { r, g, b, a };
if (viewID >= 0)
{
wiRenderer::GetDevice()->ClearRenderTarget(GetTexture(viewID), ClearColor, threadID);
}
else
{
for (int i = 0; i<numViews; ++i)
wiRenderer::GetDevice()->ClearRenderTarget(GetTexture(i), ClearColor, threadID);
}
}
void wiRenderTarget::Activate(GRAPHICSTHREAD threadID, wiDepthTarget* getDepth, bool disableColor, int viewID)
{
Activate(threadID,getDepth,0,0,0,0, disableColor, viewID);
}
void wiRenderTarget::Deactivate(GRAPHICSTHREAD threadID)
{
wiRenderer::GetDevice()->BindRenderTargets(0, nullptr, nullptr, threadID);
}
void wiRenderTarget::Set(GRAPHICSTHREAD threadID, bool disableColor, int viewID)
{
wiRenderer::GetDevice()->BindViewports(1, &viewPort, threadID);
if (viewID >= 0)
{
wiRenderer::GetDevice()->BindRenderTargets(disableColor ? 0 : 1, disableColor ? nullptr : (Texture2D**)&renderTargets[viewID], (depth ? depth->GetTexture() : nullptr), threadID);
resolvedMSAAUptodate[viewID] = false;
}
else
{
wiRenderer::GetDevice()->BindRenderTargets(disableColor ? 0 : numViews, disableColor ? nullptr : (Texture2D**)renderTargets.data(), (depth ? depth->GetTexture() : nullptr), threadID);
for (auto& x : resolvedMSAAUptodate)
{
x = false;
}
}
}
void wiRenderTarget::Set(GRAPHICSTHREAD threadID, wiDepthTarget* getDepth, bool disableColor, int viewID)
{
wiRenderer::GetDevice()->BindViewports(1, &viewPort, threadID);
if (viewID >= 0)
{
wiRenderer::GetDevice()->BindRenderTargets(disableColor ? 0 : 1, disableColor ? nullptr : (Texture2D**)&renderTargets[viewID], (getDepth ? getDepth->GetTexture() : nullptr), threadID);
resolvedMSAAUptodate[viewID] = false;
}
else
{
wiRenderer::GetDevice()->BindRenderTargets(disableColor ? 0 : numViews, disableColor ? nullptr : (Texture2D**)renderTargets.data(), (getDepth ? getDepth->GetTexture() : nullptr), threadID);
for (auto& x : resolvedMSAAUptodate)
{
x = false;
}
}
}
Texture2D* wiRenderTarget::GetTextureResolvedMSAA(GRAPHICSTHREAD threadID, int viewID)
{
if (GetDesc(viewID).SampleDesc.Count > 1)
{
if (resolvedMSAAUptodate[viewID] == false)
{
wiRenderer::GetDevice()->MSAAResolve(renderTargets_resolvedMSAA[viewID], renderTargets[viewID], threadID);
resolvedMSAAUptodate[viewID] = true;
}
return renderTargets_resolvedMSAA[viewID];
}
return renderTargets[viewID];
}
UINT wiRenderTarget::GetMipCount()
{
TextureDesc desc = GetDesc();
if (desc.MipLevels>0)
return desc.MipLevels;
UINT maxDim = max(desc.Width, desc.Height);
return static_cast<UINT>( log2(static_cast<double>(maxDim)) );
}