From 8dccdaae2ebfccd39057654c8cced268eb29a38e Mon Sep 17 00:00:00 2001 From: Sergey Date: Fri, 15 Oct 2021 21:34:52 +0300 Subject: [PATCH 1/3] impl draw_multicircle --- doc/classes/CanvasItem.xml | 13 +++++++++ doc/classes/VisualServer.xml | 15 +++++++++++ drivers/gles3/rasterizer_canvas_gles3.cpp | 32 +++++++++++++++++++++++ scene/2d/canvas_item.cpp | 10 +++++++ scene/2d/canvas_item.h | 1 + servers/visual/rasterizer.h | 15 +++++++++++ servers/visual/visual_server_canvas.cpp | 14 ++++++++++ servers/visual/visual_server_canvas.h | 1 + servers/visual/visual_server_raster.h | 1 + servers/visual/visual_server_wrap_mt.h | 1 + servers/visual_server.cpp | 1 + servers/visual_server.h | 1 + 12 files changed, 105 insertions(+) diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 79da1f67afd..3c1c05f7538 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -77,6 +77,19 @@ Draws a colored circle. + + + + + + + + + + + Draws colored circles. + + diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index b43b993c89d..a80e456bb5d 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -169,6 +169,21 @@ Adds a circle command to the [CanvasItem]'s draw commands. + + + + + + + + + + + + + + Adds a circle command to the [CanvasItem]'s draw commands. + diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index cc9f0b884c6..f79ca3af64c 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1146,6 +1146,38 @@ void RasterizerCanvasGLES3::render_batches(Item *p_current_clip, bool &r_reclip, //_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true); //canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1); } break; + case Item::Command::TYPE_MULTICIRCLE: { + + _set_texture_rect_mode(false); + + Item::CommandMultiCircle *circles = static_cast(c); + static const int numpoints = 32; + static const int n = circles->centers.size(); + + Vector2 points[(numpoints + 1) * n]; + int indices[numpoints * 3 * n]; + + for (int i = 0; i < n; ++i) { + int start_points = (numpoints + 1)*i; + int start_indices = numpoints*3*i; + + points[start_points + numpoints] = circles->centers[i]; + + for (int j = 0; j < numpoints; j++) { + + points[start_points + j] = circles->centers[i] + Vector2(Math::sin(j * Math_PI * 2.0 / numpoints), Math::cos(j * Math_PI * 2.0 / numpoints)) * circles->radii[i]; + indices[start_indices + j * 3 + 0] = start_indices + j; + indices[start_indices + j * 3 + 1] = start_indices + (j + 1) % numpoints; + indices[start_indices + j * 3 + 2] = start_indices + numpoints; + } + } + + _bind_canvas_texture(RID(), RID()); + _draw_polygon(indices, numpoints * 3 * n, (numpoints + 1) * n, points, NULL, &circles->color, true, NULL, NULL); + + //_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true); + //canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1); + } break; case Item::Command::TYPE_TRANSFORM: { Item::CommandTransform *transform = static_cast(c); diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 6d8b1508f26..e3864cc86c9 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -817,6 +817,15 @@ void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color); } +void CanvasItem::draw_multicircle(const Vector &p_centers, const Vector &p_radii, const Color &p_color) { + + ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + + VisualServer::get_singleton()->canvas_item_add_multicircle(canvas_item, p_centers, p_radii, p_color); +} + + + void CanvasItem::draw_texture(const Ref &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref &p_normal_map) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -1164,6 +1173,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle); + ClassDB::bind_method(D_METHOD("draw_multicircle", "centers", "radii", "color"), &CanvasItem::draw_multicircle); ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose", "normal_map"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture", "rect", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true)); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 6ecd0b31a12..a2485cfd82e 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -313,6 +313,7 @@ class CanvasItem : public Node { void draw_multiline_colors(const Vector &p_points, const Vector &p_colors, float p_width = 1.0, bool p_antialiased = false); void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0, bool p_antialiased = false); void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color); + void draw_multicircle(const Vector &p_centers, const Vector &p_radii, const Color &p_color); void draw_texture(const Ref &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref &p_normal_map = Ref()); void draw_texture_rect(const Ref &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()); void draw_texture_rect_region(const Ref &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = false); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 1123e524c9d..08dc94bd457 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -711,6 +711,7 @@ class RasterizerCanvas { TYPE_MULTIMESH, TYPE_PARTICLES, TYPE_CIRCLE, + TYPE_MULTICIRCLE, TYPE_TRANSFORM, TYPE_CLIP_IGNORE, }; @@ -843,6 +844,14 @@ class RasterizerCanvas { CommandCircle() { type = TYPE_CIRCLE; } }; + struct CommandMultiCircle : public Command { + + Vector centers; + Vector radii; + Color color; + CommandMultiCircle() { type = TYPE_MULTICIRCLE; } + }; + struct CommandTransform : public Command { Transform2D xform; @@ -1064,6 +1073,12 @@ class RasterizerCanvas { r.position = Point2(-circle->radius, -circle->radius) + circle->pos; r.size = Point2(circle->radius * 2.0, circle->radius * 2.0); } break; + case Item::Command::TYPE_MULTICIRCLE: { + + const Item::CommandMultiCircle *circles = static_cast(c); + r.position = Point2(-circles->radii[0], -circles->radii[0]) + circles->centers[0]; + r.size = Point2(circles->radii[0] * 2.0, circles->radii[0] * 2.0); + } break; case Item::Command::TYPE_TRANSFORM: { const Item::CommandTransform *transform = static_cast(c); diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 50206073b21..884904ca594 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -633,6 +633,20 @@ void VisualServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos, canvas_item->commands.push_back(circle); } +void VisualServerCanvas::canvas_item_add_multicircle(RID p_item, const Vector &p_centers, const Vector &p_radii, const Color &p_color) { + Item *canvas_item = canvas_item_owner.getornull(p_item); + ERR_FAIL_COND(!canvas_item); + + Item::CommandMultiCircle *circles = memnew(Item::CommandMultiCircle); + ERR_FAIL_COND(!circles); + circles->color = p_color; + circles->centers = p_centers; + circles->radii = p_radii; + + canvas_item->commands.push_back(circles); +} + + void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose, RID p_normal_map) { Item *canvas_item = canvas_item_owner.getornull(p_item); diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index 19c3ff40b52..4b03e7dbfd4 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -198,6 +198,7 @@ class VisualServerCanvas { void canvas_item_add_multiline(RID p_item, const Vector &p_points, const Vector &p_colors, float p_width = 1.0, bool p_antialiased = false); void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color); void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color); + void canvas_item_add_multicircle(RID p_item, const Vector &p_centers, const Vector &p_radii, const Color &p_color); void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()); void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = false); void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index ec760dcd783..2695635308e 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -606,6 +606,7 @@ class VisualServerRaster : public VisualServer { BIND5(canvas_item_add_multiline, RID, const Vector &, const Vector &, float, bool) BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &) BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) + BIND4(canvas_item_add_multicircle, RID, const Vector &, const Vector &, const Color &) BIND7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID) BIND8(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, bool) BIND11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 85e67be2ab4..c1e2ad342c6 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -523,6 +523,7 @@ class VisualServerWrapMT : public VisualServer { FUNC5(canvas_item_add_polyline, RID, const Vector &, const Vector &, float, bool) FUNC5(canvas_item_add_multiline, RID, const Vector &, const Vector &, float, bool) FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &) + FUNC4(canvas_item_add_multicircle, RID, const Vector &, const Vector &, const Color &) FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) FUNC7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID) FUNC8(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, bool) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index e279bd45fc2..7cd24902d6e 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1974,6 +1974,7 @@ void VisualServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_polyline", "item", "points", "colors", "width", "antialiased"), &VisualServer::canvas_item_add_polyline, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &VisualServer::canvas_item_add_rect); ClassDB::bind_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color"), &VisualServer::canvas_item_add_circle); + ClassDB::bind_method(D_METHOD("canvas_item_add_multicircle", "item", "centers", "radii", "color"), &VisualServer::canvas_item_add_multicircle); ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect", "item", "rect", "texture", "tile", "modulate", "transpose", "normal_map"), &VisualServer::canvas_item_add_texture_rect, DEFVAL(false), DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(RID())); ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(RID()), DEFVAL(true)); ClassDB::bind_method(D_METHOD("canvas_item_add_nine_patch", "item", "rect", "source", "texture", "topleft", "bottomright", "x_axis_mode", "y_axis_mode", "draw_center", "modulate", "normal_map"), &VisualServer::canvas_item_add_nine_patch, DEFVAL(NINE_PATCH_STRETCH), DEFVAL(NINE_PATCH_STRETCH), DEFVAL(true), DEFVAL(Color(1, 1, 1)), DEFVAL(RID())); diff --git a/servers/visual_server.h b/servers/visual_server.h index ae5859c65be..376273c7375 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -920,6 +920,7 @@ class VisualServer : public Object { virtual void canvas_item_add_multiline(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_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0; virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) = 0; + virtual void canvas_item_add_multicircle(RID p_item, const Vector &p_centers, const Vector &p_radii, const Color &p_color) = 0; virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()) = 0; virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = false) = 0; virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()) = 0; From 0df7da27228b455254700cbaf2cc1b0e05ae734c Mon Sep 17 00:00:00 2001 From: Sergey Date: Sun, 17 Oct 2021 01:37:17 +0300 Subject: [PATCH 2/3] fix bug --- drivers/gles3/rasterizer_canvas_gles3.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index f79ca3af64c..6f5e3222196 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1166,9 +1166,9 @@ void RasterizerCanvasGLES3::render_batches(Item *p_current_clip, bool &r_reclip, for (int j = 0; j < numpoints; j++) { points[start_points + j] = circles->centers[i] + Vector2(Math::sin(j * Math_PI * 2.0 / numpoints), Math::cos(j * Math_PI * 2.0 / numpoints)) * circles->radii[i]; - indices[start_indices + j * 3 + 0] = start_indices + j; - indices[start_indices + j * 3 + 1] = start_indices + (j + 1) % numpoints; - indices[start_indices + j * 3 + 2] = start_indices + numpoints; + indices[start_indices + j * 3 + 0] = start_points + j; + indices[start_indices + j * 3 + 1] = start_points + (j + 1) % numpoints; + indices[start_indices + j * 3 + 2] = start_points + numpoints; } } From 6a1ca7d5c614ab6b19a301bcc6ed912954794fea Mon Sep 17 00:00:00 2001 From: Sergey Date: Sun, 17 Oct 2021 15:18:29 +0300 Subject: [PATCH 3/3] bug fix 2 --- drivers/gles3/rasterizer_canvas_gles3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 6f5e3222196..b802fc17c63 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1152,7 +1152,7 @@ void RasterizerCanvasGLES3::render_batches(Item *p_current_clip, bool &r_reclip, Item::CommandMultiCircle *circles = static_cast(c); static const int numpoints = 32; - static const int n = circles->centers.size(); + int n = circles->centers.size(); Vector2 points[(numpoints + 1) * n]; int indices[numpoints * 3 * n];