diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 9972351cf4e..b1fb0208786 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -2469,6 +2469,14 @@ Returns the stride of the attribute buffer for a mesh with given [param format]. + + + + + + Returns the stride of the index buffer for a mesh with the given [param format]. + + @@ -2536,6 +2544,16 @@ + + + + + + + + Updates the index buffer of the mesh surface with the given [param data]. The expected data are 16 or 32-bit unsigned integers, which can be determined with [method mesh_surface_get_format_index_stride]. + + diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index 481633148f5..2d9b37192e0 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -534,10 +534,10 @@ RS::BlendShapeMode MeshStorage::mesh_get_blend_shape_mode(RID p_mesh) const { } void MeshStorage::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) { + ERR_FAIL_COND(p_data.is_empty()); Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); - ERR_FAIL_COND(p_data.is_empty()); uint64_t data_size = p_data.size(); ERR_FAIL_COND(p_offset + data_size > mesh->surfaces[p_surface]->vertex_buffer_size); @@ -549,10 +549,10 @@ void MeshStorage::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, i } void MeshStorage::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) { + ERR_FAIL_COND(p_data.is_empty()); Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); - ERR_FAIL_COND(p_data.is_empty()); uint64_t data_size = p_data.size(); ERR_FAIL_COND(p_offset + data_size > mesh->surfaces[p_surface]->attribute_buffer_size); @@ -564,10 +564,10 @@ void MeshStorage::mesh_surface_update_attribute_region(RID p_mesh, int p_surface } void MeshStorage::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) { + ERR_FAIL_COND(p_data.is_empty()); Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); - ERR_FAIL_COND(p_data.is_empty()); uint64_t data_size = p_data.size(); ERR_FAIL_COND(p_offset + data_size > mesh->surfaces[p_surface]->skin_buffer_size); @@ -578,6 +578,21 @@ void MeshStorage::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int glBindBuffer(GL_ARRAY_BUFFER, 0); } +void MeshStorage::mesh_surface_update_index_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) { + ERR_FAIL_COND(p_data.is_empty()); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL(mesh); + ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); + + uint64_t data_size = p_data.size(); + ERR_FAIL_COND(p_offset + data_size > mesh->surfaces[p_surface]->index_buffer_size); + const uint8_t *r = p_data.ptr(); + + glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->index_buffer); + glBufferSubData(GL_ARRAY_BUFFER, p_offset, data_size, r); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h index a364636e378..97ff643dcd3 100644 --- a/drivers/gles3/storage/mesh_storage.h +++ b/drivers/gles3/storage/mesh_storage.h @@ -301,6 +301,7 @@ public: virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override; virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override; virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override; + virtual void mesh_surface_update_index_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override; virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const override; diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index 09758e5e40b..a660a544451 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -103,6 +103,7 @@ public: virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override {} virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override {} virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override {} + virtual void mesh_surface_update_index_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override {} virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override {} virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const override { return RID(); } diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index a2341f7ae6b..9dd71d62cb6 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -565,11 +565,12 @@ RS::BlendShapeMode MeshStorage::mesh_get_blend_shape_mode(RID p_mesh) const { } void MeshStorage::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) { + ERR_FAIL_COND(p_data.is_empty()); Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); - ERR_FAIL_COND(p_data.is_empty()); ERR_FAIL_COND(mesh->surfaces[p_surface]->vertex_buffer.is_null()); + uint64_t data_size = p_data.size(); const uint8_t *r = p_data.ptr(); @@ -577,11 +578,12 @@ void MeshStorage::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, i } void MeshStorage::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) { + ERR_FAIL_COND(p_data.is_empty()); Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); - ERR_FAIL_COND(p_data.is_empty()); ERR_FAIL_COND(mesh->surfaces[p_surface]->attribute_buffer.is_null()); + uint64_t data_size = p_data.size(); const uint8_t *r = p_data.ptr(); @@ -589,17 +591,31 @@ void MeshStorage::mesh_surface_update_attribute_region(RID p_mesh, int p_surface } void MeshStorage::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) { + ERR_FAIL_COND(p_data.is_empty()); Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); - ERR_FAIL_COND(p_data.is_empty()); ERR_FAIL_COND(mesh->surfaces[p_surface]->skin_buffer.is_null()); + uint64_t data_size = p_data.size(); const uint8_t *r = p_data.ptr(); RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->skin_buffer, p_offset, data_size, r); } +void RendererRD::MeshStorage::mesh_surface_update_index_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) { + ERR_FAIL_COND(p_data.is_empty()); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL(mesh); + ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); + ERR_FAIL_COND(mesh->surfaces[p_surface]->index_buffer.is_null()); + + uint64_t data_size = p_data.size(); + const uint8_t *r = p_data.ptr(); + + RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->index_buffer, p_offset, data_size, r); +} + void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index 08f00366726..4c2ca1476f7 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -383,6 +383,7 @@ public: virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override; virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override; virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override; + virtual void mesh_surface_update_index_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override; virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const override; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index e18963c94fa..149a71b82fd 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -366,6 +366,7 @@ public: FUNC4(mesh_surface_update_vertex_region, RID, int, int, const Vector &) FUNC4(mesh_surface_update_attribute_region, RID, int, int, const Vector &) FUNC4(mesh_surface_update_skin_region, RID, int, int, const Vector &) + FUNC4(mesh_surface_update_index_region, RID, int, int, const Vector &) FUNC3(mesh_surface_set_material, RID, int, RID) FUNC2RC(RID, mesh_surface_get_material, RID, int) diff --git a/servers/rendering/storage/mesh_storage.h b/servers/rendering/storage/mesh_storage.h index b83e6df712c..ec3de58fdea 100644 --- a/servers/rendering/storage/mesh_storage.h +++ b/servers/rendering/storage/mesh_storage.h @@ -56,6 +56,7 @@ public: virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) = 0; virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) = 0; virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) = 0; + virtual void mesh_surface_update_index_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) = 0; virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index b95cf992c9e..93fa5672c5b 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1022,6 +1022,7 @@ uint32_t RenderingServer::mesh_surface_get_format_attribute_stride(BitField p_format, int p_vertex_len) const { p_format = uint64_t(p_format) & ~ARRAY_FORMAT_INDEX; uint32_t offsets[ARRAY_MAX]; @@ -1033,6 +1034,19 @@ uint32_t RenderingServer::mesh_surface_get_format_skin_stride(BitField p_format, int p_vertex_len) const { + if (!(p_format & ARRAY_FORMAT_INDEX)) { + return 0; + } + + // Determine whether using 16 or 32 bits indices. + if (p_vertex_len <= (1 << 16) && p_vertex_len > 0) { + return 2; + } else { + return 4; + } +} + void RenderingServer::mesh_surface_make_offsets_from_format(uint64_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t &r_vertex_element_size, uint32_t &r_normal_element_size, uint32_t &r_attrib_element_size, uint32_t &r_skin_element_size) const { r_vertex_element_size = 0; r_normal_element_size = 0; @@ -2339,6 +2353,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("mesh_surface_get_format_normal_tangent_stride", "format", "vertex_count"), &RenderingServer::mesh_surface_get_format_normal_tangent_stride); ClassDB::bind_method(D_METHOD("mesh_surface_get_format_attribute_stride", "format", "vertex_count"), &RenderingServer::mesh_surface_get_format_attribute_stride); ClassDB::bind_method(D_METHOD("mesh_surface_get_format_skin_stride", "format", "vertex_count"), &RenderingServer::mesh_surface_get_format_skin_stride); + ClassDB::bind_method(D_METHOD("mesh_surface_get_format_index_stride", "format", "vertex_count"), &RenderingServer::mesh_surface_get_format_index_stride); ClassDB::bind_method(D_METHOD("mesh_add_surface", "mesh", "surface"), &RenderingServer::_mesh_add_surface); ClassDB::bind_method(D_METHOD("mesh_add_surface_from_arrays", "mesh", "primitive", "arrays", "blend_shapes", "lods", "compress_format"), &RenderingServer::mesh_add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_count", "mesh"), &RenderingServer::mesh_get_blend_shape_count); @@ -2359,6 +2374,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("mesh_surface_update_vertex_region", "mesh", "surface", "offset", "data"), &RenderingServer::mesh_surface_update_vertex_region); ClassDB::bind_method(D_METHOD("mesh_surface_update_attribute_region", "mesh", "surface", "offset", "data"), &RenderingServer::mesh_surface_update_attribute_region); ClassDB::bind_method(D_METHOD("mesh_surface_update_skin_region", "mesh", "surface", "offset", "data"), &RenderingServer::mesh_surface_update_skin_region); + ClassDB::bind_method(D_METHOD("mesh_surface_update_index_region", "mesh", "surface", "offset", "data"), &RenderingServer::mesh_surface_update_index_region); ClassDB::bind_method(D_METHOD("mesh_set_shadow_mesh", "mesh", "shadow_mesh"), &RenderingServer::mesh_set_shadow_mesh); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index e71e404ac4a..a5a62b9653f 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -403,6 +403,7 @@ public: virtual uint32_t mesh_surface_get_format_normal_tangent_stride(BitField p_format, int p_vertex_len) const; virtual uint32_t mesh_surface_get_format_attribute_stride(BitField p_format, int p_vertex_len) const; virtual uint32_t mesh_surface_get_format_skin_stride(BitField p_format, int p_vertex_len) const; + virtual uint32_t mesh_surface_get_format_index_stride(BitField p_format, int p_vertex_len) const; /// Returns stride virtual void mesh_surface_make_offsets_from_format(uint64_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t &r_vertex_element_size, uint32_t &r_normal_element_size, uint32_t &r_attrib_element_size, uint32_t &r_skin_element_size) const; @@ -428,6 +429,7 @@ public: virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) = 0; virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) = 0; virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) = 0; + virtual void mesh_surface_update_index_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) = 0; virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0;