diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index 1537ad409..66867789c 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -1255,7 +1255,7 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S int frameLast = frameCount - 1; switch (timelineType) { - case ATTACHMENT_DEFORM: { + case ATTACHMENT_DEFORM: { bool weighted = attachment->_bones.size() > 0; Vector &vertices = attachment->_vertices; int deformLength = weighted ? (int) vertices.size() / 3 * 2 : (int) vertices.size(); diff --git a/spine-godot/example/project.godot b/spine-godot/example/project.godot index d1b46851c..b52e4a317 100644 --- a/spine-godot/example/project.godot +++ b/spine-godot/example/project.godot @@ -31,4 +31,5 @@ vram_compression/import_etc2=false batching/parameters/max_join_item_commands=100 batching/parameters/batch_buffer_size=65535 batching/parameters/item_reordering_lookahead=100 +batching/debug/diagnose_frame=true environment/default_environment="res://default_env.tres" diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index 1f5c9f1ae..023796d5b 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/spine-godot/spine_godot/SpineSprite.cpp @@ -58,6 +58,7 @@ static spine::Vector quad_indices; static spine::Vector scratch_vertices; static Vector scratch_points; + static void clear_triangles(SpineMesh2D *mesh_instance) { #if VERSION_MAJOR > 3 RenderingServer::get_singleton()->canvas_item_clear(mesh_instance->get_canvas_item()); @@ -74,6 +75,10 @@ static void add_triangles(SpineMesh2D *mesh_instance, SpineRendererObject *renderer_object) { #if VERSION_MAJOR > 3 mesh_instance->update_mesh(vertices, uvs, colors, indices, renderer_object); +#else +#define USE_MESH 0 +#if USE_MESH + mesh_instance->update_mesh(vertices, uvs, colors, indices, renderer_object); #else auto texture = renderer_object->texture; auto normal_map = renderer_object->normal_map; @@ -88,6 +93,7 @@ static void add_triangles(SpineMesh2D *mesh_instance, -1, normal_map.is_null() ? RID() : normal_map->get_rid()); #endif +#endif } void SpineMesh2D::_notification(int what) { @@ -173,6 +179,64 @@ void SpineMesh2D::update_mesh(const Vector &vertices, } RenderingServer::get_singleton()->canvas_item_add_mesh(this->get_canvas_item(), mesh, Transform2D(), Color(1, 1, 1, 1), renderer_object->canvas_texture->get_rid()); +#else + if (!mesh.is_valid() || vertices.size() != num_vertices || indices.size() != num_indices || last_indices_id != indices_id) { + if (mesh.is_valid()) { + VS::get_singleton()->free(mesh); + } + mesh = VS::get_singleton()->mesh_create(); + Array arrays; + arrays.resize(Mesh::ARRAY_MAX); + arrays[Mesh::ARRAY_VERTEX] = vertices; + arrays[Mesh::ARRAY_TEX_UV] = uvs; + arrays[Mesh::ARRAY_COLOR] = colors; + arrays[Mesh::ARRAY_INDEX] = indices; + uint32_t compress_format = (VS::ARRAY_COMPRESS_DEFAULT & ~VS::ARRAY_COMPRESS_TEX_UV); + VS::get_singleton()->mesh_add_surface_from_arrays(mesh, (VS::PrimitiveType) Mesh::PRIMITIVE_TRIANGLES, arrays, Array(), compress_format); + int surface_vertex_len = VS::get_singleton()->mesh_surface_get_array_len(mesh, 0); + int surface_index_len = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, 0); + mesh_surface_format = VS::get_singleton()->mesh_surface_get_format(mesh, 0); + mesh_buffer = VS::get_singleton()->mesh_surface_get_array(mesh, 0); + VS::get_singleton()->mesh_surface_make_offsets_from_format(mesh_surface_format, surface_vertex_len, surface_index_len, mesh_surface_offsets, mesh_stride); + num_vertices = vertices.size(); + num_indices = indices.size(); + last_indices_id = indices_id; + } else { + AABB aabb_new; + PoolVector::Write write_buffer = mesh_buffer.write(); + + uint8_t color[4] = { + uint8_t(CLAMP(colors[0].r * 255.0, 0.0, 255.0)), + uint8_t(CLAMP(colors[0].g * 255.0, 0.0, 255.0)), + uint8_t(CLAMP(colors[0].b * 255.0, 0.0, 255.0)), + uint8_t(CLAMP(colors[0].a * 255.0, 0.0, 255.0))}; + + for (int i = 0; i < vertices.size(); i++) { + Vector2 vertex(vertices[i]); + if (i == 0) { + aabb_new.position = Vector3(vertex.x, vertex.y, 0); + aabb_new.size = Vector3(); + } else { + aabb_new.expand_to(Vector3(vertex.x, vertex.y, 0)); + } + + float uv[2] = {(float) uvs[i].x, (float) uvs[i].y}; + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_VERTEX] + mesh_surface_offsets[VS::ARRAY_VERTEX]], &vertex, sizeof(float) * 2); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_TEX_UV] + mesh_surface_offsets[VS::ARRAY_TEX_UV]], uv, 8); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_COLOR] + mesh_surface_offsets[VS::ARRAY_COLOR]], color, 4); + } + write_buffer.release(); + VS::get_singleton()->mesh_surface_update_region(mesh, 0, 0, mesh_buffer); + VS::get_singleton()->mesh_set_custom_aabb(mesh, aabb_new); + } + + VS::get_singleton()->canvas_item_add_mesh( + this->get_canvas_item(), + mesh, + Transform2D(), + Color(1, 1, 1, 1), + renderer_object->texture.is_null() ? RID() : renderer_object->texture->get_rid(), + renderer_object->normal_map.is_null() ? RID() : renderer_object->normal_map->get_rid()); #endif } diff --git a/spine-godot/spine_godot/SpineSprite.h b/spine-godot/spine_godot/SpineSprite.h index 701c09475..0c4b3c5a4 100644 --- a/spine-godot/spine_godot/SpineSprite.h +++ b/spine-godot/spine_godot/SpineSprite.h @@ -67,6 +67,17 @@ protected: PackedByteArray attribute_buffer; uint32_t vertex_stride; uint32_t attribute_stride; +#else + uint64_t last_indices_id; + uint64_t indices_id; + RID mesh; + uint32_t surface_offsets[VS::ARRAY_MAX]; + int num_vertices; + int num_indices; + uint32_t mesh_surface_offsets[VS::ARRAY_MAX]; + PoolByteArray mesh_buffer; + uint32_t mesh_stride[VS::ARRAY_MAX]; + uint32_t mesh_surface_format; #endif public: @@ -78,8 +89,12 @@ public: } } #else - SpineMesh2D() : renderer_object(nullptr){}; - ~SpineMesh2D() {} + SpineMesh2D() : renderer_object(nullptr), last_indices_id(0), indices_id(0), num_vertices(0), num_indices(0){}; + ~SpineMesh2D() { + if (mesh.is_valid()) { + VS::get_singleton()->free(mesh); + } + } #endif void update_mesh(const Vector &vertices,