summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/input/input_event.cpp18
-rw-r--r--core/templates/rid_owner.h2
-rw-r--r--doc/classes/AcceptDialog.xml11
-rw-r--r--doc/classes/LineEdit.xml26
-rw-r--r--doc/classes/ProjectSettings.xml2
-rw-r--r--doc/classes/TileSet.xml32
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp25
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h4
-rw-r--r--editor/editor_node.cpp27
-rw-r--r--editor/editor_node.h3
-rw-r--r--editor/editor_vcs_interface.h20
-rw-r--r--editor/plugins/input_event_editor_plugin.cpp122
-rw-r--r--editor/plugins/input_event_editor_plugin.h79
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp16
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp7
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.cpp5
-rw-r--r--editor/scene_tree_dock.cpp18
-rw-r--r--editor/scene_tree_dock.h1
-rw-r--r--modules/csg/csg_shape.cpp12
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java8
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java151
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java14
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java109
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java58
-rw-r--r--platform/javascript/javascript_singleton.cpp2
-rw-r--r--scene/3d/mesh_instance_3d.cpp2
-rw-r--r--scene/3d/occluder_instance_3d.cpp28
-rw-r--r--scene/3d/occluder_instance_3d.h2
-rw-r--r--scene/3d/visual_instance_3d.cpp9
-rw-r--r--scene/gui/color_picker.cpp16
-rw-r--r--scene/gui/color_picker.h1
-rw-r--r--scene/gui/dialogs.cpp23
-rw-r--r--scene/gui/dialogs.h1
-rw-r--r--scene/gui/line_edit.cpp32
-rw-r--r--scene/gui/text_edit.cpp8
-rw-r--r--scene/gui/text_edit.h4
-rw-r--r--scene/gui/tree.cpp4
-rw-r--r--scene/main/canvas_item.cpp2
-rw-r--r--scene/main/node.cpp4
-rw-r--r--scene/main/shader_globals_override.cpp14
-rw-r--r--scene/resources/material.cpp37
-rw-r--r--scene/resources/material.h2
-rw-r--r--scene/resources/mesh.cpp4
-rw-r--r--scene/resources/particles_material.cpp36
-rw-r--r--scene/resources/primitive_meshes.cpp2
-rw-r--r--scene/resources/sky_material.cpp6
-rw-r--r--scene/resources/texture.cpp6
-rw-r--r--scene/resources/tile_set.cpp32
-rw-r--r--servers/physics_3d/collision_solver_3d_sat.cpp40
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp86
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h5
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp86
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h5
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp86
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h5
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp86
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h5
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp237
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h44
-rw-r--r--servers/rendering/renderer_scene_cull.cpp2
-rw-r--r--servers/rendering/rendering_device.h2
-rw-r--r--servers/rendering_server.cpp1
-rw-r--r--tests/test_class_db.h8
65 files changed, 879 insertions, 910 deletions
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 52a6c5d64f..4a2abffae8 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -38,6 +38,7 @@ const int InputEvent::DEVICE_ID_INTERNAL = -2;
void InputEvent::set_device(int p_device) {
device = p_device;
+ emit_changed();
}
int InputEvent::get_device() const {
@@ -131,6 +132,7 @@ void InputEventFromWindow::_bind_methods() {
void InputEventFromWindow::set_window_id(int64_t p_id) {
window_id = p_id;
+ emit_changed();
}
int64_t InputEventFromWindow::get_window_id() const {
@@ -141,6 +143,7 @@ int64_t InputEventFromWindow::get_window_id() const {
void InputEventWithModifiers::set_store_command(bool p_enabled) {
store_command = p_enabled;
+ emit_changed();
}
bool InputEventWithModifiers::is_storing_command() const {
@@ -149,6 +152,7 @@ bool InputEventWithModifiers::is_storing_command() const {
void InputEventWithModifiers::set_shift_pressed(bool p_enabled) {
shift_pressed = p_enabled;
+ emit_changed();
}
bool InputEventWithModifiers::is_shift_pressed() const {
@@ -157,6 +161,7 @@ bool InputEventWithModifiers::is_shift_pressed() const {
void InputEventWithModifiers::set_alt_pressed(bool p_enabled) {
alt_pressed = p_enabled;
+ emit_changed();
}
bool InputEventWithModifiers::is_alt_pressed() const {
@@ -165,6 +170,7 @@ bool InputEventWithModifiers::is_alt_pressed() const {
void InputEventWithModifiers::set_ctrl_pressed(bool p_enabled) {
ctrl_pressed = p_enabled;
+ emit_changed();
}
bool InputEventWithModifiers::is_ctrl_pressed() const {
@@ -173,6 +179,7 @@ bool InputEventWithModifiers::is_ctrl_pressed() const {
void InputEventWithModifiers::set_meta_pressed(bool p_enabled) {
meta_pressed = p_enabled;
+ emit_changed();
}
bool InputEventWithModifiers::is_meta_pressed() const {
@@ -181,6 +188,7 @@ bool InputEventWithModifiers::is_meta_pressed() const {
void InputEventWithModifiers::set_command_pressed(bool p_enabled) {
command_pressed = p_enabled;
+ emit_changed();
}
bool InputEventWithModifiers::is_command_pressed() const {
@@ -291,6 +299,7 @@ void InputEventWithModifiers::_validate_property(PropertyInfo &property) const {
void InputEventKey::set_pressed(bool p_pressed) {
pressed = p_pressed;
+ emit_changed();
}
bool InputEventKey::is_pressed() const {
@@ -299,6 +308,7 @@ bool InputEventKey::is_pressed() const {
void InputEventKey::set_keycode(uint32_t p_keycode) {
keycode = p_keycode;
+ emit_changed();
}
uint32_t InputEventKey::get_keycode() const {
@@ -307,6 +317,7 @@ uint32_t InputEventKey::get_keycode() const {
void InputEventKey::set_physical_keycode(uint32_t p_keycode) {
physical_keycode = p_keycode;
+ emit_changed();
}
uint32_t InputEventKey::get_physical_keycode() const {
@@ -315,6 +326,7 @@ uint32_t InputEventKey::get_physical_keycode() const {
void InputEventKey::set_unicode(uint32_t p_unicode) {
unicode = p_unicode;
+ emit_changed();
}
uint32_t InputEventKey::get_unicode() const {
@@ -323,6 +335,7 @@ uint32_t InputEventKey::get_unicode() const {
void InputEventKey::set_echo(bool p_enable) {
echo = p_enable;
+ emit_changed();
}
bool InputEventKey::is_echo() const {
@@ -469,6 +482,7 @@ void InputEventKey::_bind_methods() {
void InputEventMouse::set_button_mask(int p_mask) {
button_mask = p_mask;
+ emit_changed();
}
int InputEventMouse::get_button_mask() const {
@@ -518,6 +532,7 @@ float InputEventMouseButton::get_factor() const {
void InputEventMouseButton::set_button_index(MouseButton p_index) {
button_index = p_index;
+ emit_changed();
}
MouseButton InputEventMouseButton::get_button_index() const {
@@ -847,6 +862,7 @@ void InputEventMouseMotion::_bind_methods() {
void InputEventJoypadMotion::set_axis(JoyAxis p_axis) {
axis = p_axis;
+ emit_changed();
}
JoyAxis InputEventJoypadMotion::get_axis() const {
@@ -855,6 +871,7 @@ JoyAxis InputEventJoypadMotion::get_axis() const {
void InputEventJoypadMotion::set_axis_value(float p_value) {
axis_value = p_value;
+ emit_changed();
}
float InputEventJoypadMotion::get_axis_value() const {
@@ -949,6 +966,7 @@ void InputEventJoypadMotion::_bind_methods() {
void InputEventJoypadButton::set_button_index(JoyButton p_index) {
button_index = p_index;
+ emit_changed();
}
JoyButton InputEventJoypadButton::get_button_index() const {
diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h
index e4964f744e..4f5c74ca46 100644
--- a/core/templates/rid_owner.h
+++ b/core/templates/rid_owner.h
@@ -193,7 +193,7 @@ public:
if (THREAD_SAFE) {
spin_lock.unlock();
}
- if (validator_chunks[idx_chunk][idx_element] & 0x80000000) {
+ if ((validator_chunks[idx_chunk][idx_element] & 0x80000000) && validator_chunks[idx_chunk][idx_element] != 0xFFFFFFFF) {
ERR_FAIL_V_MSG(nullptr, "Attempting to use an uninitialized RID");
}
return nullptr;
diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml
index f644606040..fd1e2ba104 100644
--- a/doc/classes/AcceptDialog.xml
+++ b/doc/classes/AcceptDialog.xml
@@ -21,6 +21,7 @@
<description>
Adds a button with label [code]text[/code] and a custom [code]action[/code] to the dialog and returns the created button. [code]action[/code] will be passed to the [signal custom_action] signal when pressed.
If [code]true[/code], [code]right[/code] will place the button to the right of any sibling buttons.
+ You can use [method remove_button] method to remove a button created with this method from the dialog.
</description>
</method>
<method name="add_cancel_button">
@@ -30,6 +31,7 @@
</argument>
<description>
Adds a button with label [code]name[/code] and a cancel action to the dialog and returns the created button.
+ You can use [method remove_button] method to remove a button created with this method from the dialog.
</description>
</method>
<method name="get_label">
@@ -55,6 +57,15 @@
Registers a [LineEdit] in the dialog. When the enter key is pressed, the dialog will be accepted.
</description>
</method>
+ <method name="remove_button">
+ <return type="void">
+ </return>
+ <argument index="0" name="button" type="Control">
+ </argument>
+ <description>
+ Removes the [code]button[/code] from the dialog. Does NOT free the [code]button[/code]. The [code]button[/code] must be a [Button] added with [method add_button] or [method add_cancel_button] method. After removal, pressing the [code]button[/code] will no longer emit this dialog's [signal custom_action] or [signal cancelled] signals.
+ </description>
+ </method>
</methods>
<members>
<member name="dialog_autowrap" type="bool" setter="set_autowrap" getter="has_autowrap" default="false">
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index 38f31e44c9..773f7b1a02 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -196,6 +196,28 @@
</member>
<member name="max_length" type="int" setter="set_max_length" getter="get_max_length" default="0">
Maximum amount of characters that can be entered inside the [LineEdit]. If [code]0[/code], there is no limit.
+ When a limit is defined, characters that would exceed [member max_length] are truncated. This happens both for existing [member text] contents when setting the max length, or for new text inserted in the [LineEdit], including pasting. If any input text is truncated, the [signal text_change_rejected] signal is emitted with the truncated substring as parameter.
+ [b]Example:[/b]
+ [codeblocks]
+ [gdscript]
+ text = "Hello world"
+ max_length = 5
+ # `text` becomes "Hello".
+ max_length = 10
+ text += " goodbye"
+ # `text` becomes "Hello good".
+ # `text_change_rejected` is emitted with "bye" as parameter.
+ [/gdscript]
+ [csharp]
+ Text = "Hello world";
+ MaxLength = 5;
+ // `Text` becomes "Hello".
+ MaxLength = 10;
+ Text += " goodbye";
+ // `Text` becomes "Hello good".
+ // `text_change_rejected` is emitted with "bye" as parameter.
+ [/csharp]
+ [/codeblocks]
</member>
<member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" />
<member name="placeholder_alpha" type="float" setter="set_placeholder_alpha" getter="get_placeholder_alpha" default="0.6">
@@ -238,8 +260,10 @@
</members>
<signals>
<signal name="text_change_rejected">
+ <argument index="0" name="rejected_substring" type="String">
+ </argument>
<description>
- Emitted when trying to append text that would overflow the [member max_length].
+ Emitted when appending text that overflows the [member max_length]. The appended text is truncated to fit [member max_length], and the part that couldn't fit is passed as the [code]rejected_substring[/code] argument.
</description>
</signal>
<signal name="text_changed">
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 1847a316e1..366a0a5f0f 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1430,8 +1430,6 @@
</member>
<member name="rendering/global_illumination/sdfgi/probe_ray_count" type="int" setter="" getter="" default="1">
</member>
- <member name="rendering/global_illumination/voxel_gi/anisotropic" type="bool" setter="" getter="" default="false">
- </member>
<member name="rendering/global_illumination/voxel_gi/quality" type="int" setter="" getter="" default="1">
</member>
<member name="rendering/lightmapping/bake_performance/max_rays_per_pass" type="int" setter="" getter="" default="32">
diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml
index 55f232c004..436e15387d 100644
--- a/doc/classes/TileSet.xml
+++ b/doc/classes/TileSet.xml
@@ -322,37 +322,37 @@
</constant>
<constant name="TILE_OFFSET_AXIS_VERTICAL" value="1" enum="TileOffsetAxis">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_RIGHT_SIDE" value="0" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_RIGHT_SIDE" value="0" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_RIGHT_CORNER" value="1" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_RIGHT_CORNER" value="1" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE" value="2" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE" value="2" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER" value="3" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER" value="3" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_SIDE" value="4" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_BOTTOM_SIDE" value="4" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_CORNER" value="5" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_BOTTOM_CORNER" value="5" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE" value="6" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_BOTTOM_LEFT_SIDE" value="6" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER" value="7" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_BOTTOM_LEFT_CORNER" value="7" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_LEFT_SIDE" value="8" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_LEFT_SIDE" value="8" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_LEFT_CORNER" value="9" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_LEFT_CORNER" value="9" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE" value="10" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_TOP_LEFT_SIDE" value="10" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER" value="11" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_TOP_LEFT_CORNER" value="11" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_TOP_SIDE" value="12" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_TOP_SIDE" value="12" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_TOP_CORNER" value="13" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_TOP_CORNER" value="13" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE" value="14" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_TOP_RIGHT_SIDE" value="14" enum="CellNeighbor">
</constant>
- <constant name="TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER" value="15" enum="CellNeighbor">
+ <constant name="CELL_NEIGHBOR_TOP_RIGHT_CORNER" value="15" enum="CellNeighbor">
</constant>
<constant name="TERRAIN_MODE_MATCH_CORNERS_AND_SIDES" value="0" enum="TerrainMode">
</constant>
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 2a8d4fcded..6c1f1e4852 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -2032,7 +2032,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
if (p_data.size()) {
for (uint32_t i = 0; i < image_create_info.arrayLayers; i++) {
- texture_update(id, i, p_data[i]);
+ _texture_update(id, i, p_data[i], RD::BARRIER_MASK_ALL, true);
}
}
return id;
@@ -2279,10 +2279,14 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
}
Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier) {
+ return _texture_update(p_texture, p_layer, p_data, p_post_barrier, false);
+}
+
+Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier, bool p_use_setup_queue) {
_THREAD_SAFE_METHOD_
- ERR_FAIL_COND_V_MSG(draw_list || compute_list, ERR_INVALID_PARAMETER,
- "Updating textures in is forbidden during creation of a draw or compute list");
+ ERR_FAIL_COND_V_MSG((draw_list || compute_list) && !p_use_setup_queue, ERR_INVALID_PARAMETER,
+ "Updating textures is forbidden during creation of a draw or compute list");
Texture *texture = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!texture, ERR_INVALID_PARAMETER);
@@ -2323,7 +2327,7 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
const uint8_t *r = p_data.ptr();
- VkCommandBuffer command_buffer = p_post_barrier ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
+ VkCommandBuffer command_buffer = p_use_setup_queue ? frames[frame].setup_command_buffer : frames[frame].draw_command_buffer;
//barrier to transfer
{
@@ -2376,7 +2380,7 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
to_allocate >>= get_compressed_image_format_pixel_rshift(texture->format);
uint32_t alloc_offset, alloc_size;
- Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false, p_post_barrier);
+ Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false, !p_use_setup_queue);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
uint8_t *write_ptr;
@@ -5501,6 +5505,13 @@ bool RenderingDeviceVulkan::uniform_set_is_valid(RID p_uniform_set) {
return uniform_set_owner.owns(p_uniform_set);
}
+void RenderingDeviceVulkan::uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata) {
+ UniformSet *us = uniform_set_owner.getornull(p_uniform_set);
+ ERR_FAIL_COND(!us);
+ us->invalidated_callback = p_callback;
+ us->invalidated_callback_userdata = p_userdata;
+}
+
Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier) {
_THREAD_SAFE_METHOD_
@@ -7840,6 +7851,10 @@ void RenderingDeviceVulkan::_free_internal(RID p_id) {
} else if (uniform_set_owner.owns(p_id)) {
UniformSet *uniform_set = uniform_set_owner.getornull(p_id);
frames[frame].uniform_sets_to_dispose_of.push_back(*uniform_set);
+ if (uniform_set->invalidated_callback != nullptr) {
+ uniform_set->invalidated_callback(p_id, uniform_set->invalidated_callback_userdata);
+ }
+
uniform_set_owner.free(p_id);
} else if (render_pipeline_owner.owns(p_id)) {
RenderPipeline *pipeline = render_pipeline_owner.getornull(p_id);
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 1f86fe9e48..ff9ad71268 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -156,6 +156,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t texture_upload_region_size_px = 0;
Vector<uint8_t> _texture_get_data_from_image(Texture *tex, VkImage p_image, VmaAllocation p_allocation, uint32_t p_layer, bool p_2d = false);
+ Error _texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier, bool p_use_setup_queue);
/*****************/
/**** SAMPLER ****/
@@ -731,6 +732,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
LocalVector<AttachableTexture> attachable_textures; //used for validation
Vector<Texture *> mutable_sampled_textures; //used for layout change
Vector<Texture *> mutable_storage_textures; //used for layout change
+ UniformSetInvalidatedCallback invalidated_callback = nullptr;
+ void *invalidated_callback_userdata = nullptr;
};
RID_Owner<UniformSet, true> uniform_set_owner;
@@ -1087,6 +1090,7 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set);
virtual bool uniform_set_is_valid(RID p_uniform_set);
+ virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata);
virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); //works for any buffer
virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 7d6021b0f6..e7c0b02ae2 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -137,6 +137,7 @@
#include "editor/plugins/gpu_particles_3d_editor_plugin.h"
#include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h"
#include "editor/plugins/gradient_editor_plugin.h"
+#include "editor/plugins/input_event_editor_plugin.h"
#include "editor/plugins/item_list_editor_plugin.h"
#include "editor/plugins/light_occluder_2d_editor_plugin.h"
#include "editor/plugins/lightmap_gi_editor_plugin.h"
@@ -3874,6 +3875,21 @@ Ref<ImageTexture> EditorNode::_load_custom_class_icon(const String &p_path) cons
return nullptr;
}
+void EditorNode::_pick_main_scene_custom_action(const String &p_custom_action_name) {
+ if (p_custom_action_name == "select_current") {
+ Node *scene = editor_data.get_edited_scene_root();
+
+ if (!scene) {
+ show_accept(TTR("There is no defined scene to run."), TTR("OK"));
+ return;
+ }
+
+ pick_main_scene->hide();
+ current_option = SETTINGS_PICK_MAIN_SCENE;
+ _dialog_action(scene->get_filename());
+ }
+}
+
Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) const {
ERR_FAIL_COND_V(!p_object || !gui_base, nullptr);
@@ -4668,6 +4684,14 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
current_option = -1;
pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in \"Project Settings\" under the 'application' category."));
pick_main_scene->popup_centered();
+
+ if (editor_data.get_edited_scene_root()) {
+ select_current_scene_button->set_disabled(false);
+ select_current_scene_button->grab_focus();
+ } else {
+ select_current_scene_button->set_disabled(true);
+ }
+
return false;
}
@@ -6816,6 +6840,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(MeshEditorPlugin(this)));
add_editor_plugin(memnew(MaterialEditorPlugin(this)));
add_editor_plugin(memnew(GPUParticlesCollisionSDFEditorPlugin(this)));
+ add_editor_plugin(memnew(InputEventEditorPlugin(this)));
for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) {
add_editor_plugin(EditorPlugins::create(i, this));
@@ -6944,6 +6969,8 @@ EditorNode::EditorNode() {
gui_base->add_child(pick_main_scene);
pick_main_scene->get_ok_button()->set_text(TTR("Select"));
pick_main_scene->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_PICK_MAIN_SCENE));
+ select_current_scene_button = pick_main_scene->add_button(TTR("Select Current"), true, "select_current");
+ pick_main_scene->connect("custom_action", callable_mp(this, &EditorNode::_pick_main_scene_custom_action));
for (int i = 0; i < _init_callbacks.size(); i++) {
_init_callbacks[i]();
diff --git a/editor/editor_node.h b/editor/editor_node.h
index dcb6ad6e94..07bed6999b 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -301,6 +301,7 @@ private:
ConfirmationDialog *save_confirmation;
ConfirmationDialog *import_confirmation;
ConfirmationDialog *pick_main_scene;
+ Button *select_current_scene_button;
AcceptDialog *accept;
EditorAbout *about;
AcceptDialog *warning;
@@ -663,6 +664,8 @@ private:
bool _is_class_editor_disabled_by_feature_profile(const StringName &p_class);
Ref<ImageTexture> _load_custom_class_icon(const String &p_path) const;
+ void _pick_main_scene_custom_action(const String &p_custom_action_name);
+
protected:
void _notification(int p_what);
diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h
index af952eaffc..52ab6d68ee 100644
--- a/editor/editor_vcs_interface.h
+++ b/editor/editor_vcs_interface.h
@@ -46,16 +46,16 @@ protected:
static void _bind_methods();
// Implemented by addons as end points for the proxy functions
- bool _initialize(String p_project_root_path);
- bool _is_vcs_initialized();
- Dictionary _get_modified_files_data();
- void _stage_file(String p_file_path);
- void _unstage_file(String p_file_path);
- void _commit(String p_msg);
- Array _get_file_diff(String p_file_path);
- bool _shut_down();
- String _get_project_name();
- String _get_vcs_name();
+ virtual bool _initialize(String p_project_root_path);
+ virtual bool _is_vcs_initialized();
+ virtual Dictionary _get_modified_files_data();
+ virtual void _stage_file(String p_file_path);
+ virtual void _unstage_file(String p_file_path);
+ virtual void _commit(String p_msg);
+ virtual Array _get_file_diff(String p_file_path);
+ virtual bool _shut_down();
+ virtual String _get_project_name();
+ virtual String _get_vcs_name();
public:
static EditorVCSInterface *get_singleton();
diff --git a/editor/plugins/input_event_editor_plugin.cpp b/editor/plugins/input_event_editor_plugin.cpp
new file mode 100644
index 0000000000..f1aa10844b
--- /dev/null
+++ b/editor/plugins/input_event_editor_plugin.cpp
@@ -0,0 +1,122 @@
+/*************************************************************************/
+/* input_event_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "input_event_editor_plugin.h"
+
+void InputEventConfigContainer::_bind_methods() {
+}
+
+void InputEventConfigContainer::_configure_pressed() {
+ config_dialog->popup_and_configure(input_event);
+}
+
+void InputEventConfigContainer::_event_changed() {
+ input_event_text->set_text(input_event->as_text());
+}
+
+void InputEventConfigContainer::_config_dialog_confirmed() {
+ Ref<InputEvent> ie = config_dialog->get_event();
+ input_event->copy_from(ie);
+ _event_changed();
+}
+
+Size2 InputEventConfigContainer::get_minimum_size() const {
+ // Don't bother with a minimum x size for the control - we don't want the inspector
+ // to jump in size if a long text is placed in the label (e.g. Joypad Axis description)
+ return Size2(0, HBoxContainer::get_minimum_size().y);
+}
+
+void InputEventConfigContainer::set_event(const Ref<InputEvent> &p_event) {
+ Ref<InputEventKey> k = p_event;
+ Ref<InputEventMouseButton> m = p_event;
+ Ref<InputEventJoypadButton> jb = p_event;
+ Ref<InputEventJoypadMotion> jm = p_event;
+
+ if (k.is_valid()) {
+ config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY);
+ } else if (m.is_valid()) {
+ config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_MOUSE_BUTTON);
+ } else if (jb.is_valid()) {
+ config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_JOY_BUTTON);
+ } else if (jm.is_valid()) {
+ config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_JOY_MOTION);
+ }
+
+ input_event = p_event;
+ _event_changed();
+ input_event->connect("changed", callable_mp(this, &InputEventConfigContainer::_event_changed));
+}
+
+InputEventConfigContainer::InputEventConfigContainer() {
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->add_theme_constant_override("margin_left", 10);
+ mc->add_theme_constant_override("margin_right", 10);
+ mc->add_theme_constant_override("margin_top", 10);
+ mc->add_theme_constant_override("margin_bottom", 10);
+ add_child(mc);
+
+ HBoxContainer *hb = memnew(HBoxContainer);
+ mc->add_child(hb);
+
+ open_config_button = memnew(Button);
+ open_config_button->set_text("Configure");
+ open_config_button->connect("pressed", callable_mp(this, &InputEventConfigContainer::_configure_pressed));
+ hb->add_child(open_config_button);
+
+ input_event_text = memnew(Label);
+ hb->add_child(input_event_text);
+
+ config_dialog = memnew(InputEventConfigurationDialog);
+ config_dialog->connect("confirmed", callable_mp(this, &InputEventConfigContainer::_config_dialog_confirmed));
+ add_child(config_dialog);
+}
+
+bool EditorInspectorPluginInputEvent::can_handle(Object *p_object) {
+ Ref<InputEventKey> k = Ref<InputEventKey>(p_object);
+ Ref<InputEventMouseButton> m = Ref<InputEventMouseButton>(p_object);
+ Ref<InputEventJoypadButton> jb = Ref<InputEventJoypadButton>(p_object);
+ Ref<InputEventJoypadMotion> jm = Ref<InputEventJoypadMotion>(p_object);
+
+ return k.is_valid() || m.is_valid() || jb.is_valid() || jm.is_valid();
+}
+
+void EditorInspectorPluginInputEvent::parse_begin(Object *p_object) {
+ Ref<InputEvent> ie = Ref<InputEvent>(p_object);
+
+ InputEventConfigContainer *picker_controls = memnew(InputEventConfigContainer);
+ picker_controls->set_event(ie);
+ add_custom_control(picker_controls);
+}
+
+InputEventEditorPlugin::InputEventEditorPlugin(EditorNode *p_node) {
+ Ref<EditorInspectorPluginInputEvent> plugin;
+ plugin.instantiate();
+ add_inspector_plugin(plugin);
+}
diff --git a/editor/plugins/input_event_editor_plugin.h b/editor/plugins/input_event_editor_plugin.h
new file mode 100644
index 0000000000..bc8293c9e5
--- /dev/null
+++ b/editor/plugins/input_event_editor_plugin.h
@@ -0,0 +1,79 @@
+/*************************************************************************/
+/* input_event_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef INPUT_EVENT_EDITOR_PLUGIN_H
+#define INPUT_EVENT_EDITOR_PLUGIN_H
+
+#include "editor/action_map_editor.h"
+#include "editor/editor_inspector.h"
+#include "editor/editor_node.h"
+
+class InputEventConfigContainer : public HBoxContainer {
+ GDCLASS(InputEventConfigContainer, HBoxContainer);
+
+ Label *input_event_text;
+ Button *open_config_button;
+
+ Ref<InputEvent> input_event;
+ InputEventConfigurationDialog *config_dialog;
+
+ void _config_dialog_confirmed();
+ void _configure_pressed();
+
+ void _event_changed();
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual Size2 get_minimum_size() const override;
+ void set_event(const Ref<InputEvent> &p_event);
+
+ InputEventConfigContainer();
+};
+
+class EditorInspectorPluginInputEvent : public EditorInspectorPlugin {
+ GDCLASS(EditorInspectorPluginInputEvent, EditorInspectorPlugin);
+
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual void parse_begin(Object *p_object) override;
+};
+
+class InputEventEditorPlugin : public EditorPlugin {
+ GDCLASS(InputEventEditorPlugin, EditorPlugin);
+
+public:
+ virtual String get_name() const override { return "InputEvent"; }
+
+ InputEventEditorPlugin(EditorNode *p_node);
+};
+
+#endif // INPUT_EVENT_EDITOR_PLUGIN_H
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 98a36307b8..a7177faafa 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -2511,15 +2511,15 @@ void Node3DEditorViewport::_notification(int p_what) {
}
if (show_info) {
+ const String viewport_size = vformat(String::utf8("%d × %d"), viewport->get_size().x, viewport->get_size().y);
String text;
text += vformat(TTR("X: %s\n"), rtos(current_camera->get_position().x).pad_decimals(1));
text += vformat(TTR("Y: %s\n"), rtos(current_camera->get_position().y).pad_decimals(1));
text += vformat(TTR("Z: %s\n"), rtos(current_camera->get_position().z).pad_decimals(1));
text += "\n";
text += vformat(
- TTR("Size: %dx%d (%.1fMP)\n"),
- viewport->get_size().x,
- viewport->get_size().y,
+ TTR("Size: %s (%.1fMP)\n"),
+ viewport_size,
viewport->get_size().x * viewport->get_size().y * 0.000001);
text += "\n";
@@ -6223,8 +6223,9 @@ void Node3DEditor::_add_sun_to_scene() {
Node *base = get_tree()->get_edited_scene_root();
if (!base) {
- EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation"));
- return;
+ // Create a root node so we can add child nodes to it.
+ EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D));
+ base = get_tree()->get_edited_scene_root();
}
ERR_FAIL_COND(!base);
Node *new_sun = preview_sun->duplicate();
@@ -6241,8 +6242,9 @@ void Node3DEditor::_add_environment_to_scene() {
Node *base = get_tree()->get_edited_scene_root();
if (!base) {
- EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation"));
- return;
+ // Create a root node so we can add child nodes to it.
+ EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D));
+ base = get_tree()->get_edited_scene_root();
}
ERR_FAIL_COND(!base);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 1183da4d04..94863bf722 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -888,6 +888,7 @@ void VisualShaderGraphPlugin::remove_node(VisualShader::Type p_type, int p_id) {
void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
if (visual_shader->get_shader_type() == p_type) {
VisualShaderEditor::get_singleton()->graph->connect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port);
+ connections.push_back({ p_from_node, p_from_port, p_to_node, p_to_port });
if (links[p_to_node].input_ports.has(p_to_port) && links[p_to_node].input_ports[p_to_port].default_input_button != nullptr) {
links[p_to_node].input_ports[p_to_port].default_input_button->hide();
}
@@ -897,6 +898,12 @@ void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_fro
void VisualShaderGraphPlugin::disconnect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
if (visual_shader->get_shader_type() == p_type) {
VisualShaderEditor::get_singleton()->graph->disconnect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port);
+ for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
+ if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
+ connections.erase(E);
+ break;
+ }
+ }
if (links[p_to_node].input_ports.has(p_to_port) && links[p_to_node].input_ports[p_to_port].default_input_button != nullptr && links[p_to_node].visual_node->get_input_port_default_value(p_to_port).get_type() != Variant::NIL) {
links[p_to_node].input_ports[p_to_port].default_input_button->show();
set_input_port_default_value(p_type, p_to_node, p_to_port, links[p_to_node].visual_node->get_input_port_default_value(p_to_port));
diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp
index d30cc7ad17..162379a49d 100644
--- a/editor/plugins/voxel_gi_editor_plugin.cpp
+++ b/editor/plugins/voxel_gi_editor_plugin.cpp
@@ -69,10 +69,7 @@ void VoxelGIEditorPlugin::_notification(int p_what) {
const Vector3i size = voxel_gi->get_estimated_cell_size();
String text = vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z);
- int data_size = 4;
- if (GLOBAL_GET("rendering/quality/voxel_gi/anisotropic")) {
- data_size += 4;
- }
+ const int data_size = 4;
const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0);
text += " - " + vformat(TTR("VRAM Size: %s MB"), String::num(size_mb, 2));
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 262861cb11..3f66f1f375 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -359,7 +359,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
- if (reset_create_dialog) {
+ if (reset_create_dialog && !p_confirm_override) {
create_dialog->set_base_type("Node");
reset_create_dialog = false;
}
@@ -1134,12 +1134,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
- editor_data->get_undo_redo().create_action(TTR("New Scene Root"));
- editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", new_node);
- editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
- editor_data->get_undo_redo().add_do_reference(new_node);
- editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)nullptr);
- editor_data->get_undo_redo().commit_action();
+ add_root_node(new_node);
editor->edit_node(new_node);
editor_selection->clear();
@@ -1162,6 +1157,15 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
+void SceneTreeDock::add_root_node(Node *p_node) {
+ editor_data->get_undo_redo().create_action(TTR("New Scene Root"));
+ editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", p_node);
+ editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
+ editor_data->get_undo_redo().add_do_reference(p_node);
+ editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)nullptr);
+ editor_data->get_undo_redo().commit_action();
+}
+
void SceneTreeDock::_node_collapsed(Object *p_obj) {
TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
if (!ti) {
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 88c4a85f4c..08d992d465 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -261,6 +261,7 @@ public:
void _focus_node();
void import_subscene();
+ void add_root_node(Node *p_node);
void set_edited_scene(Node *p_scene);
void instantiate(const String &p_file);
void instantiate_scenes(const Vector<String> &p_files, Node *p_parent = nullptr);
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 8ce823ac9b..fd8b213293 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -868,7 +868,7 @@ void CSGMesh3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_material"), &CSGMesh3D::get_material);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
void CSGMesh3D::set_mesh(const Ref<Mesh> &p_mesh) {
@@ -1027,7 +1027,7 @@ void CSGSphere3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
void CSGSphere3D::set_radius(const float p_radius) {
@@ -1197,7 +1197,7 @@ void CSGBox3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_material"), &CSGBox3D::get_material);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
void CSGBox3D::set_size(const Vector3 &p_size) {
@@ -1378,7 +1378,7 @@ void CSGCylinder3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_sides", "get_sides");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cone"), "set_cone", "is_cone");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
void CSGCylinder3D::set_radius(const float p_radius) {
@@ -1597,7 +1597,7 @@ void CSGTorus3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_sides", "get_sides");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ring_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_ring_sides", "get_ring_sides");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
void CSGTorus3D::set_inner_radius(const float p_inner_radius) {
@@ -2234,7 +2234,7 @@ void CSGPolygon3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_continuous_u"), "set_path_continuous_u", "is_path_continuous_u");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_joined"), "set_path_joined", "is_path_joined");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
BIND_ENUM_CONSTANT(MODE_DEPTH);
BIND_ENUM_CONSTANT(MODE_SPIN);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
index 1ed16e04ca..89497d1526 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -96,14 +96,6 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God
}
}
- @Override
- public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
- if (godotFragment != null && godotFragment.onKeyMultiple(inKeyCode, repeatCount, event)) {
- return true;
- }
- return super.onKeyMultiple(inKeyCode, repeatCount, event);
- }
-
/**
* Used to initialize the Godot fragment instance in {@link FullScreenGodotApp#onCreate(Bundle)}.
*/
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index d66d7fde4b..8ffa4a9249 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -279,29 +279,20 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
editText.setView(mRenderView);
io.setEdit(editText);
- view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- Point fullSize = new Point();
- activity.getWindowManager().getDefaultDisplay().getSize(fullSize);
- Rect gameSize = new Rect();
- mRenderView.getView().getWindowVisibleDisplayFrame(gameSize);
-
- final int keyboardHeight = fullSize.y - gameSize.bottom;
- GodotLib.setVirtualKeyboardHeight(keyboardHeight);
- }
+ view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
+ Point fullSize = new Point();
+ activity.getWindowManager().getDefaultDisplay().getSize(fullSize);
+ Rect gameSize = new Rect();
+ mRenderView.getView().getWindowVisibleDisplayFrame(gameSize);
+ final int keyboardHeight = fullSize.y - gameSize.bottom;
+ GodotLib.setVirtualKeyboardHeight(keyboardHeight);
});
- mRenderView.queueOnRenderThread(new Runnable() {
- @Override
- public void run() {
- // Must occur after GodotLib.setup has completed.
- for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
- plugin.onRegisterPluginWithGodotNative();
- }
-
- setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")));
+ mRenderView.queueOnRenderThread(() -> {
+ for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
+ plugin.onRegisterPluginWithGodotNative();
}
+ setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")));
});
// Include the returned non-null views in the Godot view hierarchy.
@@ -314,14 +305,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
public void setKeepScreenOn(final boolean p_enabled) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (p_enabled) {
- getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- } else {
- getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- }
+ runOnUiThread(() -> {
+ if (p_enabled) {
+ getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ } else {
+ getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
@@ -368,21 +356,14 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
public void alert(final String message, final String title) {
final Activity activity = getActivity();
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setMessage(message).setTitle(title);
- builder.setPositiveButton(
- "OK",
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
- AlertDialog dialog = builder.create();
- dialog.show();
- }
+ runOnUiThread(() -> {
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setMessage(message).setTitle(title);
+ builder.setPositiveButton(
+ "OK",
+ (dialog, id) -> dialog.cancel());
+ AlertDialog dialog = builder.create();
+ dialog.show();
});
}
@@ -753,19 +734,16 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
public void UiChangeListener() {
final View decorView = getActivity().getWindow().getDecorView();
- decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
- @Override
- public void onSystemUiVisibilityChange(int visibility) {
- if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- decorView.setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
- View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
- View.SYSTEM_UI_FLAG_FULLSCREEN |
- View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
- }
+ decorView.setOnSystemUiVisibilityChangeListener(visibility -> {
+ if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ decorView.setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
});
@@ -796,21 +774,18 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
final int typeOfSensor = event.sensor.getType();
if (mRenderView != null) {
- mRenderView.queueOnRenderThread(new Runnable() {
- @Override
- public void run() {
- if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) {
- GodotLib.accelerometer(-x, y, -z);
- }
- if (typeOfSensor == Sensor.TYPE_GRAVITY) {
- GodotLib.gravity(-x, y, -z);
- }
- if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) {
- GodotLib.magnetometer(-x, y, -z);
- }
- if (typeOfSensor == Sensor.TYPE_GYROSCOPE) {
- GodotLib.gyroscope(x, -y, z);
- }
+ mRenderView.queueOnRenderThread(() -> {
+ if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) {
+ GodotLib.accelerometer(-x, y, -z);
+ }
+ if (typeOfSensor == Sensor.TYPE_GRAVITY) {
+ GodotLib.gravity(-x, y, -z);
+ }
+ if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) {
+ GodotLib.magnetometer(-x, y, -z);
+ }
+ if (typeOfSensor == Sensor.TYPE_GYROSCOPE) {
+ GodotLib.gyroscope(x, -y, z);
}
});
}
@@ -845,12 +820,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
if (shouldQuit && mRenderView != null) {
- mRenderView.queueOnRenderThread(new Runnable() {
- @Override
- public void run() {
- GodotLib.back();
- }
- });
+ mRenderView.queueOnRenderThread(GodotLib::back);
}
}
@@ -916,33 +886,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
}
- public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
- String s = event.getCharacters();
- if (s == null || s.length() == 0)
- return false;
-
- final char[] cc = s.toCharArray();
- int cnt = 0;
- for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0)
- ;
- if (cnt == 0)
- return false;
- mRenderView.queueOnRenderThread(new Runnable() {
- // This method will be called on the rendering thread:
- public void run() {
- for (int i = 0, n = cc.length; i < n; i++) {
- int keyCode;
- if ((keyCode = cc[i]) != 0) {
- // Simulate key down and up...
- GodotLib.key(0, 0, keyCode, true);
- GodotLib.key(0, 0, keyCode, false);
- }
- }
- }
- });
- return true;
- }
-
public boolean requestPermission(String p_name) {
return PermissionsUtil.requestPermission(p_name, getActivity());
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index b3ee55ea64..a9d45c943b 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -232,13 +232,10 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
public void onResume() {
super.onResume();
- queueEvent(new Runnable() {
- @Override
- public void run() {
- // Resume the renderer
- godotRenderer.onActivityResumed();
- GodotLib.focusin();
- }
+ queueEvent(() -> {
+ // Resume the renderer
+ godotRenderer.onActivityResumed();
+ GodotLib.focusin();
});
}
@@ -246,13 +243,10 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
public void onPause() {
super.onPause();
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.focusout();
- // Pause the renderer
- godotRenderer.onActivityPaused();
- }
+ queueEvent(() -> {
+ GodotLib.focusout();
+ // Pause the renderer
+ godotRenderer.onActivityPaused();
});
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
index 356ad7c770..6fca7f2a57 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -149,13 +149,10 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV
public void onResume() {
super.onResume();
- queueOnVkThread(new Runnable() {
- @Override
- public void run() {
- // Resume the renderer
- mRenderer.onVkResume();
- GodotLib.focusin();
- }
+ queueOnVkThread(() -> {
+ // Resume the renderer
+ mRenderer.onVkResume();
+ GodotLib.focusin();
});
}
@@ -163,13 +160,10 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV
public void onPause() {
super.onPause();
- queueOnVkThread(new Runnable() {
- @Override
- public void run() {
- GodotLib.focusout();
- // Pause the renderer
- mRenderer.onVkPause();
- }
+ queueOnVkThread(() -> {
+ GodotLib.focusout();
+ // Pause the renderer
+ mRenderer.onVkPause();
});
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
index 2c39d06832..1d60c21c60 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -75,12 +75,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
final int x = Math.round(event.getX());
final int y = Math.round(event.getY());
final int buttonMask = event.getButtonState();
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.doubleTap(buttonMask, x, y);
- }
- });
+ queueEvent(() -> GodotLib.doubleTap(buttonMask, x, y));
return true;
}
@@ -89,12 +84,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
//Log.i("GodotGesture", "onScroll");
final int x = Math.round(distanceX);
final int y = Math.round(distanceY);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.scroll(x, y);
- }
- });
+ queueEvent(() -> GodotLib.scroll(x, y));
return true;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index e8dcc5a4bc..4dc9157545 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -97,22 +97,12 @@ public class GodotInputHandler implements InputDeviceListener {
final int button = getGodotButton(keyCode);
final int godotJoyId = mJoystickIds.get(deviceId);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joybutton(godotJoyId, button, false);
- }
- });
+ queueEvent(() -> GodotLib.joybutton(godotJoyId, button, false));
}
} else {
final int scanCode = event.getScanCode();
final int chr = event.getUnicodeChar(0);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.key(keyCode, scanCode, chr, false);
- }
- });
+ queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, false));
}
return true;
@@ -143,22 +133,12 @@ public class GodotInputHandler implements InputDeviceListener {
final int button = getGodotButton(keyCode);
final int godotJoyId = mJoystickIds.get(deviceId);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joybutton(godotJoyId, button, true);
- }
- });
+ queueEvent(() -> GodotLib.joybutton(godotJoyId, button, true));
}
} else {
final int scanCode = event.getScanCode();
final int chr = event.getUnicodeChar(0);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.key(keyCode, scanCode, chr, true);
- }
- });
+ queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, true));
}
return true;
@@ -190,19 +170,16 @@ public class GodotInputHandler implements InputDeviceListener {
final int action = event.getActionMasked();
final int pointer_idx = event.getPointerId(event.getActionIndex());
- mRenderView.queueOnRenderThread(new Runnable() {
- @Override
- public void run() {
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_MOVE:
- case MotionEvent.ACTION_POINTER_UP:
- case MotionEvent.ACTION_POINTER_DOWN: {
- GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr);
- } break;
- }
+ mRenderView.queueOnRenderThread(() -> {
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_MOVE:
+ case MotionEvent.ACTION_POINTER_UP:
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr);
+ } break;
}
});
}
@@ -228,13 +205,7 @@ public class GodotInputHandler implements InputDeviceListener {
// save value to prevent repeats
joystick.axesValues.put(axis, value);
final int godotAxisIdx = i;
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyaxis(godotJoyId, godotAxisIdx, value);
- //Log.i(tag, "GodotLib.joyaxis("+godotJoyId+", "+godotAxisIdx+", "+value+");");
- }
- });
+ queueEvent(() -> GodotLib.joyaxis(godotJoyId, godotAxisIdx, value));
}
}
@@ -244,13 +215,7 @@ public class GodotInputHandler implements InputDeviceListener {
if (joystick.hatX != hatX || joystick.hatY != hatY) {
joystick.hatX = hatX;
joystick.hatY = hatY;
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyhat(godotJoyId, hatX, hatY);
- //Log.i(tag, "GodotLib.joyhat("+godotJoyId+", "+hatX+", "+hatY+");");
- }
- });
+ queueEvent(() -> GodotLib.joyhat(godotJoyId, hatX, hatY));
}
}
return true;
@@ -259,12 +224,7 @@ public class GodotInputHandler implements InputDeviceListener {
final float x = event.getX();
final float y = event.getY();
final int type = event.getAction();
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.hover(type, x, y);
- }
- });
+ queueEvent(() -> GodotLib.hover(type, x, y));
return true;
} else if (event.isFromSource(InputDevice.SOURCE_MOUSE) || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) {
@@ -356,12 +316,7 @@ public class GodotInputHandler implements InputDeviceListener {
}
mJoysticksDevices.put(deviceId, joystick);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyconnectionchanged(id, true, joystick.name);
- }
- });
+ queueEvent(() -> GodotLib.joyconnectionchanged(id, true, joystick.name));
}
@Override
@@ -374,12 +329,7 @@ public class GodotInputHandler implements InputDeviceListener {
mJoystickIds.delete(deviceId);
mJoysticksDevices.delete(deviceId);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyconnectionchanged(godotJoyId, false, "");
- }
- });
+ queueEvent(() -> GodotLib.joyconnectionchanged(godotJoyId, false, ""));
}
@Override
@@ -468,12 +418,7 @@ public class GodotInputHandler implements InputDeviceListener {
final float x = event.getX();
final float y = event.getY();
final int type = event.getAction();
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.hover(type, x, y);
- }
- });
+ queueEvent(() -> GodotLib.hover(type, x, y));
return true;
}
case MotionEvent.ACTION_BUTTON_PRESS:
@@ -483,12 +428,7 @@ public class GodotInputHandler implements InputDeviceListener {
final float y = event.getY();
final int buttonsMask = event.getButtonState();
final int action = event.getAction();
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask);
- }
- });
+ queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask));
return true;
}
case MotionEvent.ACTION_SCROLL: {
@@ -498,12 +438,7 @@ public class GodotInputHandler implements InputDeviceListener {
final int action = event.getAction();
final float verticalFactor = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
final float horizontalFactor = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor);
- }
- });
+ queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor));
}
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP: {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index 3e0e6a65fd..020870a110 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -94,17 +94,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) {
//Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after);
- mRenderView.queueOnRenderThread(new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < count; ++i) {
- GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true);
- GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false);
-
- if (mHasSelection) {
- mHasSelection = false;
- break;
- }
+ mRenderView.queueOnRenderThread(() -> {
+ for (int i = 0; i < count; ++i) {
+ GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true);
+ GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false);
+
+ if (mHasSelection) {
+ mHasSelection = false;
+ break;
}
}
});
@@ -118,18 +115,15 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
for (int i = start; i < start + count; ++i) {
newChars[i - start] = pCharSequence.charAt(i);
}
- mRenderView.queueOnRenderThread(new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < count; ++i) {
- int key = newChars[i];
- if ((key == '\n') && !mEdit.isMultiline()) {
- // Return keys are handled through action events
- continue;
- }
- GodotLib.key(0, 0, key, true);
- GodotLib.key(0, 0, key, false);
+ mRenderView.queueOnRenderThread(() -> {
+ for (int i = 0; i < count; ++i) {
+ int key = newChars[i];
+ if ((key == '\n') && !mEdit.isMultiline()) {
+ // Return keys are handled through action events
+ continue;
}
+ GodotLib.key(0, 0, key, true);
+ GodotLib.key(0, 0, key, false);
}
});
}
@@ -139,23 +133,21 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
if (mEdit == pTextView && isFullScreenEdit()) {
final String characters = pKeyEvent.getCharacters();
- mRenderView.queueOnRenderThread(new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < characters.length(); i++) {
- final int ch = characters.codePointAt(i);
- GodotLib.key(0, 0, ch, true);
- GodotLib.key(0, 0, ch, false);
- }
+ mRenderView.queueOnRenderThread(() -> {
+ for (int i = 0; i < characters.length(); i++) {
+ final int ch = characters.codePointAt(i);
+ GodotLib.key(0, 0, ch, true);
+ GodotLib.key(0, 0, ch, false);
}
});
}
if (pActionID == EditorInfo.IME_ACTION_DONE) {
// Enter key has been pressed
- GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true);
- GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false);
-
+ mRenderView.queueOnRenderThread(() -> {
+ GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true);
+ GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false);
+ });
mRenderView.getView().requestFocus();
return true;
}
diff --git a/platform/javascript/javascript_singleton.cpp b/platform/javascript/javascript_singleton.cpp
index 9de2edc9a7..1dd73ef8e9 100644
--- a/platform/javascript/javascript_singleton.cpp
+++ b/platform/javascript/javascript_singleton.cpp
@@ -183,7 +183,7 @@ Variant JavaScriptObjectImpl::_js2variant(int p_type, godot_js_wrapper_ex *p_val
case Variant::FLOAT:
return p_val->r;
case Variant::STRING: {
- String out((const char *)p_val->p);
+ String out = String::utf8((const char *)p_val->p);
free(p_val->p);
return out;
}
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index 08dec232ab..279a1fb7de 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -100,7 +100,7 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
if (mesh.is_valid()) {
for (int i = 0; i < mesh->get_surface_count(); i++) {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_material_override/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_material_override/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE));
}
}
}
diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp
index b0b9668fd2..7b736e689c 100644
--- a/scene/3d/occluder_instance_3d.cpp
+++ b/scene/3d/occluder_instance_3d.cpp
@@ -174,10 +174,12 @@ void OccluderInstance3D::set_occluder(const Ref<Occluder3D> &p_occluder) {
}
update_gizmo();
+ update_configuration_warnings();
}
void OccluderInstance3D::_occluder_changed() {
update_gizmo();
+ update_configuration_warnings();
}
Ref<Occluder3D> OccluderInstance3D::get_occluder() const {
@@ -186,6 +188,7 @@ Ref<Occluder3D> OccluderInstance3D::get_occluder() const {
void OccluderInstance3D::set_bake_mask(uint32_t p_mask) {
bake_mask = p_mask;
+ update_configuration_warnings();
}
uint32_t OccluderInstance3D::get_bake_mask() const {
@@ -314,6 +317,31 @@ OccluderInstance3D::BakeError OccluderInstance3D::bake(Node *p_from_node, String
return BAKE_ERROR_OK;
}
+TypedArray<String> OccluderInstance3D::get_configuration_warnings() const {
+ TypedArray<String> warnings = Node::get_configuration_warnings();
+
+ if (!bool(GLOBAL_GET("rendering/occlusion_culling/use_occlusion_culling"))) {
+ warnings.push_back(TTR("Occlusion culling is disabled in the Project Settings, which means occlusion culling won't be performed in the root viewport.\nTo resolve this, open the Project Settings and enable Rendering > Occlusion Culling > Use Occlusion Culling."));
+ }
+
+ if (bake_mask == 0) {
+ // NOTE: This warning will not be emitted if none of the 20 checkboxes
+ // exposed in the editor are checked. This is because there are
+ // currently 12 unexposed layers in the editor inspector.
+ warnings.push_back(TTR("The Bake Mask has no bits enabled, which means baking will not produce any occluder meshes for this OccluderInstance3D.\nTo resolve this, enable at least one bit in the Bake Mask property."));
+ }
+
+ if (occluder.is_null()) {
+ warnings.push_back(TTR("No occluder mesh is defined in the Occluder property, so no occlusion culling will be performed using this OccluderInstance3D.\nTo resolve this, select the OccluderInstance3D then use the Bake Occluders button at the top of the 3D editor viewport."));
+ } else if (occluder->get_vertices().size() < 3) {
+ // Using the "New Occluder" dropdown button won't result in a correct occluder,
+ // so warn the user about this.
+ warnings.push_back(TTR("The occluder mesh has less than 3 vertices, so no occlusion culling will be performed using this OccluderInstance3D.\nTo generate a proper occluder mesh, select the OccluderInstance3D then use the Bake Occluders button at the top of the 3D editor viewport."));
+ }
+
+ return warnings;
+}
+
void OccluderInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bake_mask", "mask"), &OccluderInstance3D::set_bake_mask);
ClassDB::bind_method(D_METHOD("get_bake_mask"), &OccluderInstance3D::get_bake_mask);
diff --git a/scene/3d/occluder_instance_3d.h b/scene/3d/occluder_instance_3d.h
index 4bb468274d..d382cd090e 100644
--- a/scene/3d/occluder_instance_3d.h
+++ b/scene/3d/occluder_instance_3d.h
@@ -82,6 +82,8 @@ protected:
static void _bind_methods();
public:
+ virtual TypedArray<String> get_configuration_warnings() const override;
+
enum BakeError {
BAKE_ERROR_OK,
BAKE_ERROR_NO_SAVE_PATH,
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index 471dc03d62..bd47af8100 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -293,7 +293,12 @@ void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform
instance_uniforms.erase(p_value);
} else {
instance_uniforms[p_uniform] = p_value;
- RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, p_value);
+ if (p_value.get_type() == Variant::OBJECT) {
+ RID tex_id = p_value;
+ RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, tex_id);
+ } else {
+ RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, p_value);
+ }
}
}
@@ -389,7 +394,7 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_aabb"), &GeometryInstance3D::get_aabb);
ADD_GROUP("Geometry", "");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override", "get_material_override");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override", "get_material_override");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01"), "set_extra_cull_margin", "get_extra_cull_margin");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_bias", PROPERTY_HINT_RANGE, "0.001,128,0.001"), "set_lod_bias", "get_lod_bias");
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 049de4c8c5..659d14ae70 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -40,6 +40,8 @@
#endif
#include "scene/main/window.h"
+List<Color> ColorPicker::preset_cache;
+
void ColorPicker::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
@@ -57,11 +59,17 @@ void ColorPicker::_notification(int p_what) {
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
- PackedColorArray saved_presets = EditorSettings::get_singleton()->get_project_metadata("color_picker", "presets", PackedColorArray());
+ if (preset_cache.is_empty()) {
+ PackedColorArray saved_presets = EditorSettings::get_singleton()->get_project_metadata("color_picker", "presets", PackedColorArray());
+ for (int i = 0; i < saved_presets.size(); i++) {
+ preset_cache.push_back(saved_presets[i]);
+ }
+ }
- for (int i = 0; i < saved_presets.size(); i++) {
- add_preset(saved_presets[i]);
+ for (int i = 0; i < preset_cache.size(); i++) {
+ presets.push_back(preset_cache[i]);
}
+ preset->update();
}
#endif
} break;
@@ -413,6 +421,7 @@ void ColorPicker::add_preset(const Color &p_color) {
presets.move_to_back(presets.find(p_color));
} else {
presets.push_back(p_color);
+ preset_cache.push_back(p_color);
}
preset->update();
@@ -427,6 +436,7 @@ void ColorPicker::add_preset(const Color &p_color) {
void ColorPicker::erase_preset(const Color &p_color) {
if (presets.find(p_color)) {
presets.erase(presets.find(p_color));
+ preset_cache.erase(preset_cache.find(p_color));
preset->update();
#ifdef TOOLS_ENABLED
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 3bd2ff9375..60da3957aa 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -58,6 +58,7 @@ public:
private:
static Ref<Shader> wheel_shader;
static Ref<Shader> circle_shader;
+ static List<Color> preset_cache;
Control *screen = nullptr;
Control *uv_edit = memnew(Control);
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index f63ae7569f..dceab00607 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -263,6 +263,28 @@ Button *AcceptDialog::add_cancel_button(const String &p_cancel) {
return b;
}
+void AcceptDialog::remove_button(Control *p_button) {
+ Button *button = Object::cast_to<Button>(p_button);
+ ERR_FAIL_NULL(button);
+ ERR_FAIL_COND_MSG(button->get_parent() != hbc, vformat("Cannot remove button %s as it does not belong to this dialog.", button->get_name()));
+ ERR_FAIL_COND_MSG(button == ok, "Cannot remove dialog's OK button.");
+
+ Node *right_spacer = hbc->get_child(button->get_index() + 1);
+ // Should always be valid but let's avoid crashing
+ if (right_spacer) {
+ hbc->remove_child(right_spacer);
+ memdelete(right_spacer);
+ }
+ hbc->remove_child(button);
+
+ if (button->is_connected("pressed", callable_mp(this, &AcceptDialog::_custom_action))) {
+ button->disconnect("pressed", callable_mp(this, &AcceptDialog::_custom_action));
+ }
+ if (button->is_connected("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed))) {
+ button->disconnect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
+ }
+}
+
void AcceptDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_ok_button"), &AcceptDialog::get_ok_button);
ClassDB::bind_method(D_METHOD("get_label"), &AcceptDialog::get_label);
@@ -270,6 +292,7 @@ void AcceptDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_hide_on_ok"), &AcceptDialog::get_hide_on_ok);
ClassDB::bind_method(D_METHOD("add_button", "text", "right", "action"), &AcceptDialog::add_button, DEFVAL(false), DEFVAL(""));
ClassDB::bind_method(D_METHOD("add_cancel_button", "name"), &AcceptDialog::add_cancel_button);
+ ClassDB::bind_method(D_METHOD("remove_button", "button"), &AcceptDialog::remove_button);
ClassDB::bind_method(D_METHOD("register_text_enter", "line_edit"), &AcceptDialog::register_text_enter);
ClassDB::bind_method(D_METHOD("set_text", "text"), &AcceptDialog::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &AcceptDialog::get_text);
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index d389806fff..8e803a2a7c 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -82,6 +82,7 @@ public:
Button *get_ok_button() { return ok; }
Button *add_button(const String &p_text, bool p_right = false, const String &p_action = "");
Button *add_cancel_button(const String &p_cancel = "");
+ void remove_button(Control *p_button);
void set_hide_on_ok(bool p_hide);
bool get_hide_on_ok() const;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 089893e63b..f2d0d9bb22 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1470,19 +1470,23 @@ int LineEdit::get_scroll_offset() const {
}
void LineEdit::insert_text_at_caret(String p_text) {
- if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) {
- String pre = text.substr(0, caret_column);
- String post = text.substr(caret_column, text.length() - caret_column);
- text = pre + p_text + post;
- _shape();
- TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, caret_column, caret_column + p_text.length());
- if (dir != TextServer::DIRECTION_AUTO) {
- input_direction = (TextDirection)dir;
+ if (max_length > 0) {
+ // Truncate text to append to fit in max_length, if needed.
+ int available_chars = max_length - text.length();
+ if (p_text.length() > available_chars) {
+ emit_signal("text_change_rejected", p_text.substr(available_chars));
+ p_text = p_text.substr(0, available_chars);
}
- set_caret_column(caret_column + p_text.length());
- } else {
- emit_signal("text_change_rejected");
}
+ String pre = text.substr(0, caret_column);
+ String post = text.substr(caret_column, text.length() - caret_column);
+ text = pre + p_text + post;
+ _shape();
+ TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, caret_column, caret_column + p_text.length());
+ if (dir != TextServer::DIRECTION_AUTO) {
+ input_direction = (TextDirection)dir;
+ }
+ set_caret_column(caret_column + p_text.length());
}
void LineEdit::clear_internal() {
@@ -2158,7 +2162,7 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon);
ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text")));
- ADD_SIGNAL(MethodInfo("text_change_rejected"));
+ ADD_SIGNAL(MethodInfo("text_change_rejected", PropertyInfo(Variant::STRING, "rejected_substring")));
ADD_SIGNAL(MethodInfo("text_submitted", PropertyInfo(Variant::STRING, "new_text")));
BIND_ENUM_CONSTANT(ALIGN_LEFT);
@@ -2198,7 +2202,7 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length"), "set_max_length", "get_max_length");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_max_length", "get_max_length");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "secret_character"), "set_secret_character", "get_secret_character");
@@ -2221,7 +2225,7 @@ void LineEdit::_bind_methods() {
ADD_GROUP("Caret", "caret_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "set_caret_blink_speed", "get_caret_blink_speed");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_column"), "set_caret_column", "get_caret_column");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_column", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_caret_column", "get_caret_column");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_force_displayed"), "set_caret_force_displayed", "is_caret_force_displayed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled");
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 370fdd8b88..6f96b530a6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -4008,14 +4008,6 @@ bool TextEdit::is_wrap_enabled() const {
return wrap_enabled;
}
-void TextEdit::set_max_chars(int p_max_chars) {
- max_chars = p_max_chars;
-}
-
-int TextEdit::get_max_chars() const {
- return max_chars;
-}
-
void TextEdit::_reset_caret_blink_timer() {
if (caret_blink_enabled) {
draw_caret = true;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 146de50275..dcd5c6d0f8 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -258,7 +258,6 @@ private:
uint32_t version = 0;
uint32_t saved_version = 0;
- int max_chars = 0;
bool readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly.
Timer *caret_blink_timer;
@@ -678,9 +677,6 @@ public:
void set_readonly(bool p_readonly);
bool is_readonly() const;
- void set_max_chars(int p_max_chars);
- int get_max_chars() const;
-
void set_wrap_enabled(bool p_wrap_enabled);
bool is_wrap_enabled() const;
bool line_wraps(int line) const;
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index fd9e87604f..98de71d81c 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2155,6 +2155,10 @@ void Tree::_range_click_timeout() {
}
}
+ if (!root) {
+ return;
+ }
+
click_handled = false;
Ref<InputEventMouseButton> mb;
mb.instantiate();
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index db55f4feb7..f81a3ef630 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -1227,7 +1227,7 @@ void CanvasItem::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Inherit,Disabled,Enabled,Mirror"), "set_texture_repeat", "get_texture_repeat");
ADD_GROUP("Material", "");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial,ShaderMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),"set_transform_notify","is_transform_notify_enabled");
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index ac092d9862..ef6d2e72f6 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2493,7 +2493,9 @@ String Node::get_configuration_warnings_as_string() const {
if (i > 0) {
all_warnings += "\n\n";
}
- all_warnings += String(warnings[i]);
+ // Format as a bullet point list to make multiple warnings easier to distinguish
+ // from each other.
+ all_warnings += String::utf8("• ") + String(warnings[i]);
}
return all_warnings;
}
diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp
index 3d65c12cb7..d22a6b2875 100644
--- a/scene/main/shader_globals_override.cpp
+++ b/scene/main/shader_globals_override.cpp
@@ -63,7 +63,12 @@ bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_valu
if (o) {
o->override = p_value;
if (active) {
- RS::get_singleton()->global_variable_set_override(*r, p_value);
+ if (o->override.get_type() == Variant::OBJECT) {
+ RID tex_rid = p_value;
+ RS::get_singleton()->global_variable_set_override(*r, tex_rid);
+ } else {
+ RS::get_singleton()->global_variable_set_override(*r, p_value);
+ }
}
o->in_use = p_value.get_type() != Variant::NIL;
return true;
@@ -228,7 +233,12 @@ void ShaderGlobalsOverride::_activate() {
while ((K = overrides.next(K))) {
Override *o = overrides.getptr(*K);
if (o->in_use && o->override.get_type() != Variant::NIL) {
- RS::get_singleton()->global_variable_set_override(*K, o->override);
+ if (o->override.get_type() == Variant::OBJECT) {
+ RID tex_rid = o->override;
+ RS::get_singleton()->global_variable_set_override(*K, tex_rid);
+ } else {
+ RS::get_singleton()->global_variable_set_override(*K, o->override);
+ }
}
}
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 4f7926d38d..a264c2d1eb 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -130,7 +130,7 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
}
}
if (pr) {
- RenderingServer::get_singleton()->material_set_param(_get_material(), pr, p_value);
+ set_shader_param(pr, p_value);
return true;
}
}
@@ -152,7 +152,12 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
}
if (pr) {
- r_ret = RenderingServer::get_singleton()->material_get_param(_get_material(), pr);
+ const Map<StringName, Variant>::Element *E = param_cache.find(pr);
+ if (E) {
+ r_ret = E->get();
+ } else {
+ r_ret = Variant();
+ }
return true;
}
}
@@ -219,11 +224,31 @@ Ref<Shader> ShaderMaterial::get_shader() const {
}
void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) {
- RS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
+ if (p_value.get_type() == Variant::NIL) {
+ param_cache.erase(p_param);
+ RS::get_singleton()->material_set_param(_get_material(), p_param, Variant());
+ } else {
+ param_cache[p_param] = p_value;
+ if (p_value.get_type() == Variant::OBJECT) {
+ RID tex_rid = p_value;
+ if (tex_rid == RID()) {
+ param_cache.erase(p_param);
+ RS::get_singleton()->material_set_param(_get_material(), p_param, Variant());
+ } else {
+ RS::get_singleton()->material_set_param(_get_material(), p_param, tex_rid);
+ }
+ } else {
+ RS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
+ }
+ }
}
Variant ShaderMaterial::get_shader_param(const StringName &p_param) const {
- return RS::get_singleton()->material_get_param(_get_material(), p_param);
+ if (param_cache.has(p_param)) {
+ return param_cache[p_param];
+ } else {
+ return Variant();
+ }
}
void ShaderMaterial::_shader_changed() {
@@ -999,9 +1024,9 @@ void BaseMaterial3D::_update_shader() {
code += "\tSPECULAR = specular;\n";
} else {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tfloat orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
+ code += "\tvec4 orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
- code += "\tfloat orm_tex = texture(texture_orm,base_uv);\n";
+ code += "\tvec4 orm_tex = texture(texture_orm,base_uv);\n";
}
code += "\tROUGHNESS = orm_tex.g;\n";
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 80e5e94466..e2838e1399 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -79,6 +79,8 @@ class ShaderMaterial : public Material {
GDCLASS(ShaderMaterial, Material);
Ref<Shader> shader;
+ Map<StringName, Variant> param_cache;
+
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index c5bfbc39db..f44c0c3ee2 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -1314,9 +1314,9 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < surfaces.size(); i++) {
p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
if (surfaces[i].is_2d) {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial,ShaderMaterial", PROPERTY_USAGE_EDITOR));
} else {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_EDITOR));
}
}
}
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index e95df31ccc..2bde98abe0 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -852,52 +852,54 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D
tex_parameters[p_param] = p_texture;
+ RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
+
switch (p_param) {
case PARAM_INITIAL_LINEAR_VELOCITY: {
//do none for this one
} break;
case PARAM_ANGULAR_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_texture, tex_rid);
_adjust_curve_range(p_texture, -360, 360);
} break;
case PARAM_ORBIT_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, tex_rid);
_adjust_curve_range(p_texture, -500, 500);
} break;
case PARAM_LINEAR_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_texture, tex_rid);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_RADIAL_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_texture, tex_rid);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_TANGENTIAL_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_texture, tex_rid);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_DAMPING: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_texture, tex_rid);
_adjust_curve_range(p_texture, 0, 100);
} break;
case PARAM_ANGLE: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angle_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angle_texture, tex_rid);
_adjust_curve_range(p_texture, -360, 360);
} break;
case PARAM_SCALE: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, tex_rid);
_adjust_curve_range(p_texture, 0, 1);
} break;
case PARAM_HUE_VARIATION: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, tex_rid);
_adjust_curve_range(p_texture, -1, 1);
} break;
case PARAM_ANIM_SPEED: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_texture, tex_rid);
_adjust_curve_range(p_texture, 0, 200);
} break;
case PARAM_ANIM_OFFSET: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, tex_rid);
} break;
case PARAM_MAX:
break; // Can't happen, but silences warning
@@ -923,7 +925,8 @@ Color ParticlesMaterial::get_color() const {
void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) {
color_ramp = p_texture;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture);
+ RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, tex_rid);
_queue_shader_change();
notify_property_list_changed();
}
@@ -965,17 +968,20 @@ void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) {
void ParticlesMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) {
emission_point_texture = p_points;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, p_points);
+ RID tex_rid = p_points.is_valid() ? p_points->get_rid() : RID();
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, tex_rid);
}
void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) {
emission_normal_texture = p_normals;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, p_normals);
+ RID tex_rid = p_normals.is_valid() ? p_normals->get_rid() : RID();
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, tex_rid);
}
void ParticlesMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) {
emission_color_texture = p_colors;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, p_colors);
+ RID tex_rid = p_colors.is_valid() ? p_colors->get_rid() : RID();
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, tex_rid);
_queue_shader_change();
}
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 2b2ebb5c16..cc3346d182 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -207,7 +207,7 @@ void PrimitiveMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flip_faces", "flip_faces"), &PrimitiveMesh::set_flip_faces);
ClassDB::bind_method(D_METHOD("get_flip_faces"), &PrimitiveMesh::get_flip_faces);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces");
}
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 9d79c22159..89b3336118 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -270,7 +270,8 @@ ProceduralSkyMaterial::~ProceduralSkyMaterial() {
void PanoramaSkyMaterial::set_panorama(const Ref<Texture2D> &p_panorama) {
panorama = p_panorama;
- RS::get_singleton()->material_set_param(_get_material(), "source_panorama", panorama);
+ RID tex_rid = p_panorama.is_valid() ? p_panorama->get_rid() : RID();
+ RS::get_singleton()->material_set_param(_get_material(), "source_panorama", tex_rid);
}
Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
@@ -411,7 +412,8 @@ float PhysicalSkyMaterial::get_dither_strength() const {
void PhysicalSkyMaterial::set_night_sky(const Ref<Texture2D> &p_night_sky) {
night_sky = p_night_sky;
- RS::get_singleton()->material_set_param(_get_material(), "night_sky", night_sky);
+ RID tex_rid = p_night_sky.is_valid() ? p_night_sky->get_rid() : RID();
+ RS::get_singleton()->material_set_param(_get_material(), "night_sky", tex_rid);
}
Ref<Texture2D> PhysicalSkyMaterial::get_night_sky() const {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index d09a1d9f90..98997e482a 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1412,7 +1412,7 @@ void CurveTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update"), &CurveTexture::_update);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "32,4096"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "RGB,Red"), "set_texture_mode", "get_texture_mode");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
@@ -1559,7 +1559,7 @@ void Curve3Texture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update"), &Curve3Texture::_update);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "32,4096"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_x", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_x", "get_curve_x");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_y", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_y", "get_curve_y");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_z", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_z", "get_curve_z");
@@ -1762,7 +1762,7 @@ void GradientTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width");
}
void GradientTexture::set_gradient(Ref<Gradient> p_gradient) {
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 4f854ff229..deee22f05f 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -2245,22 +2245,22 @@ void TileSet::_bind_methods() {
BIND_ENUM_CONSTANT(TILE_OFFSET_AXIS_HORIZONTAL);
BIND_ENUM_CONSTANT(TILE_OFFSET_AXIS_VERTICAL);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_RIGHT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_RIGHT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_LEFT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_LEFT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_RIGHT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_RIGHT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_LEFT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_LEFT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_LEFT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_LEFT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_LEFT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_LEFT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_RIGHT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_RIGHT_CORNER);
BIND_ENUM_CONSTANT(TERRAIN_MODE_MATCH_CORNERS_AND_SIDES);
BIND_ENUM_CONSTANT(TERRAIN_MODE_MATCH_CORNERS);
diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp
index b362f1ff17..1cfb9ba3ad 100644
--- a/servers/physics_3d/collision_solver_3d_sat.cpp
+++ b/servers/physics_3d/collision_solver_3d_sat.cpp
@@ -1024,7 +1024,7 @@ static void _collision_sphere_face(const Shape3DSW *p_a, const Transform3D &p_tr
n1 *= -1.0;
}
- if (!separator.test_axis(n1.normalized(), !face_B->backface_collision)) {
+ if (!separator.test_axis(n1.normalized())) {
return;
}
@@ -1035,7 +1035,7 @@ static void _collision_sphere_face(const Shape3DSW *p_a, const Transform3D &p_tr
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -1493,7 +1493,7 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform3D &p_trans
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -1509,7 +1509,7 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform3D &p_trans
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -1533,7 +1533,7 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform3D &p_trans
axis_ab *= -1.0;
}
- if (!separator.test_axis(axis_ab.normalized(), !face_B->backface_collision)) {
+ if (!separator.test_axis(axis_ab.normalized())) {
return;
}
@@ -1548,7 +1548,7 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform3D &p_trans
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -1578,7 +1578,7 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform3D &p_trans
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -1812,7 +1812,7 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform3D &p_t
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
@@ -1821,7 +1821,7 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform3D &p_t
dir_axis *= -1.0;
}
- if (!separator.test_axis(dir_axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(dir_axis)) {
return;
}
@@ -1834,7 +1834,7 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform3D &p_t
n1 *= -1.0;
}
- if (!separator.test_axis(n1.normalized(), !face_B->backface_collision)) {
+ if (!separator.test_axis(n1.normalized())) {
return;
}
@@ -1845,7 +1845,7 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform3D &p_t
axis *= -1.0;
}
- if (!separator.test_axis(axis.normalized(), !face_B->backface_collision)) {
+ if (!separator.test_axis(axis.normalized())) {
return;
}
}
@@ -1955,7 +1955,7 @@ static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform3D &p_
}
// Cylinder end caps.
- if (!separator.test_axis(cyl_axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(cyl_axis)) {
return;
}
@@ -1971,7 +1971,7 @@ static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform3D &p_
axis *= -1.0;
}
- if (!separator.test_axis(axis.normalized(), !face_B->backface_collision)) {
+ if (!separator.test_axis(axis.normalized())) {
return;
}
}
@@ -1984,7 +1984,7 @@ static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform3D &p_
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -2021,7 +2021,7 @@ static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform3D &p_
axis *= -1.0;
}
- if (!separator.test_axis(axis.normalized(), !face_B->backface_collision)) {
+ if (!separator.test_axis(axis.normalized())) {
return;
}
}
@@ -2175,7 +2175,7 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -2192,7 +2192,7 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -2209,7 +2209,7 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -2229,7 +2229,7 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
@@ -2248,7 +2248,7 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform
axis *= -1.0;
}
- if (!separator.test_axis(axis, !face_B->backface_collision)) {
+ if (!separator.test_axis(axis)) {
return;
}
}
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 61f3047a34..d39823a1a3 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -435,94 +435,14 @@ void SceneShaderForwardClustered::MaterialData::set_next_pass(RID p_pass) {
next_pass = p_pass;
}
-void SceneShaderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool SceneShaderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER);
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET, RD::BARRIER_MASK_RASTER);
}
SceneShaderForwardClustered::MaterialData::~MaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) {
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index 6d7cef68c6..810b1f3876 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -166,17 +166,14 @@ public:
struct MaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
ShaderData *shader_data;
- RID uniform_buffer;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
uint64_t last_pass = 0;
uint32_t index = 0;
RID next_pass;
uint8_t priority;
virtual void set_render_priority(int p_priority);
virtual void set_next_pass(RID p_pass);
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~MaterialData();
};
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 807417c1e3..7709c8aadc 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -429,94 +429,14 @@ void SceneShaderForwardMobile::MaterialData::set_next_pass(RID p_pass) {
next_pass = p_pass;
}
-void SceneShaderForwardMobile::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool SceneShaderForwardMobile::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
SceneShaderForwardMobile *shader_singleton = (SceneShaderForwardMobile *)SceneShaderForwardMobile::singleton;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER);
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardMobile::MATERIAL_UNIFORM_SET);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardMobile::MATERIAL_UNIFORM_SET, RD::BARRIER_MASK_RASTER);
}
SceneShaderForwardMobile::MaterialData::~MaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *SceneShaderForwardMobile::_create_material_func(ShaderData *p_shader) {
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
index 476bb57bc5..5c9e35fd0d 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
@@ -163,17 +163,14 @@ public:
struct MaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
ShaderData *shader_data;
- RID uniform_buffer;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
uint64_t last_pass = 0;
uint32_t index = 0;
RID next_pass;
uint8_t priority;
virtual void set_render_priority(int p_priority);
virtual void set_next_pass(RID p_pass);
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~MaterialData();
};
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 026969c09f..1e3dbe69a3 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -2201,94 +2201,14 @@ RendererStorageRD::ShaderData *RendererCanvasRenderRD::_create_shader_func() {
return shader_data;
}
-void RendererCanvasRenderRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool RendererCanvasRenderRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), false);
- }
-
- if (shader_data->ubo_size == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
}
RendererCanvasRenderRD::MaterialData::~MaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *RendererCanvasRenderRD::_create_material_func(ShaderData *p_shader) {
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 1bc3769450..7c4f62832c 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -201,14 +201,11 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
struct MaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
ShaderData *shader_data;
- RID uniform_buffer;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~MaterialData();
};
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 956609b77e..e701219617 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -230,96 +230,16 @@ RendererSceneSkyRD::SkyShaderData::~SkyShaderData() {
////////////////////////////////////////////////////////////////////////////////
// Sky material
-void RendererSceneSkyRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
uniform_set_updated = true;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
}
RendererSceneSkyRD::SkyMaterialData::~SkyMaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
index 1292622fca..4f852e55a7 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
@@ -224,15 +224,12 @@ public:
struct SkyMaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
SkyShaderData *shader_data;
- RID uniform_buffer;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
bool uniform_set_updated;
virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~SkyMaterialData();
};
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 942684fc3a..6738f499bd 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -1526,27 +1526,18 @@ RID RendererStorageRD::material_allocate() {
return material_owner.allocate_rid();
}
void RendererStorageRD::material_initialize(RID p_rid) {
- Material material;
- material.data = nullptr;
- material.shader = nullptr;
- material.shader_type = SHADER_TYPE_MAX;
- material.update_next = nullptr;
- material.update_requested = false;
- material.uniform_dirty = false;
- material.texture_dirty = false;
- material.priority = 0;
- material.self = p_rid;
- material_owner.initialize_rid(p_rid, material);
+ material_owner.initialize_rid(p_rid);
+ Material *material = material_owner.getornull(p_rid);
+ material->self = p_rid;
}
void RendererStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) {
- if (material->update_requested) {
+ if (material->update_element.in_list()) {
return;
}
- material->update_next = material_update_list;
- material_update_list = material;
- material->update_requested = true;
+ material_update_list.add(&material->update_element);
+
material->uniform_dirty = material->uniform_dirty || p_uniform;
material->texture_dirty = material->texture_dirty || p_texture;
}
@@ -1601,6 +1592,7 @@ void RendererStorageRD::material_set_param(RID p_material, const StringName &p_p
if (p_value.get_type() == Variant::NIL) {
material->params.erase(p_param);
} else {
+ ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); //object not allowed
material->params[p_param] = p_value;
}
@@ -2232,6 +2224,10 @@ RendererStorageRD::MaterialData::~MaterialData() {
//unregister material from those using global textures
rs->global_variables.materials_using_texture.erase(global_texture_E);
}
+
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ }
}
void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
@@ -2381,6 +2377,105 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
}
}
+void RendererStorageRD::MaterialData::free_parameters_uniform_set(RID p_uniform_set) {
+ if (p_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(p_uniform_set)) {
+ RD::get_singleton()->uniform_set_set_invalidation_callback(p_uniform_set, nullptr, nullptr);
+ RD::get_singleton()->free(p_uniform_set);
+ }
+}
+
+bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, RID> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) {
+ if ((uint32_t)ubo_data.size() != p_ubo_size) {
+ p_uniform_dirty = true;
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ uniform_buffer = RID();
+ }
+
+ ubo_data.resize(p_ubo_size);
+ if (ubo_data.size()) {
+ uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
+ memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
+ }
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, nullptr, nullptr);
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ //check whether buffer changed
+ if (p_uniform_dirty && ubo_data.size()) {
+ update_uniform_buffer(p_uniforms, p_uniform_offsets, p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), p_barrier);
+ }
+
+ uint32_t tex_uniform_count = p_texture_uniforms.size();
+
+ if ((uint32_t)texture_cache.size() != tex_uniform_count || p_textures_dirty) {
+ texture_cache.resize(tex_uniform_count);
+ p_textures_dirty = true;
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, nullptr, nullptr);
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ if (p_textures_dirty && tex_uniform_count) {
+ update_textures(p_parameters, p_default_texture_params, p_texture_uniforms, texture_cache.ptrw(), true);
+ }
+
+ if (p_ubo_size == 0 && p_texture_uniforms.size() == 0) {
+ // This material does not require an uniform set, so don't create it.
+ return false;
+ }
+
+ if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ //no reason to update uniform set, only UBO (or nothing) was needed to update
+ return false;
+ }
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ if (p_ubo_size) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ const RID *textures = texture_cache.ptrw();
+ for (uint32_t i = 0; i < tex_uniform_count; i++) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1 + i;
+ u.ids.push_back(textures[i]);
+ uniforms.push_back(u);
+ }
+ }
+
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_shader_uniform_set);
+
+ RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, _material_uniform_set_erased, &self);
+
+ return true;
+}
+
+void RendererStorageRD::_material_uniform_set_erased(const RID &p_set, void *p_material) {
+ RID rid = *(RID *)p_material;
+ Material *material = base_singleton->material_owner.getornull(rid);
+ if (material) {
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
+ }
+}
+
void RendererStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) {
Material *material = material_owner.getornull(p_material);
if (material->shader_type != p_shader_type) {
@@ -2392,20 +2487,23 @@ void RendererStorageRD::material_force_update_textures(RID p_material, ShaderTyp
}
void RendererStorageRD::_update_queued_materials() {
- Material *material = material_update_list;
- while (material) {
- Material *next = material->update_next;
+ while (material_update_list.first()) {
+ Material *material = material_update_list.first()->self();
+ bool uniforms_changed = false;
if (material->data) {
- material->data->update_parameters(material->params, material->uniform_dirty, material->texture_dirty);
+ uniforms_changed = material->data->update_parameters(material->params, material->uniform_dirty, material->texture_dirty);
}
- material->update_requested = false;
material->texture_dirty = false;
material->uniform_dirty = false;
- material->update_next = nullptr;
- material = next;
+
+ material_update_list.remove(&material->update_element);
+
+ if (uniforms_changed) {
+ //some implementations such as 3D renderer cache the matreial uniform set, so update is required
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
+ }
}
- material_update_list = nullptr;
}
/* MESH API */
@@ -5281,94 +5379,14 @@ RendererStorageRD::ShaderData *RendererStorageRD::_create_particles_shader_func(
return shader_data;
}
-void RendererStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool RendererStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
uniform_set_updated = true;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, base_singleton->particles_shader.shader.version_get_shader(shader_data->version, 0), 3);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, base_singleton->particles_shader.shader.version_get_shader(shader_data->version, 0), 3);
}
RendererStorageRD::ParticlesMaterialData::~ParticlesMaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *RendererStorageRD::_create_particles_material_func(ParticlesShaderData *p_shader) {
@@ -8322,6 +8340,9 @@ void RendererStorageRD::global_variable_set_override(const StringName &p_name, c
if (!global_variables.variables.has(p_name)) {
return; //variable may not exist
}
+
+ ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT);
+
GlobalVariables::Variable &gv = global_variables.variables[p_name];
gv.override = p_value;
@@ -8661,9 +8682,6 @@ bool RendererStorageRD::free(RID p_rid) {
} else if (material_owner.owns(p_rid)) {
Material *material = material_owner.getornull(p_rid);
- if (material->update_requested) {
- _update_queued_materials();
- }
material_set_shader(p_rid, RID()); //clean up shader
material->dependency.deleted_notify(p_rid);
@@ -8849,7 +8867,6 @@ RendererStorageRD::RendererStorageRD() {
memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE);
global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size);
- material_update_list = nullptr;
{ //create default textures
RD::TextureFormat tformat;
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index 80dea6e5ea..1a33569c33 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -155,9 +155,13 @@ public:
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0;
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0;
virtual ~MaterialData();
+ //to be used internally by update_parameters, in the most common configuration of material parameters
+ bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, RID> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ void free_parameters_uniform_set(RID p_uniform_set);
+
private:
friend class RendererStorageRD;
RID self;
@@ -165,8 +169,14 @@ public:
List<RID>::Element *global_texture_E = nullptr;
uint64_t global_textures_pass = 0;
Map<StringName, uint64_t> used_global_textures;
+
+ //internally by update_parameters_uniform_set
+ Vector<uint8_t> ubo_data;
+ RID uniform_buffer;
+ Vector<RID> texture_cache;
};
typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *);
+ static void _material_uniform_set_erased(const RID &p_set, void *p_material);
enum DefaultRDTexture {
DEFAULT_RD_TEXTURE_WHITE,
@@ -373,25 +383,28 @@ private:
struct Material {
RID self;
- MaterialData *data;
- Shader *shader;
+ MaterialData *data = nullptr;
+ Shader *shader = nullptr;
//shortcut to shader data and type
- ShaderType shader_type;
+ ShaderType shader_type = SHADER_TYPE_MAX;
uint32_t shader_id = 0;
- bool update_requested;
- bool uniform_dirty;
- bool texture_dirty;
- Material *update_next;
+ bool uniform_dirty = false;
+ bool texture_dirty = false;
Map<StringName, Variant> params;
- int32_t priority;
+ int32_t priority = 0;
RID next_pass;
+ SelfList<Material> update_element;
+
Dependency dependency;
+
+ Material() :
+ update_element(this) {}
};
MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX];
mutable RID_Owner<Material, true> material_owner;
- Material *material_update_list;
+ SelfList<Material>::List material_update_list;
void _material_queue_update(Material *material, bool p_uniform, bool p_texture);
void _update_queued_materials();
@@ -895,17 +908,14 @@ private:
}
struct ParticlesMaterialData : public MaterialData {
- uint64_t last_frame;
- ParticlesShaderData *shader_data;
- RID uniform_buffer;
+ uint64_t last_frame = 0;
+ ParticlesShaderData *shader_data = nullptr;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
- bool uniform_set_updated;
+ bool uniform_set_updated = false;
virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~ParticlesMaterialData();
};
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 84299b4ab2..271c039aad 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -1315,6 +1315,8 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
+ ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT);
+
Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter);
if (!E) {
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index ed5e73c16a..0ca84bd79e 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -715,6 +715,8 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0;
virtual bool uniform_set_is_valid(RID p_uniform_set) = 0;
+ typedef void (*UniformSetInvalidatedCallback)(const RID &, void *);
+ virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata) = 0;
virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 4ac5f9399c..748b372c62 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2772,7 +2772,6 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false);
- GLOBAL_DEF("rendering/global_illumination/voxel_gi/anisotropic", false);
GLOBAL_DEF("rendering/global_illumination/voxel_gi/quality", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/voxel_gi/quality", PropertyInfo(Variant::INT, "rendering/global_illumination/voxel_gi/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)"));
diff --git a/tests/test_class_db.h b/tests/test_class_db.h
index 75785fa5ed..29edf5a4a0 100644
--- a/tests/test_class_db.h
+++ b/tests/test_class_db.h
@@ -754,6 +754,9 @@ void add_exposed_classes(Context &r_context) {
const List<StringName> &enum_constants = enum_map.get(*k);
for (const List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) {
const StringName &constant_name = E->get();
+ TEST_FAIL_COND(String(constant_name).find("::") != -1,
+ "Enum constant contains '::', check bindings to remove the scope: '",
+ String(class_name), ".", String(enum_.name), ".", String(constant_name), "'.");
int *value = class_info->constant_map.getptr(constant_name);
TEST_FAIL_COND(!value, "Missing enum constant value: '",
String(class_name), ".", String(enum_.name), ".", String(constant_name), "'.");
@@ -773,8 +776,11 @@ void add_exposed_classes(Context &r_context) {
for (const List<String>::Element *E = constants.front(); E; E = E->next()) {
const String &constant_name = E->get();
+ TEST_FAIL_COND(constant_name.find("::") != -1,
+ "Constant contains '::', check bindings to remove the scope: '",
+ String(class_name), ".", constant_name, "'.");
int *value = class_info->constant_map.getptr(StringName(E->get()));
- TEST_FAIL_COND(!value, "Missing enum constant value: '", String(class_name), ".", String(constant_name), "'.");
+ TEST_FAIL_COND(!value, "Missing constant value: '", String(class_name), ".", String(constant_name), "'.");
ConstantData constant;
constant.name = constant_name;