diff --git a/core/array.cpp b/core/array.cpp index 90dee44a586..cd4e0fb4c89 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -121,12 +121,37 @@ void Array::_assign(const Array &p_array) { } else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway _p->array = p_array._p->array; } else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid - for (int i = 0; i < p_array._p->array.size(); i++) { - if (!_p->typed.validate(p_array._p->array[i], "assign")) { - return; + if (_p->typed.type == Variant::OBJECT) { + //for objects, it needs full validation, either can be converted or fail + for (int i = 0; i < p_array._p->array.size(); i++) { + if (!_p->typed.validate(p_array._p->array[i], "assign")) { + return; + } } + _p->array = p_array._p->array; //then just copy, which is cheap anyway + + } else { + //for non objects, we need to check if there is a valid conversion, which needs to happen one by one, so this is the worst case. + Vector new_array; + new_array.resize(p_array._p->array.size()); + for (int i = 0; i < p_array._p->array.size(); i++) { + Variant src_val = p_array._p->array[i]; + if (src_val.get_type() == _p->typed.type) { + new_array.write[i] = src_val; + } else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) { + Variant *ptr = &src_val; + Callable::CallError ce; + new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); + } + } else { + ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); + } + } + + _p->array = new_array; } - _p->array = p_array._p->array; //then just copy, which is cheap anyway } else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible _ref(p_array); } else { diff --git a/core/typed_array.h b/core/typed_array.h index c65d68b526d..5e95e81ea35 100644 --- a/core/typed_array.h +++ b/core/typed_array.h @@ -17,6 +17,9 @@ public: _FORCE_INLINE_ void operator=(const Array &p_array) { _assign(p_array); } + _FORCE_INLINE_ TypedArray(const Variant &p_variant) : + Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) { + } _FORCE_INLINE_ TypedArray(const Array &p_array) : Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) { } @@ -27,19 +30,22 @@ public: //specialization for the rest of variant types -#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \ - template <> \ - class TypedArray : public Array { \ - public: \ - _FORCE_INLINE_ void operator=(const Array &p_array) { \ - _assign(p_array); \ - } \ - _FORCE_INLINE_ TypedArray(const Array &p_array) : \ - Array(p_array, m_variant_type, StringName(), Variant()) { \ - } \ - _FORCE_INLINE_ TypedArray() { \ - set_typed(m_variant_type, StringName(), Variant()); \ - } \ +#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \ + template <> \ + class TypedArray : public Array { \ + public: \ + _FORCE_INLINE_ void operator=(const Array &p_array) { \ + _assign(p_array); \ + } \ + _FORCE_INLINE_ TypedArray(const Variant &p_variant) : \ + Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \ + } \ + _FORCE_INLINE_ TypedArray(const Array &p_array) : \ + Array(p_array, m_variant_type, StringName(), Variant()) { \ + } \ + _FORCE_INLINE_ TypedArray() { \ + set_typed(m_variant_type, StringName(), Variant()); \ + } \ }; MAKE_TYPED_ARRAY(bool, Variant::BOOL) diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index c01c325b673..23e9227a392 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -3327,7 +3327,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec } // Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated -RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector &p_vertex_formats) { +RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector &p_vertex_formats) { _THREAD_SAFE_METHOD_ @@ -3402,7 +3402,7 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo //validate with buffer { - const VertexDescription &atf = vd.vertex_formats[i]; + const VertexAttribute &atf = vd.vertex_formats[i]; uint32_t element_size = get_format_vertex_size(atf.format); ERR_FAIL_COND_V(element_size == 0, RID()); //should never happens since this was prevalidated diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 2a916b420e3..6432946fbe8 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -332,7 +332,7 @@ class RenderingDeviceVulkan : public RenderingDevice { RID_Owner vertex_buffer_owner; struct VertexDescriptionKey { - Vector vertex_formats; + Vector vertex_formats; bool operator==(const VertexDescriptionKey &p_key) const { int vdc = vertex_formats.size(); int vdck = p_key.vertex_formats.size(); @@ -340,11 +340,11 @@ class RenderingDeviceVulkan : public RenderingDevice { if (vdc != vdck) { return false; } else { - const VertexDescription *a_ptr = vertex_formats.ptr(); - const VertexDescription *b_ptr = p_key.vertex_formats.ptr(); + const VertexAttribute *a_ptr = vertex_formats.ptr(); + const VertexAttribute *b_ptr = p_key.vertex_formats.ptr(); for (int i = 0; i < vdc; i++) { - const VertexDescription &a = a_ptr[i]; - const VertexDescription &b = b_ptr[i]; + const VertexAttribute &a = a_ptr[i]; + const VertexAttribute &b = b_ptr[i]; if (a.location != b.location) { return false; @@ -369,9 +369,9 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t hash() const { int vdc = vertex_formats.size(); uint32_t h = hash_djb2_one_32(vdc); - const VertexDescription *ptr = vertex_formats.ptr(); + const VertexAttribute *ptr = vertex_formats.ptr(); for (int i = 0; i < vdc; i++) { - const VertexDescription &vd = ptr[i]; + const VertexAttribute &vd = ptr[i]; h = hash_djb2_one_32(vd.location, h); h = hash_djb2_one_32(vd.offset, h); h = hash_djb2_one_32(vd.format, h); @@ -393,7 +393,7 @@ class RenderingDeviceVulkan : public RenderingDevice { HashMap vertex_format_cache; struct VertexDescriptionCache { - Vector vertex_formats; + Vector vertex_formats; VkVertexInputBindingDescription *bindings; VkVertexInputAttributeDescription *attributes; VkPipelineVertexInputStateCreateInfo create_info; @@ -1016,7 +1016,7 @@ public: virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector &p_data = Vector()); // Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated - virtual VertexFormatID vertex_format_create(const Vector &p_vertex_formats); + virtual VertexFormatID vertex_format_create(const Vector &p_vertex_formats); virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector &p_src_buffers); virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const Vector &p_data = Vector(), bool p_use_restart_indices = false); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 942b4a8ee69..9c739474d10 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -1066,9 +1066,9 @@ Array EditorSelection::_get_transformable_selected_nodes() { return ret; } -Array EditorSelection::get_selected_nodes() { +TypedArray EditorSelection::get_selected_nodes() { - Array ret; + TypedArray ret; for (Map::Element *E = selection.front(); E; E = E->next()) { diff --git a/editor/editor_data.h b/editor/editor_data.h index 4f5d68bfed6..e4f4c67c8e7 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -257,7 +257,7 @@ protected: static void _bind_methods(); public: - Array get_selected_nodes(); + TypedArray get_selected_nodes(); void add_node(Node *p_node); void remove_node(Node *p_node); bool is_selected(Node *) const; diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index c46b6eeb5c8..8ba334bc674 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -435,10 +435,10 @@ bool Area2D::is_monitorable() const { return monitorable; } -Array Area2D::get_overlapping_bodies() const { +TypedArray Area2D::get_overlapping_bodies() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray ret; ret.resize(body_map.size()); int idx = 0; for (const Map::Element *E = body_map.front(); E; E = E->next()) { @@ -453,10 +453,10 @@ Array Area2D::get_overlapping_bodies() const { return ret; } -Array Area2D::get_overlapping_areas() const { +TypedArray Area2D::get_overlapping_areas() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray ret; ret.resize(area_map.size()); int idx = 0; for (const Map::Element *E = area_map.front(); E; E = E->next()) { diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index c5e66354121..0e2c0ac672c 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -178,8 +178,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; //function for script - Array get_overlapping_areas() const; //function for script + TypedArray get_overlapping_bodies() const; //function for script + TypedArray get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index d77fd5b0978..19484442b12 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -95,7 +95,7 @@ Vector NavigationPolygon::get_vertices() const { return vertices; } -void NavigationPolygon::_set_polygons(const Array &p_array) { +void NavigationPolygon::_set_polygons(const TypedArray> &p_array) { { MutexLock lock(navmesh_generation); @@ -118,7 +118,7 @@ Array NavigationPolygon::_get_polygons() const { return ret; } -void NavigationPolygon::_set_outlines(const Array &p_array) { +void NavigationPolygon::_set_outlines(const TypedArray> &p_array) { outlines.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 73e056a353f..cbfe4299fbb 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -55,10 +55,10 @@ class NavigationPolygon : public Resource { protected: static void _bind_methods(); - void _set_polygons(const Array &p_array); + void _set_polygons(const TypedArray> &p_array); Array _get_polygons() const; - void _set_outlines(const Array &p_array); + void _set_outlines(const TypedArray> &p_array); Array _get_outlines() const; public: diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 21dc9537ece..de15f0efc21 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -139,7 +139,7 @@ PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) : set_pickable(false); } -Array PhysicsBody2D::get_collision_exceptions() { +TypedArray PhysicsBody2D::get_collision_exceptions() { List exceptions; PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -739,11 +739,11 @@ RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() cons return ccd_mode; } -Array RigidBody2D::get_colliding_bodies() const { +TypedArray RigidBody2D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, Array()); - Array ret; + TypedArray ret; ret.resize(contact_monitor->body_map.size()); int idx = 0; for (const Map::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 0d92a820e32..75f4f778bf8 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -67,7 +67,7 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -256,7 +256,7 @@ public: void add_force(const Vector2 &p_offset, const Vector2 &p_force); void add_torque(float p_torque); - Array get_colliding_bodies() const; //function for script + TypedArray get_colliding_bodies() const; //function for script virtual String get_configuration_warning() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 14a4d24b442..9628c017184 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1705,13 +1705,13 @@ TypedArray TileMap::get_used_cells() const { return a; } -Array TileMap::get_used_cells_by_id(int p_id) const { +TypedArray TileMap::get_used_cells_by_id(int p_id) const { - Array a; + TypedArray a; for (Map::Element *E = tile_map.front(); E; E = E->next()) { if (E->value().id == p_id) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a.push_back(p); } } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index cc44bc147ba..cc1537f5835 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -329,7 +329,7 @@ public: bool is_centered_textures_enabled() const; TypedArray get_used_cells() const; - Array get_used_cells_by_id(int p_id) const; + TypedArray get_used_cells_by_id(int p_id) const; Rect2 get_used_rect(); // Not const because of cache void set_occluder_light_mask(int p_mask); diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 17ae553e5e6..b72483d71b2 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const { return monitoring; } -Array Area3D::get_overlapping_bodies() const { +TypedArray Area3D::get_overlapping_bodies() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; @@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const { return monitorable; } -Array Area3D::get_overlapping_areas() const { +TypedArray Area3D::get_overlapping_areas() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index ff6c0b6b084..f6503c6d2dd 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -184,8 +184,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; - Array get_overlapping_areas() const; //function for script + TypedArray get_overlapping_bodies() const; + TypedArray get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 72d1762ab5d..3991efc7c0b 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const { return get_collision_layer() & (1 << p_bit); } -Array PhysicsBody3D::get_collision_exceptions() { +TypedArray PhysicsBody3D::get_collision_exceptions() { List exceptions; PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 2e710202338..0e719f5108c 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -68,7 +68,7 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 59a6e230055..973822653ae 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -33,6 +33,7 @@ #include "core/engine.h" #include "core/message_queue.h" #include "core/project_settings.h" +#include "core/type_info.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/surface_tool.h" @@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect } } -void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { +void Skeleton3D::physical_bones_start_simulation_on(const TypedArray &p_bones) { set_physics_process_internal(false); Vector sim_bones; @@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { sim_bones.resize(p_bones.size()); int c = 0; for (int i = sim_bones.size() - 1; 0 <= i; --i) { - Variant::Type type = p_bones.get(i).get_type(); - if (Variant::STRING == type || Variant::STRING_NAME == type) { - int bone_id = find_bone(p_bones.get(i)); - if (bone_id != -1) - sim_bones.write[c++] = bone_id; - } + int bone_id = find_bone(p_bones[i]); + if (bone_id != -1) + sim_bones.write[c++] = bone_id; } sim_bones.resize(c); } diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 08b8691658b..0bccd3f8fc1 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -222,7 +222,7 @@ private: public: void physical_bones_stop_simulation(); - void physical_bones_start_simulation_on(const Array &p_bones); + void physical_bones_start_simulation_on(const TypedArray &p_bones); void physical_bones_add_collision_exception(RID p_exception); void physical_bones_remove_collision_exception(RID p_exception); #endif // _3D_DISABLED diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 1efa3d83a30..65947fa1b7f 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -170,7 +170,7 @@ void register_server_types() { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); - ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp index 1a21fdb4d77..956bf54d012 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -273,7 +273,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector polygon_buffer; polygon_buffer.resize(buffer_size * sizeof(float)); - Vector descriptions; + Vector descriptions; descriptions.resize(4); Vector buffers; buffers.resize(4); @@ -284,7 +284,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector vf; - RD::VertexDescription vd; + Vector vf; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; vd.location = 0; vd.offset = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index 97ef604dd21..06894290145 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -2341,14 +2341,14 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su Mesh::Surface::Version &v = s->versions[version]; - Vector attributes; + Vector attributes; Vector buffers; uint32_t stride = 0; for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { - RD::VertexDescription vd; + RD::VertexAttribute vd; RID buffer; vd.location = i; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 0c15d4645b3..3740b59430a 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -61,7 +61,7 @@ Vector RenderingDevice::shader_compile_from_source(ShaderStage p_stage, return compile_function(p_stage, p_source_code, p_language, r_error); } -RID RenderingDevice::_texture_create(const Ref &p_format, const Ref &p_view, const Array &p_data) { +RID RenderingDevice::_texture_create(const Ref &p_format, const Ref &p_view, const TypedArray &p_data) { ERR_FAIL_COND_V(p_format.is_null(), RID()); ERR_FAIL_COND_V(p_view.is_null(), RID()); @@ -86,7 +86,7 @@ RID RenderingDevice::_texture_create_shared_from_slice(const Ref return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type); } -RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const Array &p_attachments) { +RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray &p_attachments) { Vector attachments; attachments.resize(p_attachments.size()); @@ -111,20 +111,20 @@ RID RenderingDevice::_sampler_create(const Ref &p_state) { return sampler_create(p_state->base); } -RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const Array &p_vertex_formats) { +RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const TypedArray &p_vertex_formats) { - Vector descriptions; + Vector descriptions; descriptions.resize(p_vertex_formats.size()); for (int i = 0; i < p_vertex_formats.size(); i++) { - Ref af = p_vertex_formats[i]; + Ref af = p_vertex_formats[i]; ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); descriptions.write[i] = af->base; } return vertex_format_create(descriptions); } -RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Array &p_src_buffers) { +RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray &p_src_buffers) { Vector buffers = Variant(p_src_buffers); @@ -194,6 +194,10 @@ RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p PipelineMultisampleState multisample_state; if (p_multisample_state.is_valid()) { multisample_state = p_multisample_state->base; + for (int i = 0; i < p_multisample_state->sample_masks.size(); i++) { + int64_t mask = p_multisample_state->sample_masks[i]; + multisample_state.sample_mask.push_back(mask); + } } PipelineDepthStencilState depth_stencil_state; @@ -204,6 +208,12 @@ RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p PipelineColorBlendState color_blend_state; if (p_blend_state.is_valid()) { color_blend_state = p_blend_state->base; + for (int i = 0; i < p_blend_state->attachments.size(); i++) { + Ref attachment = p_blend_state->attachments[i]; + if (attachment.is_valid()) { + color_blend_state.attachments.push_back(attachment->base); + } + } } return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 6de83c9b5ba..c76fce5b5c5 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -32,13 +32,14 @@ #define RENDERING_DEVICE_H #include "core/object.h" +#include "core/typed_array.h" #include "servers/display_server.h" class RDTextureFormat; class RDTextureView; -class RDAttachments; +class RDAttachmentFormat; class RDSamplerState; -class RDVertexDescriptions; +class RDVertexAttribute; class RDShaderSource; class RDShaderBytecode; class RDUniforms; @@ -547,13 +548,13 @@ public: VERTEX_FREQUENCY_INSTANCE, }; - struct VertexDescription { + struct VertexAttribute { uint32_t location; //shader location uint32_t offset; DataFormat format; uint32_t stride; VertexFrequency frequency; - VertexDescription() { + VertexAttribute() { location = 0; offset = 0; stride = 0; @@ -566,7 +567,7 @@ public: typedef int64_t VertexFormatID; // This ID is warranted to be unique for the same formats, does not need to be freed - virtual VertexFormatID vertex_format_create(const Vector &p_vertex_formats) = 0; + virtual VertexFormatID vertex_format_create(const Vector &p_vertex_formats) = 0; virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector &p_src_buffers) = 0; enum IndexBufferFormat { @@ -1051,15 +1052,15 @@ public: protected: //binders to script API - RID _texture_create(const Ref &p_format, const Ref &p_view, const Array &p_data = Array()); + RID _texture_create(const Ref &p_format, const Ref &p_view, const TypedArray &p_data = Array()); RID _texture_create_shared(const Ref &p_view, RID p_with_texture); RID _texture_create_shared_from_slice(const Ref &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D); - FramebufferFormatID _framebuffer_format_create(const Array &p_attachments); + FramebufferFormatID _framebuffer_format_create(const TypedArray &p_attachments); RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID); RID _sampler_create(const Ref &p_state); - VertexFormatID _vertex_format_create(const Array &p_vertex_formats); - RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Array &p_src_buffers); + VertexFormatID _vertex_format_create(const TypedArray &p_vertex_formats); + RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray &p_src_buffers); Ref _shader_compile_from_source(const Ref &p_source, bool p_allow_cache = true); RID _shader_create(const Ref &p_bytecode); diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index b3d943be792..f57f59876d3 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -142,10 +142,10 @@ protected: } }; -class RDVertexDescription : public Reference { - GDCLASS(RDVertexDescription, Reference) +class RDVertexAttribute : public Reference { + GDCLASS(RDVertexAttribute, Reference) friend class RenderingDevice; - RD::VertexDescription base; + RD::VertexAttribute base; public: RD_SETGET(uint32_t, location) @@ -156,11 +156,11 @@ public: protected: static void _bind_methods() { - RD_BIND(Variant::INT, RDVertexDescription, location); - RD_BIND(Variant::INT, RDVertexDescription, offset); - RD_BIND(Variant::INT, RDVertexDescription, format); - RD_BIND(Variant::INT, RDVertexDescription, stride); - RD_BIND(Variant::INT, RDVertexDescription, frequency); + RD_BIND(Variant::INT, RDVertexAttribute, location); + RD_BIND(Variant::INT, RDVertexAttribute, offset); + RD_BIND(Variant::INT, RDVertexAttribute, format); + RD_BIND(Variant::INT, RDVertexAttribute, stride); + RD_BIND(Variant::INT, RDVertexAttribute, frequency); } }; class RDShaderSource : public Reference { @@ -412,6 +412,7 @@ class RDPipelineMultisampleState : public Reference { friend class RenderingDevice; RD::PipelineMultisampleState base; + TypedArray sample_masks; public: RD_SETGET(RD::TextureSamples, sample_count) @@ -420,24 +421,10 @@ public: RD_SETGET(bool, enable_alpha_to_coverage) RD_SETGET(bool, enable_alpha_to_one) - void add_sample_mask(uint32_t p_sample_mask) { base.sample_mask.push_back(p_sample_mask); } - void clear_sample_masks() { base.sample_mask.clear(); } - Vector get_sample_masks() const { - Vector sample_masks; - for (int i = 0; i < base.sample_mask.size(); i++) { - sample_masks.push_back(base.sample_mask[i]); - } - return sample_masks; - } + void set_sample_masks(const TypedArray &p_masks) { sample_masks = p_masks; } + TypedArray get_sample_masks() const { return sample_masks; } protected: - void _set_sample_masks(const Vector &p_masks) { - base.sample_mask.clear(); - for (int i = 0; i < p_masks.size(); i++) { - int64_t mask = p_masks[i]; - base.sample_mask.push_back(mask); - } - } static void _bind_methods() { RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count); RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading); @@ -445,11 +432,9 @@ protected: RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage); RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one); - ClassDB::bind_method(D_METHOD("add_sample_mask", "mask"), &RDPipelineMultisampleState::add_sample_mask); - ClassDB::bind_method(D_METHOD("clear_sample_masks"), &RDPipelineMultisampleState::clear_sample_masks); - ClassDB::bind_method(D_METHOD("_set_sample_masks", "sample_masks"), &RDPipelineMultisampleState::_set_sample_masks); + ClassDB::bind_method(D_METHOD("set_sample_masks", "masks"), &RDPipelineMultisampleState::set_sample_masks); ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks); - ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT64_ARRAY, "_sample_masks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_sample_masks", "get_sample_masks"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "sample_masks", PROPERTY_HINT_ARRAY_TYPE, "int"), "set_sample_masks", "get_sample_masks"); } }; @@ -514,6 +499,7 @@ protected: class RDPipelineColorBlendStateAttachment : public Reference { GDCLASS(RDPipelineColorBlendStateAttachment, Reference) + friend class RenderingDevice; RD::PipelineColorBlendState::Attachment base; public: @@ -529,10 +515,6 @@ public: RD_SETGET(bool, write_b) RD_SETGET(bool, write_a) - void set_as_disabled() { - base = RD::PipelineColorBlendState::Attachment(); - } - void set_as_mix() { base = RD::PipelineColorBlendState::Attachment(); @@ -545,6 +527,9 @@ public: protected: static void _bind_methods() { + + ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend); RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor); RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor); @@ -564,49 +549,19 @@ class RDPipelineColorBlendState : public Reference { friend class RenderingDevice; RD::PipelineColorBlendState base; - Vector> attachments; + TypedArray attachments; public: RD_SETGET(bool, enable_logic_op) RD_SETGET(RD::LogicOperation, logic_op) RD_SETGET(Color, blend_constant) - void add_attachment(const Ref &p_attachment) { - attachments.push_back(p_attachment); + void set_attachments(const TypedArray &p_attachments) { + attachments.push_back(p_attachments); } - void add_no_blend_attachment() { - Ref attachment; - attachment.instance(); - attachment->set_as_disabled(); - add_attachment(attachment); - } - - void add_blend_mix_attachment() { - Ref attachment; - attachment.instance(); - attachment->set_as_mix(); - add_attachment(attachment); - } - - void clear_attachments() { - attachments.clear(); - } - - Array get_attachments() const { - Array ret; - for (int i = 0; i < attachments.size(); i++) { - ret.push_back(attachments[i]); - } - return ret; - } - void _set_attachments(const Array &p_attachments) { - attachments.clear(); - for (int i = 0; i < p_attachments.size(); i++) { - Ref attachment = p_attachments[i]; - ERR_FAIL_COND(!attachment.is_valid()); - attachments.push_back(attachment); - } + TypedArray get_attachments() const { + return attachments; } protected: @@ -615,13 +570,9 @@ protected: RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op); RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant); - ClassDB::bind_method(D_METHOD("add_attachment", "atachment"), &RDPipelineColorBlendState::add_attachment); - ClassDB::bind_method(D_METHOD("add_no_blend_attachment"), &RDPipelineColorBlendState::add_no_blend_attachment); - ClassDB::bind_method(D_METHOD("add_blend_mix_attachment"), &RDPipelineColorBlendState::add_blend_mix_attachment); - ClassDB::bind_method(D_METHOD("clear_attachments"), &RDPipelineColorBlendState::clear_attachments); - ClassDB::bind_method(D_METHOD("_set_attachments", "attachments"), &RDPipelineColorBlendState::_set_attachments); + ClassDB::bind_method(D_METHOD("set_attachments", "atachments"), &RDPipelineColorBlendState::set_attachments); ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_attachments", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_attachments", "get_attachments"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "attachments", PROPERTY_HINT_ARRAY_TYPE, "RDPipelineColorBlendStateAttachment"), "set_attachments", "get_attachments"); } };