diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index baaf33956f2..6cd2da520ff 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -103,8 +103,9 @@
+
- Draws a line from a 2D point to another, with a given color and width. See also [method draw_multiline] and [method draw_polyline].
+ Draws a line from a 2D point to another, with a given color and width. It can be optionally antialiased. See also [method draw_multiline] and [method draw_polyline].
@@ -191,7 +192,7 @@
- Draws interconnected line segments with a uniform [code]color[/code] and [code]width[/code]. When drawing large amounts of lines, this is faster than using individual [method draw_line] calls. To draw disconnected lines, use [method draw_multiline] instead. See also [method draw_polygon].
+ Draws interconnected line segments with a uniform [code]color[/code] and [code]width[/code] and optional antialiasing. When drawing large amounts of lines, this is faster than using individual [method draw_line] calls. To draw disconnected lines, use [method draw_multiline] instead. See also [method draw_polygon].
@@ -201,7 +202,7 @@
- Draws interconnected line segments with a uniform [code]width[/code] and segment-by-segment coloring. Colors assigned to line segments match by index between [code]points[/code] and [code]colors[/code]. When drawing large amounts of lines, this is faster than using individual [method draw_line] calls. To draw disconnected lines, use [method draw_multiline_colors] instead. See also [method draw_polygon].
+ Draws interconnected line segments with a uniform [code]width[/code] and segment-by-segment coloring, and optional antialiasing. Colors assigned to line segments match by index between [code]points[/code] and [code]colors[/code]. When drawing large amounts of lines, this is faster than using individual [method draw_line] calls. To draw disconnected lines, use [method draw_multiline_colors] instead. See also [method draw_polygon].
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index f1a15a08dd9..5da9ca82a78 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -183,6 +183,7 @@
+
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index f5fe87c8082..708359f1062 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -463,10 +463,10 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons
RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, off, p_to, p_color, p_width);
}
-void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width) {
+void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, 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.");
- RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
+ RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased);
}
void CanvasItem::draw_polyline(const Vector &p_points, const Color &p_color, real_t p_width, bool p_antialiased) {
@@ -883,7 +883,7 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_draw_behind_parent", "enable"), &CanvasItem::set_draw_behind_parent);
ClassDB::bind_method(D_METHOD("is_draw_behind_parent_enabled"), &CanvasItem::is_draw_behind_parent_enabled);
- ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width"), &CanvasItem::draw_line, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash"), &CanvasItem::draw_dashed_line, DEFVAL(1.0), DEFVAL(2.0));
ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false));
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 95fae0fda71..ad64f1ab5ed 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -215,7 +215,7 @@ public:
/* DRAWING API */
void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = 1.0, real_t p_dash = 2.0);
- void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = 1.0);
+ void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = 1.0, bool p_antialiased = false);
void draw_polyline(const Vector &p_points, const Color &p_color, real_t p_width = 1.0, bool p_antialiased = false);
void draw_polyline_colors(const Vector &p_points, const Vector &p_colors, real_t p_width = 1.0, bool p_antialiased = false);
void draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_start_angle, real_t p_end_angle, int p_point_count, const Color &p_color, real_t p_width = 1.0, bool p_antialiased = false);
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index 667399ee755..c416a03f387 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -82,7 +82,7 @@ void ConvexPolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) {
if (is_collision_outline_enabled()) {
RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col);
// Draw the last segment as it's not drawn by `canvas_item_add_polyline()`.
- RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color);
+ RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color, 1.0, true);
}
}
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 8ad2d42e5f1..41034d4a022 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -552,27 +552,188 @@ void RendererCanvasCull::canvas_item_set_update_when_visible(RID p_item, bool p_
canvas_item->update_when_visible = p_update;
}
-void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
+void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width, bool p_antialiased) {
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
ERR_FAIL_COND(!canvas_item);
Item::CommandPrimitive *line = canvas_item->alloc_command();
ERR_FAIL_COND(!line);
+
+ Vector2 diff = (p_from - p_to);
+ Vector2 dir = diff.orthogonal().normalized();
+ Vector2 t = dir * p_width * 0.5;
+
+ Vector2 begin_left;
+ Vector2 begin_right;
+ Vector2 end_left;
+ Vector2 end_right;
+
if (p_width > 1.001) {
- Vector2 t = (p_from - p_to).orthogonal().normalized() * p_width * 0.5;
- line->points[0] = p_from + t;
- line->points[1] = p_from - t;
- line->points[2] = p_to - t;
- line->points[3] = p_to + t;
+ begin_left = p_from + t;
+ begin_right = p_from - t;
+ end_left = p_to + t;
+ end_right = p_to - t;
+
+ line->points[0] = begin_left;
+ line->points[1] = begin_right;
+ line->points[2] = end_right;
+ line->points[3] = end_left;
line->point_count = 4;
} else {
- line->point_count = 2;
+ begin_left = p_from;
+ begin_right = p_from;
+ end_left = p_to;
+ end_right = p_to;
+
line->points[0] = p_from;
line->points[1] = p_to;
+ line->point_count = 2;
}
for (uint32_t i = 0; i < line->point_count; i++) {
line->colors[i] = p_color;
}
+
+ if (p_antialiased) {
+ float border_size = 2.0;
+ if (p_width < border_size) {
+ border_size = p_width;
+ }
+ Vector2 dir2 = diff.normalized();
+
+ Vector2 border = dir * border_size;
+ Vector2 border2 = dir2 * border_size;
+
+ Color transparent = Color(p_color.r, p_color.g, p_color.b, 0.0);
+
+ {
+ Item::CommandPrimitive *left_border = canvas_item->alloc_command();
+ ERR_FAIL_COND(!left_border);
+
+ left_border->points[0] = begin_left;
+ left_border->points[1] = begin_left + border;
+ left_border->points[2] = end_left + border;
+ left_border->points[3] = end_left;
+
+ left_border->colors[0] = p_color;
+ left_border->colors[1] = transparent;
+ left_border->colors[2] = transparent;
+ left_border->colors[3] = p_color;
+
+ left_border->point_count = 4;
+ }
+ {
+ Item::CommandPrimitive *right_border = canvas_item->alloc_command();
+ ERR_FAIL_COND(!right_border);
+
+ right_border->points[0] = begin_right;
+ right_border->points[1] = begin_right - border;
+ right_border->points[2] = end_right - border;
+ right_border->points[3] = end_right;
+
+ right_border->colors[0] = p_color;
+ right_border->colors[1] = transparent;
+ right_border->colors[2] = transparent;
+ right_border->colors[3] = p_color;
+
+ right_border->point_count = 4;
+ }
+ {
+ Item::CommandPrimitive *top_border = canvas_item->alloc_command();
+ ERR_FAIL_COND(!top_border);
+
+ top_border->points[0] = begin_left;
+ top_border->points[1] = begin_left + border2;
+ top_border->points[2] = begin_right + border2;
+ top_border->points[3] = begin_right;
+
+ top_border->colors[0] = p_color;
+ top_border->colors[1] = transparent;
+ top_border->colors[2] = transparent;
+ top_border->colors[3] = p_color;
+
+ top_border->point_count = 4;
+ }
+ {
+ Item::CommandPrimitive *bottom_border = canvas_item->alloc_command();
+ ERR_FAIL_COND(!bottom_border);
+
+ bottom_border->points[0] = end_left;
+ bottom_border->points[1] = end_left - border2;
+ bottom_border->points[2] = end_right - border2;
+ bottom_border->points[3] = end_right;
+
+ bottom_border->colors[0] = p_color;
+ bottom_border->colors[1] = transparent;
+ bottom_border->colors[2] = transparent;
+ bottom_border->colors[3] = p_color;
+
+ bottom_border->point_count = 4;
+ }
+ {
+ Item::CommandPrimitive *top_left_corner = canvas_item->alloc_command();
+ ERR_FAIL_COND(!top_left_corner);
+
+ top_left_corner->points[0] = begin_left;
+ top_left_corner->points[1] = begin_left + border2;
+ top_left_corner->points[2] = begin_left + border + border2;
+ top_left_corner->points[3] = begin_left + border;
+
+ top_left_corner->colors[0] = p_color;
+ top_left_corner->colors[1] = transparent;
+ top_left_corner->colors[2] = transparent;
+ top_left_corner->colors[3] = transparent;
+
+ top_left_corner->point_count = 4;
+ }
+ {
+ Item::CommandPrimitive *top_right_corner = canvas_item->alloc_command();
+ ERR_FAIL_COND(!top_right_corner);
+
+ top_right_corner->points[0] = begin_right;
+ top_right_corner->points[1] = begin_right + border2;
+ top_right_corner->points[2] = begin_right - border + border2;
+ top_right_corner->points[3] = begin_right - border;
+
+ top_right_corner->colors[0] = p_color;
+ top_right_corner->colors[1] = transparent;
+ top_right_corner->colors[2] = transparent;
+ top_right_corner->colors[3] = transparent;
+
+ top_right_corner->point_count = 4;
+ }
+ {
+ Item::CommandPrimitive *bottom_left_corner = canvas_item->alloc_command();
+ ERR_FAIL_COND(!bottom_left_corner);
+
+ bottom_left_corner->points[0] = end_left;
+ bottom_left_corner->points[1] = end_left - border2;
+ bottom_left_corner->points[2] = end_left + border - border2;
+ bottom_left_corner->points[3] = end_left + border;
+
+ bottom_left_corner->colors[0] = p_color;
+ bottom_left_corner->colors[1] = transparent;
+ bottom_left_corner->colors[2] = transparent;
+ bottom_left_corner->colors[3] = transparent;
+
+ bottom_left_corner->point_count = 4;
+ }
+ {
+ Item::CommandPrimitive *bottom_right_corner = canvas_item->alloc_command();
+ ERR_FAIL_COND(!bottom_right_corner);
+
+ bottom_right_corner->points[0] = end_right;
+ bottom_right_corner->points[1] = end_right - border2;
+ bottom_right_corner->points[2] = end_right - border - border2;
+ bottom_right_corner->points[3] = end_right - border;
+
+ bottom_right_corner->colors[0] = p_color;
+ bottom_right_corner->colors[1] = transparent;
+ bottom_right_corner->colors[2] = transparent;
+ bottom_right_corner->colors[3] = transparent;
+
+ bottom_right_corner->point_count = 4;
+ }
+ }
}
void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector &p_points, const Vector &p_colors, float p_width, bool p_antialiased) {
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index 94bae30ae04..637245502dd 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -215,7 +215,7 @@ public:
void canvas_item_set_update_when_visible(RID p_item, bool p_update);
- void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0);
+ void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
void canvas_item_add_polyline(RID p_item, const Vector &p_points, const Vector &p_colors, float p_width = 1.0, bool p_antialiased = false);
void canvas_item_add_multiline(RID p_item, const Vector &p_points, const Vector &p_colors, float p_width = 1.0);
void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color);
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index cc1edc728a8..21e11c6d71f 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -799,7 +799,7 @@ public:
FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
- FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float)
+ FUNC6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool)
FUNC5(canvas_item_add_polyline, RID, const Vector &, const Vector &, float, bool)
FUNC4(canvas_item_add_multiline, RID, const Vector &, const Vector &, float)
FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index fa6c3fac686..b58e6138eb9 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2566,7 +2566,7 @@ void RenderingServer::_bind_methods() {
/* Primitives */
- ClassDB::bind_method(D_METHOD("canvas_item_add_line", "item", "from", "to", "color", "width"), &RenderingServer::canvas_item_add_line, DEFVAL(1.0));
+ 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_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);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 94692ba68d8..71896e9d110 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -1293,7 +1293,7 @@ public:
NINE_PATCH_TILE_FIT,
};
- virtual void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0) = 0;
+ virtual void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false) = 0;
virtual void canvas_item_add_polyline(RID p_item, const Vector &p_points, const Vector &p_colors, float p_width = 1.0, bool p_antialiased = false) = 0;
virtual void canvas_item_add_multiline(RID p_item, const Vector &p_points, const Vector &p_colors, float p_width = 1.0) = 0;
virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0;