diff --git a/src/BizHawk.Bizware.Graphics/D3D11/D3D11Resources.cs b/src/BizHawk.Bizware.Graphics/D3D11/D3D11Resources.cs index 416b2309a0..168673172f 100644 --- a/src/BizHawk.Bizware.Graphics/D3D11/D3D11Resources.cs +++ b/src/BizHawk.Bizware.Graphics/D3D11/D3D11Resources.cs @@ -18,7 +18,6 @@ namespace BizHawk.Bizware.Graphics public IDXGIFactory1 Factory1; public IDXGIFactory2 Factory2; public ID3D11BlendState BlendNormalState; - public ID3D11BlendState BlendAlphaState; public ID3D11BlendState BlendDisableState; public ID3D11SamplerState PointSamplerState; public ID3D11SamplerState LinearSamplerState; @@ -89,8 +88,6 @@ namespace BizHawk.Bizware.Graphics bd.RenderTarget[0].SourceBlend = Blend.One; bd.RenderTarget[0].DestinationBlend = Blend.Zero; - BlendAlphaState = Device.CreateBlendState(bd); - bd.RenderTarget[0].BlendEnable = false; BlendDisableState = Device.CreateBlendState(bd); @@ -154,8 +151,6 @@ namespace BizHawk.Bizware.Graphics BlendNormalState?.Dispose(); BlendNormalState = null; - BlendAlphaState?.Dispose(); - BlendAlphaState = null; BlendDisableState?.Dispose(); BlendDisableState = null; diff --git a/src/BizHawk.Bizware.Graphics/D3D11/IGL_D3D11.cs b/src/BizHawk.Bizware.Graphics/D3D11/IGL_D3D11.cs index bcc76f8d8f..a0ae2797d1 100644 --- a/src/BizHawk.Bizware.Graphics/D3D11/IGL_D3D11.cs +++ b/src/BizHawk.Bizware.Graphics/D3D11/IGL_D3D11.cs @@ -25,7 +25,6 @@ namespace BizHawk.Bizware.Graphics private IDXGIFactory1 Factory1 => _resources.Factory1; private IDXGIFactory2 Factory2 => _resources.Factory2; private ID3D11BlendState BlendNormalState => _resources.BlendNormalState; - private ID3D11BlendState BlendAlphaState => _resources.BlendAlphaState; private ID3D11BlendState BlendDisableState => _resources.BlendDisableState; private ID3D11RasterizerState RasterizerState => _resources.RasterizerState; @@ -186,12 +185,9 @@ namespace BizHawk.Bizware.Graphics public void ClearColor(Color color) => Context.ClearRenderTargetView(CurRenderTarget?.RTV ?? _controlSwapChain.RTV, new(color.R, color.B, color.G, color.A)); - public void EnableBlendNormal() + public void EnableBlending() => Context.OMSetBlendState(BlendNormalState); - public void EnableBlendAlpha() - => Context.OMSetBlendState(BlendAlphaState); - public void DisableBlending() => Context.OMSetBlendState(BlendDisableState); diff --git a/src/BizHawk.Bizware.Graphics/GDIPlus/IGL_GDIPlus.cs b/src/BizHawk.Bizware.Graphics/GDIPlus/IGL_GDIPlus.cs index 17534c1fc4..3a9cb3239d 100644 --- a/src/BizHawk.Bizware.Graphics/GDIPlus/IGL_GDIPlus.cs +++ b/src/BizHawk.Bizware.Graphics/GDIPlus/IGL_GDIPlus.cs @@ -27,14 +27,7 @@ namespace BizHawk.Bizware.Graphics public void ClearColor(Color color) => GetCurrentGraphics().Clear(color); - public void EnableBlendNormal() - { - var g = GetCurrentGraphics(); - g.CompositingMode = CompositingMode.SourceOver; - g.CompositingQuality = CompositingQuality.Default; - } - - public void EnableBlendAlpha() + public void EnableBlending() { var g = GetCurrentGraphics(); g.CompositingMode = CompositingMode.SourceOver; diff --git a/src/BizHawk.Bizware.Graphics/ImGuiResourceCache.cs b/src/BizHawk.Bizware.Graphics/ImGuiResourceCache.cs index aac5be832e..0c7eea3cbd 100644 --- a/src/BizHawk.Bizware.Graphics/ImGuiResourceCache.cs +++ b/src/BizHawk.Bizware.Graphics/ImGuiResourceCache.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Drawing; +using System.Numerics; namespace BizHawk.Bizware.Graphics { @@ -51,6 +52,7 @@ namespace BizHawk.Bizware.Graphics igl.BindPipeline(Pipeline); SetTexture(null); + SetBlendingParamters(null, true); igl.BindPipeline(null); } } @@ -67,6 +69,18 @@ namespace BizHawk.Bizware.Graphics Pipeline.SetUniformSampler("uSampler0", texture2D); } + internal void SetBlendingParamters(ITexture2D secondaryTexture, bool doBlendPass) + { + Pipeline.SetUniformSampler("uSampler1", secondaryTexture); + Pipeline.SetUniform("uBlendEnable", secondaryTexture != null); + Pipeline.SetUniform("uBlendPass", doBlendPass); + + if (secondaryTexture != null) + { + Pipeline.SetUniform("uSamplerSize", new Vector2(secondaryTexture.Width, secondaryTexture.Height)); + } + } + public void Dispose() { foreach (var cachedTex in TextureCache.Values) @@ -94,6 +108,8 @@ namespace BizHawk.Bizware.Graphics TextureCache.Clear(); } + // ReSharper disable UseRawString + public const string ImGuiVertexShader_d3d11 = @" //vertex shader uniforms float4x4 um44Projection; @@ -125,9 +141,10 @@ VS_OUTPUT vsmain(VS_INPUT src) public const string ImGuiPixelShader_d3d11 = @" //pixel shader uniforms -bool uSamplerEnable; -Texture2D uTexture0; -sampler uSampler0; +bool uSamplerEnable, uBlendPass, uBlendEnable; +float2 uSamplerSize; +Texture2D uTexture0, uTexture1; +sampler uSampler0, uSampler1; struct PS_INPUT { @@ -138,9 +155,37 @@ struct PS_INPUT float4 psmain(PS_INPUT src) : SV_Target { - float4 temp = src.vColor0; - if(uSamplerEnable) temp *= uTexture0.Sample(uSampler0,src.vTexcoord0); - return temp; + if (uBlendPass) + { + float4 temp = src.vColor0; + if(uSamplerEnable) temp *= uTexture0.Sample(uSampler0, src.vTexcoord0); + + if (uBlendEnable) + { + if (temp.a != 1.0) + { + float4 prev = uTexture1.Sample(uSampler1, src.vPosition.xy / uSamplerSize); + if (temp.a == 0.0) + { + temp = prev; + } + else + { + float alpha = prev.a + temp.a - (prev.a * temp.a); + temp.r = ((temp.r * temp.a) + (prev.r * prev.a * (1.0 - temp.a))) / alpha; + temp.g = ((temp.g * temp.a) + (prev.g * prev.a * (1.0 - temp.a))) / alpha; + temp.b = ((temp.b * temp.a) + (prev.b * prev.a * (1.0 - temp.a))) / alpha; + temp.a = alpha; + } + } + } + + return temp; + } + else + { + return uTexture1.Sample(uSampler1, src.vPosition.xy / uSamplerSize); + } } "; @@ -167,8 +212,9 @@ void main() public const string ImGuiPixelShader_gl = @" //opengl 3.2 #version 150 -uniform bool uSamplerEnable; -uniform sampler2D uSampler0; +uniform bool uSamplerEnable, uBlendPass, uBlendEnable; +uniform vec2 uSamplerSize; +uniform sampler2D uSampler0, uSampler1; in vec2 vTexcoord0; in vec4 vColor0; @@ -177,9 +223,37 @@ out vec4 FragColor; void main() { - vec4 temp = vColor0; - if(uSamplerEnable) temp *= texture(uSampler0, vTexcoord0); - FragColor = temp; + if (uBlendPass) + { + vec4 temp = vColor0; + if(uSamplerEnable) temp *= texture(uSampler0, vTexcoord0); + + if (uBlendEnable) + { + if (temp.a != 1.0) + { + vec4 prev = texture(uSampler1, gl_FragCoord.xy / uSamplerSize); + if (temp.a == 0.0) + { + temp = prev; + } + else + { + float alpha = prev.a + temp.a - (prev.a * temp.a); + temp.r = ((temp.r * temp.a) + (prev.r * prev.a * (1.0 - temp.a))) / alpha; + temp.g = ((temp.g * temp.a) + (prev.g * prev.a * (1.0 - temp.a))) / alpha; + temp.b = ((temp.b * temp.a) + (prev.b * prev.a * (1.0 - temp.a))) / alpha; + temp.a = alpha; + } + } + } + + FragColor = temp; + } + else + { + FragColor = texture(uSampler1, gl_FragCoord.xy / uSamplerSize); + } }"; } } diff --git a/src/BizHawk.Bizware.Graphics/Interfaces/IGL.cs b/src/BizHawk.Bizware.Graphics/Interfaces/IGL.cs index b08b6c4836..9ee78ed56e 100644 --- a/src/BizHawk.Bizware.Graphics/Interfaces/IGL.cs +++ b/src/BizHawk.Bizware.Graphics/Interfaces/IGL.cs @@ -62,13 +62,7 @@ namespace BizHawk.Bizware.Graphics /// <summary> /// Enables normal (non-premultiplied) alpha blending. /// </summary> - void EnableBlendNormal(); - - /// <summary> - /// Enables alpha blending (non-alpha values are copied from the source fragment). - /// This mimics GDI+ blending - /// </summary> - void EnableBlendAlpha(); + void EnableBlending(); /// <summary> /// Disables blending (alpha values are copied from the source fragment) diff --git a/src/BizHawk.Bizware.Graphics/OpenGL/IGL_OpenGL.cs b/src/BizHawk.Bizware.Graphics/OpenGL/IGL_OpenGL.cs index 85c18dccd5..c59fe4b233 100644 --- a/src/BizHawk.Bizware.Graphics/OpenGL/IGL_OpenGL.cs +++ b/src/BizHawk.Bizware.Graphics/OpenGL/IGL_OpenGL.cs @@ -58,20 +58,13 @@ namespace BizHawk.Bizware.Graphics GL.Clear(ClearBufferMask.ColorBufferBit); } - public void EnableBlendNormal() + public void EnableBlending() { GL.Enable(EnableCap.Blend); GL.BlendEquation(GLEnum.FuncAdd); GL.BlendFuncSeparate(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha, BlendingFactor.One, BlendingFactor.OneMinusSrcAlpha); } - public void EnableBlendAlpha() - { - GL.Enable(EnableCap.Blend); - GL.BlendEquation(GLEnum.FuncAdd); - GL.BlendFuncSeparate(BlendingFactor.One, BlendingFactor.Zero, BlendingFactor.One, BlendingFactor.OneMinusSrcAlpha); - } - public void DisableBlending() => GL.Disable(EnableCap.Blend); diff --git a/src/BizHawk.Bizware.Graphics/Renderers/GDIPlusGuiRenderer.cs b/src/BizHawk.Bizware.Graphics/Renderers/GDIPlusGuiRenderer.cs index dfd621c31b..1724ac3c01 100644 --- a/src/BizHawk.Bizware.Graphics/Renderers/GDIPlusGuiRenderer.cs +++ b/src/BizHawk.Bizware.Graphics/Renderers/GDIPlusGuiRenderer.cs @@ -87,7 +87,7 @@ namespace BizHawk.Bizware.Graphics } public void EnableBlending() - => Owner.EnableBlendNormal(); + => Owner.EnableBlending(); public void DisableBlending() => Owner.DisableBlending(); diff --git a/src/BizHawk.Bizware.Graphics/Renderers/GuiRenderer.cs b/src/BizHawk.Bizware.Graphics/Renderers/GuiRenderer.cs index e9781a46f5..3252adc24f 100644 --- a/src/BizHawk.Bizware.Graphics/Renderers/GuiRenderer.cs +++ b/src/BizHawk.Bizware.Graphics/Renderers/GuiRenderer.cs @@ -116,7 +116,7 @@ namespace BizHawk.Bizware.Graphics public void EnableBlending() { Flush(); - Owner.EnableBlendNormal(); + Owner.EnableBlending(); } public void DisableBlending() diff --git a/src/BizHawk.Bizware.Graphics/Renderers/ImGui2DRenderer.cs b/src/BizHawk.Bizware.Graphics/Renderers/ImGui2DRenderer.cs index 0ec1adc910..05905765f2 100644 --- a/src/BizHawk.Bizware.Graphics/Renderers/ImGui2DRenderer.cs +++ b/src/BizHawk.Bizware.Graphics/Renderers/ImGui2DRenderer.cs @@ -53,6 +53,8 @@ namespace BizHawk.Bizware.Graphics } private readonly HashSet<GCHandle> _gcHandles = [ ]; + private ITexture2D _stringTexture; + private IRenderTarget _pass1RenderTarget; protected virtual float RenderThickness => 1; @@ -63,8 +65,7 @@ namespace BizHawk.Bizware.Graphics protected bool _hasClearPending; protected Bitmap _stringOutput; protected SDGraphics _stringGraphics; - protected ITexture2D _stringTexture; - protected IRenderTarget _renderTarget; + protected IRenderTarget _pass2RenderTarget; public ImGui2DRenderer(IGL igl, ImGuiResourceCache resourceCache) { @@ -83,8 +84,10 @@ namespace BizHawk.Bizware.Graphics public void Dispose() { ClearGCHandles(); - _renderTarget?.Dispose(); - _renderTarget = null; + _pass2RenderTarget?.Dispose(); + _pass2RenderTarget = null; + _pass1RenderTarget?.Dispose(); + _pass1RenderTarget = null; _stringTexture?.Dispose(); _stringTexture = null; _stringGraphics?.Dispose(); @@ -160,21 +163,34 @@ namespace BizHawk.Bizware.Graphics { None, DisableBlending, - EnableBlendAlpha, - EnableBlendNormal, + EnableBlending, DrawString, } + private void PerformPasses(ImDrawCmdPtr cmd) + { + if (EnableBlending) + { + _pass1RenderTarget.Bind(); + _resourceCache.SetBlendingParamters(_pass2RenderTarget, false); + _igl.DrawIndexed((int)cmd.ElemCount, (int)cmd.IdxOffset, (int)cmd.VtxOffset); + + _pass2RenderTarget.Bind(); + _resourceCache.SetBlendingParamters(_pass1RenderTarget, true); + _igl.DrawIndexed((int)cmd.ElemCount, (int)cmd.IdxOffset, (int)cmd.VtxOffset); + } + else + { + _resourceCache.SetBlendingParamters(null, true); + _igl.DrawIndexed((int)cmd.ElemCount, (int)cmd.IdxOffset, (int)cmd.VtxOffset); + } + } + protected virtual void RenderInternal(int width, int height) { - if (EnableBlending) - { - _igl.EnableBlendAlpha(); - } - else - { - _igl.DisableBlending(); - } + // we handle blending programmatically with 2 passes + // therefore, we disable normal blending operations + _igl.DisableBlending(); _igl.BindPipeline(_resourceCache.Pipeline); _resourceCache.SetProjection(width, height); @@ -229,21 +245,16 @@ namespace BizHawk.Bizware.Graphics _resourceCache.SetTexture(null); } - _igl.DrawIndexed((int)cmd.ElemCount, (int)cmd.IdxOffset, (int)cmd.VtxOffset); + PerformPasses(cmd); tempTex?.Dispose(); break; } case DrawCallbackId.DisableBlending: - _igl.DisableBlending(); EnableBlending = false; break; - case DrawCallbackId.EnableBlendAlpha: - _igl.EnableBlendAlpha(); + case DrawCallbackId.EnableBlending: EnableBlending = true; break; - case DrawCallbackId.EnableBlendNormal: - _igl.EnableBlendNormal(); - break; case DrawCallbackId.DrawString: { var stringArgs = (DrawStringArgs)GCHandle.FromIntPtr(cmd.UserCallbackData).Target!; @@ -264,21 +275,9 @@ namespace BizHawk.Bizware.Graphics throw new InvalidOperationException("Unexpected bitmap mismatch!"); } - // we want to normal blend the text image rather than alpha blend it (matches GDI+ behavior it seems?) - if (EnableBlending) - { - _igl.EnableBlendNormal(); - } - - _stringTexture.LoadFrom(new BitmapBuffer(userTex.Bitmap, new())); + _stringTexture.LoadFrom(new BitmapBuffer(_stringOutput, new())); _resourceCache.SetTexture(_stringTexture); - _igl.DrawIndexed((int)lastCmd.ElemCount, (int)lastCmd.IdxOffset, (int)lastCmd.VtxOffset); - - if (EnableBlending) - { - _igl.EnableBlendAlpha(); - } - + PerformPasses(lastCmd); ClearStringOutput(); } @@ -294,10 +293,12 @@ namespace BizHawk.Bizware.Graphics { var needsRender = _imGuiDrawList.VtxBuffer.Size > 0 || _imGuiDrawList.IdxBuffer.Size > 0 || _hasDrawStringCommand; var needsClear = needsRender || _hasClearPending; - if (_renderTarget == null || _renderTarget.Width != width || _renderTarget.Height != height) + if (_pass1RenderTarget == null || _pass1RenderTarget.Width != width || _pass1RenderTarget.Height != height) { - _renderTarget?.Dispose(); - _renderTarget = _igl.CreateRenderTarget(width, height); + _pass1RenderTarget?.Dispose(); + _pass1RenderTarget = _igl.CreateRenderTarget(width, height); + _pass2RenderTarget?.Dispose(); + _pass2RenderTarget = _igl.CreateRenderTarget(width, height); needsClear = true; } @@ -314,7 +315,7 @@ namespace BizHawk.Bizware.Graphics _stringTexture = _igl.CreateTexture(width, height); } - _renderTarget.Bind(); + _pass2RenderTarget.Bind(); _igl.SetViewport(width, height); if (needsClear) @@ -347,7 +348,7 @@ namespace BizHawk.Bizware.Graphics ResetDrawList(); } - return _renderTarget; + return _pass2RenderTarget; } public void Clear() @@ -375,7 +376,7 @@ namespace BizHawk.Bizware.Graphics break; // CompositingMode.SourceOver means enable blending case false when value == CompositingMode.SourceOver: - _imGuiDrawList.AddCallback((IntPtr)DrawCallbackId.EnableBlendAlpha, IntPtr.Zero); + _imGuiDrawList.AddCallback((IntPtr)DrawCallbackId.EnableBlending, IntPtr.Zero); _pendingBlendEnable = true; break; } @@ -384,6 +385,11 @@ namespace BizHawk.Bizware.Graphics public void DrawBezier(Color color, Point pt1, Point pt2, Point pt3, Point pt4) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + _imGuiDrawList.AddBezierCubic( p1: pt1.ToVector(), p2: pt2.ToVector(), @@ -391,6 +397,11 @@ namespace BizHawk.Bizware.Graphics p4: pt4.ToVector(), col: (uint)color.ToArgb(), thickness: RenderThickness); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } public void DrawBeziers(Color color, Point[] points) @@ -404,6 +415,11 @@ namespace BizHawk.Bizware.Graphics var col = (uint)color.ToArgb(); for (var i = 1; i < points.Length; i += 3) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + _imGuiDrawList.AddBezierCubic( p1: startPt.ToVector(), p2: points[i + 0].ToVector(), @@ -412,11 +428,21 @@ namespace BizHawk.Bizware.Graphics col: col, thickness: RenderThickness); startPt = points[i + 2]; + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } } public void DrawRectangle(Color color, int x, int y, int width, int height) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + // we don't use AddRect as we want to avoid double drawing at the corners // as that produces artifacts with alpha blending @@ -428,30 +454,56 @@ namespace BizHawk.Bizware.Graphics if (width == 1 || height == 1) { // width or height of 1 is just a single line - DrawLine(color, x, y, right, bottom); + DrawLineInternal(color, x, y, right, bottom); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + return; } // top left to top right - DrawLine(color, x, y, right, y); + DrawLineInternal(color, x, y, right, y); // top right (and 1 pixel down) to bottom right - DrawLine(color, right, y + 1, right, bottom); + DrawLineInternal(color, right, y + 1, right, bottom); // bottom right (and 1 pixel left) to bottom left - DrawLine(color, right - 1, bottom, x, bottom); + DrawLineInternal(color, right - 1, bottom, x, bottom); // bottom left (and 1 pixel up) to top left (and 1 pixel down) - DrawLine(color, x, bottom - 1, x, y + 1); + DrawLineInternal(color, x, bottom - 1, x, y + 1); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } public void FillRectangle(Color color, int x, int y, int width, int height) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + _imGuiDrawList.AddRectFilled( p_min: new(x, y), p_max: new(x + width, y + height), col: (uint)color.ToArgb()); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } public void DrawEllipse(Color color, int x, int y, int width, int height) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + var radius = new Vector2(width / 2.0f, height / 2.0f); _imGuiDrawList.AddEllipse( center: new(x + radius.X, y + radius.Y), @@ -460,25 +512,34 @@ namespace BizHawk.Bizware.Graphics rot: 0, num_segments: 0, RenderThickness); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } public void FillEllipse(Color color, int x, int y, int width, int height) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + var radius = new Vector2(width / 2.0f, height / 2.0f); _imGuiDrawList.AddEllipseFilled( center: new(x + radius.X, y + radius.Y), radius: radius, col: (uint)color.ToArgb()); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } public void DrawImage(Bitmap image, int x, int y) { - // use normal blending for images - if (_pendingBlendEnable) - { - _imGuiDrawList.AddCallback((IntPtr)DrawCallbackId.EnableBlendNormal, IntPtr.Zero); - } - var texture = new ImGuiUserTexture { Bitmap = image, WantCache = false }; var handle = GCHandle.Alloc(texture, GCHandleType.Normal); _gcHandles.Add(handle); @@ -486,21 +547,10 @@ namespace BizHawk.Bizware.Graphics user_texture_id: GCHandle.ToIntPtr(handle), p_min: new(x, y), p_max: new(x + image.Width, y + image.Height)); - - if (_pendingBlendEnable) - { - _imGuiDrawList.AddCallback((IntPtr)DrawCallbackId.EnableBlendAlpha, IntPtr.Zero); - } } public void DrawImage(Bitmap image, Rectangle destRect, int srcX, int srcY, int srcWidth, int srcHeight, bool cache) { - // use normal blending for images - if (_pendingBlendEnable) - { - _imGuiDrawList.AddCallback((IntPtr)DrawCallbackId.EnableBlendNormal, IntPtr.Zero); - } - var texture = new ImGuiUserTexture { Bitmap = image, WantCache = cache }; var handle = GCHandle.Alloc(texture, GCHandleType.Normal); _gcHandles.Add(handle); @@ -512,14 +562,9 @@ namespace BizHawk.Bizware.Graphics p_max: new(destRect.Right, destRect.Bottom), uv_min: new(srcX / imgWidth, srcY / imgHeight), uv_max: new((srcX + srcWidth) / imgWidth, (srcY + srcHeight) / imgHeight)); - - if (_pendingBlendEnable) - { - _imGuiDrawList.AddCallback((IntPtr)DrawCallbackId.EnableBlendAlpha, IntPtr.Zero); - } } - public void DrawLine(Color color, int x1, int y1, int x2, int y2) + private void DrawLineInternal(Color color, int x1, int y1, int x2, int y2) { var p1 = new Vector2(x1, y1); var p2 = new Vector2(x2, y2); @@ -553,8 +598,28 @@ namespace BizHawk.Bizware.Graphics _imGuiDrawList.PathStroke((uint)color.ToArgb(), 0, RenderThickness); } + public void DrawLine(Color color, int x1, int y1, int x2, int y2) + { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + + DrawLineInternal(color, x1, y1, x2, y2); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + } + public void DrawPie(Color color, int x, int y, int width, int height, int startAngle, int sweepAngle) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + var radius = new Vector2(width / 2.0f, height / 2.0f); var center = new Vector2(x + radius.X, y + radius.Y); var aMin = (float)(Math.PI / 180 * startAngle); @@ -562,10 +627,20 @@ namespace BizHawk.Bizware.Graphics _imGuiDrawList.PathEllipticalArcTo(center, radius, 0, aMin, aMax); _imGuiDrawList.PathLineTo(center); _imGuiDrawList.PathStroke((uint)color.ToArgb(), ImDrawFlags.Closed, RenderThickness); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } public void FillPie(Color color, int x, int y, int width, int height, int startAngle, int sweepAngle) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + var radius = new Vector2(width / 2.0f, height / 2.0f); var center = new Vector2(x + radius.X, y + radius.Y); var aMin = (float)(Math.PI / 180 * startAngle); @@ -573,6 +648,11 @@ namespace BizHawk.Bizware.Graphics _imGuiDrawList.PathEllipticalArcTo(center, radius, 0, aMin, aMax); _imGuiDrawList.PathLineTo(center); _imGuiDrawList.PathFillConvex((uint)color.ToArgb()); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } public unsafe void DrawPolygon(Color color, Point[] points) @@ -580,12 +660,22 @@ namespace BizHawk.Bizware.Graphics var vectorPoints = Array.ConvertAll(points, static p => new Vector2(p.X + 0.5f, p.Y + 0.5f)); fixed (Vector2* p = vectorPoints) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + _imGuiDrawList.AddPolyline( points: ref *p, num_points: vectorPoints.Length, col: (uint)color.ToArgb(), flags: ImDrawFlags.Closed, thickness: RenderThickness); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } } @@ -594,10 +684,20 @@ namespace BizHawk.Bizware.Graphics var vectorPoints = Array.ConvertAll(points, static p => new Vector2(p.X + 0.5f, p.Y + 0.5f)); fixed (Vector2* p = vectorPoints) { + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } + _imGuiDrawList.AddConcavePolyFilled( points: ref *p, num_points: vectorPoints.Length, col: (uint)color.ToArgb()); + + if (color.A != 0xFF) + { + _imGuiDrawList.AddDrawCmd(); + } } } diff --git a/src/BizHawk.Bizware.Graphics/Renderers/SDLImGui2DRenderer.cs b/src/BizHawk.Bizware.Graphics/Renderers/SDLImGui2DRenderer.cs index 264c154610..30f1f477bc 100644 --- a/src/BizHawk.Bizware.Graphics/Renderers/SDLImGui2DRenderer.cs +++ b/src/BizHawk.Bizware.Graphics/Renderers/SDLImGui2DRenderer.cs @@ -102,7 +102,7 @@ namespace BizHawk.Bizware.Graphics protected override void RenderInternal(int width, int height) { - var rt = (GDIPlusRenderTarget)_renderTarget; + var rt = (GDIPlusRenderTarget)_pass2RenderTarget; var bmpData = rt.SDBitmap.LockBits(rt.GetRectangle(), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); try { @@ -172,8 +172,7 @@ namespace BizHawk.Bizware.Graphics case DrawCallbackId.DisableBlending: _ = SDL_SetRenderDrawBlendMode(sdlRenderer, SDL_BlendMode.SDL_BLENDMODE_NONE); break; - case DrawCallbackId.EnableBlendAlpha: - case DrawCallbackId.EnableBlendNormal: + case DrawCallbackId.EnableBlending: _ = SDL_SetRenderDrawBlendMode(sdlRenderer, SDL_BlendMode.SDL_BLENDMODE_BLEND); break; case DrawCallbackId.DrawString: