From bda12e5fdd829e44e01a25aac015e156f3dad761 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 17 Feb 2021 19:29:07 +0100 Subject: [PATCH] Backends: Rework blending equation to preserve alpha in output buffer accross all backends. (#2693, #2764, #2766, #2873, #3447, #3813, #3816) Some of the viewport ideas from #2766 are not in there yet (e.g. Vulkan: setting compositeAlpha based on cap.supportedCompositeAlpha) --- backends/imgui_impl_allegro5.cpp | 3 ++- backends/imgui_impl_dx10.cpp | 5 +++-- backends/imgui_impl_dx11.cpp | 5 +++-- backends/imgui_impl_dx12.cpp | 5 +++-- backends/imgui_impl_dx9.cpp | 4 ++++ backends/imgui_impl_metal.mm | 5 +++-- backends/imgui_impl_opengl2.cpp | 1 + backends/imgui_impl_opengl3.cpp | 3 ++- backends/imgui_impl_vulkan.cpp | 5 +++-- backends/imgui_impl_wgpu.cpp | 3 ++- docs/CHANGELOG.txt | 6 +++++- 11 files changed, 31 insertions(+), 14 deletions(-) diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index db608e020a39..c4832b6b151a 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -15,6 +15,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: Change blending equation to preserve alpha in output buffer. // 2020-08-10: Inputs: Fixed horizontal mouse wheel direction. // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. @@ -68,7 +69,7 @@ struct ImDrawVertAllegro static void ImGui_ImplAllegro5_SetupRenderState(ImDrawData* draw_data) { // Setup blending - al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); // Setup orthographic projection matrix // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). diff --git a/backends/imgui_impl_dx10.cpp b/backends/imgui_impl_dx10.cpp index 422f65290251..28842755347c 100644 --- a/backends/imgui_impl_dx10.cpp +++ b/backends/imgui_impl_dx10.cpp @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer. // 2019-07-21: DirectX10: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData(). // 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: DirectX10: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. @@ -439,8 +440,8 @@ bool ImGui_ImplDX10_CreateDeviceObjects() desc.SrcBlend = D3D10_BLEND_SRC_ALPHA; desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; desc.BlendOp = D3D10_BLEND_OP_ADD; - desc.SrcBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; - desc.DestBlendAlpha = D3D10_BLEND_ZERO; + desc.SrcBlendAlpha = D3D10_BLEND_ONE; + desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState); diff --git a/backends/imgui_impl_dx11.cpp b/backends/imgui_impl_dx11.cpp index 3edfeae692bc..f114cdc153cc 100644 --- a/backends/imgui_impl_dx11.cpp +++ b/backends/imgui_impl_dx11.cpp @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer. // 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled). // 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore. // 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. @@ -451,8 +452,8 @@ bool ImGui_ImplDX11_CreateDeviceObjects() desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState); diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 39ca8f8df5b4..860fe6601f5c 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -15,6 +15,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer. // 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically. // 2020-09-16: DirectX12: Avoid rendering calls with zero-sized scissor rectangle since it generates a validation layer warning. // 2020-09-08: DirectX12: Clarified support for building on 32-bit systems by redefining ImTextureID. @@ -585,8 +586,8 @@ bool ImGui_ImplDX12_CreateDeviceObjects() desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; + desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; } diff --git a/backends/imgui_impl_dx9.cpp b/backends/imgui_impl_dx9.cpp index 2a575e81de85..44dea33788c9 100644 --- a/backends/imgui_impl_dx9.cpp +++ b/backends/imgui_impl_dx9.cpp @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer. // 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. // 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). @@ -67,6 +68,9 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data) g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + g_pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + g_pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); + g_pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index b67c3ef3fc58..cb57c123b3c8 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: Metal: Change blending equation to preserve alpha in output buffer. // 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst. // 2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: Metal: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. @@ -386,10 +387,10 @@ - (void)enqueueReusableBuffer:(MetalBuffer *)buffer pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat; pipelineDescriptor.colorAttachments[0].blendingEnabled = YES; pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; - pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha; pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat; pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat; diff --git a/backends/imgui_impl_opengl2.cpp b/backends/imgui_impl_opengl2.cpp index 1419e2d85663..5771049c76f3 100644 --- a/backends/imgui_impl_opengl2.cpp +++ b/backends/imgui_impl_opengl2.cpp @@ -81,6 +81,7 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // In order to composite our output buffer we need to preserve alpha glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index f3b2a937b167..b582851e897e 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer. // 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state. // 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state. // 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x) @@ -247,7 +248,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 44a555a5dd0f..d8c00e9b6449 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer. // 2021-01-27: Vulkan: Added support for custom function load and IMGUI_IMPL_VULKAN_NO_PROTOTYPES by using ImGui_ImplVulkan_LoadFunctions(). // 2020-11-11: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation. // 2020-09-07: Vulkan: Added VkPipeline parameter to ImGui_ImplVulkan_RenderDrawData (default to one passed to ImGui_ImplVulkan_Init). @@ -815,8 +816,8 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; color_attachment[0].colorBlendOp = VK_BLEND_OP_ADD; - color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; color_attachment[0].alphaBlendOp = VK_BLEND_OP_ADD; color_attachment[0].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index 089dbfd74af9..1eb290a3cc07 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: Change blending equation to preserve alpha in output buffer. // 2021-01-28: Initial version. #include "imgui.h" @@ -638,7 +639,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() { color_state.format = g_renderTargetFormat; color_state.alphaBlend.operation = WGPUBlendOperation_Add; - color_state.alphaBlend.srcFactor = WGPUBlendFactor_SrcAlpha; + color_state.alphaBlend.srcFactor = WGPUBlendFactor_One; color_state.alphaBlend.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; color_state.colorBlend.operation = WGPUBlendOperation_Add; color_state.colorBlend.srcFactor = WGPUBlendFactor_SrcAlpha; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index c41e31517899..4a87a64b27f8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -45,7 +45,11 @@ Other Changes: - ImDrawList: AddCircle, AddCircleFilled(): Tweaked default segment count calculation to honor MaxError with more accuracy. Made default segment count always even for better looking result. (#3808) [@thedmd] - ImDrawList: AddCircle, AddCircleFilled(): New default for style. -- CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if +- Backends: OpenGL, Vulkan, DX9, DX10, DX11, DX12, Metal, WebGPU, Allegro: Rework blending equation to + preserve alpha in output buffer (using SrcBlendAlpha = ONE, DstBlendAlpha = ONE_MINUS_SRC_ALPHA consistently + accross all backends), facilitating compositing of the output buffer with another buffer. + (#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick] +- CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if scheduled builds builds are not required. [@rokups]