From 707added91630a1a90f5f97270c65bf9460b711a Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Wed, 29 Nov 2023 12:53:49 +0100 Subject: [PATCH] LibAccelGfx: Premultiply linear gradient colors by alpha With this change color blending for gradients matches CPU painter. --- Userland/Libraries/LibAccelGfx/GL.cpp | 17 +++++++++++-- Userland/Libraries/LibAccelGfx/GL.h | 8 ++++++- Userland/Libraries/LibAccelGfx/Painter.cpp | 28 ++++++++++++---------- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/Userland/Libraries/LibAccelGfx/GL.cpp b/Userland/Libraries/LibAccelGfx/GL.cpp index 787a6e8528..392476606d 100644 --- a/Userland/Libraries/LibAccelGfx/GL.cpp +++ b/Userland/Libraries/LibAccelGfx/GL.cpp @@ -23,10 +23,23 @@ void set_viewport(Gfx::IntRect rect) verify_no_error(); } -void enable_blending() +static GLenum to_gl_enum(BlendFactor factor) +{ + switch (factor) { + case BlendFactor::SrcAlpha: + return GL_SRC_ALPHA; + case BlendFactor::One: + return GL_ONE; + case BlendFactor::OneMinusSrcAlpha: + return GL_ONE_MINUS_SRC_ALPHA; + } + VERIFY_NOT_REACHED(); +} + +void enable_blending(BlendFactor source, BlendFactor destination) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(to_gl_enum(source), to_gl_enum(destination)); verify_no_error(); } diff --git a/Userland/Libraries/LibAccelGfx/GL.h b/Userland/Libraries/LibAccelGfx/GL.h index 14d1d0cdb7..841f41dc73 100644 --- a/Userland/Libraries/LibAccelGfx/GL.h +++ b/Userland/Libraries/LibAccelGfx/GL.h @@ -59,7 +59,13 @@ struct Framebuffer { }; void set_viewport(Gfx::IntRect); -void enable_blending(); + +enum class BlendFactor { + One, + OneMinusSrcAlpha, + SrcAlpha, +}; +void enable_blending(BlendFactor source, BlendFactor destination); void read_pixels(Gfx::IntRect, Gfx::Bitmap&); diff --git a/Userland/Libraries/LibAccelGfx/Painter.cpp b/Userland/Libraries/LibAccelGfx/Painter.cpp index 25867205c0..0b53d1cc0a 100644 --- a/Userland/Libraries/LibAccelGfx/Painter.cpp +++ b/Userland/Libraries/LibAccelGfx/Painter.cpp @@ -205,7 +205,7 @@ void Painter::fill_rect(Gfx::FloatRect rect, Gfx::Color color) GL::set_uniform(color_uniform, red, green, blue, alpha); GL::set_vertex_attribute(position_attribute, 0, 2); - GL::enable_blending(); + GL::enable_blending(GL::BlendFactor::SrcAlpha, GL::BlendFactor::OneMinusSrcAlpha); GL::draw_arrays(GL::DrawPrimitive::TriangleFan, 4); GL::delete_buffer(vbo); @@ -254,7 +254,7 @@ void Painter::fill_rect_with_rounded_corners(Gfx::FloatRect const& rect, Color c auto bottom_right_corner_radius_uniform = m_rounded_rectangle_program.get_uniform_location("uBottomRightRadius"); GL::set_uniform(bottom_right_corner_radius_uniform, bottom_right_radius.horizontal_radius, bottom_right_radius.vertical_radius); - GL::enable_blending(); + GL::enable_blending(GL::BlendFactor::SrcAlpha, GL::BlendFactor::OneMinusSrcAlpha); GL::draw_arrays(GL::DrawPrimitive::TriangleFan, 4); GL::delete_buffer(vbo); @@ -297,7 +297,7 @@ void Painter::draw_line(Gfx::FloatPoint a, Gfx::FloatPoint b, float thickness, C GL::set_uniform(color_uniform, red, green, blue, alpha); GL::set_vertex_attribute(position_attribute, 0, 2); - GL::enable_blending(); + GL::enable_blending(GL::BlendFactor::SrcAlpha, GL::BlendFactor::OneMinusSrcAlpha); GL::draw_arrays(GL::DrawPrimitive::TriangleFan, 4); GL::delete_buffer(vbo); @@ -438,6 +438,7 @@ void Painter::draw_glyph_run(Vector const& glyph_run, Col GL::set_uniform(color_uniform, red, green, blue, alpha); GL::set_vertex_attribute(position_attribute, 0, 4); + GL::enable_blending(GL::BlendFactor::SrcAlpha, GL::BlendFactor::OneMinusSrcAlpha); GL::draw_arrays(GL::DrawPrimitive::Triangles, vertices.size() / 4); GL::delete_buffer(vbo); @@ -491,23 +492,23 @@ void Painter::fill_rect_with_linear_gradient(Gfx::FloatRect const& rect, Readonl auto add_triangle = [&](auto& p1, auto& p2, auto& p3, auto& c1, auto& c2, auto& c3) { vertices.append(p1.x()); vertices.append(p1.y()); - colors.append(c1.red); - colors.append(c1.green); - colors.append(c1.blue); + colors.append(c1.red * c1.alpha); + colors.append(c1.green * c1.alpha); + colors.append(c1.blue * c1.alpha); colors.append(c1.alpha); vertices.append(p2.x()); vertices.append(p2.y()); - colors.append(c2.red); - colors.append(c2.green); - colors.append(c2.blue); + colors.append(c2.red * c2.alpha); + colors.append(c2.green * c2.alpha); + colors.append(c2.blue * c2.alpha); colors.append(c2.alpha); vertices.append(p3.x()); vertices.append(p3.y()); - colors.append(c3.red); - colors.append(c3.green); - colors.append(c3.blue); + colors.append(c3.red * c3.alpha); + colors.append(c3.green * c3.alpha); + colors.append(c3.blue * c3.alpha); colors.append(c3.alpha); }; @@ -534,6 +535,7 @@ void Painter::fill_rect_with_linear_gradient(Gfx::FloatRect const& rect, Readonl GL::bind_buffer(vbo_colors); GL::set_vertex_attribute(color_attribute, 0, 4); + GL::enable_blending(GL::BlendFactor::One, GL::BlendFactor::OneMinusSrcAlpha); GL::draw_arrays(GL::DrawPrimitive::Triangles, vertices.size() / 2); } @@ -633,7 +635,7 @@ void Painter::blit_scaled_texture(Gfx::FloatRect const& dst_rect, GL::Texture co auto scaling_mode_gl = to_gl_scaling_mode(scaling_mode); GL::set_texture_scale_mode(scaling_mode_gl); - GL::enable_blending(); + GL::enable_blending(GL::BlendFactor::SrcAlpha, GL::BlendFactor::OneMinusSrcAlpha); GL::draw_arrays(GL::DrawPrimitive::TriangleFan, 4);