diff --git a/Engine/src/Engine/Graphics/Blender.cpp b/Engine/src/Engine/Graphics/Blender.cpp new file mode 100644 index 0000000..b57c87b --- /dev/null +++ b/Engine/src/Engine/Graphics/Blender.cpp @@ -0,0 +1,30 @@ +#include "ltpch.h" +#include "Blender.h" +#include "OpenGL/glBlender.h" + +#ifdef LIGHT_PLATFORM_WINDOWS + #include "DirectX/dxBlender.h" + #include "DirectX/dxSharedContext.h" +#endif + +#include "GraphicsContext.h" + + +namespace Light { + + Blender* Blender::Create(std::shared_ptr sharedContext) + { + switch (GraphicsContext::GetGraphicsAPI()) + { + case GraphicsAPI::OpenGL: + return new glBlender(); + + case GraphicsAPI::DirectX: LT_WIN( + return new dxBlender(std::static_pointer_cast(sharedContext));) + + default: + LT_ENGINE_ASSERT(false, "Blender::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI()); + } + } + +} \ No newline at end of file diff --git a/Engine/src/Engine/Graphics/Blender.h b/Engine/src/Engine/Graphics/Blender.h new file mode 100644 index 0000000..6e548ee --- /dev/null +++ b/Engine/src/Engine/Graphics/Blender.h @@ -0,0 +1,50 @@ +#pragma once + +#include "Base.h" + +namespace Light { + + class SharedContext; + + enum class BlendFactor : uint8_t + { + // constants + ZERO, ONE, + + // source + SRC_COLOR, + INVERSE_SRC_COLOR, + + SRC_ALPHA, + INVERSE_SRC_ALPHA, + + // destination + DST_COLOR, + INVERSE_DST_COLOR, + + DST_ALPHA, + INVERSE_DST_ALPHA, + + // source1 + SRC1_COLOR, + INVERSE_SRC1_COLOR, + + SRC1_ALPHA, + INVERSE_SRC1_ALPHA, + }; + + class Blender + { + private: + + public: + static Blender* Create(std::shared_ptr sharedContext); + + virtual void Enable(BlendFactor srcFactor, BlendFactor dstFactor) = 0; + virtual void Disable() = 0; + + protected: + Blender() = default; + }; + +} \ No newline at end of file diff --git a/Engine/src/Engine/Graphics/Renderer.cpp b/Engine/src/Engine/Graphics/Renderer.cpp index 5354a4d..d7dd1f4 100644 --- a/Engine/src/Engine/Graphics/Renderer.cpp +++ b/Engine/src/Engine/Graphics/Renderer.cpp @@ -1,9 +1,10 @@ #include "ltpch.h" #include "Renderer.h" -#include "RenderCommand.h" -#include "Texture.h" +#include "Blender.h" #include "Buffers.h" +#include "Texture.h" +#include "RenderCommand.h" #include "Camera/Camera.h" @@ -25,6 +26,8 @@ namespace Light { m_RenderCommand = std::unique_ptr(RenderCommand::Create(windowHandle, sharedContext)); m_ViewProjectionBuffer = std::unique_ptr(ConstantBuffer::Create(ConstantBufferIndex::ViewProjection, sizeof(glm::mat4), sharedContext)); + + m_Blender = std::unique_ptr(Blender::Create(sharedContext)); } Renderer* Renderer::Create(GLFWwindow* windowHandle, std::shared_ptr sharedContext) @@ -128,6 +131,8 @@ namespace Light { m_QuadRenderer.UnMap(); m_TextureRenderer.UnMap(); + m_Blender->Enable(BlendFactor::SRC_ALPHA, BlendFactor::INVERSE_SRC_ALPHA); + //** QUAD_RENDERER **// if (m_QuadRenderer.GetQuadCount()) { diff --git a/Engine/src/Engine/Graphics/Renderer.h b/Engine/src/Engine/Graphics/Renderer.h index c541e2a..3db7ca7 100644 --- a/Engine/src/Engine/Graphics/Renderer.h +++ b/Engine/src/Engine/Graphics/Renderer.h @@ -3,6 +3,7 @@ #include "Base.h" #include "Buffers.h" +#include "Blender.h" #include "RendererPrograms/QuadRendererProgram.h" #include "RendererPrograms/TextureRendererProgram.h" @@ -15,10 +16,12 @@ struct GLFWwindow; namespace Light { class RenderCommand; - class Texture; + class Blender; class Camera; + class Texture; + class SharedContext; class Renderer @@ -32,6 +35,8 @@ namespace Light { std::unique_ptr m_RenderCommand; std::unique_ptr m_ViewProjectionBuffer; + std::unique_ptr m_Blender; + public: static Renderer* Create(GLFWwindow* windowHandle, std::shared_ptr sharedContext); diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxBlender.cpp b/Engine/src/Platform/GraphicsAPI/DirectX/dxBlender.cpp new file mode 100644 index 0000000..bb68b07 --- /dev/null +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxBlender.cpp @@ -0,0 +1,84 @@ +#include "ltpch.h" +#include "dxBlender.h" + +#include "dxSharedContext.h" + +namespace Light { + + dxBlender::dxBlender(std::shared_ptr sharedContext) + : m_Context(sharedContext) + { + // factor map + m_FactorMap = { + // constants + { BlendFactor::ZERO, D3D11_BLEND_ZERO }, + { BlendFactor::ONE, D3D11_BLEND_ONE }, + + // source + { BlendFactor::SRC_COLOR, D3D11_BLEND_SRC_COLOR }, + { BlendFactor::INVERSE_SRC_COLOR, D3D11_BLEND_INV_SRC_COLOR }, + + { BlendFactor::SRC_ALPHA, D3D11_BLEND_SRC_ALPHA }, + { BlendFactor::INVERSE_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA }, + + // destination + { BlendFactor::DST_COLOR, D3D11_BLEND_DEST_COLOR }, + { BlendFactor::INVERSE_DST_COLOR, D3D11_BLEND_INV_DEST_COLOR }, + + { BlendFactor::DST_ALPHA, D3D11_BLEND_DEST_ALPHA }, + { BlendFactor::INVERSE_DST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA }, + + // source1 + { BlendFactor::SRC1_COLOR, D3D11_BLEND_SRC1_COLOR }, + { BlendFactor::INVERSE_SRC1_COLOR, D3D11_BLEND_INV_SRC1_COLOR }, + + { BlendFactor::SRC1_ALPHA, D3D11_BLEND_SRC1_ALPHA }, + { BlendFactor::INVERSE_SRC1_ALPHA, D3D11_BLEND_INV_SRC1_ALPHA } + }; + + // blender desc + m_Desc = { }; + + m_Desc.RenderTarget[0].BlendEnable = true; + m_Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ZERO; + m_Desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; + m_Desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + m_Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; + m_Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + m_Desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + m_Desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + // create blend state + HRESULT hr; + DXC(m_Context->GetDevice()->CreateBlendState( &m_Desc, &m_BlendState ) ); + } + + void dxBlender::Enable(BlendFactor srcFactor, BlendFactor dstFactor) + { + // update desc + m_Desc.RenderTarget[0].BlendEnable = true; + m_Desc.RenderTarget[0].SrcBlend = m_FactorMap[srcFactor]; + m_Desc.RenderTarget[0].DestBlend = m_FactorMap[dstFactor]; + + // re-create blind state + HRESULT hr; + DXC(m_Context->GetDevice()->CreateBlendState(&m_Desc, &m_BlendState)); + + // bind blend state + m_Context->GetDeviceContext()->OMSetBlendState(m_BlendState.Get(), nullptr, 0xffffffff); + } + + void dxBlender::Disable() + { + // update desc + m_Desc.RenderTarget[0].BlendEnable = false; + + // re-create blind state + HRESULT hr; + DXC(m_Context->GetDevice()->CreateBlendState(&m_Desc, &m_BlendState)); + + // bind blend state + m_Context->GetDeviceContext()->OMSetBlendState(m_BlendState.Get(), nullptr, 0xffffffff); + } + +} \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxBlender.h b/Engine/src/Platform/GraphicsAPI/DirectX/dxBlender.h new file mode 100644 index 0000000..c7d0e0d --- /dev/null +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxBlender.h @@ -0,0 +1,30 @@ +#pragma once + +#include "Base.h" +#include "Graphics/Blender.h" + +#include +#include + +namespace Light { + + class dxSharedContext; + + class dxBlender : public Blender + { + private: + std::shared_ptr m_Context; + std::unordered_map m_FactorMap; + + Microsoft::WRL::ComPtr m_BlendState; + + D3D11_BLEND_DESC m_Desc; + + public: + dxBlender(std::shared_ptr sharedContext); + + void Enable(BlendFactor srcFactor, BlendFactor dstFactor) override; + void Disable() override; + }; + +} \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glBlender.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glBlender.cpp new file mode 100644 index 0000000..40ae77a --- /dev/null +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glBlender.cpp @@ -0,0 +1,49 @@ +#include "ltpch.h" +#include "glBlender.h" + +#include + +namespace Light { + + glBlender::glBlender() + { + m_FactorMap = { + // constants + { BlendFactor::ZERO, GL_ZERO }, + { BlendFactor::ONE, GL_ZERO }, + + // source + { BlendFactor::SRC_COLOR, GL_SRC_COLOR }, + { BlendFactor::INVERSE_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR }, + + { BlendFactor::SRC_ALPHA, GL_SRC_ALPHA }, + { BlendFactor::INVERSE_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, + + // destination + { BlendFactor::DST_COLOR, GL_DST_COLOR }, + { BlendFactor::INVERSE_DST_COLOR, GL_ONE_MINUS_DST_COLOR }, + + { BlendFactor::DST_ALPHA, GL_DST_ALPHA }, + { BlendFactor::INVERSE_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA }, + + // source1 + { BlendFactor::SRC1_COLOR, GL_SRC1_COLOR }, + { BlendFactor::INVERSE_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR }, + + { BlendFactor::SRC1_ALPHA, GL_SRC1_ALPHA }, + { BlendFactor::INVERSE_SRC1_ALPHA, GL_ONE_MINUS_SRC_ALPHA } + }; + } + + void glBlender::Enable(BlendFactor srcFactor, BlendFactor dstFactor) + { + glEnable(GL_BLEND); + glBlendFunc(m_FactorMap[srcFactor], m_FactorMap[dstFactor]); + } + + void glBlender::Disable() + { + glDisable(GL_BLEND); + } + +} \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glBlender.h b/Engine/src/Platform/GraphicsAPI/OpenGL/glBlender.h new file mode 100644 index 0000000..8b8b6e3 --- /dev/null +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glBlender.h @@ -0,0 +1,20 @@ +#pragma pnce + +#include "Base.h" +#include "Graphics/Blender.h" + +namespace Light { + + class glBlender : public Blender + { + private: + std::unordered_map m_FactorMap; + + public: + glBlender(); + + void Enable(BlendFactor srcFactor, BlendFactor dstFactor) override; + void Disable() override; + }; + +} \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.cpp index 8328735..acd9d88 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.cpp +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.cpp @@ -27,10 +27,6 @@ namespace Light { LT_ENGINE_ASSERT(gladLoadGLLoader((GLADloadproc)glfwGetProcAddress), "glGraphicsContext::glGraphicsContext: failed to initialize opengl (glad)"); SetDebugMessageCallback(); - - // #todo: add blender - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void glGraphicsContext::OnWindowResize(const WindowResizedEvent& event)