diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 00ecdde81f3..d87d2a48e6e 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -410,7 +410,7 @@ Draws a triangle array on the [CanvasItem] pointed to by the [param item] [RID]. This is internally used by [Line2D] and [StyleBoxFlat] for rendering. [method canvas_item_add_triangle_array] is highly flexible, but more complex to use than [method canvas_item_add_polygon]. - [b]Note:[/b] [param count] is unused and can be left unspecified. + [b]Note:[/b] If [param count] is set to a non-negative value, only the first [code]count * 3[/code] indices (corresponding to [code skip-lint]count[/code] triangles) will be drawn. Otherwise, all indices are drawn. diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 17dc7be20bd..f8c0a1d5858 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -2424,7 +2424,7 @@ void RasterizerCanvasGLES3::reset_canvas() { void RasterizerCanvasGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) { } -RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs, const Vector &p_bones, const Vector &p_weights) { +RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs, const Vector &p_bones, const Vector &p_weights, int p_count) { // We interleave the vertex data into one big VBO to improve cache coherence uint32_t vertex_count = p_points.size(); uint32_t stride = 2; @@ -2552,15 +2552,15 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec if (p_indices.size()) { //create indices, as indices were requested Vector index_buffer; - index_buffer.resize(p_indices.size() * sizeof(int32_t)); + index_buffer.resize(p_count * sizeof(int32_t)); { uint8_t *w = index_buffer.ptrw(); - memcpy(w, p_indices.ptr(), sizeof(int32_t) * p_indices.size()); + memcpy(w, p_indices.ptr(), sizeof(int32_t) * p_count); } glGenBuffers(1, &pb.index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer); - GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer, p_indices.size() * 4, index_buffer.ptr(), GL_STATIC_DRAW, "Polygon 2D index buffer"); - pb.count = p_indices.size(); + GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer, p_count * 4, index_buffer.ptr(), GL_STATIC_DRAW, "Polygon 2D index buffer"); + pb.count = p_count; } glBindVertexArray(0); diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index f68c319c38e..ff1b18c3186 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -200,7 +200,7 @@ public: PolygonID last_id = 0; } polygon_buffers; - RendererCanvasRender::PolygonID request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector()) override; + RendererCanvasRender::PolygonID request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector(), int p_count = -1) override; void free_polygon(PolygonID p_polygon) override; struct InstanceData { diff --git a/servers/rendering/dummy/rasterizer_canvas_dummy.h b/servers/rendering/dummy/rasterizer_canvas_dummy.h index 80ec9318457..7f4c8a14a87 100644 --- a/servers/rendering/dummy/rasterizer_canvas_dummy.h +++ b/servers/rendering/dummy/rasterizer_canvas_dummy.h @@ -34,7 +34,7 @@ class RasterizerCanvasDummy : public RendererCanvasRender { public: - PolygonID request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector()) override { return 0; } + PolygonID request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector(), int p_count = -1) override { return 0; } void free_polygon(PolygonID p_polygon) override {} void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used, RenderingMethod::RenderInfo *r_render_info = nullptr) override {} diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index ea904dd357d..3b91bace7e1 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -1735,7 +1735,7 @@ void RendererCanvasCull::canvas_item_add_triangle_array(RID p_item, const Vector polygon->texture = p_texture; - polygon->polygon.create(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights); + polygon->polygon.create(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights, p_count); polygon->primitive = RS::PRIMITIVE_TRIANGLES; } diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h index cd15c6f4be4..24c5bd45488 100644 --- a/servers/rendering/renderer_canvas_render.h +++ b/servers/rendering/renderer_canvas_render.h @@ -130,7 +130,7 @@ public: //easier wrap to avoid mistakes typedef uint64_t PolygonID; - virtual PolygonID request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector()) = 0; + virtual PolygonID request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector(), int p_count = -1) = 0; virtual void free_polygon(PolygonID p_polygon) = 0; //also easier to wrap to avoid mistakes @@ -138,8 +138,10 @@ public: PolygonID polygon_id; Rect2 rect_cache; - _FORCE_INLINE_ void create(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector()) { + _FORCE_INLINE_ void create(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector(), int p_count = -1) { ERR_FAIL_COND(polygon_id != 0); + int count = p_count < 0 ? p_indices.size() : p_count * 3; + ERR_FAIL_COND(count > p_indices.size()); { uint32_t pc = p_points.size(); const Vector2 *v2 = p_points.ptr(); @@ -148,7 +150,7 @@ public: rect_cache.expand_to(v2[i]); } } - polygon_id = singleton->request_polygon(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights); + polygon_id = singleton->request_polygon(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights, count); } _FORCE_INLINE_ Polygon() { polygon_id = 0; } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 8f79a02c0b1..4fd83e42f81 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -100,7 +100,7 @@ void RendererCanvasRenderRD::_update_transform_to_mat4(const Transform3D &p_tran p_mat4[15] = 1; } -RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs, const Vector &p_bones, const Vector &p_weights) { +RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs, const Vector &p_bones, const Vector &p_weights, int p_count) { // Care must be taken to generate array formats // in ways where they could be reused, so we will // put single-occurring elements first, and repeated @@ -311,14 +311,14 @@ RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Ve if (p_indices.size()) { //create indices, as indices were requested Vector index_buffer; - index_buffer.resize(p_indices.size() * sizeof(int32_t)); + index_buffer.resize(p_count * sizeof(int32_t)); { uint8_t *w = index_buffer.ptrw(); memcpy(w, p_indices.ptr(), sizeof(int32_t) * p_indices.size()); } - pb.index_buffer = RD::get_singleton()->index_buffer_create(p_indices.size(), RD::INDEX_BUFFER_FORMAT_UINT32, index_buffer); - pb.indices = RD::get_singleton()->index_array_create(pb.index_buffer, 0, p_indices.size()); - pb.primitive_count = p_indices.size(); + pb.index_buffer = RD::get_singleton()->index_buffer_create(p_count, RD::INDEX_BUFFER_FORMAT_UINT32, index_buffer); + pb.indices = RD::get_singleton()->index_array_create(pb.index_buffer, 0, p_count); + pb.primitive_count = p_count; } pb.vertex_format_id = vertex_id; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 23b293767c8..23a0a98f2a1 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -638,7 +638,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { void _update_occluder_buffer(uint32_t p_size); public: - PolygonID request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector()) override; + PolygonID request_polygon(const Vector &p_indices, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), const Vector &p_bones = Vector(), const Vector &p_weights = Vector(), int p_count = -1) override; void free_polygon(PolygonID p_polygon) override; RID light_create() override;