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;