diff options
author | David Giardi <david.giardi.eng@gmail.com> | 2023-05-20 00:04:01 +0200 |
---|---|---|
committer | David Giardi <david.giardi.eng@gmail.com> | 2023-05-20 14:28:47 +0200 |
commit | 16f6f4066980bdeba78afb82404f6ab4a78972b2 (patch) | |
tree | f48fef92c7da87237332aacff92894a3511309bc | |
parent | 809a98216267f3066b9fec2f02b2042bdc9d3e0d (diff) | |
download | redot-engine-16f6f4066980bdeba78afb82404f6ab4a78972b2.tar.gz |
Remove useless polygons from StyleBoxFlat drawing
-rw-r--r-- | scene/resources/style_box.cpp | 62 |
1 files changed, 38 insertions, 24 deletions
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 27ae83908e..a9ebb21345 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -562,8 +562,8 @@ inline void set_inner_corner_radius(const Rect2 style_rect, const Rect2 inner_re inner_corner_radius[3] = MAX(corner_radius[3] - rad, 0); } -inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color> &colors, const Rect2 &style_rect, const real_t corner_radius[4], - const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const Vector2 &skew, bool fill_center = false) { +inline void draw_rounded_rectangle(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color> &colors, const Rect2 &style_rect, const real_t corner_radius[4], + const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const Vector2 &skew, bool is_filled = false) { int vert_offset = verts.size(); if (!vert_offset) { vert_offset = 0; @@ -571,6 +571,8 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color int adapted_corner_detail = (corner_radius[0] == 0 && corner_radius[1] == 0 && corner_radius[2] == 0 && corner_radius[3] == 0) ? 1 : corner_detail; + bool draw_border = !is_filled; + real_t ring_corner_radius[4]; set_inner_corner_radius(style_rect, ring_rect, corner_radius, ring_corner_radius); @@ -592,9 +594,14 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3]) //bl }; // Calculate the vertices. + + // If the center is filled, we do not draw the border and directly use the inner ring as reference. Because all calls to this + // method either draw a ring or a filled rounded rectangle, but not both. + int max_inner_outer = draw_border ? 2 : 1; + for (int corner_index = 0; corner_index < 4; corner_index++) { for (int detail = 0; detail <= adapted_corner_detail; detail++) { - for (int inner_outer = 0; inner_outer < 2; inner_outer++) { + for (int inner_outer = 0; inner_outer < max_inner_outer; inner_outer++) { real_t radius; Color color; Point2 corner_point; @@ -621,24 +628,31 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color int ring_vert_count = verts.size() - vert_offset; // Fill the indices and the colors for the border. - for (int i = 0; i < ring_vert_count; i++) { - indices.push_back(vert_offset + ((i + 0) % ring_vert_count)); - indices.push_back(vert_offset + ((i + 2) % ring_vert_count)); - indices.push_back(vert_offset + ((i + 1) % ring_vert_count)); + + if (draw_border) { + for (int i = 0; i < ring_vert_count; i++) { + indices.push_back(vert_offset + ((i + 0) % ring_vert_count)); + indices.push_back(vert_offset + ((i + 2) % ring_vert_count)); + indices.push_back(vert_offset + ((i + 1) % ring_vert_count)); + } } - if (fill_center) { - //Fill the indices and the colors for the center. - for (int index = 0; index < ring_vert_count / 2; index += 2) { - int i = index; + if (is_filled) { + // Compute the triangles pattern to draw the rounded rectangle. + // Consists of vertical stripes of two triangles each. + + int stripes_count = ring_vert_count / 2 - 1; + int last_vert_id = ring_vert_count - 1; + + for (int i = 0; i < stripes_count; i++) { // Polygon 1. indices.push_back(vert_offset + i); - indices.push_back(vert_offset + ring_vert_count - 4 - i); - indices.push_back(vert_offset + i + 2); + indices.push_back(vert_offset + last_vert_id - i - 1); + indices.push_back(vert_offset + i + 1); // Polygon 2. indices.push_back(vert_offset + i); - indices.push_back(vert_offset + ring_vert_count - 2 - i); - indices.push_back(vert_offset + ring_vert_count - 4 - i); + indices.push_back(vert_offset + last_vert_id - 0 - i); + indices.push_back(vert_offset + last_vert_id - 1 - i); } } } @@ -741,24 +755,24 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { Color shadow_color_transparent = Color(shadow_color.r, shadow_color.g, shadow_color.b, 0); - draw_ring(verts, indices, colors, shadow_inner_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, shadow_inner_rect, adapted_corner, shadow_rect, shadow_inner_rect, shadow_color, shadow_color_transparent, corner_detail, skew); if (draw_center) { - draw_ring(verts, indices, colors, shadow_inner_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, shadow_inner_rect, adapted_corner, shadow_inner_rect, shadow_inner_rect, shadow_color, shadow_color, corner_detail, skew, true); } } // Create border (no AA). if (draw_border && !aa_on) { - draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, border_style_rect, adapted_corner, border_style_rect, infill_rect, border_color_inner, border_color, corner_detail, skew); } // Create infill (no AA). if (draw_center && (!aa_on || blend_on)) { - draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, border_style_rect, adapted_corner, infill_rect, infill_rect, bg_color, bg_color, corner_detail, skew, true); } @@ -799,13 +813,13 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { -aa_fill_width[SIDE_RIGHT], -aa_fill_width[SIDE_BOTTOM]); if (!blend_on) { // Create center fill, not antialiased yet - draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, border_style_rect, adapted_corner, infill_rect_aa_colored, infill_rect_aa_colored, bg_color, bg_color, corner_detail, skew, true); } if (!blend_on || !draw_border) { Color alpha_bg = Color(bg_color.r, bg_color.g, bg_color.b, 0); // Add antialiasing on the center fill - draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, border_style_rect, adapted_corner, infill_rect_aa_transparent, infill_rect_aa_colored, bg_color, alpha_bg, corner_detail, skew); } } @@ -825,15 +839,15 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { aa_border_width_half[SIDE_RIGHT], aa_border_width_half[SIDE_BOTTOM]); // Create border ring, not antialiased yet - draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, border_style_rect, adapted_corner, outer_rect_aa_colored, ((blend_on) ? infill_rect : inner_rect_aa_colored), border_color_inner, border_color, corner_detail, skew); if (!blend_on) { // Add antialiasing on the ring inner border - draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, border_style_rect, adapted_corner, inner_rect_aa_colored, inner_rect_aa_transparent, border_color_blend, border_color, corner_detail, skew); } // Add antialiasing on the ring outer border - draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + draw_rounded_rectangle(verts, indices, colors, border_style_rect, adapted_corner, outer_rect_aa_transparent, outer_rect_aa_colored, border_color, border_color_alpha, corner_detail, skew); } } |