diff options
24 files changed, 374 insertions, 102 deletions
diff --git a/doc/classes/ConfigFile.xml b/doc/classes/ConfigFile.xml index 04e4164415..e6b28ae98e 100644 --- a/doc/classes/ConfigFile.xml +++ b/doc/classes/ConfigFile.xml @@ -163,7 +163,7 @@ <param index="0" name="path" type="String" /> <description> Loads the config file specified as a parameter. The file's contents are parsed and loaded in the [ConfigFile] object which the method was called on. - Returns one of the [enum Error] code constants ([constant OK] on success). + Returns [constant OK] on success, or one of the other [enum Error] values if the operation failed. </description> </method> <method name="load_encrypted"> @@ -172,7 +172,7 @@ <param index="1" name="key" type="PackedByteArray" /> <description> Loads the encrypted config file specified as a parameter, using the provided [param key] to decrypt it. The file's contents are parsed and loaded in the [ConfigFile] object which the method was called on. - Returns one of the [enum Error] code constants ([constant OK] on success). + Returns [constant OK] on success, or one of the other [enum Error] values if the operation failed. </description> </method> <method name="load_encrypted_pass"> @@ -181,7 +181,7 @@ <param index="1" name="password" type="String" /> <description> Loads the encrypted config file specified as a parameter, using the provided [param password] to decrypt it. The file's contents are parsed and loaded in the [ConfigFile] object which the method was called on. - Returns one of the [enum Error] code constants ([constant OK] on success). + Returns [constant OK] on success, or one of the other [enum Error] values if the operation failed. </description> </method> <method name="parse"> @@ -189,7 +189,7 @@ <param index="0" name="data" type="String" /> <description> Parses the passed string as the contents of a config file. The string is parsed and loaded in the ConfigFile object which the method was called on. - Returns one of the [enum Error] code constants ([constant OK] on success). + Returns [constant OK] on success, or one of the other [enum Error] values if the operation failed. </description> </method> <method name="save"> @@ -197,7 +197,7 @@ <param index="0" name="path" type="String" /> <description> Saves the contents of the [ConfigFile] object to the file specified as a parameter. The output file uses an INI-style structure. - Returns one of the [enum Error] code constants ([constant OK] on success). + Returns [constant OK] on success, or one of the other [enum Error] values if the operation failed. </description> </method> <method name="save_encrypted"> @@ -206,7 +206,7 @@ <param index="1" name="key" type="PackedByteArray" /> <description> Saves the contents of the [ConfigFile] object to the AES-256 encrypted file specified as a parameter, using the provided [param key] to encrypt it. The output file uses an INI-style structure. - Returns one of the [enum Error] code constants ([constant OK] on success). + Returns [constant OK] on success, or one of the other [enum Error] values if the operation failed. </description> </method> <method name="save_encrypted_pass"> @@ -215,7 +215,7 @@ <param index="1" name="password" type="String" /> <description> Saves the contents of the [ConfigFile] object to the AES-256 encrypted file specified as a parameter, using the provided [param password] to encrypt it. The output file uses an INI-style structure. - Returns one of the [enum Error] code constants ([constant OK] on success). + Returns [constant OK] on success, or one of the other [enum Error] values if the operation failed. </description> </method> <method name="set_value"> diff --git a/doc/classes/MovieWriter.xml b/doc/classes/MovieWriter.xml index 4cd89e5e2d..e96080d6a8 100644 --- a/doc/classes/MovieWriter.xml +++ b/doc/classes/MovieWriter.xml @@ -9,7 +9,7 @@ - AVI container with MJPEG for video and uncompressed audio ([code].avi[/code] file extension). Lossy compression, medium file sizes, fast encoding. The lossy compression quality can be adjusted by changing [member ProjectSettings.editor/movie_writer/mjpeg_quality]. The resulting file can be viewed in most video players, but it must be converted to another format for viewing on the web or by Godot with [VideoStreamPlayer]. MJPEG does not support transparency. AVI output is currently limited to a file of 4 GB in size at most. - PNG image sequence for video and WAV for audio ([code].png[/code] file extension). Lossless compression, large file sizes, slow encoding. Designed to be encoded to a video file with another tool such as [url=https://ffmpeg.org/]FFmpeg[/url] after recording. Transparency is currently not supported, even if the root viewport is set to be transparent. If you need to encode to a different format or pipe a stream through third-party software, you can extend the [MovieWriter] class to create your own movie writers. This should typically be done using GDExtension for performance reasons. - [b]Editor usage:[/b] A default movie file path can be specified in [member ProjectSettings.editor/movie_writer/movie_file]. Alternatively, for running single scenes, a [code]movie_path[/code] metadata can be added to the root node, specifying the path to a movie file that will be used when recording that scene. Once a path is set, click the video reel icon in the top-right corner of the editor to enable Movie Maker mode, then run any scene as usual. The engine will start recording as soon as the splash screen is finished, and it will only stop recording when the engine quits. Click the video reel icon again to disable Movie Maker mode. Note that toggling Movie Maker mode does not affect project instances that are already running. + [b]Editor usage:[/b] A default movie file path can be specified in [member ProjectSettings.editor/movie_writer/movie_file]. Alternatively, for running single scenes, a [code]movie_file[/code] metadata can be added to the root node, specifying the path to a movie file that will be used when recording that scene. Once a path is set, click the video reel icon in the top-right corner of the editor to enable Movie Maker mode, then run any scene as usual. The engine will start recording as soon as the splash screen is finished, and it will only stop recording when the engine quits. Click the video reel icon again to disable Movie Maker mode. Note that toggling Movie Maker mode does not affect project instances that are already running. [b]Note:[/b] MovieWriter is available for use in both the editor and exported projects, but it is [i]not[/i] designed for use by end users to record videos while playing. Players wishing to record gameplay videos should install tools such as [url=https://obsproject.com/]OBS Studio[/url] or [url=https://www.maartenbaert.be/simplescreenrecorder/]SimpleScreenRecorder[/url] instead. </description> <tutorials> diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml index 8a90d5dd0f..5db0dfb327 100644 --- a/doc/classes/VisualShaderNodeCustom.xml +++ b/doc/classes/VisualShaderNodeCustom.xml @@ -80,6 +80,14 @@ Defining this method is [b]required[/b]. If not overridden, the node has no input ports. </description> </method> + <method name="_get_input_port_default_value" qualifiers="virtual const"> + <return type="Variant" /> + <param index="0" name="port" type="int" /> + <description> + Override this method to define the default value for the specified input port. Prefer use this over [method VisualShaderNode.set_input_port_default_value]. + Defining this method is [b]required[/b]. If not overridden, the node has no default values for their input ports. + </description> + </method> <method name="_get_input_port_name" qualifiers="virtual const"> <return type="String" /> <param index="0" name="port" type="int" /> @@ -126,6 +134,37 @@ Defining this method is [b]optional[/b], but recommended. If not overridden, output ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] type. </description> </method> + <method name="_get_property_count" qualifiers="virtual const"> + <return type="int" /> + <description> + Override this method to define the number of the properties. + Defining this method is [b]optional[/b]. + </description> + </method> + <method name="_get_property_default_index" qualifiers="virtual const"> + <return type="int" /> + <param index="0" name="index" type="int" /> + <description> + Override this method to define the default index of the property of the associated custom node. + Defining this method is [b]optional[/b]. + </description> + </method> + <method name="_get_property_name" qualifiers="virtual const"> + <return type="String" /> + <param index="0" name="index" type="int" /> + <description> + Override this method to define the names of the property of the associated custom node. + Defining this method is [b]optional[/b]. + </description> + </method> + <method name="_get_property_options" qualifiers="virtual const"> + <return type="PackedStringArray" /> + <param index="0" name="index" type="int" /> + <description> + Override this method to define the options inside the drop-down list property of the associated custom node. + Defining this method is [b]optional[/b]. + </description> + </method> <method name="_get_return_icon_type" qualifiers="virtual const"> <return type="int" enum="VisualShaderNode.PortType" /> <description> @@ -149,5 +188,12 @@ Defining this method is [b]optional[/b]. If not overridden, it's [code]false[/code]. </description> </method> + <method name="get_option_index" qualifiers="const"> + <return type="int" /> + <param index="0" name="option" type="int" /> + <description> + Returns the selected index of the drop-down list option within a graph. You may use this function to define the specific behavior in the [method _get_code] or [method _get_global_code]. + </description> + </method> </methods> </class> diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index ab689ad056..382b182e0e 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1188,7 +1188,8 @@ Size2 EditorInspectorCategory::get_minimum_size() const { Size2 ms; ms.height = font->get_height(font_size); if (icon.is_valid()) { - ms.height = MAX(icon->get_height(), ms.height); + int icon_size = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor)); + ms.height = MAX(icon_size, ms.height); } ms.height += get_theme_constant(SNAME("v_separation"), SNAME("Tree")); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 41591c366f..b80d3c1869 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1363,15 +1363,15 @@ void FileSystemDock::_get_all_items_in_dir(EditorFileSystemDirectory *p_efsd, Ve } } -void FileSystemDock::_find_remaps(EditorFileSystemDirectory *p_efsd, const Vector<String> &r_renames, Vector<String> &r_to_remaps) const { +void FileSystemDock::_find_file_owners(EditorFileSystemDirectory *p_efsd, const Vector<String> &p_renames, Vector<String> &r_file_owners) const { for (int i = 0; i < p_efsd->get_subdir_count(); i++) { - _find_remaps(p_efsd->get_subdir(i), r_renames, r_to_remaps); + _find_file_owners(p_efsd->get_subdir(i), p_renames, r_file_owners); } for (int i = 0; i < p_efsd->get_file_count(); i++) { Vector<String> deps = p_efsd->get_file_deps(i); for (int j = 0; j < deps.size(); j++) { - if (r_renames.has(deps[j])) { - r_to_remaps.push_back(p_efsd->get_file_path(i)); + if (p_renames.has(deps[j])) { + r_file_owners.push_back(p_efsd->get_file_path(i)); break; } } @@ -1562,22 +1562,22 @@ void FileSystemDock::_update_resource_paths_after_move(const HashMap<String, Str } } -void FileSystemDock::_update_dependencies_after_move(const HashMap<String, String> &p_renames, const Vector<String> &p_remaps) const { +void FileSystemDock::_update_dependencies_after_move(const HashMap<String, String> &p_renames, const Vector<String> &p_file_owners) const { // The following code assumes that the following holds: // 1) EditorFileSystem contains the old paths/folder structure from before the rename/move. // 2) ResourceLoader can use the new paths without needing to call rescan. List<String> scenes_to_reload; - for (int i = 0; i < p_remaps.size(); ++i) { + for (int i = 0; i < p_file_owners.size(); ++i) { // Because we haven't called a rescan yet the found remap might still be an old path itself. - String file = p_renames.has(p_remaps[i]) ? p_renames[p_remaps[i]] : p_remaps[i]; + const String file = p_renames.has(p_file_owners[i]) ? p_renames[p_file_owners[i]] : p_file_owners[i]; print_verbose("Remapping dependencies for: " + file); - Error err = ResourceLoader::rename_dependencies(file, p_renames); + const Error err = ResourceLoader::rename_dependencies(file, p_renames); if (err == OK) { if (ResourceLoader::get_resource_type(file) == "PackedScene") { scenes_to_reload.push_back(file); } } else { - EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies:") + "\n" + p_remaps[i] + "\n"); + EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies for:") + "\n" + p_file_owners[i] + "\n"); } } @@ -1773,10 +1773,9 @@ void FileSystemDock::_rename_operation_confirm() { return; } - Vector<String> old_paths; HashMap<String, ResourceUID::ID> uids; - Vector<String> remaps; - _before_move(old_paths, uids, remaps); + Vector<String> file_owners; // The files that use these moved/renamed resource files. + _before_move(uids, file_owners); HashMap<String, String> file_renames; HashMap<String, String> folder_renames; @@ -1784,7 +1783,7 @@ void FileSystemDock::_rename_operation_confirm() { int current_tab = EditorSceneTabs::get_singleton()->get_current_tab(); _update_resource_paths_after_move(file_renames, uids); - _update_dependencies_after_move(file_renames, remaps); + _update_dependencies_after_move(file_renames, file_owners); _update_project_settings_after_move(file_renames, folder_renames); _update_favorites_list_after_move(file_renames, folder_renames); @@ -1910,10 +1909,9 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_cop } } - Vector<String> old_paths; HashMap<String, ResourceUID::ID> uids; - Vector<String> remaps; - _before_move(old_paths, uids, remaps); + Vector<String> file_owners; // The files that use these moved/renamed resource files. + _before_move(uids, file_owners); bool is_moved = false; HashMap<String, String> file_renames; @@ -1936,7 +1934,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_cop if (is_moved) { int current_tab = EditorSceneTabs::get_singleton()->get_current_tab(); _update_resource_paths_after_move(file_renames, uids); - _update_dependencies_after_move(file_renames, remaps); + _update_dependencies_after_move(file_renames, file_owners); _update_project_settings_after_move(file_renames, folder_renames); _update_favorites_list_after_move(file_renames, folder_renames); @@ -1951,20 +1949,43 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_cop } } -void FileSystemDock::_before_move(Vector<String> &r_old_paths, HashMap<String, ResourceUID::ID> &r_uids, Vector<String> &r_remaps) const { +void FileSystemDock::_before_move(HashMap<String, ResourceUID::ID> &r_uids, Vector<String> &r_file_owners) const { + Vector<String> renamed_files; for (int i = 0; i < to_move.size(); i++) { - r_old_paths.push_back(to_move[i].path); - ResourceUID::ID uid = ResourceLoader::get_resource_uid(to_move[i].path); - if (uid != ResourceUID::INVALID_ID) { - r_uids[to_move[i].path] = uid; + if (to_move[i].is_file) { + renamed_files.push_back(to_move[i].path); + ResourceUID::ID uid = ResourceLoader::get_resource_uid(to_move[i].path); + if (uid != ResourceUID::INVALID_ID) { + r_uids[to_move[i].path] = uid; + } + } else { + EditorFileSystemDirectory *current_folder = EditorFileSystem::get_singleton()->get_filesystem_path(to_move[i].path); + List<EditorFileSystemDirectory *> folders; + folders.push_back(current_folder); + while (folders.front()) { + current_folder = folders.front()->get(); + for (int j = 0; j < current_folder->get_file_count(); j++) { + const String file_path = current_folder->get_file_path(j); + renamed_files.push_back(file_path); + ResourceUID::ID uid = ResourceLoader::get_resource_uid(file_path); + if (uid != ResourceUID::INVALID_ID) { + r_uids[file_path] = uid; + } + } + for (int j = 0; j < current_folder->get_subdir_count(); j++) { + folders.push_back(current_folder->get_subdir(j)); + } + folders.pop_front(); + } } } - _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), r_old_paths, r_remaps); + // Look for files that use these moved/renamed resource files. + _find_file_owners(EditorFileSystem::get_singleton()->get_filesystem(), renamed_files, r_file_owners); // Open scenes with dependencies on the ones about to be moved will be reloaded, // so save them first to prevent losing unsaved changes. - EditorNode::get_singleton()->save_scene_list(r_remaps); + EditorNode::get_singleton()->save_scene_list(r_file_owners); } Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) const { @@ -2201,6 +2222,10 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected break; } + // Rename has same logic as move for resource files. + to_move.clear(); + to_move.push_back(to_rename); + if (tree->has_focus()) { // Edit node in Tree. tree->edit_selected(true); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index e900ac0037..818b91bdb9 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -262,11 +262,11 @@ private: void _update_import_dock(); void _get_all_items_in_dir(EditorFileSystemDirectory *p_efsd, Vector<String> &r_files, Vector<String> &r_folders) const; - void _find_remaps(EditorFileSystemDirectory *p_efsd, const Vector<String> &r_renames, Vector<String> &r_to_remaps) const; + void _find_file_owners(EditorFileSystemDirectory *p_efsd, const Vector<String> &p_renames, Vector<String> &r_file_owners) const; void _try_move_item(const FileOrFolder &p_item, const String &p_new_path, HashMap<String, String> &p_file_renames, HashMap<String, String> &p_folder_renames); void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const; - void _before_move(Vector<String> &r_old_paths, HashMap<String, ResourceUID::ID> &r_uids, Vector<String> &r_remaps) const; - void _update_dependencies_after_move(const HashMap<String, String> &p_renames, const Vector<String> &p_remaps) const; + void _before_move(HashMap<String, ResourceUID::ID> &r_uids, Vector<String> &r_file_owners) const; + void _update_dependencies_after_move(const HashMap<String, String> &p_renames, const Vector<String> &p_file_owners) const; void _update_resource_paths_after_move(const HashMap<String, String> &p_renames, const HashMap<String, ResourceUID::ID> &p_uids) const; void _update_favorites_list_after_move(const HashMap<String, String> &p_files_renames, const HashMap<String, String> &p_folders_renames) const; void _update_project_settings_after_move(const HashMap<String, String> &p_renames, const HashMap<String, String> &p_folders_renames); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 25cbbbf6de..8b1053b79b 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -551,6 +551,47 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool } } + if (custom_node.is_valid()) { + bool first = true; + VBoxContainer *vbox = nullptr; + + for (int i = 0; i < custom_node->dp_props.size(); i++) { + const VisualShaderNodeCustom::DropDownListProperty &dp = custom_node->dp_props[i]; + + if (first) { + first = false; + vbox = memnew(VBoxContainer); + node->add_child(vbox); + port_offset++; + } + + HBoxContainer *hbox = memnew(HBoxContainer); + vbox->add_child(hbox); + hbox->set_h_size_flags(Control::SIZE_EXPAND_FILL); + + String prop_name = dp.name.strip_edges(); + if (!prop_name.is_empty()) { + Label *label = memnew(Label); + label->set_text(prop_name + ":"); + hbox->add_child(label); + } + + OptionButton *op = memnew(OptionButton); + hbox->add_child(op); + op->set_h_size_flags(Control::SIZE_EXPAND_FILL); + op->connect("item_selected", callable_mp(editor, &VisualShaderEditor::_set_custom_node_option).bind(p_id, i), CONNECT_DEFERRED); + + for (const String &s : dp.options) { + op->add_item(s); + } + if (custom_node->dp_selected_cache.has(i)) { + op->select(custom_node->dp_selected_cache[i]); + } else { + op->select(0); + } + } + } + Ref<VisualShaderNodeCurveTexture> curve = vsnode; Ref<VisualShaderNodeCurveXYZTexture> curve_xyz = vsnode; @@ -2704,6 +2745,22 @@ void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node, editing_port = p_port; } +void VisualShaderEditor::_set_custom_node_option(int p_index, int p_node, int p_op) { + VisualShader::Type type = get_current_shader_type(); + Ref<VisualShaderNodeCustom> node = visual_shader->get_node(type, p_node); + if (node.is_null()) { + return; + } + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Set Custom Node Option")); + undo_redo->add_do_method(node.ptr(), "_set_option_index", p_op, p_index); + undo_redo->add_undo_method(node.ptr(), "_set_option_index", p_op, node->get_option_index(p_op)); + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node); + undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node); + undo_redo->commit_action(); +} + void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, const Vector<Variant> &p_ops) { // INPUT { @@ -3084,7 +3141,9 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri } VisualShaderNodeCustom *custom_node = Object::cast_to<VisualShaderNodeCustom>(vsn); ERR_FAIL_NULL(custom_node); - custom_node->update_ports(); + custom_node->update_property_default_values(); + custom_node->update_input_port_default_values(); + custom_node->update_properties(); } bool is_texture2d = (Object::cast_to<VisualShaderNodeTexture>(vsnode.ptr()) != nullptr); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index e0a0f3a096..8629e64467 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -493,6 +493,8 @@ class VisualShaderEditor : public VBoxContainer { void _varying_unselected(); void _update_varying_tree(); + void _set_custom_node_option(int p_index, int p_node, int p_op); + Vector2 menu_point; void _node_menu_id_pressed(int p_idx); diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index b2994f3065..d6ed5eb995 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -139,6 +139,9 @@ public: LocalVector<RegEx *> color_regexes; LocalVector<String> color_renamed; + RegEx color_hexadecimal_short_constructor = RegEx("Color\\(\"#?([a-fA-F0-9]{1})([a-fA-F0-9]{3})\\b"); + RegEx color_hexadecimal_full_constructor = RegEx("Color\\(\"#?([a-fA-F0-9]{2})([a-fA-F0-9]{6})\\b"); + // Classes. LocalVector<RegEx *> class_tscn_regexes; LocalVector<RegEx *> class_gd_regexes; @@ -409,6 +412,8 @@ bool ProjectConverter3To4::convert() { rename_common(RenamesMap3To4::theme_override_renames, reg_container.theme_override_regexes, source_lines); custom_rename(source_lines, "\\.shader", ".gdshader"); + + convert_hexadecimal_colors(source_lines, reg_container); } else if (file_name.ends_with(".tscn")) { fix_pause_mode(source_lines, reg_container); @@ -429,6 +434,8 @@ bool ProjectConverter3To4::convert() { rename_common(RenamesMap3To4::theme_override_renames, reg_container.theme_override_regexes, source_lines); custom_rename(source_lines, "\\.shader", ".gdshader"); + + convert_hexadecimal_colors(source_lines, reg_container); } else if (file_name.ends_with(".cs")) { // TODO, C# should use different methods. rename_classes(source_lines, reg_container); // Using only specialized function. rename_common(RenamesMap3To4::csharp_function_renames, reg_container.csharp_function_regexes, source_lines); @@ -438,6 +445,7 @@ bool ProjectConverter3To4::convert() { rename_csharp_functions(source_lines, reg_container); rename_csharp_attributes(source_lines, reg_container); custom_rename(source_lines, "public class ", "public partial class "); + convert_hexadecimal_colors(source_lines, reg_container); } else if (file_name.ends_with(".gdshader") || file_name.ends_with(".shader")) { rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, source_lines); } else if (file_name.ends_with("tres")) { @@ -1004,7 +1012,10 @@ bool ProjectConverter3To4::test_conversion(RegExContainer ®_container) { valid = valid && test_conversion_gdscript_builtin("button.pressed=1", "button.button_pressed=1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("button.pressed SF", "button.pressed SF", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid && test_conversion_with_regex("AAA Color.white AF", "AAA Color.WHITE AF", &ProjectConverter3To4::rename_colors, "custom rename", reg_container); + valid = valid && test_conversion_with_regex("Color(\"#f47d\")", "Color(\"#47df\")", &ProjectConverter3To4::convert_hexadecimal_colors, "color literals", reg_container); + valid = valid && test_conversion_with_regex("Color(\"#ff478cbf\")", "Color(\"#478cbfff\")", &ProjectConverter3To4::convert_hexadecimal_colors, "color literals", reg_container); + valid = valid && test_conversion_with_regex("Color(\"#de32bf\")", "Color(\"#de32bf\")", &ProjectConverter3To4::convert_hexadecimal_colors, "color literals", reg_container); + valid = valid && test_conversion_with_regex("AAA Color.white AF", "AAA Color.WHITE AF", &ProjectConverter3To4::rename_colors, "color constants", reg_container); // Note: Do not change to *scancode*, it is applied before that conversion. valid = valid && test_conversion_with_regex("\"device\":-1,\"scancode\":16777231,\"physical_scancode\":16777232", "\"device\":-1,\"scancode\":4194319,\"physical_scancode\":4194320", &ProjectConverter3To4::rename_input_map_scancode, "custom rename", reg_container); @@ -1458,6 +1469,23 @@ void ProjectConverter3To4::rename_colors(Vector<SourceLine> &source_lines, const } }; +// Convert hexadecimal colors from ARGB to RGBA +void ProjectConverter3To4::convert_hexadecimal_colors(Vector<SourceLine> &source_lines, const RegExContainer ®_container) { + for (SourceLine &source_line : source_lines) { + if (source_line.is_comment) { + continue; + } + + String &line = source_line.line; + if (uint64_t(line.length()) <= maximum_line_length) { + if (line.contains("Color(\"")) { + line = reg_container.color_hexadecimal_short_constructor.sub(line, "Color(\"#$2$1", true); + line = reg_container.color_hexadecimal_full_constructor.sub(line, "Color(\"#$2$1", true); + } + } + } +} + Vector<String> ProjectConverter3To4::check_for_rename_colors(Vector<String> &lines, const RegExContainer ®_container) { Vector<String> found_renames; diff --git a/editor/project_converter_3_to_4.h b/editor/project_converter_3_to_4.h index e26f4ee49a..2afd0a24e8 100644 --- a/editor/project_converter_3_to_4.h +++ b/editor/project_converter_3_to_4.h @@ -75,6 +75,7 @@ class ProjectConverter3To4 { void fix_pause_mode(Vector<SourceLine> &source_lines, const RegExContainer ®_container); void rename_colors(Vector<SourceLine> &source_lines, const RegExContainer ®_container); + void convert_hexadecimal_colors(Vector<SourceLine> &source_lines, const RegExContainer ®_container); Vector<String> check_for_rename_colors(Vector<String> &lines, const RegExContainer ®_container); void rename_classes(Vector<SourceLine> &source_lines, const RegExContainer ®_container); diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj index 09e8bf4cc7..cc2b1c64f8 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj @@ -254,8 +254,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - OTHER_LDFLAGS = "$linker_flags"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + OTHER_LDFLAGS = "-ld_classic $linker_flags"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "$targeted_device_family"; }; @@ -293,8 +293,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - OTHER_LDFLAGS = "$linker_flags"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + OTHER_LDFLAGS = "-ld_classic $linker_flags"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "$targeted_device_family"; VALIDATE_PRODUCT = YES; @@ -314,7 +314,7 @@ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; DEVELOPMENT_TEAM = $team_id; INFOPLIST_FILE = "$binary/$binary-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -350,7 +350,7 @@ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; DEVELOPMENT_TEAM = $team_id; INFOPLIST_FILE = "$binary/$binary-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/modules/lightmapper_rd/config.py b/modules/lightmapper_rd/config.py index d22f9454ed..ecc61c2d7e 100644 --- a/modules/lightmapper_rd/config.py +++ b/modules/lightmapper_rd/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return env.editor_build and platform not in ["android", "ios"] def configure(env): diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index e9550f9c28..556b0b4374 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -1493,14 +1493,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d } #endif - { - SWAP(light_accum_tex, light_accum_tex2); - BakeError error = _dilate(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices * (p_bake_sh ? 4 : 1)); - if (unlikely(error != BAKE_OK)) { - return error; - } - } - /* DENOISE */ if (p_use_denoiser) { @@ -1515,13 +1507,13 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d return error; } } + } - { - SWAP(light_accum_tex, light_accum_tex2); - BakeError error = _dilate(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices * (p_bake_sh ? 4 : 1)); - if (unlikely(error != BAKE_OK)) { - return error; - } + { + SWAP(light_accum_tex, light_accum_tex2); + BakeError error = _dilate(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices * (p_bake_sh ? 4 : 1)); + if (unlikely(error != BAKE_OK)) { + return error; } } diff --git a/modules/lightmapper_rd/register_types.cpp b/modules/lightmapper_rd/register_types.cpp index 7ec4a40766..984ce88316 100644 --- a/modules/lightmapper_rd/register_types.cpp +++ b/modules/lightmapper_rd/register_types.cpp @@ -58,7 +58,6 @@ void initialize_lightmapper_rd_module(ModuleInitializationLevel p_level) { GLOBAL_DEF("rendering/lightmapping/bake_quality/high_quality_probe_ray_count", 512); GLOBAL_DEF("rendering/lightmapping/bake_quality/ultra_quality_probe_ray_count", 2048); GLOBAL_DEF("rendering/lightmapping/bake_performance/max_rays_per_probe_pass", 64); - GLOBAL_DEF("rendering/lightmapping/primitive_meshes/texel_size", 0.2); #ifndef _3D_DISABLED GDREGISTER_CLASS(LightmapperRD); Lightmapper::create_gpu = create_lightmapper_rd; diff --git a/platform/ios/detect.py b/platform/ios/detect.py index e11c0b7d91..40eb61abc8 100644 --- a/platform/ios/detect.py +++ b/platform/ios/detect.py @@ -103,13 +103,13 @@ def configure(env: "Environment"): if env["ios_simulator"]: detect_darwin_sdk_path("iossimulator", env) - env.Append(ASFLAGS=["-mios-simulator-version-min=11.0"]) - env.Append(CCFLAGS=["-mios-simulator-version-min=11.0"]) + env.Append(ASFLAGS=["-mios-simulator-version-min=12.0"]) + env.Append(CCFLAGS=["-mios-simulator-version-min=12.0"]) env.extra_suffix = ".simulator" + env.extra_suffix else: detect_darwin_sdk_path("ios", env) - env.Append(ASFLAGS=["-miphoneos-version-min=11.0"]) - env.Append(CCFLAGS=["-miphoneos-version-min=11.0"]) + env.Append(ASFLAGS=["-miphoneos-version-min=12.0"]) + env.Append(CCFLAGS=["-miphoneos-version-min=12.0"]) if env["arch"] == "x86_64": if not env["ios_simulator"]: @@ -154,7 +154,7 @@ def configure(env: "Environment"): env.Append(CPPDEFINES=["VULKAN_ENABLED"]) if env["opengl3"]: - env.Append(CPPDEFINES=["GLES3_ENABLED"]) + env.Append(CPPDEFINES=["GLES3_ENABLED", "GLES_SILENCE_DEPRECATION"]) env.Prepend( CPPPATH=[ "$IOS_SDK_PATH/System/Library/Frameworks/OpenGLES.framework/Headers", diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 7d0228ff68..489894a135 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -371,19 +371,15 @@ bool DisplayServerIOS::is_dark_mode() const { } Rect2i DisplayServerIOS::get_display_safe_area() const { - if (@available(iOS 11, *)) { - UIEdgeInsets insets = UIEdgeInsetsZero; - UIView *view = AppDelegate.viewController.godotView; - if ([view respondsToSelector:@selector(safeAreaInsets)]) { - insets = [view safeAreaInsets]; - } - float scale = screen_get_scale(); - Size2i insets_position = Size2i(insets.left, insets.top) * scale; - Size2i insets_size = Size2i(insets.left + insets.right, insets.top + insets.bottom) * scale; - return Rect2i(screen_get_position() + insets_position, screen_get_size() - insets_size); - } else { - return Rect2i(screen_get_position(), screen_get_size()); + UIEdgeInsets insets = UIEdgeInsetsZero; + UIView *view = AppDelegate.viewController.godotView; + if ([view respondsToSelector:@selector(safeAreaInsets)]) { + insets = [view safeAreaInsets]; } + float scale = screen_get_scale(); + Size2i insets_position = Size2i(insets.left, insets.top) * scale; + Size2i insets_size = Size2i(insets.left + insets.right, insets.top + insets.bottom) * scale; + return Rect2i(screen_get_position() + insets_position, screen_get_size() - insets_size); } int DisplayServerIOS::get_screen_count() const { diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm index 4c9a75fdc0..ff8a4f8921 100644 --- a/platform/ios/godot_view.mm +++ b/platform/ios/godot_view.mm @@ -82,10 +82,10 @@ static const float earth_gravity = 9.80665; layer = [GodotMetalLayer layer]; #endif } else if ([driverName isEqualToString:@"opengl3"]) { - if (@available(iOS 13, *)) { - NSLog(@"OpenGL ES is deprecated on iOS 13"); - } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in iOS 12.0 layer = [GodotOpenGLLayer layer]; +#pragma clang diagnostic pop } else { return nil; } diff --git a/platform/ios/view_controller.mm b/platform/ios/view_controller.mm index 0ef61da646..1f55670b68 100644 --- a/platform/ios/view_controller.mm +++ b/platform/ios/view_controller.mm @@ -161,9 +161,7 @@ [self observeKeyboard]; [self displayLoadingOverlay]; - if (@available(iOS 11.0, *)) { - [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; - } + [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; } - (void)observeKeyboard { diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index e13fd21949..26dbe1cb0c 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -263,6 +263,9 @@ void SpinBox::_notification(int p_what) { _update_text(); } break; + case NOTIFICATION_VISIBILITY_CHANGED: + drag.allowed = false; + [[fallthrough]]; case NOTIFICATION_EXIT_TREE: { _release_mouse(); } break; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index b372fcb1e9..dce0d87d10 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -327,22 +327,22 @@ TileSet::TerrainsPattern::TerrainsPattern(const TileSet *p_tile_set, int p_terra const int TileSet::INVALID_SOURCE = -1; const char *TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[] = { - "right_side", - "right_corner", - "bottom_right_side", - "bottom_right_corner", - "bottom_side", - "bottom_corner", - "bottom_left_side", - "bottom_left_corner", - "left_side", - "left_corner", - "top_left_side", - "top_left_corner", - "top_side", - "top_corner", - "top_right_side", - "top_right_corner" + PNAME("right_side"), + PNAME("right_corner"), + PNAME("bottom_right_side"), + PNAME("bottom_right_corner"), + PNAME("bottom_side"), + PNAME("bottom_corner"), + PNAME("bottom_left_side"), + PNAME("bottom_left_corner"), + PNAME("left_side"), + PNAME("left_corner"), + PNAME("top_left_side"), + PNAME("top_left_corner"), + PNAME("top_side"), + PNAME("top_corner"), + PNAME("top_right_side"), + PNAME("top_right_corner"), }; // -- Shape and layout -- @@ -5839,7 +5839,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); if (is_valid_terrain_peering_bit(bit)) { - property_info = PropertyInfo(Variant::INT, "terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i])); + property_info = PropertyInfo(Variant::INT, vformat("%s/%s", PNAME("terrains_peering_bit"), TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i])); if (get_terrain_peering_bit(bit) == -1) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index ea1207605c..489b866e70 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -435,8 +435,62 @@ VisualShaderNode::VisualShaderNode() { ///////////////////////////////////////////////////////// +void VisualShaderNodeCustom::update_property_default_values() { + int prop_count; + if (GDVIRTUAL_CALL(_get_property_count, prop_count)) { + for (int i = 0; i < prop_count; i++) { + int selected = 0; + if (GDVIRTUAL_CALL(_get_property_default_index, i, selected)) { + dp_selected_cache[i] = selected; + } + } + } +} + +void VisualShaderNodeCustom::update_input_port_default_values() { + int input_port_count; + if (GDVIRTUAL_CALL(_get_input_port_count, input_port_count)) { + for (int i = 0; i < input_port_count; i++) { + Variant value; + if (GDVIRTUAL_CALL(_get_input_port_default_value, i, value)) { + default_input_values[i] = value; + } + } + } +} + void VisualShaderNodeCustom::update_ports() { { + dp_props.clear(); + int prop_count; + if (GDVIRTUAL_CALL(_get_property_count, prop_count)) { + for (int i = 0; i < prop_count; i++) { + DropDownListProperty prop; + if (!GDVIRTUAL_CALL(_get_property_name, i, prop.name)) { + prop.name = "prop"; + } + if (!GDVIRTUAL_CALL(_get_property_options, i, prop.options)) { + prop.options.push_back("Default"); + } + dp_props.push_back(prop); + } + } + } + + { + Vector<String> vprops = properties.split(";", false); + for (int i = 0; i < vprops.size(); i++) { + Vector<String> arr = vprops[i].split(",", false); + ERR_FAIL_COND(arr.size() != 2); + ERR_FAIL_COND(!arr[0].is_valid_int()); + ERR_FAIL_COND(!arr[1].is_valid_int()); + int index = arr[0].to_int(); + int selected = arr[1].to_int(); + dp_selected_cache[index] = selected; + } + } + + { input_ports.clear(); int input_port_count; if (GDVIRTUAL_CALL(_get_input_port_count, input_port_count)) { @@ -479,6 +533,15 @@ void VisualShaderNodeCustom::update_ports() { } } +void VisualShaderNodeCustom::update_properties() { + properties = ""; + for (const KeyValue<int, int> &p : dp_selected_cache) { + if (p.value != 0) { + properties += itos(p.key) + "," + itos(p.value) + ";"; + } + } +} + String VisualShaderNodeCustom::get_caption() const { String ret = "Unnamed"; GDVIRTUAL_CALL(_get_name, ret); @@ -635,6 +698,14 @@ void VisualShaderNodeCustom::_set_initialized(bool p_enabled) { is_initialized = p_enabled; } +void VisualShaderNodeCustom::_set_properties(const String &p_properties) { + properties = p_properties; +} + +String VisualShaderNodeCustom::_get_properties() const { + return properties; +} + String VisualShaderNodeCustom::_get_name() const { String ret; GDVIRTUAL_CALL(_get_name, ret); @@ -665,6 +736,21 @@ bool VisualShaderNodeCustom::_is_highend() const { return ret; } +void VisualShaderNodeCustom::_set_option_index(int p_option, int p_value) { + dp_selected_cache[p_option] = p_value; + update_properties(); + update_ports(); + update_input_port_default_values(); + emit_changed(); +} + +int VisualShaderNodeCustom::get_option_index(int p_option) const { + if (!dp_selected_cache.has(p_option)) { + return 0; + } + return dp_selected_cache[p_option]; +} + void VisualShaderNodeCustom::_bind_methods() { GDVIRTUAL_BIND(_get_name); GDVIRTUAL_BIND(_get_description); @@ -673,10 +759,15 @@ void VisualShaderNodeCustom::_bind_methods() { GDVIRTUAL_BIND(_get_input_port_count); GDVIRTUAL_BIND(_get_input_port_type, "port"); GDVIRTUAL_BIND(_get_input_port_name, "port"); + GDVIRTUAL_BIND(_get_input_port_default_value, "port"); GDVIRTUAL_BIND(_get_default_input_port, "type"); GDVIRTUAL_BIND(_get_output_port_count); GDVIRTUAL_BIND(_get_output_port_type, "port"); GDVIRTUAL_BIND(_get_output_port_name, "port"); + GDVIRTUAL_BIND(_get_property_count); + GDVIRTUAL_BIND(_get_property_name, "index"); + GDVIRTUAL_BIND(_get_property_default_index, "index"); + GDVIRTUAL_BIND(_get_property_options, "index"); GDVIRTUAL_BIND(_get_code, "input_vars", "output_vars", "mode", "type"); GDVIRTUAL_BIND(_get_func_code, "mode", "type"); GDVIRTUAL_BIND(_get_global_code, "mode"); @@ -686,8 +777,14 @@ void VisualShaderNodeCustom::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_initialized", "enabled"), &VisualShaderNodeCustom::_set_initialized); ClassDB::bind_method(D_METHOD("_is_initialized"), &VisualShaderNodeCustom::_is_initialized); ClassDB::bind_method(D_METHOD("_set_input_port_default_value", "port", "value"), &VisualShaderNodeCustom::_set_input_port_default_value); + ClassDB::bind_method(D_METHOD("_set_option_index", "option", "value"), &VisualShaderNodeCustom::_set_option_index); + ClassDB::bind_method(D_METHOD("_set_properties", "properties"), &VisualShaderNodeCustom::_set_properties); + ClassDB::bind_method(D_METHOD("_get_properties"), &VisualShaderNodeCustom::_get_properties); + + ClassDB::bind_method(D_METHOD("get_option_index", "option"), &VisualShaderNodeCustom::get_option_index); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "initialized", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_initialized", "_is_initialized"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "properties", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_properties", "_get_properties"); } VisualShaderNodeCustom::VisualShaderNodeCustom() { diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 1d23b80839..501a538c86 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -257,12 +257,12 @@ class VisualShaderNode : public Resource { int port_preview = -1; - HashMap<int, Variant> default_input_values; HashMap<int, bool> connected_input_ports; HashMap<int, int> connected_output_ports; HashMap<int, bool> expanded_output_ports; protected: + HashMap<int, Variant> default_input_values; bool simple_decl = true; bool disabled = false; bool closable = false; @@ -363,8 +363,19 @@ class VisualShaderNodeCustom : public VisualShaderNode { bool is_initialized = false; List<Port> input_ports; List<Port> output_ports; + struct Property { + String name; + }; + struct DropDownListProperty : public Property { + Vector<String> options; + }; + HashMap<int, int> dp_selected_cache; + HashMap<int, int> dp_default_cache; + List<DropDownListProperty> dp_props; + String properties; friend class VisualShaderEditor; + friend class VisualShaderGraphPlugin; protected: virtual String get_caption() const override; @@ -390,10 +401,15 @@ protected: GDVIRTUAL0RC(int, _get_input_port_count) GDVIRTUAL1RC(PortType, _get_input_port_type, int) GDVIRTUAL1RC(String, _get_input_port_name, int) + GDVIRTUAL1RC(Variant, _get_input_port_default_value, int) GDVIRTUAL1RC(int, _get_default_input_port, PortType) GDVIRTUAL0RC(int, _get_output_port_count) GDVIRTUAL1RC(PortType, _get_output_port_type, int) GDVIRTUAL1RC(String, _get_output_port_name, int) + GDVIRTUAL0RC(int, _get_property_count) + GDVIRTUAL1RC(String, _get_property_name, int) + GDVIRTUAL1RC(int, _get_property_default_index, int) + GDVIRTUAL1RC(Vector<String>, _get_property_options, int) GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type) GDVIRTUAL2RC(String, _get_func_code, Shader::Mode, VisualShader::Type) GDVIRTUAL1RC(String, _get_global_code, Shader::Mode) @@ -414,16 +430,24 @@ protected: public: VisualShaderNodeCustom(); + void update_property_default_values(); + void update_input_port_default_values(); void update_ports(); + void update_properties(); bool _is_initialized(); void _set_initialized(bool p_enabled); + void _set_properties(const String &p_properties); + String _get_properties() const; String _get_name() const; String _get_description() const; String _get_category() const; PortType _get_return_icon_type() const; bool _is_highend() const; + void _set_option_index(int p_op, int p_index); + + int get_option_index(int p_op) const; }; ///// diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 7696bddbca..07d56eae0c 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -418,7 +418,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende double step = RSG::camera_attributes->camera_attributes_get_auto_exposure_adjust_speed(p_render_data->camera_attributes) * time_step; float auto_exposure_min_sensitivity = RSG::camera_attributes->camera_attributes_get_auto_exposure_min_sensitivity(p_render_data->camera_attributes); float auto_exposure_max_sensitivity = RSG::camera_attributes->camera_attributes_get_auto_exposure_max_sensitivity(p_render_data->camera_attributes); - luminance->luminance_reduction(color_texture, color_size, luminance_buffers, auto_exposure_min_sensitivity, auto_exposure_max_sensitivity, step, set_immediate); + luminance->luminance_reduction(rb->get_internal_texture(), rb->get_internal_size(), luminance_buffers, auto_exposure_min_sensitivity, auto_exposure_max_sensitivity, step, set_immediate); // Swap final reduce with prev luminance. diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index b7c40600cb..9a3b7b9f3c 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2983,6 +2983,7 @@ void RenderingServer::init() { GLOBAL_DEF("rendering/limits/global_shader_variables/buffer_size", 65536); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "rendering/lightmapping/probe_capture/update_speed", PROPERTY_HINT_RANGE, "0.001,256,0.001"), 15); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "rendering/lightmapping/primitive_meshes/texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.2); GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/probe_ray_count", PROPERTY_HINT_ENUM, "8 (Fastest),16,32,64,96,128 (Slowest)"), 1); GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/frames_to_converge", PROPERTY_HINT_ENUM, "5 (Less Latency but Lower Quality),10,15,20,25,30 (More Latency but Higher Quality)"), 5); |