diff --git a/framework/platform/blendstate-dx.cpp b/framework/platform/blendstate-dx.cpp index 59167d0..2259604 100644 --- a/framework/platform/blendstate-dx.cpp +++ b/framework/platform/blendstate-dx.cpp @@ -1,7 +1,23 @@ -#include "platform-dx/blendstate-dx.hpp" +#include "graphics/blendstate.hpp" +#include "graphics/gresource.hpp" #include "platform-dx/device-dx.hpp" +#include "platform-dx/dxheaders.hpp" +#include "graphics/blendstate.hpp" +#include "platform-dx/implementations.hpp" namespace xna { + BlendState::BlendState() : GraphicsResource(nullptr) { + impl = uNew(); + } + + BlendState::BlendState(sptr const& device) : GraphicsResource(device) { + impl = uNew(); + } + + BlendState::~BlendState() { + impl = nullptr; + } + bool BlendState::Initialize(xna_error_ptr_arg) { if (!m_device || !m_device->_device) { @@ -9,12 +25,14 @@ namespace xna { return false; } - if (dxBlendState) { - dxBlendState->Release(); - dxBlendState = nullptr; + if (impl->dxBlendState) { + impl->dxBlendState->Release(); + impl->dxBlendState = nullptr; } - const auto hr = m_device->_device->CreateBlendState(&dxDescription, &dxBlendState); + const auto hr = m_device->_device->CreateBlendState( + &impl->dxDescription, + &impl->dxBlendState); if (FAILED(hr)) { xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); @@ -30,52 +48,76 @@ namespace xna { return false; } - if (!dxBlendState) { + if (!impl->dxBlendState) { xna_error_apply(err, XnaErrorCode::UNINTIALIZED_RESOURCE); return false; } - m_device->_context->OMSetBlendState(dxBlendState, blendFactor, sampleMask); + m_device->_context->OMSetBlendState( + impl->dxBlendState, + impl->blendFactor, + impl->sampleMask); return true; } + void BlendState::AlphaToCoverageEnable(bool value) { + impl->dxDescription.AlphaToCoverageEnable = value; + } + + void BlendState::IndependentBlendEnable(bool value) { + impl->dxDescription.IndependentBlendEnable = value; + } + + void BlendState::RenderTargets(std::vector const& value) { + for (size_t i = 0; i < value.size() && i < 8; ++i) { + impl->dxDescription.RenderTarget[i].BlendEnable = value[i].Enabled; + impl->dxDescription.RenderTarget[i].SrcBlend = PlatformImplementation::ConvertBlend(value[i].Source); + impl->dxDescription.RenderTarget[i].DestBlend = PlatformImplementation::ConvertBlend(value[i].Destination); + impl->dxDescription.RenderTarget[i].BlendOp = PlatformImplementation::ConvertOperation(value[i].Operation); + impl->dxDescription.RenderTarget[i].SrcBlendAlpha = PlatformImplementation::ConvertBlend(value[i].SourceAlpha); + impl->dxDescription.RenderTarget[i].DestBlendAlpha = PlatformImplementation::ConvertBlend(value[i].DestinationAlpha); + impl->dxDescription.RenderTarget[i].BlendOpAlpha = PlatformImplementation::ConvertOperation(value[i].OperationAlpha); + impl->dxDescription.RenderTarget[i].RenderTargetWriteMask = PlatformImplementation::ConvertColorWrite(value[i].WriteMask); + } + } + uptr BlendState::Opaque() { - auto blendState = std::unique_ptr(new BlendState()); - blendState->dxDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - blendState->dxDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; - blendState->dxDescription.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_ALPHA; - blendState->dxDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + auto blendState = uNew(); + blendState->impl->dxDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blendState->impl->dxDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; + blendState->impl->dxDescription.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; return blendState; } uptr BlendState::AlphaBlend() { auto blendState = std::unique_ptr(new BlendState()); - blendState->dxDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - blendState->dxDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - blendState->dxDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - blendState->dxDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blendState->impl->dxDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendState->impl->dxDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; return blendState; } uptr BlendState::Additive() { auto blendState = std::unique_ptr(new BlendState()); - blendState->dxDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - blendState->dxDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; - blendState->dxDescription.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; - blendState->dxDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; + blendState->impl->dxDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; + blendState->impl->dxDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; return blendState; } uptr BlendState::NonPremultiplied() { auto blendState = std::unique_ptr(new BlendState()); - blendState->dxDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - blendState->dxDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; - blendState->dxDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - blendState->dxDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blendState->impl->dxDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; return blendState; } diff --git a/framework/platform/device-dx.cpp b/framework/platform/device-dx.cpp index 2dce495..e62b6e7 100644 --- a/framework/platform/device-dx.cpp +++ b/framework/platform/device-dx.cpp @@ -1,13 +1,13 @@ -#include "platform-dx/device-dx.hpp" -#include "platform-dx/window-dx.hpp" -#include "platform-dx/swapchain-dx.hpp" -#include "platform-dx/rendertarget-dx.hpp" -#include "platform-dx/blendstate-dx.hpp" -#include "platform-dx/gdeviceinfo-dx.hpp" #include "common/color.hpp" -#include "platform-dx/gdevicemanager-dx.hpp" #include "graphics/adapter.hpp" +#include "graphics/blendstate.hpp" +#include "platform-dx/device-dx.hpp" +#include "platform-dx/gdeviceinfo-dx.hpp" +#include "platform-dx/gdevicemanager-dx.hpp" #include "platform-dx/implementations.hpp" +#include "platform-dx/rendertarget-dx.hpp" +#include "platform-dx/swapchain-dx.hpp" +#include "platform-dx/window-dx.hpp" namespace xna { GraphicsDevice::GraphicsDevice() { diff --git a/framework/platform/sprite-dx.cpp b/framework/platform/sprite-dx.cpp index 5d3b077..836507d 100644 --- a/framework/platform/sprite-dx.cpp +++ b/framework/platform/sprite-dx.cpp @@ -1,4 +1,3 @@ -#include "platform-dx/blendstate-dx.hpp" #include "platform-dx/device-dx.hpp" #include "platform-dx/rasterizerstate-dx.hpp" #include "platform-dx/depthstencilstate-dx.hpp" @@ -8,6 +7,7 @@ #include "common/numerics.hpp" #include "graphics/sprite.hpp" #include "graphics/viewport.hpp" +#include "graphics/blendstate.hpp" #include "platform-dx/implementations.hpp" using DxSpriteBatch = DirectX::SpriteBatch; @@ -78,7 +78,7 @@ namespace xna { implementation->_dxspriteBatch->Begin( sort, - blendState ? blendState->dxBlendState : nullptr, + blendState ? blendState->impl->dxBlendState : nullptr, samplerState ? samplerState->_samplerState : nullptr, depthStencil ? depthStencil->dxDepthStencil : nullptr, rasterizerState ? rasterizerState->dxRasterizerState : nullptr, diff --git a/inc/graphics/blendstate.hpp b/inc/graphics/blendstate.hpp index b851270..0a37ddb 100644 --- a/inc/graphics/blendstate.hpp +++ b/inc/graphics/blendstate.hpp @@ -2,19 +2,30 @@ #define XNA_GRAPHICS_BLENDSTATE_HPP #include "../default.hpp" +#include "gresource.hpp" namespace xna { struct BlendRenderTarget; - class IBlendState { + class BlendState : public GraphicsResource { public: - virtual ~IBlendState() {} - virtual bool Initialize(xna_error_nullarg) = 0; - virtual void AlphaToCoverageEnable(bool value) = 0; - virtual void IndependentBlendEnable(bool value) = 0; - virtual void RenderTargets(std::vector const& value) = 0; + BlendState(); + BlendState(sptr const& device); + ~BlendState(); + bool Initialize(xna_error_nullarg) ; + void AlphaToCoverageEnable(bool value) ; + void IndependentBlendEnable(bool value) ; + void RenderTargets(std::vector const& value); + bool Apply(xna_error_nullarg); - virtual bool Apply(xna_error_nullarg) = 0; + static uptr Opaque(); + static uptr AlphaBlend(); + static uptr Additive(); + static uptr NonPremultiplied(); + + public: + struct PlatformImplementation; + uptr impl = nullptr; }; } diff --git a/inc/platform-dx/blendstate-dx.hpp b/inc/platform-dx/blendstate-dx.hpp deleted file mode 100644 index 1941daa..0000000 --- a/inc/platform-dx/blendstate-dx.hpp +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef XNA_PLATFORM_BLENDSTATE_HPP -#define XNA_PLATFORM_BLENDSTATE_HPP - -#include "../graphics/blendstate.hpp" -#include "../graphics/gresource.hpp" -#include "dxheaders.hpp" - -namespace xna { - struct BlendRenderTarget { - bool Enabled{ true }; - Blend Source{ Blend::SourceAlpha }; - Blend Destination{ Blend::InverseSourceAlpha }; - BlendOperation Operation{ BlendOperation::Add }; - Blend SourceAlpha{ Blend::One }; - Blend DestinationAlpha{ Blend::Zero }; - BlendOperation OperationAlpha{ BlendOperation::Add }; - ColorWriteChannels WriteMask{ ColorWriteChannels::All }; - - constexpr BlendRenderTarget() = default; - }; - - class BlendState : public IBlendState, public GraphicsResource { - public: - BlendState(sptr const& device) : GraphicsResource(device) {}; - - virtual ~BlendState() override { - if (dxBlendState) { - dxBlendState->Release(); - dxBlendState = nullptr; - } - } - virtual bool Initialize(xna_error_nullarg) override; - - virtual constexpr void AlphaToCoverageEnable(bool value) override { - dxDescription.AlphaToCoverageEnable = value; - } - - virtual constexpr void IndependentBlendEnable(bool value) override { - dxDescription.IndependentBlendEnable = value; - } - - virtual void RenderTargets(std::vector const& value) override { - for (size_t i = 0; i < value.size() && i < 8; ++i) { - dxDescription.RenderTarget[i].BlendEnable = value[i].Enabled; - dxDescription.RenderTarget[i].SrcBlend = ConvertBlend(value[i].Source); - dxDescription.RenderTarget[i].DestBlend = ConvertBlend(value[i].Destination); - dxDescription.RenderTarget[i].BlendOp = ConvertOperation(value[i].Operation); - dxDescription.RenderTarget[i].SrcBlendAlpha = ConvertBlend(value[i].SourceAlpha); - dxDescription.RenderTarget[i].DestBlendAlpha = ConvertBlend(value[i].DestinationAlpha); - dxDescription.RenderTarget[i].BlendOpAlpha = ConvertOperation(value[i].OperationAlpha); - dxDescription.RenderTarget[i].RenderTargetWriteMask = ConvertColorWrite(value[i].WriteMask); - } - } - - virtual bool Apply(xna_error_nullarg) override; - - static uptr Opaque(); - static uptr AlphaBlend(); - static uptr Additive(); - static uptr NonPremultiplied(); - - public: - ID3D11BlendState* dxBlendState{ nullptr }; - D3D11_BLEND_DESC dxDescription{}; - float blendFactor[4] { 1.0F, 1.0F, 1.0F, 1.0F }; - UINT sampleMask{ 0xffffffff }; - - private: - BlendState() : GraphicsResource(nullptr){} - - public: - static constexpr D3D11_BLEND ConvertBlend(Blend blend) { - switch (blend) - { - case xna::Blend::Zero: - return D3D11_BLEND_ZERO; - case xna::Blend::One: - return D3D11_BLEND_ONE; - case xna::Blend::SourceColor: - return D3D11_BLEND_SRC_COLOR; - case xna::Blend::InverseSourceColor: - return D3D11_BLEND_INV_SRC_COLOR; - case xna::Blend::SourceAlpha: - return D3D11_BLEND_SRC_ALPHA; - case xna::Blend::InverseSourceAlpha: - return D3D11_BLEND_INV_SRC_ALPHA; - case xna::Blend::DestinationAlpha: - return D3D11_BLEND_DEST_ALPHA; - case xna::Blend::InverseDestinationAlpha: - return D3D11_BLEND_INV_DEST_ALPHA; - case xna::Blend::DestinationColor: - return D3D11_BLEND_DEST_COLOR; - case xna::Blend::InverseDestinationColor: - return D3D11_BLEND_INV_DEST_COLOR; - case xna::Blend::SourceAlphaSaturation: - return D3D11_BLEND_SRC_ALPHA_SAT; - case xna::Blend::BlendFactor: - return D3D11_BLEND_BLEND_FACTOR; - case xna::Blend::InverseBlendFactor: - return D3D11_BLEND_INV_BLEND_FACTOR; - case xna::Blend::Source1Color: - return D3D11_BLEND_SRC1_COLOR; - case xna::Blend::InverseSource1Color: - return D3D11_BLEND_INV_SRC1_COLOR; - case xna::Blend::Source1Alpha: - return D3D11_BLEND_SRC1_ALPHA; - case xna::Blend::InverseSource1Alpha: - return D3D11_BLEND_INV_SRC1_ALPHA; - default: - return D3D11_BLEND_ZERO; - } - } - - static constexpr D3D11_BLEND_OP ConvertOperation(BlendOperation op) { - return static_cast(static_cast(op) + 1); - } - - static constexpr D3D11_COLOR_WRITE_ENABLE ConvertColorWrite(ColorWriteChannels colorWrite) { - switch (colorWrite) - { - case xna::ColorWriteChannels::Red: - return D3D11_COLOR_WRITE_ENABLE_RED; - case xna::ColorWriteChannels::Green: - return D3D11_COLOR_WRITE_ENABLE_GREEN; - case xna::ColorWriteChannels::Blue: - return D3D11_COLOR_WRITE_ENABLE_BLUE; - case xna::ColorWriteChannels::Alpha: - return D3D11_COLOR_WRITE_ENABLE_ALPHA; - case xna::ColorWriteChannels::All: - return D3D11_COLOR_WRITE_ENABLE_ALL; - default: - return D3D11_COLOR_WRITE_ENABLE_ALL; - } - } - }; -} - -#endif \ No newline at end of file diff --git a/inc/platform-dx/implementations.hpp b/inc/platform-dx/implementations.hpp index 5ceb5d5..0b324b1 100644 --- a/inc/platform-dx/implementations.hpp +++ b/inc/platform-dx/implementations.hpp @@ -5,7 +5,7 @@ #include "dxheaders.hpp" #include "platform-dx/swapchain-dx.hpp" #include "platform-dx/rendertarget-dx.hpp" -#include "platform-dx/blendstate-dx.hpp" +#include "graphics/blendstate.hpp" namespace xna { struct SpriteFont::PlatformImplementation { @@ -127,4 +127,95 @@ namespace xna { } } }; + + struct BlendRenderTarget { + bool Enabled{ true }; + Blend Source{ Blend::SourceAlpha }; + Blend Destination{ Blend::InverseSourceAlpha }; + BlendOperation Operation{ BlendOperation::Add }; + Blend SourceAlpha{ Blend::One }; + Blend DestinationAlpha{ Blend::Zero }; + BlendOperation OperationAlpha{ BlendOperation::Add }; + ColorWriteChannels WriteMask{ ColorWriteChannels::All }; + + constexpr BlendRenderTarget() = default; + }; + + struct BlendState::PlatformImplementation { + ~PlatformImplementation() { + if (dxBlendState) { + dxBlendState->Release(); + dxBlendState = nullptr; + } + } + + ID3D11BlendState* dxBlendState = nullptr; + D3D11_BLEND_DESC dxDescription{}; + float blendFactor[4]{ 1.0F, 1.0F, 1.0F, 1.0F }; + UINT sampleMask{ 0xffffffff }; + + static constexpr D3D11_BLEND ConvertBlend(Blend blend) { + switch (blend) + { + case xna::Blend::Zero: + return D3D11_BLEND_ZERO; + case xna::Blend::One: + return D3D11_BLEND_ONE; + case xna::Blend::SourceColor: + return D3D11_BLEND_SRC_COLOR; + case xna::Blend::InverseSourceColor: + return D3D11_BLEND_INV_SRC_COLOR; + case xna::Blend::SourceAlpha: + return D3D11_BLEND_SRC_ALPHA; + case xna::Blend::InverseSourceAlpha: + return D3D11_BLEND_INV_SRC_ALPHA; + case xna::Blend::DestinationAlpha: + return D3D11_BLEND_DEST_ALPHA; + case xna::Blend::InverseDestinationAlpha: + return D3D11_BLEND_INV_DEST_ALPHA; + case xna::Blend::DestinationColor: + return D3D11_BLEND_DEST_COLOR; + case xna::Blend::InverseDestinationColor: + return D3D11_BLEND_INV_DEST_COLOR; + case xna::Blend::SourceAlphaSaturation: + return D3D11_BLEND_SRC_ALPHA_SAT; + case xna::Blend::BlendFactor: + return D3D11_BLEND_BLEND_FACTOR; + case xna::Blend::InverseBlendFactor: + return D3D11_BLEND_INV_BLEND_FACTOR; + case xna::Blend::Source1Color: + return D3D11_BLEND_SRC1_COLOR; + case xna::Blend::InverseSource1Color: + return D3D11_BLEND_INV_SRC1_COLOR; + case xna::Blend::Source1Alpha: + return D3D11_BLEND_SRC1_ALPHA; + case xna::Blend::InverseSource1Alpha: + return D3D11_BLEND_INV_SRC1_ALPHA; + default: + return D3D11_BLEND_ZERO; + } + } + + static constexpr D3D11_BLEND_OP ConvertOperation(BlendOperation op) { + return static_cast(static_cast(op) + 1); + } + + static constexpr D3D11_COLOR_WRITE_ENABLE ConvertColorWrite(ColorWriteChannels colorWrite) { + switch (colorWrite) + { + case xna::ColorWriteChannels::Red: + return D3D11_COLOR_WRITE_ENABLE_RED; + case xna::ColorWriteChannels::Green: + return D3D11_COLOR_WRITE_ENABLE_GREEN; + case xna::ColorWriteChannels::Blue: + return D3D11_COLOR_WRITE_ENABLE_BLUE; + case xna::ColorWriteChannels::Alpha: + return D3D11_COLOR_WRITE_ENABLE_ALPHA; + case xna::ColorWriteChannels::All: + return D3D11_COLOR_WRITE_ENABLE_ALL; + default: + return D3D11_COLOR_WRITE_ENABLE_ALL; + } + } + }; } \ No newline at end of file diff --git a/inc/platform-dx/xna-dx.hpp b/inc/platform-dx/xna-dx.hpp index c0a906f..b251868 100644 --- a/inc/platform-dx/xna-dx.hpp +++ b/inc/platform-dx/xna-dx.hpp @@ -1,5 +1,4 @@ #include "audioengine-dx.hpp" -#include "blendstate-dx.hpp" #include "clock-dx.hpp" #include "constbuffer-dx.hpp" #include "databuffer-dx.hpp"