diff options
-rw-r--r-- | doc/classes/ProjectSettings.xml | 2 | ||||
-rw-r--r-- | doc/classes/RichTextLabel.xml | 4 | ||||
-rw-r--r-- | doc/classes/VisualShaderNodeSample3D.xml | 26 | ||||
-rw-r--r-- | doc/classes/VisualShaderNodeTexture2DArray.xml | 20 | ||||
-rw-r--r-- | editor/plugins/animation_player_editor_plugin.cpp | 15 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | main/main.cpp | 2 | ||||
-rw-r--r-- | misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj | 4 | ||||
-rw-r--r-- | misc/dist/ios_xcode/godot_ios/export_options.plist | 4 | ||||
-rwxr-xr-x | misc/dist/osx_template.app/Contents/Info.plist | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 4 | ||||
-rw-r--r-- | platform/iphone/export/export.cpp | 8 | ||||
-rw-r--r-- | platform/osx/export/export.cpp | 10 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 16 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 33 | ||||
-rw-r--r-- | scene/gui/rich_text_label.h | 7 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 3 | ||||
-rw-r--r-- | scene/resources/visual_shader_nodes.cpp | 245 | ||||
-rw-r--r-- | scene/resources/visual_shader_nodes.h | 87 |
19 files changed, 465 insertions, 29 deletions
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 92e5b4a84f..7191492098 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -821,6 +821,8 @@ </member> <member name="mono/profiler/enabled" type="bool" setter="" getter="" default="false"> </member> + <member name="mono/project/auto_update_project" type="bool" setter="" getter="" default="true"> + </member> <member name="mono/unhandled_exception_policy" type="int" setter="" getter="" default="0"> </member> <member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="32768"> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index db036d7d88..d4eba77ffa 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -294,6 +294,10 @@ The currently installed custom effects. This is an array of [RichTextEffect]s. To add a custom effect, it's more convenient to use [method install_effect]. </member> + <member name="fit_content_height" type="bool" setter="set_fit_content_height" getter="is_fit_content_height_enabled" default="false"> + If [code]true[/code], the label's height will be automatically updated to fit its content. + [b]Note:[/b] This property is used as a workaround to fix issues with [RichTextLabel] in [Container]s, but it's unreliable in some cases and will be removed in future versions. + </member> <member name="meta_underlined" type="bool" setter="set_meta_underline" getter="is_meta_underlined" default="true"> If [code]true[/code], the label underlines meta tags such as [code][url]{text}[/url][/code]. </member> diff --git a/doc/classes/VisualShaderNodeSample3D.xml b/doc/classes/VisualShaderNodeSample3D.xml new file mode 100644 index 0000000000..cf6933ab55 --- /dev/null +++ b/doc/classes/VisualShaderNodeSample3D.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeSample3D" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A base node for nodes which samples 3D textures in the visual shader graph. + </brief_description> + <description> + A virtual class, use the descendants instead. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="source" type="int" setter="set_source" getter="get_source" enum="VisualShaderNodeSample3D.Source" default="0"> + An input source type. + </member> + </members> + <constants> + <constant name="SOURCE_TEXTURE" value="0" enum="Source"> + Creates internal uniform and provides a way to assign it within node. + </constant> + <constant name="SOURCE_PORT" value="1" enum="Source"> + Use the uniform texture from sampler port. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeTexture2DArray.xml b/doc/classes/VisualShaderNodeTexture2DArray.xml new file mode 100644 index 0000000000..3c6d328ed0 --- /dev/null +++ b/doc/classes/VisualShaderNodeTexture2DArray.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTexture2DArray" inherits="VisualShaderNodeSample3D" version="4.0"> + <brief_description> + A 2D texture uniform array to be used within the visual shader graph. + </brief_description> + <description> + Translated to [code]uniform sampler2DArray[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="texture_array" type="Texture2DArray" setter="set_texture_array" getter="get_texture_array"> + A source texture array. Used if [member VisualShaderNodeSample3D.source] is set to [constant VisualShaderNodeSample3D.SOURCE_TEXTURE]. + </member> + </members> + <constants> + </constants> +</class> diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 1e0a9535e2..9a5b825683 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -380,26 +380,25 @@ void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource) file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); } + String path; //file->set_current_path(current_path); if (p_resource->get_path() != "") { - file->set_current_path(p_resource->get_path()); + path = p_resource->get_path(); if (extensions.size()) { - String ext = p_resource->get_path().get_extension().to_lower(); - if (extensions.find(ext) == nullptr) { - file->set_current_path(p_resource->get_path().replacen("." + ext, "." + extensions.front()->get())); + if (extensions.find(p_resource->get_path().get_extension().to_lower()) == nullptr) { + path = p_resource->get_path().get_base_dir() + p_resource->get_name() + "." + extensions.front()->get(); } } } else { - String existing; if (extensions.size()) { if (p_resource->get_name() != "") { - existing = p_resource->get_name() + "." + extensions.front()->get().to_lower(); + path = p_resource->get_name() + "." + extensions.front()->get().to_lower(); } else { - existing = "new_" + p_resource->get_class().to_lower() + "." + extensions.front()->get().to_lower(); + path = "new_" + p_resource->get_class().to_lower() + "." + extensions.front()->get().to_lower(); } } - file->set_current_path(existing); } + file->set_current_path(path); file->popup_centered_ratio(); file->set_title(TTR("Save Resource As...")); current_option = RESOURCE_SAVE; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 92bdba93e7..1c2a8e48d3 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -2750,8 +2750,10 @@ VisualShaderEditor::VisualShaderEditor() { texture_node_option_idx = add_options.size(); add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, -1)); add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1)); + add_options.push_back(AddOption("Texture2DArray", "Textures", "Functions", "VisualShaderNodeTexture2DArray", TTR("Perform the 2D-array texture lookup."), -1, -1, -1, -1, -1)); add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, -1)); add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, -1, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Texture2DArrayUniform", "Textures", "Variables", "VisualShaderNodeTexture2DArrayUniform", TTR("2D array of textures uniform lookup."), -1, -1, -1, -1, -1)); // TRANSFORM diff --git a/main/main.cpp b/main/main.cpp index 92b07dc83b..747b12677d 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1633,6 +1633,8 @@ bool Main::start() { GLOBAL_DEF("mono/profiler/args", "log:calls,alloc,sample,output=output.mlpd"); GLOBAL_DEF("mono/profiler/enabled", false); GLOBAL_DEF("mono/unhandled_exception_policy", 0); + // From editor/csharp_project.cpp. + GLOBAL_DEF("mono/project/auto_update_project", true); #endif DocData doc; diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj index 4b2870b67a..d21e78ccea 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj @@ -433,7 +433,7 @@ "$(inherited)", "$(PROJECT_DIR)", ); - PRODUCT_BUNDLE_IDENTIFIER = $identifier; + PRODUCT_BUNDLE_IDENTIFIER = $bundle_identifier; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = "$provisioning_profile_uuid_debug"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -459,7 +459,7 @@ "$(inherited)", "$(PROJECT_DIR)", ); - PRODUCT_BUNDLE_IDENTIFIER = $identifier; + PRODUCT_BUNDLE_IDENTIFIER = $bundle_identifier; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = "$provisioning_profile_uuid_release"; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/misc/dist/ios_xcode/godot_ios/export_options.plist b/misc/dist/ios_xcode/godot_ios/export_options.plist index 3878a4dbe6..71073d9a07 100644 --- a/misc/dist/ios_xcode/godot_ios/export_options.plist +++ b/misc/dist/ios_xcode/godot_ios/export_options.plist @@ -10,11 +10,11 @@ <key>provisioningProfiles</key> <dict> - <key>$identifier</key> + <key>$bundle_identifier</key> <string>$provisioning_profile_uuid</string> </dict> <key>compileBitcode</key> <false/> </dict> -</plist>
\ No newline at end of file +</plist> diff --git a/misc/dist/osx_template.app/Contents/Info.plist b/misc/dist/osx_template.app/Contents/Info.plist index 3b765e6bb8..aaee42aa5f 100755 --- a/misc/dist/osx_template.app/Contents/Info.plist +++ b/misc/dist/osx_template.app/Contents/Info.plist @@ -13,7 +13,7 @@ <key>CFBundleIconFile</key> <string>icon.icns</string> <key>CFBundleIdentifier</key> - <string>$identifier</string> + <string>$bundle_identifier</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 085062261d..158742846b 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -624,8 +624,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return BOX_BOOLEAN(val); } case Variant::INT: { - int32_t val = p_var->operator signed int(); - return BOX_INT32(val); + int64_t val = p_var->operator int64_t(); + return BOX_INT64(val); } case Variant::FLOAT: { #ifdef REAL_T_IS_DOUBLE diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 63c3cb8c23..aadc60175b 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -217,7 +217,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/bundle_identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0")); @@ -293,8 +293,8 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ strnew += lines[i].replace("$name", p_config.pkg_name) + "\n"; } else if (lines[i].find("$info") != -1) { strnew += lines[i].replace("$info", p_preset->get("application/info")) + "\n"; - } else if (lines[i].find("$identifier") != -1) { - strnew += lines[i].replace("$identifier", p_preset->get("application/identifier")) + "\n"; + } else if (lines[i].find("$bundle_identifier") != -1) { + strnew += lines[i].replace("$bundle_identifier", p_preset->get("application/bundle_identifier")) + "\n"; } else if (lines[i].find("$short_version") != -1) { strnew += lines[i].replace("$short_version", p_preset->get("application/short_version")) + "\n"; } else if (lines[i].find("$version") != -1) { @@ -1346,7 +1346,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset valid = false; } - String identifier = p_preset->get("application/identifier"); + String identifier = p_preset->get("application/bundle_identifier"); String pn_err; if (!is_package_name_valid(identifier, &pn_err)) { err += TTR("Invalid Identifier:") + " " + pn_err + "\n"; diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index c9b01ebbb4..8905950020 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -145,7 +145,7 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.png,*.icns"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/bundle_identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0")); @@ -354,8 +354,8 @@ void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset strnew += lines[i].replace("$name", p_binary) + "\n"; } else if (lines[i].find("$info") != -1) { strnew += lines[i].replace("$info", p_preset->get("application/info")) + "\n"; - } else if (lines[i].find("$identifier") != -1) { - strnew += lines[i].replace("$identifier", p_preset->get("application/identifier")) + "\n"; + } else if (lines[i].find("$bundle_identifier") != -1) { + strnew += lines[i].replace("$bundle_identifier", p_preset->get("application/bundle_identifier")) + "\n"; } else if (lines[i].find("$short_version") != -1) { strnew += lines[i].replace("$short_version", p_preset->get("application/short_version")) + "\n"; } else if (lines[i].find("$version") != -1) { @@ -399,7 +399,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset args.push_back("--notarize-app"); args.push_back("--primary-bundle-id"); - args.push_back(p_preset->get("application/identifier")); + args.push_back(p_preset->get("application/bundle_identifier")); args.push_back("--username"); args.push_back(p_preset->get("notarization/apple_id_name")); @@ -885,7 +885,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset valid = dvalid || rvalid; r_missing_templates = !valid; - String identifier = p_preset->get("application/identifier"); + String identifier = p_preset->get("application/bundle_identifier"); String pn_err; if (!is_package_name_valid(identifier, &pn_err)) { err += TTR("Invalid bundle identifier:") + " " + pn_err + "\n"; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index ee6783167a..ba55927980 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -274,6 +274,22 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { set_cursor_position(text.length()); shift_selection_check_post(k->get_shift()); } break; + case (KEY_BACKSPACE): { + if (!editable) + break; + + // If selected, delete the selection + if (selection.enabled) { + selection_delete(); + break; + } + + // Otherwise delete from cursor to beginning of text edit + int current_pos = get_cursor_position(); + if (current_pos != 0) { + delete_text(0, current_pos); + } + } break; #endif default: { handled = false; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 92508f7fd2..5ae27081ea 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1570,6 +1570,10 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { } updating_scroll = false; + + if (fit_content_height) { + minimum_size_changed(); + } } void RichTextLabel::_invalidate_current_line(ItemFrame *p_frame) { @@ -1989,6 +1993,17 @@ int RichTextLabel::get_tab_size() const { return tab_size; } +void RichTextLabel::set_fit_content_height(bool p_enabled) { + if (p_enabled != fit_content_height) { + fit_content_height = p_enabled; + minimum_size_changed(); + } +} + +bool RichTextLabel::is_fit_content_height_enabled() const { + return fit_content_height; +} + void RichTextLabel::set_meta_underline(bool p_underline) { underline_meta = p_underline; update(); @@ -2646,7 +2661,7 @@ void RichTextLabel::install_effect(const Variant effect) { } } -int RichTextLabel::get_content_height() { +int RichTextLabel::get_content_height() const { int total_height = 0; if (main->lines.size()) { total_height = main->lines[main->lines.size() - 1].height_accum_cache + get_theme_stylebox("normal")->get_minimum_size().height; @@ -2701,6 +2716,9 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tab_size", "spaces"), &RichTextLabel::set_tab_size); ClassDB::bind_method(D_METHOD("get_tab_size"), &RichTextLabel::get_tab_size); + ClassDB::bind_method(D_METHOD("set_fit_content_height", "enabled"), &RichTextLabel::set_fit_content_height); + ClassDB::bind_method(D_METHOD("is_fit_content_height_enabled"), &RichTextLabel::is_fit_content_height_enabled); + ClassDB::bind_method(D_METHOD("set_selection_enabled", "enabled"), &RichTextLabel::set_selection_enabled); ClassDB::bind_method(D_METHOD("is_selection_enabled"), &RichTextLabel::is_selection_enabled); @@ -2743,6 +2761,8 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_size", PROPERTY_HINT_RANGE, "0,24,1"), "set_tab_size", "get_tab_size"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fit_content_height"), "set_fit_content_height", "is_fit_content_height_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_active"), "set_scroll_active", "is_scroll_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_following"), "set_scroll_follow", "is_scroll_following"); @@ -2809,12 +2829,17 @@ void RichTextLabel::set_fixed_size_to_width(int p_width) { } Size2 RichTextLabel::get_minimum_size() const { + Size2 size(0, 0); if (fixed_width != -1) { + size.x = fixed_width; + } + + if (fixed_width != -1 || fit_content_height) { const_cast<RichTextLabel *>(this)->_validate_line_caches(main); - return Size2(fixed_width, const_cast<RichTextLabel *>(this)->get_content_height()); + size.y = get_content_height(); } - return Size2(); + return size; } Ref<RichTextEffect> RichTextLabel::_get_custom_effect_by_code(String p_bbcode_identifier) { @@ -2934,6 +2959,8 @@ RichTextLabel::RichTextLabel() { visible_line_count = 0; fixed_width = -1; + fit_content_height = false; + set_clip_contents(true); } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 4cec435568..7eeb071cb5 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -403,6 +403,8 @@ private: int fixed_width; + bool fit_content_height; + protected: void _notification(int p_what); @@ -456,13 +458,16 @@ public: void set_tab_size(int p_spaces); int get_tab_size() const; + void set_fit_content_height(bool p_enabled); + bool is_fit_content_height_enabled() const; + bool search(const String &p_string, bool p_from_selection = false, bool p_search_previous = false); void scroll_to_line(int p_line); int get_line_count() const; int get_visible_line_count() const; - int get_content_height(); + int get_content_height() const; VScrollBar *get_v_scroll() { return vscroll; } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 2d0e2daf41..ad8a43743a 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -541,6 +541,8 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeVectorDecompose>(); ClassDB::register_class<VisualShaderNodeTransformDecompose>(); ClassDB::register_class<VisualShaderNodeTexture>(); + ClassDB::register_virtual_class<VisualShaderNodeSample3D>(); + ClassDB::register_class<VisualShaderNodeTexture2DArray>(); ClassDB::register_class<VisualShaderNodeCubemap>(); ClassDB::register_virtual_class<VisualShaderNodeUniform>(); ClassDB::register_class<VisualShaderNodeFloatUniform>(); @@ -551,6 +553,7 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeTransformUniform>(); ClassDB::register_class<VisualShaderNodeTextureUniform>(); ClassDB::register_class<VisualShaderNodeTextureUniformTriplanar>(); + ClassDB::register_class<VisualShaderNodeTexture2DArrayUniform>(); ClassDB::register_class<VisualShaderNodeCubemapUniform>(); ClassDB::register_class<VisualShaderNodeIf>(); ClassDB::register_class<VisualShaderNodeSwitch>(); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 87720cf110..5c6b13a527 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -781,6 +781,183 @@ VisualShaderNodeTexture::VisualShaderNodeTexture() { source = SOURCE_TEXTURE; } +////////////// Sample3D + +int VisualShaderNodeSample3D::get_input_port_count() const { + return 3; +} + +VisualShaderNodeSample3D::PortType VisualShaderNodeSample3D::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SAMPLER; + default: + return PORT_TYPE_SCALAR; + } +} + +String VisualShaderNodeSample3D::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "uvw"; + case 1: + return "lod"; + default: + return ""; + } +} + +int VisualShaderNodeSample3D::get_output_port_count() const { + return 2; +} + +VisualShaderNodeSample3D::PortType VisualShaderNodeSample3D::get_output_port_type(int p_port) const { + return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; +} + +String VisualShaderNodeSample3D::get_output_port_name(int p_port) const { + return p_port == 0 ? "rgb" : "alpha"; +} + +String VisualShaderNodeSample3D::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "vec3(UV.xy, 0.0)"; + } + return ""; +} + +String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + if (source == SOURCE_TEXTURE || source == SOURCE_PORT) { + String id; + code += "\t{\n"; + if (source == SOURCE_TEXTURE) { + id = make_unique_id(p_type, p_id, "tex3d"); + } else { + id = p_input_vars[2]; + } + if (id != String()) { + if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[1] == String()) { + code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", vec3(UV.xy, 0.0));\n"; + } else { + code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", vec3(UV.xy, 0.0), " + p_input_vars[1] + ");\n"; + } + } else if (p_input_vars[1] == String()) { + //no lod + code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; + } else { + code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; + } + } else { + code += "\t\tvec4 " + id + "_tex_read = vec4(0.0);\n"; + } + + code += "\t\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n"; + code += "\t\t" + p_output_vars[1] + " = " + id + "_tex_read.a;\n"; + code += "\t}\n"; + return code; + } + code += "\t" + p_output_vars[0] + " = vec3(0.0);\n"; + code += "\t" + p_output_vars[1] + " = 1.0;\n"; + return code; +} + +void VisualShaderNodeSample3D::set_source(Source p_source) { + source = p_source; + emit_changed(); + emit_signal("editor_refresh_request"); +} + +VisualShaderNodeSample3D::Source VisualShaderNodeSample3D::get_source() const { + return source; +} + +void VisualShaderNodeSample3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeSample3D::set_source); + ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeSample3D::get_source); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source"); + + BIND_ENUM_CONSTANT(SOURCE_TEXTURE); + BIND_ENUM_CONSTANT(SOURCE_PORT); +} + +String VisualShaderNodeSample3D::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + if (source == SOURCE_TEXTURE) { + return String(); // all good + } + if (source == SOURCE_PORT) { + return String(); // all good + } + return TTR("Invalid source for shader."); +} + +VisualShaderNodeSample3D::VisualShaderNodeSample3D() { + source = SOURCE_TEXTURE; + simple_decl = false; +} + +////////////// Texture2DArray + +String VisualShaderNodeTexture2DArray::get_caption() const { + return "Texture2DArray"; +} + +String VisualShaderNodeTexture2DArray::get_input_port_name(int p_port) const { + if (p_port == 2) { + return "sampler2DArray"; + } + return VisualShaderNodeSample3D::get_input_port_name(p_port); +} + +Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture2DArray::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { + VisualShader::DefaultTextureParam dtp; + dtp.name = make_unique_id(p_type, p_id, "tex3d"); + dtp.param = texture; + Vector<VisualShader::DefaultTextureParam> ret; + ret.push_back(dtp); + return ret; +} + +String VisualShaderNodeTexture2DArray::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + if (source == SOURCE_TEXTURE) { + return "uniform sampler2DArray " + make_unique_id(p_type, p_id, "tex3d") + ";\n"; + } + return String(); +} + +void VisualShaderNodeTexture2DArray::set_texture_array(Ref<Texture2DArray> p_value) { + texture = p_value; + emit_changed(); +} + +Ref<Texture2DArray> VisualShaderNodeTexture2DArray::get_texture_array() const { + return texture; +} + +Vector<StringName> VisualShaderNodeTexture2DArray::get_editable_properties() const { + Vector<StringName> props; + props.push_back("source"); + if (source == SOURCE_TEXTURE) { + props.push_back("texture_array"); + } + return props; +} + +void VisualShaderNodeTexture2DArray::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture_array", "value"), &VisualShaderNodeTexture2DArray::set_texture_array); + ClassDB::bind_method(D_METHOD("get_texture_array"), &VisualShaderNodeTexture2DArray::get_texture_array); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_array", PROPERTY_HINT_RESOURCE_TYPE, "Texture2DArray"), "set_texture_array", "get_texture_array"); +} + +VisualShaderNodeTexture2DArray::VisualShaderNodeTexture2DArray() { +} ////////////// Cubemap String VisualShaderNodeCubemap::get_caption() const { @@ -3926,6 +4103,74 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_default_hint(int VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { } +////////////// Texture2DArray Uniform + +String VisualShaderNodeTexture2DArrayUniform::get_caption() const { + return "Texture2DArrayUniform"; +} + +int VisualShaderNodeTexture2DArrayUniform::get_output_port_count() const { + return 1; +} + +VisualShaderNodeTexture2DArrayUniform::PortType VisualShaderNodeTexture2DArrayUniform::get_output_port_type(int p_port) const { + return PORT_TYPE_SAMPLER; +} + +String VisualShaderNodeTexture2DArrayUniform::get_output_port_name(int p_port) const { + return "sampler2DArray"; +} + +int VisualShaderNodeTexture2DArrayUniform::get_input_port_count() const { + return 0; +} + +VisualShaderNodeTexture2DArrayUniform::PortType VisualShaderNodeTexture2DArrayUniform::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeTexture2DArrayUniform::get_input_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeTexture2DArrayUniform::get_input_port_default_hint(int p_port) const { + return ""; +} + +String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler2DArray " + get_uniform_name(); + + switch (texture_type) { + case TYPE_DATA: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black;\n"; + else + code += ";\n"; + break; + case TYPE_COLOR: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black_albedo;\n"; + else + code += " : hint_albedo;\n"; + break; + case TYPE_NORMALMAP: + code += " : hint_normal;\n"; + break; + case TYPE_ANISO: + code += " : hint_aniso;\n"; + break; + } + + return code; +} + +String VisualShaderNodeTexture2DArrayUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return String(); +} + +VisualShaderNodeTexture2DArrayUniform::VisualShaderNodeTexture2DArrayUniform() { +} + ////////////// Cubemap Uniform String VisualShaderNodeCubemapUniform::get_caption() const { diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 69f42f621a..28a9de6819 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -236,7 +236,7 @@ public: enum TextureType { TYPE_DATA, TYPE_COLOR, - TYPE_NORMALMAP + TYPE_NORMALMAP, }; private: @@ -284,6 +284,68 @@ VARIANT_ENUM_CAST(VisualShaderNodeTexture::Source) /////////////////////////////////////// +class VisualShaderNodeSample3D : public VisualShaderNode { + GDCLASS(VisualShaderNodeSample3D, VisualShaderNode); + +public: + enum Source { + SOURCE_TEXTURE, + SOURCE_PORT, + }; + +protected: + Source source; + + static void _bind_methods(); + +public: + virtual String get_caption() const = 0; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const = 0; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_source(Source p_source); + Source get_source() const; + + virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const; + + VisualShaderNodeSample3D(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeSample3D::Source) + +class VisualShaderNodeTexture2DArray : public VisualShaderNodeSample3D { + GDCLASS(VisualShaderNodeTexture2DArray, VisualShaderNodeSample3D); + Ref<Texture2DArray> texture; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual String get_input_port_name(int p_port) const; + + virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + + void set_texture_array(Ref<Texture2DArray> p_value); + Ref<Texture2DArray> get_texture_array() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeTexture2DArray(); +}; + class VisualShaderNodeCubemap : public VisualShaderNode { GDCLASS(VisualShaderNodeCubemap, VisualShaderNode); Ref<Cubemap> cube_map; @@ -1695,6 +1757,29 @@ public: /////////////////////////////////////// +class VisualShaderNodeTexture2DArrayUniform : public VisualShaderNodeTextureUniform { + GDCLASS(VisualShaderNodeTexture2DArrayUniform, VisualShaderNodeTextureUniform); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + virtual String get_input_port_default_hint(int p_port) const; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + VisualShaderNodeTexture2DArrayUniform(); +}; + +/////////////////////////////////////// + class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform { GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform); |