From e6daec9cf8b76a0cd8cc583c4ac0136d842b2a00 Mon Sep 17 00:00:00 2001 From: David House Date: Tue, 19 Nov 2024 08:34:01 -0600 Subject: [PATCH] Added indirect drawing functionality to MultiMesh Update doc/classes/RenderingServer.xml Co-Authored-By: Micky <66727710+Mickeon@users.noreply.github.com> --- doc/classes/RenderingServer.xml | 24 ++++++++++ drivers/gles3/storage/mesh_storage.cpp | 6 ++- drivers/gles3/storage/mesh_storage.h | 3 +- .../4.3-stable.expected | 7 +++ .../rendering/dummy/storage/mesh_storage.h | 3 +- .../render_forward_clustered.cpp | 12 ++++- .../render_forward_clustered.h | 1 + .../forward_mobile/render_forward_mobile.cpp | 10 ++++- .../forward_mobile/render_forward_mobile.h | 1 + .../renderer_rd/storage_rd/mesh_storage.cpp | 44 ++++++++++++++++++- .../renderer_rd/storage_rd/mesh_storage.h | 14 +++++- servers/rendering/rendering_server_default.h | 3 +- servers/rendering/storage/mesh_storage.cpp | 8 +++- servers/rendering/storage/mesh_storage.h | 6 ++- servers/rendering_server.compat.inc | 5 +++ servers/rendering_server.cpp | 3 +- servers/rendering_server.h | 8 +++- 17 files changed, 143 insertions(+), 15 deletions(-) diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 93ae82f52a0..fafd1292608 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -2559,6 +2559,7 @@ + @@ -2593,6 +2594,29 @@ Returns the [RenderingDevice] [RID] handle of the [MultiMesh], which can be used as any other buffer on the Rendering Device. + + + + + Returns the [RenderingDevice] [RID] handle of the [MultiMesh] command buffer. This [RID] is only valid if [code]use_indirect[/code] is set to [code]true[/code] when allocating data through [method multimesh_allocate_data]. It can be used to directly modify the instance count via buffer. + The data structure is dependent on both how many surfaces the mesh contains and whether it is indexed or not, the buffer has 5 integers in it, with the last unused if the mesh is not indexed. + Each of the values in the buffer correspond to these options: + [codeblock lang=text] + Indexed: + 0 - indexCount; + 1 - instanceCount; + 2 - firstIndex; + 3 - vertexOffset; + 4 - firstInstance; + Non Indexed: + 0 - vertexCount; + 1 - instanceCount; + 2 - firstVertex; + 3 - firstInstance; + 4 - unused; + [/codeblock] + + diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index a3362942320..428646aaf71 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -1518,7 +1518,7 @@ void MeshStorage::_multimesh_free(RID p_rid) { multimesh_owner.free(p_rid); } -void MeshStorage::_multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { +void MeshStorage::_multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data, bool p_use_indirect) { MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_NULL(multimesh); @@ -2041,6 +2041,10 @@ void MeshStorage::_multimesh_set_buffer(RID p_multimesh, const Vector &p_ } } +RID MeshStorage::_multimesh_get_command_buffer_rd_rid(RID p_multimesh) const { + ERR_FAIL_V_MSG(RID(), "GLES3 does not implement indirect multimeshes."); +} + RID MeshStorage::_multimesh_get_buffer_rd_rid(RID p_multimesh) const { ERR_FAIL_V_MSG(RID(), "GLES3 does not contain a Rid for the multimesh buffer."); } diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h index 83ac0efc5c8..3b9084a04ce 100644 --- a/drivers/gles3/storage/mesh_storage.h +++ b/drivers/gles3/storage/mesh_storage.h @@ -502,7 +502,7 @@ public: virtual RID _multimesh_allocate() override; virtual void _multimesh_initialize(RID p_rid) override; virtual void _multimesh_free(RID p_rid) override; - virtual void _multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override; + virtual void _multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false, bool p_use_indirect = false) override; virtual int _multimesh_get_instance_count(RID p_multimesh) const override; virtual void _multimesh_set_mesh(RID p_multimesh, RID p_mesh) override; @@ -521,6 +521,7 @@ public: virtual Color _multimesh_instance_get_color(RID p_multimesh, int p_index) const override; virtual Color _multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override; virtual void _multimesh_set_buffer(RID p_multimesh, const Vector &p_buffer) override; + virtual RID _multimesh_get_command_buffer_rd_rid(RID p_multimesh) const override; virtual RID _multimesh_get_buffer_rd_rid(RID p_multimesh) const override; virtual Vector _multimesh_get_buffer(RID p_multimesh) const override; diff --git a/misc/extension_api_validation/4.3-stable.expected b/misc/extension_api_validation/4.3-stable.expected index 91db0dd9b7a..cf3aa2d0582 100644 --- a/misc/extension_api_validation/4.3-stable.expected +++ b/misc/extension_api_validation/4.3-stable.expected @@ -217,6 +217,13 @@ Validate extension JSON: Error: Field 'classes/Control/properties/offset_top': t Property type changed to float to match the actual internal API and documentation. +GH-99455 +-------- +Validate extension JSON: Error: Field 'classes/RenderingServer/methods/multimesh_allocate_data/arguments': size changed value in new API, from 5 to 6. + +Optional argument added to allow setting indirect draw mode on Multimesh. Compatibility method registered. + + GH-100129 --------- Validate extension JSON: Error: Field 'classes/NavigationServer2D/methods/query_path': is_const changed value in new API, from true to false. diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index 97789d3a82d..ffffa4ef534 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -151,7 +151,7 @@ public: virtual void _multimesh_initialize(RID p_rid) override; virtual void _multimesh_free(RID p_rid) override; - virtual void _multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override {} + virtual void _multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false, bool p_use_indirect = false) override {} virtual int _multimesh_get_instance_count(RID p_multimesh) const override { return 0; } virtual void _multimesh_set_mesh(RID p_multimesh, RID p_mesh) override {} @@ -171,6 +171,7 @@ public: virtual Color _multimesh_instance_get_color(RID p_multimesh, int p_index) const override { return Color(); } virtual Color _multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override { return Color(); } virtual void _multimesh_set_buffer(RID p_multimesh, const Vector &p_buffer) override; + virtual RID _multimesh_get_command_buffer_rd_rid(RID p_multimesh) const override { return RID(); } virtual RID _multimesh_get_buffer_rd_rid(RID p_multimesh) const override { return RID(); } virtual Vector _multimesh_get_buffer(RID p_multimesh) const override; diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 207538c7104..70b3a89c4a6 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -599,7 +599,11 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p instance_count /= surf->owner->trail_steps; } - RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); + if (bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_INDIRECT)) { + RD::get_singleton()->draw_list_draw_indirect(draw_list, index_array_rd.is_valid(), mesh_storage->_multimesh_get_command_buffer_rd_rid(surf->owner->data->base), surf->surface_index * sizeof(uint32_t) * mesh_storage->INDIRECT_MULTIMESH_COMMAND_STRIDE, 1, 0); + } else { + RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); + } } i += element_info.repeat - 1; //skip equal elements @@ -1083,6 +1087,7 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con } else { surf->sort.lod_index = 0; if (p_render_data->render_info) { + // This does not include primitives rendered via indirect draw calls. uint32_t to_draw = mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface); to_draw = _indices_to_primitives(surf->primitive, to_draw); to_draw *= inst->instance_count; @@ -4205,9 +4210,9 @@ void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p ginstance->base_flags = 0; bool store_transform = true; - if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) { ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH; + if (mesh_storage->multimesh_get_transform_format(ginstance->data->base) == RS::MULTIMESH_TRANSFORM_2D) { ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D; } @@ -4217,6 +4222,9 @@ void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p if (mesh_storage->multimesh_uses_custom_data(ginstance->data->base)) { ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA; } + if (mesh_storage->multimesh_uses_indirect(ginstance->data->base)) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_INDIRECT; + } ginstance->transforms_uniform_set = mesh_storage->multimesh_get_3d_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 42c1da1a971..567ca5d80fa 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -255,6 +255,7 @@ private: // When changing any of these enums, remember to change the corresponding enums in the shader files as well. enum { + INSTANCE_DATA_FLAG_MULTIMESH_INDIRECT = 1 << 2, INSTANCE_DATA_FLAGS_DYNAMIC = 1 << 3, INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4, INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5, diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 6d217964366..1651e82276d 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -2380,7 +2380,11 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr instance_count /= surf->owner->trail_steps; } - RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); + if (bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_INDIRECT)) { + RD::get_singleton()->draw_list_draw_indirect(draw_list, index_array_rd.is_valid(), mesh_storage->_multimesh_get_command_buffer_rd_rid(surf->owner->data->base), surf->surface_index * sizeof(uint32_t) * mesh_storage->INDIRECT_MULTIMESH_COMMAND_STRIDE, 1, 0); + } else { + RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); + } } } @@ -2801,6 +2805,7 @@ void RenderForwardMobile::_geometry_instance_update(RenderGeometryInstance *p_ge if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) { ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH; + if (mesh_storage->multimesh_get_transform_format(ginstance->data->base) == RS::MULTIMESH_TRANSFORM_2D) { ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D; } @@ -2810,6 +2815,9 @@ void RenderForwardMobile::_geometry_instance_update(RenderGeometryInstance *p_ge if (mesh_storage->multimesh_uses_custom_data(ginstance->data->base)) { ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA; } + if (mesh_storage->multimesh_uses_indirect(ginstance->data->base)) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_INDIRECT; + } ginstance->transforms_uniform_set = mesh_storage->multimesh_get_3d_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 77242c8c93c..e6aec9752ec 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -358,6 +358,7 @@ protected: // When changing any of these enums, remember to change the corresponding enums in the shader files as well. enum { + INSTANCE_DATA_FLAG_MULTIMESH_INDIRECT = 1 << 2, INSTANCE_DATA_FLAGS_DYNAMIC = 1 << 3, INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4, INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5, diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index bd5f8dc787e..84f4b452996 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -1485,7 +1485,7 @@ void MeshStorage::_multimesh_free(RID p_rid) { multimesh_owner.free(p_rid); } -void MeshStorage::_multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { +void MeshStorage::_multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data, bool p_use_indirect) { MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_NULL(multimesh); @@ -1521,6 +1521,9 @@ void MeshStorage::_multimesh_allocate_data(RID p_multimesh, int p_instances, RS: multimesh->stride_cache = multimesh->custom_data_offset_cache + (p_use_custom_data ? 4 : 0); multimesh->buffer_set = false; + multimesh->indirect = p_use_indirect; + multimesh->command_buffer = RID(); + //print_line("allocate, elements: " + itos(p_instances) + " 2D: " + itos(p_transform_format == RS::MULTIMESH_TRANSFORM_2D) + " colors " + itos(multimesh->uses_colors) + " data " + itos(multimesh->uses_custom_data) + " stride " + itos(multimesh->stride_cache) + " total size " + itos(multimesh->stride_cache * multimesh->instances)); multimesh->data_cache = Vector(); multimesh->aabb = AABB(); @@ -1609,6 +1612,30 @@ void MeshStorage::_multimesh_set_mesh(RID p_multimesh, RID p_mesh) { } multimesh->mesh = p_mesh; + if (multimesh->indirect) { + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL(mesh); + if (mesh->surface_count > 0) { + if (multimesh->command_buffer.is_valid()) { + RD::get_singleton()->free(multimesh->command_buffer); + } + + Vector newVector; + newVector.resize_zeroed(sizeof(uint32_t) * INDIRECT_MULTIMESH_COMMAND_STRIDE * mesh->surface_count); + + for (uint32_t i = 0; i < mesh->surface_count; i++) { + uint32_t count = mesh_surface_get_vertices_drawn_count(mesh->surfaces[i]); + newVector.set(i * sizeof(uint32_t) * INDIRECT_MULTIMESH_COMMAND_STRIDE, static_cast(count)); + newVector.set(i * sizeof(uint32_t) * INDIRECT_MULTIMESH_COMMAND_STRIDE + 1, static_cast(count >> 8)); + newVector.set(i * sizeof(uint32_t) * INDIRECT_MULTIMESH_COMMAND_STRIDE + 2, static_cast(count >> 16)); + newVector.set(i * sizeof(uint32_t) * INDIRECT_MULTIMESH_COMMAND_STRIDE + 3, static_cast(count >> 24)); + } + + RID newBuffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * INDIRECT_MULTIMESH_COMMAND_STRIDE * mesh->surface_count, newVector, RD::STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT); + multimesh->command_buffer = newBuffer; + } + } + if (multimesh->instances == 0) { return; } @@ -2064,6 +2091,12 @@ void MeshStorage::_multimesh_set_buffer(RID p_multimesh, const Vector &p_ } } +RID MeshStorage::_multimesh_get_command_buffer_rd_rid(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + ERR_FAIL_NULL_V(multimesh, RID()); + return multimesh->command_buffer; +} + RID MeshStorage::_multimesh_get_buffer_rd_rid(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_NULL_V(multimesh, RID()); @@ -2111,6 +2144,15 @@ void MeshStorage::_multimesh_set_visible_instances(RID p_multimesh, int p_visibl multimesh->visible_instances = p_visible; + if (multimesh->indirect) { //we have to update the command buffer for the instance counts, in each stride this will be the second integer. + Mesh *mesh = mesh_owner.get_or_null(multimesh->mesh); + if (mesh != nullptr) { + for (uint32_t i = 0; i < mesh->surface_count; i++) { + RD::get_singleton()->buffer_update(multimesh->command_buffer, (i * sizeof(uint32_t) * INDIRECT_MULTIMESH_COMMAND_STRIDE) + sizeof(uint32_t), sizeof(uint32_t), &p_visible); + } + } + } + multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES); } diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index 7a8f0c8e608..5b8ed343857 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -59,6 +59,10 @@ public: DEFAULT_RD_BUFFER_MAX, }; + enum IndirectMultiMesh : uint32_t { + INDIRECT_MULTIMESH_COMMAND_STRIDE = 5 + }; + private: static MeshStorage *singleton; @@ -226,6 +230,7 @@ private: AABB custom_aabb; bool aabb_dirty = false; bool buffer_set = false; + bool indirect = false; bool motion_vectors_enabled = false; uint32_t motion_vectors_current_offset = 0; uint32_t motion_vectors_previous_offset = 0; @@ -243,6 +248,7 @@ private: RID buffer; //storage buffer RID uniform_set_3d; RID uniform_set_2d; + RID command_buffer; //used if indirect setting is used bool dirty = false; MultiMesh *dirty_list = nullptr; @@ -637,7 +643,7 @@ public: virtual void _multimesh_initialize(RID p_multimesh) override; virtual void _multimesh_free(RID p_rid) override; - virtual void _multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override; + virtual void _multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false, bool p_use_indirect = false) override; virtual int _multimesh_get_instance_count(RID p_multimesh) const override; virtual void _multimesh_set_mesh(RID p_multimesh, RID p_mesh) override; @@ -654,6 +660,7 @@ public: virtual Color _multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override; virtual void _multimesh_set_buffer(RID p_multimesh, const Vector &p_buffer) override; + virtual RID _multimesh_get_command_buffer_rd_rid(RID p_multimesh) const override; virtual RID _multimesh_get_buffer_rd_rid(RID p_multimesh) const override; virtual Vector _multimesh_get_buffer(RID p_multimesh) const override; @@ -672,6 +679,11 @@ public: bool _multimesh_uses_motion_vectors_offsets(RID p_multimesh); bool _multimesh_uses_motion_vectors(RID p_multimesh); + _FORCE_INLINE_ bool multimesh_uses_indirect(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + return multimesh->indirect; + } + _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); return multimesh->xform_format; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 16d32f00a46..14794f7bab7 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -382,7 +382,7 @@ public: FUNCRIDSPLIT(multimesh) - FUNC5(multimesh_allocate_data, RID, int, MultimeshTransformFormat, bool, bool) + FUNC6(multimesh_allocate_data, RID, int, MultimeshTransformFormat, bool, bool, bool) FUNC1RC(int, multimesh_get_instance_count, RID) FUNC2(multimesh_set_mesh, RID, RID) @@ -403,6 +403,7 @@ public: FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int) FUNC2(multimesh_set_buffer, RID, const Vector &) + FUNC1RC(RID, multimesh_get_command_buffer_rd_rid, RID) FUNC1RC(RID, multimesh_get_buffer_rd_rid, RID) FUNC1RC(Vector, multimesh_get_buffer, RID) diff --git a/servers/rendering/storage/mesh_storage.cpp b/servers/rendering/storage/mesh_storage.cpp index 4a6746e6c91..5b899878039 100644 --- a/servers/rendering/storage/mesh_storage.cpp +++ b/servers/rendering/storage/mesh_storage.cpp @@ -48,7 +48,7 @@ void RendererMeshStorage::multimesh_free(RID p_rid) { _multimesh_free(p_rid); } -void RendererMeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { +void RendererMeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data, bool p_use_indirect) { MultiMeshInterpolator *mmi = _multimesh_get_interpolator(p_multimesh); if (mmi) { mmi->_transform_format = p_transform_format; @@ -68,7 +68,7 @@ void RendererMeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instanc mmi->_data_interpolated.resize_zeroed(size_in_floats); } - _multimesh_allocate_data(p_multimesh, p_instances, p_transform_format, p_use_colors, p_use_custom_data); + _multimesh_allocate_data(p_multimesh, p_instances, p_transform_format, p_use_colors, p_use_custom_data, p_use_indirect); } int RendererMeshStorage::multimesh_get_instance_count(RID p_multimesh) const { @@ -223,6 +223,10 @@ void RendererMeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector &p_buffer); + virtual RID multimesh_get_command_buffer_rd_rid(RID p_multimesh) const; virtual RID multimesh_get_buffer_rd_rid(RID p_multimesh) const; virtual Vector multimesh_get_buffer(RID p_multimesh) const; @@ -159,7 +160,7 @@ public: virtual void _multimesh_initialize(RID p_rid) = 0; virtual void _multimesh_free(RID p_rid) = 0; - virtual void _multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; + virtual void _multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false, bool p_use_indirect = false) = 0; virtual int _multimesh_get_instance_count(RID p_multimesh) const = 0; @@ -180,6 +181,7 @@ public: virtual Color _multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0; virtual void _multimesh_set_buffer(RID p_multimesh, const Vector &p_buffer) = 0; + virtual RID _multimesh_get_command_buffer_rd_rid(RID p_multimesh) const = 0; virtual RID _multimesh_get_buffer_rd_rid(RID p_multimesh) const = 0; virtual Vector _multimesh_get_buffer(RID p_multimesh) const = 0; diff --git a/servers/rendering_server.compat.inc b/servers/rendering_server.compat.inc index 99f2de9a9a3..2ae2f3c8844 100644 --- a/servers/rendering_server.compat.inc +++ b/servers/rendering_server.compat.inc @@ -30,6 +30,10 @@ #ifndef DISABLE_DEPRECATED +void RenderingServer::_multimesh_allocate_data_bind_compat_99455(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { + multimesh_allocate_data(p_multimesh, p_instances, p_transform_format, p_use_colors, p_use_custom_data, false); +} + void RenderingServer::_environment_set_fog_bind_compat_84792(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect) { environment_set_fog(p_env, p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_aerial_perspective, p_sky_affect, RS::EnvironmentFogMode::ENV_FOG_MODE_EXPONENTIAL); } @@ -47,6 +51,7 @@ void RenderingServer::_canvas_item_add_circle_bind_compat_84523(RID p_item, cons } void RenderingServer::_bind_compatibility_methods() { + ClassDB::bind_compatibility_method(D_METHOD("multimesh_allocate_data", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &RenderingServer::_multimesh_allocate_data_bind_compat_99455, DEFVAL(false), DEFVAL(false)); ClassDB::bind_compatibility_method(D_METHOD("environment_set_fog", "env", "enable", "light_color", "light_energy", "sun_scatter", "density", "height", "height_density", "aerial_perspective", "sky_affect"), &RenderingServer::_environment_set_fog_bind_compat_84792); ClassDB::bind_compatibility_method(D_METHOD("canvas_item_add_multiline", "item", "points", "colors", "width"), &RenderingServer::_canvas_item_add_multiline_bind_compat_84523, DEFVAL(-1.0)); ClassDB::bind_compatibility_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &RenderingServer::_canvas_item_add_rect_bind_compat_84523); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index a38d9a4b05c..422faa13a09 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2441,7 +2441,7 @@ void RenderingServer::_bind_methods() { /* MULTIMESH API */ ClassDB::bind_method(D_METHOD("multimesh_create"), &RenderingServer::multimesh_create); - ClassDB::bind_method(D_METHOD("multimesh_allocate_data", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &RenderingServer::multimesh_allocate_data, DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("multimesh_allocate_data", "multimesh", "instances", "transform_format", "color_format", "custom_data_format", "use_indirect"), &RenderingServer::multimesh_allocate_data, DEFVAL(false), DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("multimesh_get_instance_count", "multimesh"), &RenderingServer::multimesh_get_instance_count); ClassDB::bind_method(D_METHOD("multimesh_set_mesh", "multimesh", "mesh"), &RenderingServer::multimesh_set_mesh); ClassDB::bind_method(D_METHOD("multimesh_instance_set_transform", "multimesh", "index", "transform"), &RenderingServer::multimesh_instance_set_transform); @@ -2459,6 +2459,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("multimesh_set_visible_instances", "multimesh", "visible"), &RenderingServer::multimesh_set_visible_instances); ClassDB::bind_method(D_METHOD("multimesh_get_visible_instances", "multimesh"), &RenderingServer::multimesh_get_visible_instances); ClassDB::bind_method(D_METHOD("multimesh_set_buffer", "multimesh", "buffer"), &RenderingServer::multimesh_set_buffer); + ClassDB::bind_method(D_METHOD("multimesh_get_command_buffer_rd_rid", "multimesh"), &RenderingServer::multimesh_get_command_buffer_rd_rid); ClassDB::bind_method(D_METHOD("multimesh_get_buffer_rd_rid", "multimesh"), &RenderingServer::multimesh_get_buffer_rd_rid); ClassDB::bind_method(D_METHOD("multimesh_get_buffer", "multimesh"), &RenderingServer::multimesh_get_buffer); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 94447baf67c..1206911e4b2 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -457,7 +457,12 @@ public: MULTIMESH_INTERP_QUALITY_HIGH, }; - virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; +protected: +#ifndef DISABLE_DEPRECATED + void _multimesh_allocate_data_bind_compat_99455(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data); +#endif +public: + virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false, bool p_use_indirect = false) = 0; virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0; @@ -478,6 +483,7 @@ public: virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0; virtual void multimesh_set_buffer(RID p_multimesh, const Vector &p_buffer) = 0; + virtual RID multimesh_get_command_buffer_rd_rid(RID p_multimesh) const = 0; virtual RID multimesh_get_buffer_rd_rid(RID p_multimesh) const = 0; virtual Vector multimesh_get_buffer(RID p_multimesh) const = 0;