#ifndef __URDE_TMULTIBLENDSHADER_HPP__ #define __URDE_TMULTIBLENDSHADER_HPP__ #include "Graphics/CGraphics.hpp" #include "boo/graphicsdev/GL.hpp" #include "boo/graphicsdev/D3D.hpp" #include "boo/graphicsdev/Metal.hpp" #include "boo/graphicsdev/Vulkan.hpp" #include "Camera/CCameraFilter.hpp" namespace urde { template class TMultiBlendShader { public: struct IDataBindingFactory { virtual boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, boo::IShaderPipeline* pipeline, boo::IVertexFormat* vtxFmt, FilterImp& filter)=0; }; static boo::IShaderPipeline* m_alphaBlendPipeline; static boo::IShaderPipeline* m_additiveAlphaPipeline; static boo::IShaderPipeline* m_colorMultiplyPipeline; static boo::IVertexFormat* m_vtxFmt; /* No OpenGL */ static std::unique_ptr m_bindFactory; static boo::GraphicsDataToken m_gfxToken; static void Initialize() { if (!CGraphics::g_BooFactory) return; m_gfxToken = CGraphics::CommitResources( [&](boo::IGraphicsDataFactory::Context& ctx) -> bool { switch (ctx.platform()) { case boo::IGraphicsDataFactory::Platform::OpenGL: m_bindFactory.reset(FilterImp::Initialize(static_cast(ctx), m_alphaBlendPipeline, m_additiveAlphaPipeline, m_colorMultiplyPipeline)); break; #if _WIN32 case boo::IGraphicsDataFactory::Platform::D3D11: case boo::IGraphicsDataFactory::Platform::D3D12: m_bindFactory.reset(FilterImp::Initialize(static_cast(ctx), m_alphaBlendPipeline, m_additiveAlphaPipeline, m_colorMultiplyPipeline, m_vtxFmt)); break; #endif #if BOO_HAS_METAL case boo::IGraphicsDataFactory::Platform::Metal: m_bindFactory.reset(FilterImp::Initialize(static_cast(ctx), m_alphaBlendPipeline, m_additiveAlphaPipeline, m_colorMultiplyPipeline, m_vtxFmt)); break; #endif #if BOO_HAS_VULKAN case boo::IGraphicsDataFactory::Platform::Vulkan: m_bindFactory.reset(FilterImp::Initialize(static_cast(ctx), m_alphaBlendPipeline, m_additiveAlphaPipeline, m_colorMultiplyPipeline, m_vtxFmt)); break; #endif default: break; } return true; }); } static void Shutdown() { m_gfxToken.doDestroy(); } static boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CCameraFilterPass::EFilterType type, FilterImp& filter) { if (type == CCameraFilterPass::EFilterType::Add) return m_bindFactory->BuildShaderDataBinding(ctx, m_additiveAlphaPipeline, m_vtxFmt, filter); else if (type == CCameraFilterPass::EFilterType::Multiply) return m_bindFactory->BuildShaderDataBinding(ctx, m_colorMultiplyPipeline, m_vtxFmt, filter); else return m_bindFactory->BuildShaderDataBinding(ctx, m_alphaBlendPipeline, m_vtxFmt, filter); } }; #define URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(cls) \ template <> boo::IShaderPipeline* \ TMultiBlendShader::m_alphaBlendPipeline; \ template <> boo::IShaderPipeline* \ TMultiBlendShader::m_additiveAlphaPipeline; \ template <> boo::IShaderPipeline* \ TMultiBlendShader::m_colorMultiplyPipeline; \ template <> boo::IVertexFormat* \ TMultiBlendShader::m_vtxFmt; \ \ template <> std::unique_ptr::IDataBindingFactory> \ TMultiBlendShader::m_bindFactory; \ template <> boo::GraphicsDataToken \ TMultiBlendShader::m_gfxToken; \ #define URDE_SPECIALIZE_MULTI_BLEND_SHADER(cls) \ template <> boo::IShaderPipeline* \ TMultiBlendShader::m_alphaBlendPipeline = nullptr; \ template <> boo::IShaderPipeline* \ TMultiBlendShader::m_additiveAlphaPipeline = nullptr; \ template <> boo::IShaderPipeline* \ TMultiBlendShader::m_colorMultiplyPipeline = nullptr; \ template <> boo::IVertexFormat* \ TMultiBlendShader::m_vtxFmt = nullptr; \ \ template <> std::unique_ptr::IDataBindingFactory> \ TMultiBlendShader::m_bindFactory = {}; \ template <> boo::GraphicsDataToken \ TMultiBlendShader::m_gfxToken = {}; \ \ template class TMultiBlendShader; } #endif // __URDE_TMULTIBLENDSHADER_HPP__