From ba985ecf3f8e09027ed8a3993c93a8be3b9b74cb Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Tue, 14 Mar 2023 00:09:55 +0300 Subject: [PATCH] Fix `draw_multiline_colors()` for `width < 0` --- doc/classes/RenderingServer.xml | 12 ++++++++++- scene/main/canvas_item.cpp | 9 +++----- servers/rendering/renderer_canvas_cull.cpp | 24 ++++++++++++++++------ servers/rendering_server.cpp | 1 + 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 03248b7dcb0..3e04af839d9 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -257,6 +257,16 @@ See also [method CanvasItem.draw_msdf_texture_rect_region]. + + + + + + + + Draws a 2D multiline on the [CanvasItem] pointed to by the [param item] [RID]. See also [method CanvasItem.draw_multiline] and [method CanvasItem.draw_multiline_colors]. + + @@ -310,7 +320,7 @@ - Draws a 2D polyline on the [CanvasItem] pointed to by the [param item] [RID]. See also [method CanvasItem.draw_polyline]. + Draws a 2D polyline on the [CanvasItem] pointed to by the [param item] [RID]. See also [method CanvasItem.draw_polyline] and [method CanvasItem.draw_polyline_colors]. diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index b36353158b7..57c1b10f1f3 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -555,8 +555,7 @@ void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color void CanvasItem::draw_polyline(const Vector &p_points, const Color &p_color, real_t p_width, bool p_antialiased) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - Vector colors; - colors.push_back(p_color); + Vector colors = { p_color }; RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, colors, p_width, p_antialiased); } @@ -584,8 +583,7 @@ void CanvasItem::draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_sta void CanvasItem::draw_multiline(const Vector &p_points, const Color &p_color, real_t p_width) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - Vector colors; - colors.push_back(p_color); + Vector colors = { p_color }; RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width); } @@ -713,8 +711,7 @@ void CanvasItem::draw_polygon(const Vector &p_points, const Vector &p_points, const Color &p_color, const Vector &p_uvs, Ref p_texture) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - Vector colors; - colors.push_back(p_color); + Vector colors = { p_color }; RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RenderingServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid); } diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index b9e3c4f303e..706477cedb4 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -1177,17 +1177,31 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector &p_points, const Vector &p_colors, float p_width) { - ERR_FAIL_COND(p_points.size() < 2); + ERR_FAIL_COND(p_points.is_empty() || p_points.size() % 2 != 0); + ERR_FAIL_COND(p_colors.size() != 1 && p_colors.size() * 2 != p_points.size()); // TODO: `canvas_item_add_line`(`multiline`, `polyline`) share logic, should factor out. if (p_width < 0) { Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); + Vector colors; + if (p_colors.size() == 1) { + colors = p_colors; + } else { //} else if (p_colors.size() << 1 == p_points.size()) { + colors.resize(p_points.size()); + Color *colors_ptr = colors.ptrw(); + for (int i = 0; i < p_colors.size(); i++) { + Color color = p_colors[i]; + colors_ptr[i * 2 + 0] = color; + colors_ptr[i * 2 + 1] = color; + } + } + Item::CommandPolygon *pline = canvas_item->alloc_command(); ERR_FAIL_COND(!pline); pline->primitive = RS::PRIMITIVE_LINES; - pline->polygon.create(Vector(), p_points, p_colors); + pline->polygon.create(Vector(), p_points, colors); } else { if (p_colors.size() == 1) { Color color = p_colors[0]; @@ -1197,16 +1211,14 @@ void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector> 1) { - for (int i = 0; i < p_points.size() >> 1; i++) { + } else { //} else if (p_colors.size() << 1 == p_points.size()) { + for (int i = 0; i < p_colors.size(); i++) { Color color = p_colors[i]; Vector2 from = p_points[i * 2 + 0]; Vector2 to = p_points[i * 2 + 1]; canvas_item_add_line(p_item, from, to, color, p_width); } - } else { - ERR_FAIL_MSG("Length of p_colors is invalid."); } } } diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index d88cbec13b5..06329d0cd31 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2602,6 +2602,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_line", "item", "from", "to", "color", "width", "antialiased"), &RenderingServer::canvas_item_add_line, DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("canvas_item_add_polyline", "item", "points", "colors", "width", "antialiased"), &RenderingServer::canvas_item_add_polyline, DEFVAL(-1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("canvas_item_add_multiline", "item", "points", "colors", "width"), &RenderingServer::canvas_item_add_multiline, DEFVAL(-1.0)); ClassDB::bind_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &RenderingServer::canvas_item_add_rect); ClassDB::bind_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color"), &RenderingServer::canvas_item_add_circle); ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect", "item", "rect", "texture", "tile", "modulate", "transpose"), &RenderingServer::canvas_item_add_texture_rect, DEFVAL(false), DEFVAL(Color(1, 1, 1)), DEFVAL(false));