From 5edaf3b5743b1e1d788a91ca2b3e3278e6c52d84 Mon Sep 17 00:00:00 2001 From: Ange Yaghi Date: Thu, 4 Jun 2020 19:59:28 -0400 Subject: [PATCH] [#17] : Fixed offscreen render target support --- include/yds_d3d10_device.h | 4 +- include/yds_d3d11_device.h | 7 +- include/yds_device.h | 2 +- include/yds_opengl_device.h | 4 +- include/yds_render_target.h | 8 +- src/yds_d3d10_device.cpp | 18 ++-- src/yds_d3d11_device.cpp | 161 +++++++++++++++++++++--------------- src/yds_device.cpp | 1 - src/yds_opengl_device.cpp | 20 +++-- 9 files changed, 132 insertions(+), 93 deletions(-) diff --git a/include/yds_d3d10_device.h b/include/yds_d3d10_device.h index e2c28b41..005a9cf1 100644 --- a/include/yds_d3d10_device.h +++ b/include/yds_d3d10_device.h @@ -29,7 +29,7 @@ class ysD3D10Device : public ysDevice { virtual ysError SetContextMode(ysRenderingContext *context, ysRenderingContext::ContextMode mode); virtual ysError CreateOnScreenRenderTarget(ysRenderTarget **newTarget, ysRenderingContext *context, bool depthBuffer); - virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer); + virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer); virtual ysError CreateSubRenderTarget(ysRenderTarget **newTarget, ysRenderTarget *parent, int x, int y, int width, int height); virtual ysError ResizeRenderTarget(ysRenderTarget *target, int width, int height); virtual ysError DestroyRenderTarget(ysRenderTarget *&target); @@ -96,7 +96,7 @@ class ysD3D10Device : public ysDevice { ysError DestroyD3D10DepthBuffer(ID3D10DepthStencilView *&depthStencil); ysError CreateD3D10OnScreenRenderTarget(ysRenderTarget *target, ysRenderingContext *context, bool depthBuffer); - ysError CreateD3D10OffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer); + ysError CreateD3D10OffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer); ysError DestroyD3D10RenderTarget(ysRenderTarget *target); }; diff --git a/include/yds_d3d11_device.h b/include/yds_d3d11_device.h index 9a425ecb..03c5f0ac 100644 --- a/include/yds_d3d11_device.h +++ b/include/yds_d3d11_device.h @@ -10,6 +10,7 @@ struct IDXGIFactory; struct ID3D11Device; struct ID3D11RasterizerState; struct ID3D11DepthStencilView; +struct ID3D11ShaderResourceView; enum DXGI_FORMAT; class ysD3D11Device : public ysDevice { @@ -32,7 +33,7 @@ class ysD3D11Device : public ysDevice { virtual ysError SetContextMode(ysRenderingContext *context, ysRenderingContext::ContextMode mode); virtual ysError CreateOnScreenRenderTarget(ysRenderTarget **newTarget, ysRenderingContext *context, bool depthBuffer); - virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer); + virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer); virtual ysError CreateSubRenderTarget(ysRenderTarget **newTarget, ysRenderTarget *parent, int x, int y, int width, int height); virtual ysError ResizeRenderTarget(ysRenderTarget *target, int width, int height); virtual ysError DestroyRenderTarget(ysRenderTarget *&target); @@ -108,11 +109,11 @@ class ysD3D11Device : public ysDevice { protected: // Platform specific functionality - ysError CreateD3D11DepthStencilView(ID3D11DepthStencilView **newDepthStencil, int width, int height, int count, int quality); + ysError CreateD3D11DepthStencilView(ID3D11DepthStencilView **newDepthStencil, ID3D11ShaderResourceView **shaderResourceView, int width, int height, int count, int quality, bool shaderResource); ysError DestroyD3D11DepthStencilView(ID3D11DepthStencilView *&depthStencil); ysError CreateD3D11OnScreenRenderTarget(ysRenderTarget *target, ysRenderingContext *context, bool depthBuffer); - ysError CreateD3D11OffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer); + ysError CreateD3D11OffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer); ysError DestroyD3D11RenderTarget(ysRenderTarget *target); }; diff --git a/include/yds_device.h b/include/yds_device.h index cd1fb720..545b9dfa 100644 --- a/include/yds_device.h +++ b/include/yds_device.h @@ -61,7 +61,7 @@ class ysDevice : public ysContextObject { virtual ysError CreateOnScreenRenderTarget(ysRenderTarget **newTarget, ysRenderingContext *context, bool depthBuffer) = 0; // Create an off-screen render target - virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer) = 0; + virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, bool colorData = true, bool depthBuffer = true) = 0; // Create a off-screen copy virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, const ysRenderTarget *reference); diff --git a/include/yds_opengl_device.h b/include/yds_opengl_device.h index d740924e..9de0fbb9 100644 --- a/include/yds_opengl_device.h +++ b/include/yds_opengl_device.h @@ -25,7 +25,7 @@ class ysOpenGLDevice : public ysDevice { virtual ysError SetContextMode(ysRenderingContext *context, ysRenderingContext::ContextMode mode); virtual ysError CreateOnScreenRenderTarget(ysRenderTarget **newTarget, ysRenderingContext *context, bool depthBuffer); - virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer); + virtual ysError CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer); virtual ysError CreateSubRenderTarget(ysRenderTarget **newTarget, ysRenderTarget *parent, int x, int y, int width, int height); virtual ysError ResizeRenderTarget(ysRenderTarget *target, int width, int height); virtual ysError DestroyRenderTarget(ysRenderTarget *&target); @@ -97,7 +97,7 @@ class ysOpenGLDevice : public ysDevice { protected: // Hidden functionality - ysError CreateOpenGLOffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer); + ysError CreateOpenGLOffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer); ysError DestroyOpenGLRenderTarget(ysRenderTarget *target); }; diff --git a/include/yds_render_target.h b/include/yds_render_target.h index c4709c79..46bc73ca 100644 --- a/include/yds_render_target.h +++ b/include/yds_render_target.h @@ -19,8 +19,9 @@ class ysRenderTarget : public ysContextObject { }; enum class Format { - RTF_R8G8B8A8_UNORM, - RTF_R32G32B32_FLOAT + R8G8B8A8_UNORM, + R32G32B32_FLOAT, + R32_FLOAT }; public: @@ -40,6 +41,8 @@ class ysRenderTarget : public ysContextObject { int GetSampleCount() const { return m_sampleCount; } bool HasDepthBuffer() const { return m_hasDepthBuffer; } + bool HasColorData() const { return m_hasColorData; } + ysRenderingContext *GetAssociatedContext() { return m_associatedContext; } ysRenderTarget *GetParent() { return m_parent; } @@ -57,6 +60,7 @@ class ysRenderTarget : public ysContextObject { Format m_format; int m_sampleCount; + bool m_hasColorData; bool m_hasDepthBuffer; bool m_depthTestEnabled; diff --git a/src/yds_d3d10_device.cpp b/src/yds_d3d10_device.cpp index 508e343b..cf605f8d 100644 --- a/src/yds_d3d10_device.cpp +++ b/src/yds_d3d10_device.cpp @@ -295,7 +295,7 @@ ysError ysD3D10Device::CreateOnScreenRenderTarget(ysRenderTarget **newTarget, ys return YDS_ERROR_RETURN(ysError::YDS_NO_ERROR); } -ysError ysD3D10Device::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer) { +ysError ysD3D10Device::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer) { YDS_ERROR_DECLARE("CreateOffScreenRenderTarget"); if (newTarget == nullptr) return YDS_ERROR_RETURN(ysError::YDS_INVALID_PARAMETER); @@ -303,7 +303,7 @@ ysError ysD3D10Device::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, i ysD3D10RenderTarget *d3d10Target = m_renderTargets.NewGeneric(); - ysError result = CreateD3D10OffScreenRenderTarget(d3d10Target, width, height, format, sampleCount, depthBuffer); + ysError result = CreateD3D10OffScreenRenderTarget(d3d10Target, width, height, format, colorData, depthBuffer); if (result != ysError::YDS_NO_ERROR) { m_renderTargets.Delete(d3d10Target->GetIndex()); @@ -328,7 +328,7 @@ ysError ysD3D10Device::CreateSubRenderTarget(ysRenderTarget **newTarget, ysRende newRenderTarget->m_posY = y; newRenderTarget->m_width = width; newRenderTarget->m_height = height; - newRenderTarget->m_format = ysRenderTarget::Format::RTF_R8G8B8A8_UNORM; + newRenderTarget->m_format = ysRenderTarget::Format::R8G8B8A8_UNORM; newRenderTarget->m_hasDepthBuffer = parent->HasDepthBuffer(); newRenderTarget->m_associatedContext = parent->GetAssociatedContext(); newRenderTarget->m_parent = parent; @@ -353,7 +353,7 @@ ysError ysD3D10Device::ResizeRenderTarget(ysRenderTarget *target, int width, int return YDS_ERROR_RETURN(ysError::YDS_NO_ERROR); } else if (target->GetType() == ysRenderTarget::Type::OffScreen) { - YDS_NESTED_ERROR_CALL( CreateD3D10OffScreenRenderTarget(target, width, height, target->GetFormat(), target->GetSampleCount(), target->HasDepthBuffer()) ); + YDS_NESTED_ERROR_CALL( CreateD3D10OffScreenRenderTarget(target, width, height, target->GetFormat(), target->HasColorData(), target->HasDepthBuffer()) ); return YDS_ERROR_RETURN(ysError::YDS_NOT_IMPLEMENTED); } else if (target->GetType() == ysRenderTarget::Type::Subdivision) { @@ -1227,7 +1227,7 @@ ysError ysD3D10Device::CreateD3D10OnScreenRenderTarget(ysRenderTarget *newTarget newRenderTarget->m_posY = 0; newRenderTarget->m_width = context->GetWindow()->GetScreenWidth(); newRenderTarget->m_height = context->GetWindow()->GetScreenHeight(); - newRenderTarget->m_format = ysRenderTarget::Format::RTF_R8G8B8A8_UNORM; + newRenderTarget->m_format = ysRenderTarget::Format::R8G8B8A8_UNORM; newRenderTarget->m_hasDepthBuffer = depthBuffer; newRenderTarget->m_associatedContext = context; @@ -1238,7 +1238,7 @@ ysError ysD3D10Device::CreateD3D10OnScreenRenderTarget(ysRenderTarget *newTarget return YDS_ERROR_RETURN(ysError::YDS_NO_ERROR); } -ysError ysD3D10Device::CreateD3D10OffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer) { +ysError ysD3D10Device::CreateD3D10OffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer) { YDS_ERROR_DECLARE("CreateD3D10OffScreenRenderTarget"); HRESULT result; @@ -1256,9 +1256,9 @@ ysError ysD3D10Device::CreateD3D10OffScreenRenderTarget(ysRenderTarget *target, descBuffer.MipLevels = 1; descBuffer.ArraySize = 1; - if (format == ysRenderTarget::Format::RTF_R32G32B32_FLOAT) + if (format == ysRenderTarget::Format::R32G32B32_FLOAT) descBuffer.Format = DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT; - else if (format == ysRenderTarget::Format::RTF_R8G8B8A8_UNORM) + else if (format == ysRenderTarget::Format::R8G8B8A8_UNORM) descBuffer.Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM; descBuffer.SampleDesc.Count = 1; @@ -1324,7 +1324,7 @@ ysError ysD3D10Device::CreateD3D10OffScreenRenderTarget(ysRenderTarget *target, newRenderTarget->m_posY = 0; newRenderTarget->m_width = width; newRenderTarget->m_height = height; - newRenderTarget->m_format = ysRenderTarget::Format::RTF_R8G8B8A8_UNORM; + newRenderTarget->m_format = ysRenderTarget::Format::R8G8B8A8_UNORM; newRenderTarget->m_hasDepthBuffer = depthBuffer; newRenderTarget->m_associatedContext = nullptr; diff --git a/src/yds_d3d11_device.cpp b/src/yds_d3d11_device.cpp index 92081c1a..6c8be347 100644 --- a/src/yds_d3d11_device.cpp +++ b/src/yds_d3d11_device.cpp @@ -372,7 +372,7 @@ ysError ysD3D11Device::CreateOnScreenRenderTarget(ysRenderTarget **newTarget, ys return YDS_ERROR_RETURN(ysError::YDS_NO_ERROR); } -ysError ysD3D11Device::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer) { +ysError ysD3D11Device::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer) { YDS_ERROR_DECLARE("CreateOffScreenRenderTarget"); if (newTarget == nullptr) return YDS_ERROR_RETURN(ysError::YDS_INVALID_PARAMETER); @@ -380,7 +380,7 @@ ysError ysD3D11Device::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, i ysD3D11RenderTarget *d3d11Target = m_renderTargets.NewGeneric(); - ysError result = CreateD3D11OffScreenRenderTarget(d3d11Target, width, height, format, sampleCount, depthBuffer); + ysError result = CreateD3D11OffScreenRenderTarget(d3d11Target, width, height, format, colorData, depthBuffer); if (result != ysError::YDS_NO_ERROR) { m_renderTargets.Delete(d3d11Target->GetIndex()); @@ -405,7 +405,7 @@ ysError ysD3D11Device::CreateSubRenderTarget(ysRenderTarget **newTarget, ysRende newRenderTarget->m_posY = y; newRenderTarget->m_width = width; newRenderTarget->m_height = height; - newRenderTarget->m_format = ysRenderTarget::Format::RTF_R8G8B8A8_UNORM; + newRenderTarget->m_format = ysRenderTarget::Format::R8G8B8A8_UNORM; newRenderTarget->m_hasDepthBuffer = parent->HasDepthBuffer(); newRenderTarget->m_associatedContext = parent->GetAssociatedContext(); newRenderTarget->m_parent = parent; @@ -491,7 +491,7 @@ ysError ysD3D11Device::ResizeRenderTarget(ysRenderTarget *target, int width, int YDS_NESTED_ERROR_CALL(CreateD3D11OnScreenRenderTarget(target, target->GetAssociatedContext(), target->HasDepthBuffer())); } else if (target->GetType() == ysRenderTarget::Type::OffScreen) { - YDS_NESTED_ERROR_CALL(CreateD3D11OffScreenRenderTarget(target, width, height, target->GetFormat(), target->GetSampleCount(), target->HasDepthBuffer())); + YDS_NESTED_ERROR_CALL(CreateD3D11OffScreenRenderTarget(target, width, height, target->GetFormat(), target->HasColorData(), target->HasDepthBuffer())); } else if (target->GetType() == ysRenderTarget::Type::Subdivision) { // Nothing needs to be done @@ -527,8 +527,8 @@ ysError ysD3D11Device::ClearBuffers(const float *clearColor) { if (m_activeRenderTarget != nullptr) { ysD3D11RenderTarget *renderTarget = static_cast(m_activeRenderTarget); - GetImmediateContext()->ClearRenderTargetView(renderTarget->m_renderTargetView, clearColor); - if (renderTarget->m_hasDepthBuffer) GetImmediateContext()->ClearDepthStencilView(renderTarget->m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); + if (renderTarget->HasColorData()) GetImmediateContext()->ClearRenderTargetView(renderTarget->m_renderTargetView, clearColor); + if (renderTarget->HasDepthBuffer()) GetImmediateContext()->ClearDepthStencilView(renderTarget->m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); return YDS_ERROR_RETURN(ysError::YDS_NO_ERROR); } @@ -1259,7 +1259,7 @@ DXGI_FORMAT ysD3D11Device::ConvertInputLayoutFormat(ysRenderGeometryChannel::Cha } } -ysError ysD3D11Device::CreateD3D11DepthStencilView(ID3D11DepthStencilView **newDepthStencil, int width, int height, int count, int quality) { +ysError ysD3D11Device::CreateD3D11DepthStencilView(ID3D11DepthStencilView **newDepthStencil, ID3D11ShaderResourceView **shaderResourceView, int width, int height, int count, int quality, bool shaderResource) { YDS_ERROR_DECLARE("CreateD3D11DepthBuffer"); if (newDepthStencil == nullptr) return YDS_ERROR_RETURN(ysError::YDS_INVALID_PARAMETER); @@ -1275,11 +1275,19 @@ ysError ysD3D11Device::CreateD3D11DepthStencilView(ID3D11DepthStencilView **newD descDepth.Height = height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; - descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + if (shaderResource) { + descDepth.Format = DXGI_FORMAT_R32_TYPELESS; + } + else { + descDepth.Format = DXGI_FORMAT_D32_FLOAT; + } + descDepth.SampleDesc.Count = count; descDepth.SampleDesc.Quality = quality; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; + if (shaderResource) descDepth.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; result = m_device->CreateTexture2D(&descDepth, nullptr, &depthBuffer); @@ -1289,18 +1297,24 @@ ysError ysD3D11Device::CreateD3D11DepthStencilView(ID3D11DepthStencilView **newD } D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; - descDSV.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + ZeroMemory(&descDSV, sizeof(descDSV)); + descDSV.Format = DXGI_FORMAT_D32_FLOAT; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; - result = m_device->CreateDepthStencilView(depthBuffer, nullptr, newDepthStencil); - if (FAILED(result)) { - depthBuffer->Release(); - return YDS_ERROR_RETURN(ysError::YDS_COULD_NOT_CREATE_DEPTH_BUFFER); + if (shaderResource) { + result = m_device->CreateDepthStencilView(depthBuffer, &descDSV, newDepthStencil); + } + else { + result = m_device->CreateDepthStencilView(depthBuffer, nullptr, newDepthStencil); } depthBuffer->Release(); + if (FAILED(result)) { + return YDS_ERROR_RETURN(ysError::YDS_COULD_NOT_CREATE_DEPTH_BUFFER); + } + return YDS_ERROR_RETURN(ysError::YDS_NO_ERROR); } @@ -1341,8 +1355,8 @@ ysError ysD3D11Device::CreateD3D11OnScreenRenderTarget(ysRenderTarget *newTarget if (depthBuffer) { ysError depthResult = CreateD3D11DepthStencilView( - &newDepthStencilView, context->GetWindow()->GetScreenWidth(), context->GetWindow()->GetScreenHeight(), - m_multisampleCount, m_multisampleQuality); + &newDepthStencilView, nullptr, context->GetWindow()->GetScreenWidth(), context->GetWindow()->GetScreenHeight(), + m_multisampleCount, m_multisampleQuality, false); if (depthResult != ysError::YDS_NO_ERROR) { newRenderTargetView->Release(); @@ -1358,7 +1372,7 @@ ysError ysD3D11Device::CreateD3D11OnScreenRenderTarget(ysRenderTarget *newTarget newRenderTarget->m_posY = 0; newRenderTarget->m_width = context->GetWindow()->GetScreenWidth(); newRenderTarget->m_height = context->GetWindow()->GetScreenHeight(); - newRenderTarget->m_format = ysRenderTarget::Format::RTF_R8G8B8A8_UNORM; + newRenderTarget->m_format = ysRenderTarget::Format::R8G8B8A8_UNORM; newRenderTarget->m_hasDepthBuffer = depthBuffer; newRenderTarget->m_associatedContext = context; @@ -1370,7 +1384,7 @@ ysError ysD3D11Device::CreateD3D11OnScreenRenderTarget(ysRenderTarget *newTarget } ysError ysD3D11Device::CreateD3D11OffScreenRenderTarget( - ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer) + ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, bool colorData, bool depthBuffer) { YDS_ERROR_DECLARE("CreateD3D11OffScreenRenderTarget"); @@ -1381,66 +1395,81 @@ ysError ysD3D11Device::CreateD3D11OffScreenRenderTarget( ID3D11ShaderResourceView *shaderResourceView = nullptr; ID3D11DepthStencilView *newDepthStencil = nullptr; - // Create the texture - D3D11_TEXTURE2D_DESC descBuffer; - ZeroMemory(&descBuffer, sizeof(descBuffer)); - descBuffer.Width = width; - descBuffer.Height = height; - descBuffer.MipLevels = 1; - descBuffer.ArraySize = 1; - - if (format == ysRenderTarget::Format::RTF_R32G32B32_FLOAT) - descBuffer.Format = DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT; - else if (format == ysRenderTarget::Format::RTF_R8G8B8A8_UNORM) - descBuffer.Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM; - - descBuffer.SampleDesc.Count = 1; - descBuffer.SampleDesc.Quality = 0; - descBuffer.Usage = D3D11_USAGE_DEFAULT; - descBuffer.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; - descBuffer.CPUAccessFlags = 0; - descBuffer.MiscFlags = 0; - result = m_device->CreateTexture2D(&descBuffer, nullptr, &renderTarget); + if (colorData) { + // Create the texture + D3D11_TEXTURE2D_DESC descBuffer; + ZeroMemory(&descBuffer, sizeof(descBuffer)); + descBuffer.Width = width; + descBuffer.Height = height; + descBuffer.MipLevels = 1; + descBuffer.ArraySize = 1; + + if (format == ysRenderTarget::Format::R32G32B32_FLOAT) { + descBuffer.Format = DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT; + } + else if (format == ysRenderTarget::Format::R8G8B8A8_UNORM) { + descBuffer.Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM; + } + else if (format == ysRenderTarget::Format::R32_FLOAT) { + descBuffer.Format = DXGI_FORMAT::DXGI_FORMAT_R32_FLOAT; + } - if (FAILED(result)) { - return YDS_ERROR_RETURN(ysError::YDS_COULD_NOT_CREATE_RENDER_TARGET); - } + descBuffer.SampleDesc.Count = 1; + descBuffer.SampleDesc.Quality = 0; + descBuffer.Usage = D3D11_USAGE_DEFAULT; - // Create the render target view - D3D11_RENDER_TARGET_VIEW_DESC rtDesc; - ZeroMemory(&rtDesc, sizeof(rtDesc)); - rtDesc.Format = descBuffer.Format; - rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtDesc.Texture2D.MipSlice = 0; + descBuffer.BindFlags = 0; + if (colorData) descBuffer.BindFlags |= D3D11_BIND_RENDER_TARGET; + else if (depthBuffer) descBuffer.BindFlags |= D3D11_BIND_DEPTH_STENCIL; - result = m_device->CreateRenderTargetView(renderTarget, &rtDesc, &newRenderTargetView); + descBuffer.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + descBuffer.CPUAccessFlags = 0; + descBuffer.MiscFlags = 0; + result = m_device->CreateTexture2D(&descBuffer, nullptr, &renderTarget); - if (FAILED(result)) { - return YDS_ERROR_RETURN(ysError::YDS_COULD_NOT_CREATE_RENDER_TARGET); - } + if (FAILED(result)) { + return YDS_ERROR_RETURN(ysError::YDS_COULD_NOT_CREATE_RENDER_TARGET); + } - // Create the shader resource view - D3D11_SHADER_RESOURCE_VIEW_DESC srDesc; - ZeroMemory(&srDesc, sizeof(srDesc)); - srDesc.Format = descBuffer.Format; - srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srDesc.Texture2D.MostDetailedMip = 0; - srDesc.Texture2D.MipLevels = 1; + // Create the render target view + D3D11_RENDER_TARGET_VIEW_DESC rtDesc; + ZeroMemory(&rtDesc, sizeof(rtDesc)); + rtDesc.Format = descBuffer.Format; + rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtDesc.Texture2D.MipSlice = 0; - result = m_device->CreateShaderResourceView(renderTarget, &srDesc, &shaderResourceView); + result = m_device->CreateRenderTargetView(renderTarget, &rtDesc, &newRenderTargetView); - if (FAILED(result)) { - return YDS_ERROR_RETURN(ysError::YDS_COULD_NOT_CREATE_RENDER_TARGET); - } + if (FAILED(result)) { + return YDS_ERROR_RETURN(ysError::YDS_COULD_NOT_CREATE_RENDER_TARGET); + } + + // Create the shader resource view + D3D11_SHADER_RESOURCE_VIEW_DESC srDesc; + ZeroMemory(&srDesc, sizeof(srDesc)); + srDesc.Format = descBuffer.Format; + srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srDesc.Texture2D.MostDetailedMip = 0; + srDesc.Texture2D.MipLevels = 1; - renderTarget->Release(); + result = m_device->CreateShaderResourceView(renderTarget, &srDesc, &shaderResourceView); + + if (FAILED(result)) { + return YDS_ERROR_RETURN(ysError::YDS_COULD_NOT_CREATE_RENDER_TARGET); + } + + renderTarget->Release(); + } // Create Depth Buffer if (depthBuffer) { - ysError depthResult = CreateD3D11DepthStencilView(&newDepthStencil, width, height, 1, 0); + ysError depthResult; + + if (!colorData) depthResult = CreateD3D11DepthStencilView(&newDepthStencil, &shaderResourceView, width, height, 1, 0, true); + else depthResult = CreateD3D11DepthStencilView(&newDepthStencil, nullptr, width, height, 1, 0, false); if (depthResult != ysError::YDS_NO_ERROR) { - newRenderTargetView->Release(); + if (newRenderTargetView != nullptr) newRenderTargetView->Release(); return YDS_ERROR_RETURN(depthResult); } } @@ -1454,9 +1483,11 @@ ysError ysD3D11Device::CreateD3D11OffScreenRenderTarget( newRenderTarget->m_posY = 0; newRenderTarget->m_width = width; newRenderTarget->m_height = height; - newRenderTarget->m_format = ysRenderTarget::Format::RTF_R8G8B8A8_UNORM; + newRenderTarget->m_format = format; newRenderTarget->m_hasDepthBuffer = depthBuffer; + newRenderTarget->m_hasColorData = colorData; newRenderTarget->m_associatedContext = nullptr; + newRenderTarget->m_depthTestEnabled = depthBuffer; newRenderTarget->m_renderTargetView = newRenderTargetView; newRenderTarget->m_depthStencilView = newDepthStencil; diff --git a/src/yds_device.cpp b/src/yds_device.cpp index 37562ea6..fffce8c0 100644 --- a/src/yds_device.cpp +++ b/src/yds_device.cpp @@ -119,7 +119,6 @@ ysError ysDevice::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, const reference->GetWidth(), reference->GetHeight(), reference->GetFormat(), - reference->GetSampleCount(), reference->HasDepthBuffer()) ); return YDS_ERROR_RETURN(ysError::YDS_NO_ERROR); diff --git a/src/yds_opengl_device.cpp b/src/yds_opengl_device.cpp index e1500e82..b8c70006 100644 --- a/src/yds_opengl_device.cpp +++ b/src/yds_opengl_device.cpp @@ -167,7 +167,7 @@ ysError ysOpenGLDevice::CreateOnScreenRenderTarget(ysRenderTarget **newTarget, y newRenderTarget->m_posY = 0; newRenderTarget->m_width = context->GetWindow()->GetScreenWidth(); newRenderTarget->m_height = context->GetWindow()->GetScreenHeight(); - newRenderTarget->m_format = ysRenderTarget::Format::RTF_R8G8B8A8_UNORM; + newRenderTarget->m_format = ysRenderTarget::Format::R8G8B8A8_UNORM; newRenderTarget->m_hasDepthBuffer = depthBuffer; newRenderTarget->m_associatedContext = context; @@ -176,14 +176,16 @@ ysError ysOpenGLDevice::CreateOnScreenRenderTarget(ysRenderTarget **newTarget, y return YDS_ERROR_RETURN(ysError::YDS_NO_ERROR); } -ysError ysOpenGLDevice::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer) { +ysError ysOpenGLDevice::CreateOffScreenRenderTarget(ysRenderTarget **newTarget, int width, int height, + ysRenderTarget::Format format, bool colorData, bool depthBuffer) +{ YDS_ERROR_DECLARE("CreateOffScreenRenderTarget"); if (newTarget == nullptr) return YDS_ERROR_RETURN(ysError::YDS_INVALID_PARAMETER); ysOpenGLRenderTarget *newRenderTarget = m_renderTargets.NewGeneric(); - ysError result = CreateOpenGLOffScreenRenderTarget(newRenderTarget, width, height, format, sampleCount, depthBuffer); + ysError result = CreateOpenGLOffScreenRenderTarget(newRenderTarget, width, height, format, colorData, depthBuffer); if (result != ysError::YDS_NO_ERROR) { m_renderTargets.Delete(newRenderTarget->GetIndex()); return result; @@ -207,7 +209,7 @@ ysError ysOpenGLDevice::CreateSubRenderTarget(ysRenderTarget **newTarget, ysRend newRenderTarget->m_posY = y; newRenderTarget->m_width = width; newRenderTarget->m_height = height; - newRenderTarget->m_format = ysRenderTarget::Format::RTF_R8G8B8A8_UNORM; + newRenderTarget->m_format = ysRenderTarget::Format::R8G8B8A8_UNORM; newRenderTarget->m_hasDepthBuffer = parent->HasDepthBuffer(); newRenderTarget->m_associatedContext = parent->GetAssociatedContext(); newRenderTarget->m_parent = parent; @@ -234,7 +236,7 @@ ysError ysOpenGLDevice::ResizeRenderTarget(ysRenderTarget *target, int width, in } else if (target->GetType() == ysRenderTarget::Type::OffScreen) { YDS_NESTED_ERROR_CALL(CreateOpenGLOffScreenRenderTarget( - target, width, height, target->GetFormat(), target->GetSampleCount(), target->HasDepthBuffer())); + target, width, height, target->GetFormat(), target->HasColorData(), target->HasDepthBuffer())); } else if (target->GetType() == ysRenderTarget::Type::Subdivision) { // Nothing needs to be done @@ -1044,7 +1046,9 @@ void ysOpenGLDevice::Draw(int numFaces, int indexOffset, int vertexOffset) { } } -ysError ysOpenGLDevice::CreateOpenGLOffScreenRenderTarget(ysRenderTarget *target, int width, int height, ysRenderTarget::Format format, int sampleCount, bool depthBuffer) { +ysError ysOpenGLDevice::CreateOpenGLOffScreenRenderTarget(ysRenderTarget *target, int width, int height, + ysRenderTarget::Format format, bool colorData, bool depthBuffer) +{ YDS_ERROR_DECLARE("CreateOpenGLOffScreenRenderTarget"); // Generate the empty texture @@ -1061,11 +1065,11 @@ ysError ysOpenGLDevice::CreateOpenGLOffScreenRenderTarget(ysRenderTarget *target int glType; switch (format) { - case ysRenderTarget::Format::RTF_R8G8B8A8_UNORM: + case ysRenderTarget::Format::R8G8B8A8_UNORM: glFormat = GL_RGBA8; glType = GL_UNSIGNED_BYTE; break; - case ysRenderTarget::Format::RTF_R32G32B32_FLOAT: + case ysRenderTarget::Format::R32G32B32_FLOAT: glFormat = GL_RGBA32F_ARB; glType = GL_FLOAT; break;