summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format231
-rw-r--r--.git-blame-ignore-revs3
-rw-r--r--.github/workflows/godot_cpp_test.yml53
-rw-r--r--.github/workflows/static_checks.yml4
-rw-r--r--.pre-commit-config.yaml2
-rw-r--r--core/io/resource_loader.cpp4
-rw-r--r--core/math/basis.h8
-rw-r--r--core/object/object.cpp34
-rw-r--r--core/object/object.h5
-rw-r--r--core/register_core_types.cpp1
-rw-r--r--core/string/translation_domain.cpp165
-rw-r--r--core/string/translation_domain.h65
-rw-r--r--core/string/translation_server.cpp254
-rw-r--r--core/string/translation_server.h25
-rw-r--r--core/variant/array.cpp65
-rw-r--r--core/variant/array.h2
-rw-r--r--core/variant/variant_call.cpp2
-rw-r--r--doc/classes/Array.xml39
-rw-r--r--doc/classes/CompositorEffect.xml2
-rw-r--r--doc/classes/EditorPlugin.xml2
-rw-r--r--doc/classes/Node.xml7
-rw-r--r--doc/classes/Object.xml15
-rw-r--r--doc/classes/ProjectSettings.xml4
-rw-r--r--doc/classes/RenderingServer.xml26
-rw-r--r--doc/classes/TextEdit.xml3
-rw-r--r--doc/classes/TranslationDomain.xml60
-rw-r--r--doc/classes/TranslationServer.xml40
-rw-r--r--doc/classes/Viewport.xml12
-rw-r--r--drivers/gles3/shaders/sky.glsl2
-rw-r--r--drivers/gles3/storage/render_scene_buffers_gles3.h6
-rw-r--r--drivers/gles3/storage/texture_storage.cpp18
-rw-r--r--drivers/gles3/storage/texture_storage.h8
-rw-r--r--drivers/metal/metal_objects.h7
-rw-r--r--drivers/metal/metal_objects.mm4
-rw-r--r--editor/action_map_editor.cpp3
-rw-r--r--editor/animation_bezier_editor.cpp14
-rw-r--r--editor/animation_track_editor.cpp1
-rw-r--r--editor/code_editor.cpp8
-rw-r--r--editor/create_dialog.cpp1
-rw-r--r--editor/directory_create_dialog.cpp11
-rw-r--r--editor/editor_audio_buses.cpp3
-rw-r--r--editor/editor_autoload_settings.cpp1
-rw-r--r--editor/editor_file_system.cpp51
-rw-r--r--editor/editor_file_system.h2
-rw-r--r--editor/editor_inspector.cpp1
-rw-r--r--editor/editor_node.cpp19
-rw-r--r--editor/editor_resource_preview.h2
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--editor/editor_settings_dialog.cpp2
-rw-r--r--editor/editor_translation.cpp16
-rw-r--r--editor/export/editor_export_platform.h2
-rw-r--r--editor/export/project_export.cpp1
-rw-r--r--editor/filesystem_dock.cpp49
-rw-r--r--editor/filesystem_dock.h2
-rw-r--r--editor/gui/editor_dir_dialog.cpp1
-rw-r--r--editor/gui/editor_file_dialog.cpp4
-rw-r--r--editor/gui/editor_title_bar.h2
-rw-r--r--editor/gui/scene_tree_editor.cpp1
-rw-r--r--editor/localization_editor.cpp2
-rw-r--r--editor/plugins/animation_state_machine_editor.h2
-rw-r--r--editor/plugins/font_config_plugin.h12
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.h2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp1
-rw-r--r--editor/plugins/shader_editor_plugin.cpp1
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp1
-rw-r--r--editor/plugins/text_editor.h4
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp2
-rw-r--r--editor/plugins/tiles/tile_data_editors.h12
-rw-r--r--editor/plugins/tiles/tile_map_layer_editor.h6
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp2
-rw-r--r--editor/project_manager.cpp2
-rw-r--r--editor/project_settings_editor.cpp4
-rw-r--r--main/main.cpp1
-rw-r--r--modules/bmp/image_loader_bmp.cpp67
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.h4
-rw-r--r--modules/mono/csharp_script.cpp41
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.OpenVisualStudio/GodotTools.OpenVisualStudio.csproj1
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs3
-rw-r--r--modules/mono/editor/bindings_generator.cpp24
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs4
-rw-r--r--modules/navigation/nav_base.h2
-rw-r--r--modules/openxr/extensions/platform/openxr_opengl_extension.cpp4
-rw-r--r--modules/text_server_adv/text_server_adv.h2
-rw-r--r--modules/text_server_fb/text_server_fb.h2
-rw-r--r--modules/webxr/webxr_interface_js.cpp4
-rw-r--r--platform/android/display_server_android.cpp14
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java2
-rw-r--r--platform/ios/display_server_ios.mm14
-rw-r--r--platform/linuxbsd/export/export_plugin.h2
-rw-r--r--platform/linuxbsd/joypad_linux.cpp2
-rw-r--r--platform/linuxbsd/wayland/key_mapping_xkb.h2
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp32
-rw-r--r--platform/linuxbsd/x11/gl_manager_x11_egl.h4
-rw-r--r--platform/macos/display_server_macos.mm12
-rw-r--r--platform/macos/export/export_plugin.h2
-rw-r--r--platform/windows/detect.py13
-rw-r--r--platform/windows/display_server_windows.cpp13
-rw-r--r--platform/windows/export/export_plugin.h2
-rw-r--r--platform/windows/gl_manager_windows_angle.h4
-rw-r--r--scene/2d/tile_map_layer.h2
-rw-r--r--scene/3d/audio_stream_player_3d.cpp11
-rw-r--r--scene/3d/audio_stream_player_3d.h1
-rw-r--r--scene/animation/animation_blend_tree.cpp6
-rw-r--r--scene/gui/color_mode.h14
-rw-r--r--scene/gui/line_edit.cpp1
-rw-r--r--scene/gui/rich_text_label.cpp1
-rw-r--r--scene/gui/tab_bar.cpp1
-rw-r--r--scene/gui/tab_container.cpp9
-rw-r--r--scene/gui/text_edit.cpp1
-rw-r--r--scene/main/node.cpp47
-rw-r--r--scene/main/node.h8
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/resources/2d/tile_set.h38
-rw-r--r--scene/resources/3d/primitive_meshes.h6
-rw-r--r--scene/resources/camera_attributes.h2
-rw-r--r--servers/rendering/dummy/storage/material_storage.h2
-rw-r--r--servers/rendering/dummy/storage/texture_storage.h50
-rw-r--r--servers/rendering/renderer_rd/environment/fog.h4
-rw-r--r--servers/rendering/renderer_rd/environment/gi.h4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h10
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp5
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h6
-rw-r--r--servers/rendering/renderer_rd/shader_rd.h2
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl12
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sky.glsl6
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl10
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl12
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl6
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp189
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h2
-rw-r--r--servers/rendering/renderer_scene_occlusion_cull.h2
-rw-r--r--servers/rendering/rendering_device_commons.h2
-rw-r--r--servers/rendering/rendering_server_default.h5
-rw-r--r--servers/rendering/storage/material_storage.h2
-rw-r--r--servers/rendering/storage/render_scene_buffers.h8
-rw-r--r--servers/rendering/storage/texture_storage.h4
-rw-r--r--servers/rendering_server.cpp5
-rw-r--r--servers/rendering_server.h9
-rw-r--r--servers/xr/xr_controller_tracker.cpp2
-rw-r--r--servers/xr/xr_interface.h4
-rw-r--r--tests/core/variant/test_array.h18
143 files changed, 1519 insertions, 725 deletions
diff --git a/.clang-format b/.clang-format
index 1df6c35bfb..eda00dd8dd 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,29 +1,59 @@
# Commented out parameters are those with the same value as base LLVM style.
# We can uncomment them if we want to change their value, or enforce the
-# chosen value in case the base style changes (last sync: Clang 14.0).
----
-### General config, applies to all languages ###
-BasedOnStyle: LLVM
+# chosen value in case the base style changes (last sync: Clang 18.1.8).
+BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
# AlignArrayOfStructures: None
-# AlignConsecutiveMacros: None
-# AlignConsecutiveAssignments: None
-# AlignConsecutiveBitFields: None
-# AlignConsecutiveDeclarations: None
+# AlignConsecutiveAssignments:
+# Enabled: false
+# AcrossEmptyLines: false
+# AcrossComments: false
+# AlignCompound: false
+# AlignFunctionPointers: false
+# PadOperators: true
+# AlignConsecutiveBitFields:
+# Enabled: false
+# AcrossEmptyLines: false
+# AcrossComments: false
+# AlignCompound: false
+# AlignFunctionPointers: false
+# PadOperators: false
+# AlignConsecutiveDeclarations:
+# Enabled: false
+# AcrossEmptyLines: false
+# AcrossComments: false
+# AlignCompound: false
+# AlignFunctionPointers: false
+# PadOperators: false
+# AlignConsecutiveMacros:
+# Enabled: false
+# AcrossEmptyLines: false
+# AcrossComments: false
+# AlignCompound: false
+# AlignFunctionPointers: false
+# PadOperators: false
+# AlignConsecutiveShortCaseStatements:
+# Enabled: false
+# AcrossEmptyLines: false
+# AcrossComments: false
+# AlignCaseColons: false
# AlignEscapedNewlines: Right
-AlignOperands: DontAlign
-AlignTrailingComments: false
+AlignOperands: DontAlign
+AlignTrailingComments:
+ Kind: Never
+ OverEmptyLines: 0
# AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
-# AllowShortEnumsOnASingleLine: true
+# AllowBreakBeforeNoexceptSpecifier: Never
# AllowShortBlocksOnASingleLine: Never
# AllowShortCaseLabelsOnASingleLine: false
+# AllowShortCompoundRequirementOnASingleLine: true
+# AllowShortEnumsOnASingleLine: true
# AllowShortFunctionsOnASingleLine: All
-# AllowShortLambdasOnASingleLine: All
# AllowShortIfStatementsOnASingleLine: Never
+# AllowShortLambdasOnASingleLine: All
# AllowShortLoopsOnASingleLine: false
-# AlwaysBreakAfterDefinitionReturnType: None
# AlwaysBreakAfterReturnType: None
# AlwaysBreakBeforeMultilineStrings: false
# AlwaysBreakTemplateDeclarations: MultiLine
@@ -31,50 +61,49 @@ AllowAllParametersOfDeclarationOnNextLine: false
# - __capability
# BinPackArguments: true
# BinPackParameters: true
+# BitFieldColonSpacing: Both
# BraceWrapping:
-# AfterCaseLabel: false
-# AfterClass: false
+# AfterCaseLabel: false
+# AfterClass: false
# AfterControlStatement: Never
-# AfterEnum: false
-# AfterFunction: false
-# AfterNamespace: false
+# AfterEnum: false
+# AfterFunction: false
+# AfterNamespace: false
# AfterObjCDeclaration: false
-# AfterStruct: false
-# AfterUnion: false
+# AfterStruct: false
+# AfterUnion: false
# AfterExternBlock: false
-# BeforeCatch: false
-# BeforeElse: false
+# BeforeCatch: false
+# BeforeElse: false
# BeforeLambdaBody: false
-# BeforeWhile: false
-# IndentBraces: false
+# BeforeWhile: false
+# IndentBraces: false
# SplitEmptyFunction: true
# SplitEmptyRecord: true
# SplitEmptyNamespace: true
+# BreakAdjacentStringLiterals: true
+# BreakAfterAttributes: Leave
+# BreakAfterJavaFieldAnnotations: false
+# BreakArrays: true
# BreakBeforeBinaryOperators: None
-# BreakBeforeConceptDeclarations: true
# BreakBeforeBraces: Attach
-# BreakBeforeInheritanceComma: false
-# BreakInheritanceList: BeforeColon
+# BreakBeforeConceptDeclarations: Always
+# BreakBeforeInlineASMColon: OnlyMultiline
# BreakBeforeTernaryOperators: true
-# BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon
+# BreakInheritanceList: BeforeColon
# BreakStringLiterals: true
-ColumnLimit: 0
-# CommentPragmas: '^ IWYU pragma:'
-# QualifierAlignment: Leave
+ColumnLimit: 0
+# CommentPragmas: '^ IWYU pragma:'
# CompactNamespaces: false
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
-# DeriveLineEnding: true
# DerivePointerAlignment: false
-# DisableFormat: false
+# DisableFormat: false
# EmptyLineAfterAccessModifier: Never
# EmptyLineBeforeAccessModifier: LogicalBlock
# ExperimentalAutoDetectBinPacking: false
-# PackConstructorInitializers: BinPack
-ConstructorInitializerAllOnOneLineOrOnePerLine: true
-# AllowAllConstructorInitializersOnNextLine: true
# FixNamespaceComments: true
# ForEachMacros:
# - foreach
@@ -82,118 +111,138 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: true
# - BOOST_FOREACH
# IfMacros:
# - KJ_IF_MAYBE
-# IncludeBlocks: Preserve
+# IncludeBlocks: Preserve
IncludeCategories:
- - Regex: '".*"'
- Priority: 1
- - Regex: '^<.*\.h>'
- Priority: 2
- - Regex: '^<.*'
- Priority: 3
-# IncludeIsMainRegex: '(Test)?$'
+ - Regex: ^".*"$
+ Priority: 1
+ - Regex: ^<.*\.h>$
+ Priority: 2
+ - Regex: ^<.*>$
+ Priority: 3
+# IncludeIsMainRegex: (Test)?$
# IncludeIsMainSourceRegex: ''
# IndentAccessModifiers: false
-IndentCaseLabels: true
# IndentCaseBlocks: false
+IndentCaseLabels: true
+# IndentExternBlock: AfterExternBlock
# IndentGotoLabels: true
# IndentPPDirectives: None
-# IndentExternBlock: AfterExternBlock
-# IndentRequires: false
-IndentWidth: 4
+# IndentRequiresClause: true
+IndentWidth: 4
# IndentWrappedFunctionNames: false
+# InsertBraces: false
+# InsertNewlineAtEOF: false
# InsertTrailingCommas: None
+# IntegerLiteralSeparator:
+# Binary: 0
+# BinaryMinDigits: 0
+# Decimal: 0
+# DecimalMinDigits: 0
+# Hex: 0
+# HexMinDigits: 0
+JavaImportGroups:
+ - org.godotengine
+ - android
+ - androidx
+ - com.android
+ - com.google
+ - java
+ - javax
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
+# KeepEmptyLinesAtEOF: false
KeepEmptyLinesAtTheStartOfBlocks: false
# LambdaBodyIndentation: Signature
+# Language: Cpp
+# LineEnding: DeriveLF
# MacroBlockBegin: ''
-# MacroBlockEnd: ''
+# MacroBlockEnd: ''
# MaxEmptyLinesToKeep: 1
# NamespaceIndentation: None
+# ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 4
+# ObjCBreakBeforeNestedBlockParam: true
+# ObjCSpaceAfterProperty: false
+# ObjCSpaceBeforeProtocolList: true
+# PPIndentWidth: -1
+PackConstructorInitializers: NextLine
# PenaltyBreakAssignment: 2
# PenaltyBreakBeforeFirstCallParameter: 19
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakOpenParenthesis: 0
+# PenaltyBreakScopeResolution: 500
# PenaltyBreakString: 1000
# PenaltyBreakTemplateDeclaration: 10
# PenaltyExcessCharacter: 1000000
-# PenaltyReturnTypeOnItsOwnLine: 60
# PenaltyIndentedWhitespace: 0
+# PenaltyReturnTypeOnItsOwnLine: 60
# PointerAlignment: Right
-# PPIndentWidth: -1
+# QualifierAlignment: Leave
# ReferenceAlignment: Pointer
-# ReflowComments: true
+# ReflowComments: true
# RemoveBracesLLVM: false
+# RemoveParentheses: Leave
+# RemoveSemicolon: false
+# RequiresClausePosition: OwnLine
+# RequiresExpressionIndentation: OuterScope
# SeparateDefinitionBlocks: Leave
# ShortNamespaceLines: 1
-# SortIncludes: CaseSensitive
+# SkipMacroDefinitionBody: false
+# SortIncludes: CaseSensitive
# SortJavaStaticImport: Before
-# SortUsingDeclarations: true
+# SortUsingDeclarations: LexicographicNumeric
# SpaceAfterCStyleCast: false
# SpaceAfterLogicalNot: false
# SpaceAfterTemplateKeyword: true
+# SpaceAroundPointerQualifiers: Default
# SpaceBeforeAssignmentOperators: true
# SpaceBeforeCaseColon: false
# SpaceBeforeCpp11BracedList: false
# SpaceBeforeCtorInitializerColon: true
# SpaceBeforeInheritanceColon: true
-# SpaceBeforeParens: ControlStatements
+# SpaceBeforeJsonColon: false
# SpaceBeforeParensOptions:
# AfterControlStatements: true
# AfterForeachMacros: true
-# AfterFunctionDefinitionName: false
# AfterFunctionDeclarationName: false
-# AfterIfMacros: true
+# AfterFunctionDefinitionName: false
+# AfterIfMacros: true
# AfterOverloadedOperator: false
+# AfterPlacementOperator: true
+# AfterRequiresInClause: false
+# AfterRequiresInExpression: false
# BeforeNonEmptyParentheses: false
-# SpaceAroundPointerQualifiers: Default
# SpaceBeforeRangeBasedForLoopColon: true
+# SpaceBeforeSquareBrackets: false
# SpaceInEmptyBlock: false
-# SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 1
-# SpacesInAngles: Never
-# SpacesInConditionalStatement: false
+# SpacesInAngles: Never
# SpacesInContainerLiterals: true
-# SpacesInCStyleCastParentheses: false
## Godot TODO: We'll want to use a min of 1, but we need to see how to fix
## our comment capitalization at the same time.
SpacesInLineCommentPrefix:
- Minimum: 0
- Maximum: -1
-# SpacesInParentheses: false
+ Minimum: 0
+ Maximum: -1
+# SpacesInParens: Never
+# SpacesInParensOptions:
+# InConditionalStatements: false
+# InCStyleCasts: false
+# InEmptyParentheses: false
+# Other: false
# SpacesInSquareBrackets: false
-# SpaceBeforeSquareBrackets: false
-# BitFieldColonSpacing: Both
+Standard: c++17
# StatementAttributeLikeMacros:
# - Q_EMIT
# StatementMacros:
# - Q_UNUSED
# - QT_REQUIRE_VERSION
-TabWidth: 4
-# UseCRLF: false
-UseTab: Always
+TabWidth: 4
+UseTab: Always
+# VerilogBreakBetweenInstancePorts: true
# WhitespaceSensitiveMacros:
-# - STRINGIZE
-# - PP_STRINGIZE
# - BOOST_PP_STRINGIZE
-# - NS_SWIFT_NAME
# - CF_SWIFT_NAME
----
-### C++ specific config ###
-Language: Cpp
-Standard: c++17
----
-### ObjC specific config ###
-Language: ObjC
-# ObjCBinPackProtocolList: Auto
-ObjCBlockIndentWidth: 4
-# ObjCBreakBeforeNestedBlockParam: true
-# ObjCSpaceAfterProperty: false
-# ObjCSpaceBeforeProtocolList: true
----
-### Java specific config ###
-Language: Java
-# BreakAfterJavaFieldAnnotations: false
-JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax']
-...
+# - NS_SWIFT_NAME
+# - PP_STRINGIZE
+# - STRINGIZE
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index ebfd3b515a..1c78dde7a4 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -54,3 +54,6 @@ df61dc4b2bd54a5a40c515493c76f5a458e5b541
# Enforce template syntax `typename` over `class`
9903e6779b70fc03aae70a37b9cf053f4f355b91
+
+# Style: Apply new `clang-format` fixes
+b37fc1014abf7adda70dc30b0822d775b3a4433f
diff --git a/.github/workflows/godot_cpp_test.yml b/.github/workflows/godot_cpp_test.yml
index 61bb0d1d8d..e26c109d75 100644
--- a/.github/workflows/godot_cpp_test.yml
+++ b/.github/workflows/godot_cpp_test.yml
@@ -21,49 +21,44 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
with:
- submodules: recursive
-
- - name: Setup Python and SCons
- uses: ./.github/actions/godot-deps
+ sparse-checkout: .github
- # Checkout godot-cpp
- name: Checkout godot-cpp
uses: actions/checkout@v4
with:
+ submodules: recursive
repository: godotengine/godot-cpp
ref: ${{ env.GODOT_CPP_BRANCH }}
- submodules: recursive
path: godot-cpp
- # Download generated API dump
+ - name: Setup Python and SCons
+ uses: ./.github/actions/godot-deps
+
+ - name: Setup GCC problem matcher
+ uses: ammaraskar/gcc-problem-matcher@master
+
- name: Download GDExtension interface and API dump
uses: ./.github/actions/download-artifact
with:
name: godot-api-dump
- path: ./godot-api
+ path: ./godot-cpp/gdextension
- # Extract and override existing files with generated files
- - name: Extract GDExtension interface and API dump
- run: |
- cp -f godot-api/gdextension_interface.h godot-cpp/gdextension/
- cp -f godot-api/extension_api.json godot-cpp/gdextension/
+ # TODO: Enable caching when godot-cpp has proper cache limiting.
- # TODO: Add caching to the SCons build and store it for CI via the godot-cache
- # action.
+ # - name: Restore Godot build cache
+ # uses: ./.github/actions/godot-cache-restore
+ # with:
+ # cache-name: godot-cpp
+ # continue-on-error: true
- # Build godot-cpp test extension
- name: Build godot-cpp test extension
- run: |
- cd godot-cpp/test
- scons target=template_debug dev_build=yes
- cd ../..
-
- gdextension-c-compile:
- runs-on: 'ubuntu-20.04'
- name: 'Check GDExtension header with a C compiler'
- steps:
- - uses: actions/checkout@v4
+ env: # Keep synced with godot-build.
+ SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
+ SCONS_CACHE_LIMIT: 7168
+ run: scons --directory=./godot-cpp/test target=template_debug dev_build=yes verbose=yes
- - name: 'Run C compiler on gdextension_interface.h'
- run: |
- gcc -c core/extension/gdextension_interface.h
+ # - name: Save Godot build cache
+ # uses: ./.github/actions/godot-cache-save
+ # with:
+ # cache-name: godot-cpp
+ # continue-on-error: true
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index 233ab569a2..ff102a06cc 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -57,3 +57,7 @@ jobs:
- name: Class reference schema checks
run: |
xmllint --noout --schema doc/class.xsd doc/classes/*.xml modules/*/doc_classes/*.xml platform/*/doc_classes/*.xml
+
+ - name: Run C compiler on `gdextension_interface.h`
+ run: |
+ gcc -c core/extension/gdextension_interface.h
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a3bf09bb56..cb25337fad 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -9,7 +9,7 @@ exclude: |
repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
- rev: v17.0.6
+ rev: v18.1.8
hooks:
- id: clang-format
files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java|glsl)$
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 94f6caf6eb..f026d5416c 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -303,10 +303,6 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin
return res;
}
- if (r_error) {
- *r_error = ERR_FILE_UNRECOGNIZED;
- }
-
ERR_FAIL_COND_V_MSG(found, Ref<Resource>(),
vformat("Failed loading resource: %s. Make sure resources have been imported by opening the project in the editor at least once.", p_path));
diff --git a/core/math/basis.h b/core/math/basis.h
index 5c1a5fbdda..236d666103 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -41,11 +41,11 @@ struct [[nodiscard]] Basis {
Vector3(0, 0, 1)
};
- _FORCE_INLINE_ const Vector3 &operator[](int p_axis) const {
- return rows[p_axis];
+ _FORCE_INLINE_ const Vector3 &operator[](int p_row) const {
+ return rows[p_row];
}
- _FORCE_INLINE_ Vector3 &operator[](int p_axis) {
- return rows[p_axis];
+ _FORCE_INLINE_ Vector3 &operator[](int p_row) {
+ return rows[p_row];
}
void invert();
diff --git a/core/object/object.cpp b/core/object/object.cpp
index da3ca6bc61..2d9d468d38 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1527,21 +1527,21 @@ void Object::initialize_class() {
initialized = true;
}
+StringName Object::get_translation_domain() const {
+ return _translation_domain;
+}
+
+void Object::set_translation_domain(const StringName &p_domain) {
+ _translation_domain = p_domain;
+}
+
String Object::tr(const StringName &p_message, const StringName &p_context) const {
if (!_can_translate || !TranslationServer::get_singleton()) {
return p_message;
}
- if (Engine::get_singleton()->is_editor_hint() || Engine::get_singleton()->is_project_manager_hint()) {
- String tr_msg = TranslationServer::get_singleton()->extractable_translate(p_message, p_context);
- if (!tr_msg.is_empty() && tr_msg != p_message) {
- return tr_msg;
- }
-
- return TranslationServer::get_singleton()->tool_translate(p_message, p_context);
- }
-
- return TranslationServer::get_singleton()->translate(p_message, p_context);
+ const Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_or_add_domain(get_translation_domain());
+ return domain->translate(p_message, p_context);
}
String Object::tr_n(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
@@ -1553,16 +1553,8 @@ String Object::tr_n(const StringName &p_message, const StringName &p_message_plu
return p_message_plural;
}
- if (Engine::get_singleton()->is_editor_hint() || Engine::get_singleton()->is_project_manager_hint()) {
- String tr_msg = TranslationServer::get_singleton()->extractable_translate_plural(p_message, p_message_plural, p_n, p_context);
- if (!tr_msg.is_empty() && tr_msg != p_message && tr_msg != p_message_plural) {
- return tr_msg;
- }
-
- return TranslationServer::get_singleton()->tool_translate_plural(p_message, p_message_plural, p_n, p_context);
- }
-
- return TranslationServer::get_singleton()->translate_plural(p_message, p_message_plural, p_n, p_context);
+ const Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_or_add_domain(get_translation_domain());
+ return domain->translate_plural(p_message, p_message_plural, p_n, p_context);
}
void Object::_clear_internal_resource_paths(const Variant &p_var) {
@@ -1714,6 +1706,8 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("can_translate_messages"), &Object::can_translate_messages);
ClassDB::bind_method(D_METHOD("tr", "message", "context"), &Object::tr, DEFVAL(StringName()));
ClassDB::bind_method(D_METHOD("tr_n", "message", "plural_message", "n", "context"), &Object::tr_n, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("get_translation_domain"), &Object::get_translation_domain);
+ ClassDB::bind_method(D_METHOD("set_translation_domain", "domain"), &Object::set_translation_domain);
ClassDB::bind_method(D_METHOD("is_queued_for_deletion"), &Object::is_queued_for_deletion);
ClassDB::bind_method(D_METHOD("cancel_free"), &Object::cancel_free);
diff --git a/core/object/object.h b/core/object/object.h
index 6d22f320af..1274247d71 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -665,6 +665,8 @@ private:
Object(bool p_reference);
protected:
+ StringName _translation_domain;
+
_FORCE_INLINE_ bool _instance_binding_reference(bool p_reference) {
bool can_die = true;
if (_instance_bindings) {
@@ -954,6 +956,9 @@ public:
_FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate = p_enable; }
_FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; }
+ virtual StringName get_translation_domain() const;
+ virtual void set_translation_domain(const StringName &p_domain);
+
#ifdef TOOLS_ENABLED
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
void editor_set_section_unfold(const String &p_section, bool p_unfolded);
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index c866ff0415..3a578d01a6 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -233,6 +233,7 @@ void register_core_types() {
GDREGISTER_CLASS(MainLoop);
GDREGISTER_CLASS(Translation);
+ GDREGISTER_CLASS(TranslationDomain);
GDREGISTER_CLASS(OptimizedTranslation);
GDREGISTER_CLASS(UndoRedo);
GDREGISTER_CLASS(TriangleMesh);
diff --git a/core/string/translation_domain.cpp b/core/string/translation_domain.cpp
new file mode 100644
index 0000000000..b44eb40366
--- /dev/null
+++ b/core/string/translation_domain.cpp
@@ -0,0 +1,165 @@
+/**************************************************************************/
+/* translation_domain.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 "translation_domain.h"
+
+#include "core/string/translation.h"
+#include "core/string/translation_server.h"
+
+StringName TranslationDomain::get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_context) const {
+ StringName res;
+ int best_score = 0;
+
+ for (const Ref<Translation> &E : translations) {
+ ERR_CONTINUE(E.is_null());
+ int score = TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale());
+ if (score > 0 && score >= best_score) {
+ const StringName r = E->get_message(p_message, p_context);
+ if (!r) {
+ continue;
+ }
+ res = r;
+ best_score = score;
+ if (score == 10) {
+ break; // Exact match, skip the rest.
+ }
+ }
+ }
+
+ return res;
+}
+
+StringName TranslationDomain::get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
+ StringName res;
+ int best_score = 0;
+
+ for (const Ref<Translation> &E : translations) {
+ ERR_CONTINUE(E.is_null());
+ int score = TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale());
+ if (score > 0 && score >= best_score) {
+ const StringName r = E->get_plural_message(p_message, p_message_plural, p_n, p_context);
+ if (!r) {
+ continue;
+ }
+ res = r;
+ best_score = score;
+ if (score == 10) {
+ break; // Exact match, skip the rest.
+ }
+ }
+ }
+
+ return res;
+}
+
+PackedStringArray TranslationDomain::get_loaded_locales() const {
+ PackedStringArray locales;
+ for (const Ref<Translation> &E : translations) {
+ ERR_CONTINUE(E.is_null());
+ locales.push_back(E->get_locale());
+ }
+ return locales;
+}
+
+Ref<Translation> TranslationDomain::get_translation_object(const String &p_locale) const {
+ Ref<Translation> res;
+ int best_score = 0;
+
+ for (const Ref<Translation> &E : translations) {
+ ERR_CONTINUE(E.is_null());
+
+ int score = TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale());
+ if (score > 0 && score >= best_score) {
+ res = E;
+ best_score = score;
+ if (score == 10) {
+ break; // Exact match, skip the rest.
+ }
+ }
+ }
+ return res;
+}
+
+void TranslationDomain::add_translation(const Ref<Translation> &p_translation) {
+ translations.insert(p_translation);
+}
+
+void TranslationDomain::remove_translation(const Ref<Translation> &p_translation) {
+ translations.erase(p_translation);
+}
+
+void TranslationDomain::clear() {
+ translations.clear();
+}
+
+StringName TranslationDomain::translate(const StringName &p_message, const StringName &p_context) const {
+ const String &locale = TranslationServer::get_singleton()->get_locale();
+ StringName res = get_message_from_translations(locale, p_message, p_context);
+
+ const String &fallback = TranslationServer::get_singleton()->get_fallback_locale();
+ if (!res && fallback.length() >= 2) {
+ res = get_message_from_translations(fallback, p_message, p_context);
+ }
+
+ if (!res) {
+ return p_message;
+ }
+ return res;
+}
+
+StringName TranslationDomain::translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
+ const String &locale = TranslationServer::get_singleton()->get_locale();
+ StringName res = get_message_from_translations(locale, p_message, p_message_plural, p_n, p_context);
+
+ const String &fallback = TranslationServer::get_singleton()->get_fallback_locale();
+ if (!res && fallback.length() >= 2) {
+ res = get_message_from_translations(fallback, p_message, p_message_plural, p_n, p_context);
+ }
+
+ if (!res) {
+ if (p_n == 1) {
+ return p_message;
+ }
+ return p_message_plural;
+ }
+ return res;
+}
+
+void TranslationDomain::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_translation_object", "locale"), &TranslationDomain::get_translation_object);
+ ClassDB::bind_method(D_METHOD("add_translation", "translation"), &TranslationDomain::add_translation);
+ ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationDomain::remove_translation);
+ ClassDB::bind_method(D_METHOD("clear"), &TranslationDomain::clear);
+ ClassDB::bind_method(D_METHOD("translate", "message", "context"), &TranslationDomain::translate, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("translate_plural", "message", "message_plural", "n", "context"), &TranslationDomain::translate_plural, DEFVAL(StringName()));
+}
+
+TranslationDomain::TranslationDomain() {
+}
diff --git a/core/string/translation_domain.h b/core/string/translation_domain.h
new file mode 100644
index 0000000000..6139967217
--- /dev/null
+++ b/core/string/translation_domain.h
@@ -0,0 +1,65 @@
+/**************************************************************************/
+/* translation_domain.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 TRANSLATION_DOMAIN_H
+#define TRANSLATION_DOMAIN_H
+
+#include "core/object/ref_counted.h"
+
+class Translation;
+
+class TranslationDomain : public RefCounted {
+ GDCLASS(TranslationDomain, RefCounted);
+
+ HashSet<Ref<Translation>> translations;
+
+protected:
+ static void _bind_methods();
+
+public:
+ // Methods in this section are not intended for scripting.
+ StringName get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_context) const;
+ StringName get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const;
+ PackedStringArray get_loaded_locales() const;
+
+public:
+ Ref<Translation> get_translation_object(const String &p_locale) const;
+
+ void add_translation(const Ref<Translation> &p_translation);
+ void remove_translation(const Ref<Translation> &p_translation);
+ void clear();
+
+ StringName translate(const StringName &p_message, const StringName &p_context) const;
+ StringName translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const;
+
+ TranslationDomain();
+};
+
+#endif // TRANSLATION_DOMAIN_H
diff --git a/core/string/translation_server.cpp b/core/string/translation_server.cpp
index d4aa152340..c6b818a49b 100644
--- a/core/string/translation_server.cpp
+++ b/core/string/translation_server.cpp
@@ -404,69 +404,36 @@ String TranslationServer::get_locale() const {
return locale;
}
-PackedStringArray TranslationServer::get_loaded_locales() const {
- PackedStringArray locales;
- for (const Ref<Translation> &E : translations) {
- const Ref<Translation> &t = E;
- ERR_FAIL_COND_V(t.is_null(), PackedStringArray());
- String l = t->get_locale();
-
- locales.push_back(l);
- }
+String TranslationServer::get_fallback_locale() const {
+ return fallback;
+}
- return locales;
+PackedStringArray TranslationServer::get_loaded_locales() const {
+ return main_domain->get_loaded_locales();
}
void TranslationServer::add_translation(const Ref<Translation> &p_translation) {
- translations.insert(p_translation);
+ main_domain->add_translation(p_translation);
}
void TranslationServer::remove_translation(const Ref<Translation> &p_translation) {
- translations.erase(p_translation);
+ main_domain->remove_translation(p_translation);
}
Ref<Translation> TranslationServer::get_translation_object(const String &p_locale) {
- Ref<Translation> res;
- int best_score = 0;
-
- for (const Ref<Translation> &E : translations) {
- const Ref<Translation> &t = E;
- ERR_FAIL_COND_V(t.is_null(), nullptr);
- String l = t->get_locale();
-
- int score = compare_locales(p_locale, l);
- if (score > 0 && score >= best_score) {
- res = t;
- best_score = score;
- if (score == 10) {
- break; // Exact match, skip the rest.
- }
- }
- }
- return res;
+ return main_domain->get_translation_object(p_locale);
}
void TranslationServer::clear() {
- translations.clear();
+ main_domain->clear();
}
StringName TranslationServer::translate(const StringName &p_message, const StringName &p_context) const {
- // Match given message against the translation catalog for the project locale.
-
if (!enabled) {
return p_message;
}
- StringName res = _get_message_from_translations(p_message, p_context, locale, false);
-
- if (!res && fallback.length() >= 2) {
- res = _get_message_from_translations(p_message, p_context, fallback, false);
- }
-
- if (!res) {
- return pseudolocalization_enabled ? pseudolocalize(p_message) : p_message;
- }
-
+ const StringName res = main_domain->translate(p_message, p_context);
return pseudolocalization_enabled ? pseudolocalize(res) : res;
}
@@ -478,51 +445,7 @@ StringName TranslationServer::translate_plural(const StringName &p_message, cons
return p_message_plural;
}
- StringName res = _get_message_from_translations(p_message, p_context, locale, true, p_message_plural, p_n);
-
- if (!res && fallback.length() >= 2) {
- res = _get_message_from_translations(p_message, p_context, fallback, true, p_message_plural, p_n);
- }
-
- if (!res) {
- if (p_n == 1) {
- return p_message;
- }
- return p_message_plural;
- }
-
- return res;
-}
-
-StringName TranslationServer::_get_message_from_translations(const StringName &p_message, const StringName &p_context, const String &p_locale, bool plural, const String &p_message_plural, int p_n) const {
- StringName res;
- int best_score = 0;
-
- for (const Ref<Translation> &E : translations) {
- const Ref<Translation> &t = E;
- ERR_FAIL_COND_V(t.is_null(), p_message);
- String l = t->get_locale();
-
- int score = compare_locales(p_locale, l);
- if (score > 0 && score >= best_score) {
- StringName r;
- if (!plural) {
- r = t->get_message(p_message, p_context);
- } else {
- r = t->get_plural_message(p_message, p_message_plural, p_n, p_context);
- }
- if (!r) {
- continue;
- }
- res = r;
- best_score = score;
- if (score == 10) {
- break; // Exact match, skip the rest.
- }
- }
- }
-
- return res;
+ return main_domain->translate_plural(p_message, p_message_plural, p_n, p_context);
}
TranslationServer *TranslationServer::singleton = nullptr;
@@ -549,6 +472,34 @@ bool TranslationServer::_load_translations(const String &p_from) {
return false;
}
+bool TranslationServer::has_domain(const StringName &p_domain) const {
+ if (p_domain == StringName()) {
+ return true;
+ }
+ return custom_domains.has(p_domain);
+}
+
+Ref<TranslationDomain> TranslationServer::get_or_add_domain(const StringName &p_domain) {
+ if (p_domain == StringName()) {
+ return main_domain;
+ }
+ const Ref<TranslationDomain> *domain = custom_domains.getptr(p_domain);
+ if (domain) {
+ if (domain->is_valid()) {
+ return *domain;
+ }
+ ERR_PRINT("Bug (please report): Found invalid translation domain.");
+ }
+ Ref<TranslationDomain> new_domain = memnew(TranslationDomain);
+ custom_domains[p_domain] = new_domain;
+ return new_domain;
+}
+
+void TranslationServer::remove_domain(const StringName &p_domain) {
+ ERR_FAIL_COND_MSG(p_domain == StringName(), "Cannot remove main translation domain.");
+ custom_domains.erase(p_domain);
+}
+
void TranslationServer::setup() {
String test = GLOBAL_DEF("internationalization/locale/test", "");
test = test.strip_edges();
@@ -574,140 +525,45 @@ void TranslationServer::setup() {
#endif
}
-void TranslationServer::set_tool_translation(const Ref<Translation> &p_translation) {
- tool_translation = p_translation;
-}
-
-Ref<Translation> TranslationServer::get_tool_translation() const {
- return tool_translation;
-}
-
String TranslationServer::get_tool_locale() {
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() || Engine::get_singleton()->is_project_manager_hint()) {
- if (TranslationServer::get_singleton()->get_tool_translation().is_valid()) {
- return tool_translation->get_locale();
- } else {
+ const PackedStringArray &locales = editor_domain->get_loaded_locales();
+ if (locales.is_empty()) {
return "en";
}
+ return locales[0];
} else {
#else
{
#endif
// Look for best matching loaded translation.
- String best_locale = "en";
- int best_score = 0;
-
- for (const Ref<Translation> &E : translations) {
- const Ref<Translation> &t = E;
- ERR_FAIL_COND_V(t.is_null(), best_locale);
- String l = t->get_locale();
-
- int score = compare_locales(locale, l);
- if (score > 0 && score >= best_score) {
- best_locale = l;
- best_score = score;
- if (score == 10) {
- break; // Exact match, skip the rest.
- }
- }
+ Ref<Translation> t = main_domain->get_translation_object(locale);
+ if (t.is_null()) {
+ return "en";
}
- return best_locale;
+ return t->get_locale();
}
}
StringName TranslationServer::tool_translate(const StringName &p_message, const StringName &p_context) const {
- if (tool_translation.is_valid()) {
- StringName r = tool_translation->get_message(p_message, p_context);
- if (r) {
- return r;
- }
- }
- return p_message;
+ return editor_domain->translate(p_message, p_context);
}
StringName TranslationServer::tool_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
- if (tool_translation.is_valid()) {
- StringName r = tool_translation->get_plural_message(p_message, p_message_plural, p_n, p_context);
- if (r) {
- return r;
- }
- }
-
- if (p_n == 1) {
- return p_message;
- }
- return p_message_plural;
-}
-
-void TranslationServer::set_property_translation(const Ref<Translation> &p_translation) {
- property_translation = p_translation;
+ return editor_domain->translate_plural(p_message, p_message_plural, p_n, p_context);
}
StringName TranslationServer::property_translate(const StringName &p_message, const StringName &p_context) const {
- if (property_translation.is_valid()) {
- StringName r = property_translation->get_message(p_message, p_context);
- if (r) {
- return r;
- }
- }
- return p_message;
-}
-
-void TranslationServer::set_doc_translation(const Ref<Translation> &p_translation) {
- doc_translation = p_translation;
+ return property_domain->translate(p_message, p_context);
}
StringName TranslationServer::doc_translate(const StringName &p_message, const StringName &p_context) const {
- if (doc_translation.is_valid()) {
- StringName r = doc_translation->get_message(p_message, p_context);
- if (r) {
- return r;
- }
- }
- return p_message;
+ return doc_domain->translate(p_message, p_context);
}
StringName TranslationServer::doc_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
- if (doc_translation.is_valid()) {
- StringName r = doc_translation->get_plural_message(p_message, p_message_plural, p_n, p_context);
- if (r) {
- return r;
- }
- }
-
- if (p_n == 1) {
- return p_message;
- }
- return p_message_plural;
-}
-
-void TranslationServer::set_extractable_translation(const Ref<Translation> &p_translation) {
- extractable_translation = p_translation;
-}
-
-StringName TranslationServer::extractable_translate(const StringName &p_message, const StringName &p_context) const {
- if (extractable_translation.is_valid()) {
- StringName r = extractable_translation->get_message(p_message, p_context);
- if (r) {
- return r;
- }
- }
- return p_message;
-}
-
-StringName TranslationServer::extractable_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
- if (extractable_translation.is_valid()) {
- StringName r = extractable_translation->get_plural_message(p_message, p_message_plural, p_n, p_context);
- if (r) {
- return r;
- }
- }
-
- if (p_n == 1) {
- return p_message;
- }
- return p_message_plural;
+ return doc_domain->translate_plural(p_message, p_message_plural, p_n, p_context);
}
bool TranslationServer::is_pseudolocalization_enabled() const {
@@ -925,6 +781,10 @@ void TranslationServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationServer::remove_translation);
ClassDB::bind_method(D_METHOD("get_translation_object", "locale"), &TranslationServer::get_translation_object);
+ ClassDB::bind_method(D_METHOD("has_domain", "domain"), &TranslationServer::has_domain);
+ ClassDB::bind_method(D_METHOD("get_or_add_domain", "domain"), &TranslationServer::get_or_add_domain);
+ ClassDB::bind_method(D_METHOD("remove_domain", "domain"), &TranslationServer::remove_domain);
+
ClassDB::bind_method(D_METHOD("clear"), &TranslationServer::clear);
ClassDB::bind_method(D_METHOD("get_loaded_locales"), &TranslationServer::get_loaded_locales);
@@ -947,5 +807,9 @@ void TranslationServer::load_translations() {
TranslationServer::TranslationServer() {
singleton = this;
+ main_domain.instantiate();
+ editor_domain = get_or_add_domain("godot.editor");
+ property_domain = get_or_add_domain("godot.properties");
+ doc_domain = get_or_add_domain("godot.documentation");
init_locale_info();
}
diff --git a/core/string/translation_server.h b/core/string/translation_server.h
index bb285ab19c..272fa1f11c 100644
--- a/core/string/translation_server.h
+++ b/core/string/translation_server.h
@@ -32,6 +32,7 @@
#define TRANSLATION_SERVER_H
#include "core/string/translation.h"
+#include "core/string/translation_domain.h"
class TranslationServer : public Object {
GDCLASS(TranslationServer, Object);
@@ -39,11 +40,11 @@ class TranslationServer : public Object {
String locale = "en";
String fallback;
- HashSet<Ref<Translation>> translations;
- Ref<Translation> tool_translation;
- Ref<Translation> property_translation;
- Ref<Translation> doc_translation;
- Ref<Translation> extractable_translation;
+ Ref<TranslationDomain> main_domain;
+ Ref<TranslationDomain> editor_domain;
+ Ref<TranslationDomain> property_domain;
+ Ref<TranslationDomain> doc_domain;
+ HashMap<StringName, Ref<TranslationDomain>> custom_domains;
bool enabled = true;
@@ -70,8 +71,6 @@ class TranslationServer : public Object {
bool _load_translations(const String &p_from);
String _standardize_locale(const String &p_locale, bool p_add_defaults) const;
- StringName _get_message_from_translations(const StringName &p_message, const StringName &p_context, const String &p_locale, bool plural, const String &p_message_plural = "", int p_n = 0) const;
-
static void _bind_methods();
struct LocaleScriptInfo {
@@ -99,6 +98,7 @@ public:
void set_locale(const String &p_locale);
String get_locale() const;
+ String get_fallback_locale() const;
Ref<Translation> get_translation_object(const String &p_locale);
Vector<String> get_all_languages() const;
@@ -131,18 +131,15 @@ public:
int compare_locales(const String &p_locale_a, const String &p_locale_b) const;
String get_tool_locale();
- void set_tool_translation(const Ref<Translation> &p_translation);
- Ref<Translation> get_tool_translation() const;
StringName tool_translate(const StringName &p_message, const StringName &p_context = "") const;
StringName tool_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
- void set_property_translation(const Ref<Translation> &p_translation);
StringName property_translate(const StringName &p_message, const StringName &p_context = "") const;
- void set_doc_translation(const Ref<Translation> &p_translation);
StringName doc_translate(const StringName &p_message, const StringName &p_context = "") const;
StringName doc_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
- void set_extractable_translation(const Ref<Translation> &p_translation);
- StringName extractable_translate(const StringName &p_message, const StringName &p_context = "") const;
- StringName extractable_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
+
+ bool has_domain(const StringName &p_domain) const;
+ Ref<TranslationDomain> get_or_add_domain(const StringName &p_domain);
+ void remove_domain(const StringName &p_domain);
void setup();
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 869499e668..3e62d3dffa 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -369,6 +369,34 @@ int Array::find(const Variant &p_value, int p_from) const {
return ret;
}
+int Array::find_custom(const Callable &p_callable, int p_from) const {
+ int ret = -1;
+
+ if (p_from < 0 || size() == 0) {
+ return ret;
+ }
+
+ const Variant *argptrs[1];
+
+ for (int i = p_from; i < size(); i++) {
+ const Variant &val = _p->array[i];
+ argptrs[0] = &val;
+ Variant res;
+ Callable::CallError ce;
+ p_callable.callp(argptrs, 1, res, ce);
+ if (unlikely(ce.error != Callable::CallError::CALL_OK)) {
+ ERR_FAIL_V_MSG(ret, "Error calling method from 'find_custom': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
+ }
+
+ ERR_FAIL_COND_V_MSG(res.get_type() != Variant::Type::BOOL, ret, "Error on method from 'find_custom': Return type of callable must be boolean.");
+ if (res.operator bool()) {
+ return i;
+ }
+ }
+
+ return ret;
+}
+
int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array.size() == 0) {
return -1;
@@ -394,6 +422,41 @@ int Array::rfind(const Variant &p_value, int p_from) const {
return -1;
}
+int Array::rfind_custom(const Callable &p_callable, int p_from) const {
+ if (_p->array.size() == 0) {
+ return -1;
+ }
+
+ if (p_from < 0) {
+ // Relative offset from the end.
+ p_from = _p->array.size() + p_from;
+ }
+ if (p_from < 0 || p_from >= _p->array.size()) {
+ // Limit to array boundaries.
+ p_from = _p->array.size() - 1;
+ }
+
+ const Variant *argptrs[1];
+
+ for (int i = p_from; i >= 0; i--) {
+ const Variant &val = _p->array[i];
+ argptrs[0] = &val;
+ Variant res;
+ Callable::CallError ce;
+ p_callable.callp(argptrs, 1, res, ce);
+ if (unlikely(ce.error != Callable::CallError::CALL_OK)) {
+ ERR_FAIL_V_MSG(-1, "Error calling method from 'rfind_custom': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
+ }
+
+ ERR_FAIL_COND_V_MSG(res.get_type() != Variant::Type::BOOL, -1, "Error on method from 'rfind_custom': Return type of callable must be boolean.");
+ if (res.operator bool()) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
int Array::count(const Variant &p_value) const {
Variant value = p_value;
ERR_FAIL_COND_V(!_p->typed.validate(value, "count"), 0);
@@ -761,7 +824,7 @@ Variant Array::max() const {
return Variant(); //not a valid comparison
}
if (bool(ret)) {
- //is less
+ //is greater
maxval = test;
}
}
diff --git a/core/variant/array.h b/core/variant/array.h
index 12824ee3f6..6c3bae6ccb 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -152,7 +152,9 @@ public:
void reverse();
int find(const Variant &p_value, int p_from = 0) const;
+ int find_custom(const Callable &p_callable, int p_from = 0) const;
int rfind(const Variant &p_value, int p_from = -1) const;
+ int rfind_custom(const Callable &p_callable, int p_from = -1) const;
int count(const Variant &p_value) const;
bool has(const Variant &p_value) const;
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 2da94de875..178c0bc4ec 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -2305,7 +2305,9 @@ static void _register_variant_builtin_methods_array() {
bind_method(Array, back, sarray(), varray());
bind_method(Array, pick_random, sarray(), varray());
bind_method(Array, find, sarray("what", "from"), varray(0));
+ bind_method(Array, find_custom, sarray("method", "from"), varray(0));
bind_method(Array, rfind, sarray("what", "from"), varray(-1));
+ bind_method(Array, rfind_custom, sarray("method", "from"), varray(-1));
bind_method(Array, count, sarray("value"), varray());
bind_method(Array, has, sarray("value"), varray());
bind_method(Array, pop_back, sarray(), varray());
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index 2a06b98d06..adb6be1070 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -324,6 +324,7 @@
<param index="0" name="value" type="Variant" />
<description>
Returns the number of times an element is in the array.
+ To count how many elements in an array satisfy a condition, see [method reduce].
</description>
</method>
<method name="duplicate" qualifiers="const">
@@ -395,6 +396,25 @@
[b]Note:[/b] For performance reasons, the search is affected by [param what]'s [enum Variant.Type]. For example, [code]7[/code] ([int]) and [code]7.0[/code] ([float]) are not considered equal for this method.
</description>
</method>
+ <method name="find_custom" qualifiers="const">
+ <return type="int" />
+ <param index="0" name="method" type="Callable" />
+ <param index="1" name="from" type="int" default="0" />
+ <description>
+ Returns the index of the [b]first[/b] element in the array that causes [param method] to return [code]true[/code], or [code]-1[/code] if there are none. The search's start can be specified with [param from], continuing to the end of the array.
+ [param method] is a callable that takes an element of the array, and returns a [bool].
+ [b]Note:[/b] If you just want to know whether the array contains [i]anything[/i] that satisfies [param method], use [method any].
+ [codeblocks]
+ [gdscript]
+ func is_even(number):
+ return number % 2 == 0
+
+ func _ready():
+ print([1, 3, 4, 7].find_custom(is_even.bind())) # prints 2
+ [/gdscript]
+ [/codeblocks]
+ </description>
+ </method>
<method name="front" qualifiers="const">
<return type="Variant" />
<description>
@@ -618,6 +638,17 @@
func is_length_greater(a, b):
return a.length() &gt; b.length()
[/codeblock]
+ This method can also be used to count how many elements in an array satisfy a certain condition, similar to [method count]:
+ [codeblock]
+ func is_even(number):
+ return number % 2 == 0
+
+ func _ready():
+ var arr = [1, 2, 3, 4, 5]
+ # Increment count if it's even, else leaves count the same.
+ var even_count = arr.reduce(func(count, next): return count + 1 if is_even(next) else count, 0)
+ print(even_count) # Prints 2
+ [/codeblock]
See also [method map], [method filter], [method any] and [method all].
</description>
</method>
@@ -654,6 +685,14 @@
Returns the index of the [b]last[/b] occurrence of [param what] in this array, or [code]-1[/code] if there are none. The search's start can be specified with [param from], continuing to the beginning of the array. This method is the reverse of [method find].
</description>
</method>
+ <method name="rfind_custom" qualifiers="const">
+ <return type="int" />
+ <param index="0" name="method" type="Callable" />
+ <param index="1" name="from" type="int" default="-1" />
+ <description>
+ Returns the index of the [b]last[/b] element of the array that causes [param method] to return [code]true[/code], or [code]-1[/code] if there are none. The search's start can be specified with [param from], continuing to the beginning of the array. This method is the reverse of [method find_custom].
+ </description>
+ </method>
<method name="shuffle">
<return type="void" />
<description>
diff --git a/doc/classes/CompositorEffect.xml b/doc/classes/CompositorEffect.xml
index 9ac54edb11..8961e10f91 100644
--- a/doc/classes/CompositorEffect.xml
+++ b/doc/classes/CompositorEffect.xml
@@ -87,7 +87,7 @@
The callback is called before our transparent rendering pass, but after our sky is rendered and we've created our back buffers.
</constant>
<constant name="EFFECT_CALLBACK_TYPE_POST_TRANSPARENT" value="4" enum="EffectCallbackType">
- The callback is called after our transparent rendering pass, but before any build in post effects and output to our render target.
+ The callback is called after our transparent rendering pass, but before any built-in post-processing effects and output to our render target.
</constant>
<constant name="EFFECT_CALLBACK_TYPE_MAX" value="5" enum="EffectCallbackType">
Represents the size of the [enum EffectCallbackType] enum.
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index de49764f0d..8189f253fb 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -701,7 +701,7 @@
<return type="void" />
<param index="0" name="plugin" type="EditorInspectorPlugin" />
<description>
- Removes an inspector plugin registered by [method add_import_plugin]
+ Removes an inspector plugin registered by [method add_inspector_plugin].
</description>
</method>
<method name="remove_node_3d_gizmo_plugin">
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 0042ce67d5..42753f7071 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -973,6 +973,13 @@
Similar to [method call_thread_safe], but for setting properties.
</description>
</method>
+ <method name="set_translation_domain_inherited">
+ <return type="void" />
+ <description>
+ Makes this node inherit the translation domain from its parent node. If this node has no parent, the main translation domain will be used.
+ This is the default behavior for all nodes. Calling [method Object.set_translation_domain] disables this behavior.
+ </description>
+ </method>
<method name="update_configuration_warnings">
<return type="void" />
<description>
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index a331c05e47..d0d0876108 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -818,6 +818,12 @@
[b]Note:[/b] Due of the implementation, each [Dictionary] is formatted very similarly to the returned values of [method get_method_list].
</description>
</method>
+ <method name="get_translation_domain" qualifiers="const">
+ <return type="StringName" />
+ <description>
+ Returns the name of the translation domain used by [method tr] and [method tr_n]. See also [TranslationServer].
+ </description>
+ </method>
<method name="has_meta" qualifiers="const">
<return type="bool" />
<param index="0" name="name" type="StringName" />
@@ -1070,6 +1076,13 @@
If a script already exists, its instance is detached, and its property values and state are lost. Built-in property values are still kept.
</description>
</method>
+ <method name="set_translation_domain">
+ <return type="void" />
+ <param index="0" name="domain" type="StringName" />
+ <description>
+ Sets the name of the translation domain used by [method tr] and [method tr_n]. See also [TranslationServer].
+ </description>
+ </method>
<method name="to_string">
<return type="String" />
<description>
@@ -1121,7 +1134,7 @@
Notification received when the object is initialized, before its script is attached. Used internally.
</constant>
<constant name="NOTIFICATION_PREDELETE" value="1">
- Notification received when the object is about to be deleted. Can act as the deconstructor of some programming languages.
+ Notification received when the object is about to be deleted. Can be used like destructors in object-oriented programming languages.
</constant>
<constant name="NOTIFICATION_EXTENSION_RELOADED" value="2">
Notification received when the object finishes hot reloading. This notification is only sent for extensions classes and derived.
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index d35d30efd8..758e98ad85 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -2795,6 +2795,10 @@
If [code]true[/code], the forward renderer will fall back to Direct3D 12 if Vulkan is not supported.
[b]Note:[/b] This setting is implemented only on Windows.
</member>
+ <member name="rendering/rendering_device/fallback_to_opengl3" type="bool" setter="" getter="" default="true">
+ If [code]true[/code], the forward renderer will fall back to OpenGL 3 if both Direct3D 12, Metal and Vulkan are not supported.
+ [b]Note:[/b] This setting is implemented only on Windows, Android, macOS, iOS, and Linux/X11.
+ </member>
<member name="rendering/rendering_device/fallback_to_vulkan" type="bool" setter="" getter="" default="true">
If [code]true[/code], the forward renderer will fall back to Vulkan if Direct3D 12 is not supported.
[b]Note:[/b] This setting is implemented only on Windows.
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 58e88a3bdc..c62770cf1f 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -3583,6 +3583,21 @@
[b]Note:[/b] The [param texture] must have the same width, height, depth and format as the current texture data. Otherwise, an error will be printed and the original texture won't be modified. If you need to use different width, height, depth or format, use [method texture_replace] instead.
</description>
</method>
+ <method name="texture_create_from_native_handle">
+ <return type="RID" />
+ <param index="0" name="type" type="int" enum="RenderingServer.TextureType" />
+ <param index="1" name="format" type="int" enum="Image.Format" />
+ <param index="2" name="native_handle" type="int" />
+ <param index="3" name="width" type="int" />
+ <param index="4" name="height" type="int" />
+ <param index="5" name="depth" type="int" />
+ <param index="6" name="layers" type="int" default="1" />
+ <param index="7" name="layered_type" type="int" enum="RenderingServer.TextureLayeredType" default="0" />
+ <description>
+ Creates a texture based on a native handle that was created outside of Godot's renderer.
+ [b]Note:[/b] If using the rendering device renderer, using [method RenderingDevice.texture_create_from_extension] rather than this method is recommended. It will give you much more control over the texture's format and usage.
+ </description>
+ </method>
<method name="texture_get_format" qualifiers="const">
<return type="int" enum="Image.Format" />
<param index="0" name="texture" type="RID" />
@@ -4311,6 +4326,15 @@
<constant name="MAX_MESH_SURFACES" value="256">
The maximum number of surfaces a mesh can have.
</constant>
+ <constant name="TEXTURE_TYPE_2D" value="0" enum="TextureType">
+ 2D texture.
+ </constant>
+ <constant name="TEXTURE_TYPE_LAYERED" value="1" enum="TextureType">
+ Layered texture.
+ </constant>
+ <constant name="TEXTURE_TYPE_3D" value="2" enum="TextureType">
+ 3D texture.
+ </constant>
<constant name="TEXTURE_LAYERED_2D_ARRAY" value="0" enum="TextureLayeredType">
Array of 2-dimensional textures (see [Texture2DArray]).
</constant>
@@ -5124,7 +5148,7 @@
The callback is called before our transparent rendering pass, but after our sky is rendered and we've created our back buffers.
</constant>
<constant name="COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT" value="4" enum="CompositorEffectCallbackType">
- The callback is called after our transparent rendering pass, but before any build in post effects and output to our render target.
+ The callback is called after our transparent rendering pass, but before any built-in post-processing effects and output to our render target.
</constant>
<constant name="COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY" value="-1" enum="CompositorEffectCallbackType">
</constant>
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 6505e48fb9..9fada9db35 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -1361,7 +1361,8 @@
Set additional options for BiDi override.
</member>
<member name="syntax_highlighter" type="SyntaxHighlighter" setter="set_syntax_highlighter" getter="get_syntax_highlighter">
- Sets the [SyntaxHighlighter] to use.
+ The syntax highlighter to use.
+ [b]Note:[/b] A [SyntaxHighlighter] instance should not be used across multiple [TextEdit] nodes.
</member>
<member name="text" type="String" setter="set_text" getter="get_text" default="&quot;&quot;">
String value of the [TextEdit].
diff --git a/doc/classes/TranslationDomain.xml b/doc/classes/TranslationDomain.xml
new file mode 100644
index 0000000000..da6f2704bf
--- /dev/null
+++ b/doc/classes/TranslationDomain.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="TranslationDomain" inherits="RefCounted" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ A self-contained collection of [Translation] resources.
+ </brief_description>
+ <description>
+ [TranslationDomain] is a self-contained collection of [Translation] resources. Translations can be added to or removed from it.
+ If you're working with the main translation domain, it is more convenient to use the wrap methods on [TranslationServer].
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_translation">
+ <return type="void" />
+ <param index="0" name="translation" type="Translation" />
+ <description>
+ Adds a translation.
+ </description>
+ </method>
+ <method name="clear">
+ <return type="void" />
+ <description>
+ Removes all translations.
+ </description>
+ </method>
+ <method name="get_translation_object" qualifiers="const">
+ <return type="Translation" />
+ <param index="0" name="locale" type="String" />
+ <description>
+ Returns the [Translation] instance that best matches [param locale]. Returns [code]null[/code] if there are no matches.
+ </description>
+ </method>
+ <method name="remove_translation">
+ <return type="void" />
+ <param index="0" name="translation" type="Translation" />
+ <description>
+ Removes the given translation.
+ </description>
+ </method>
+ <method name="translate" qualifiers="const">
+ <return type="StringName" />
+ <param index="0" name="message" type="StringName" />
+ <param index="1" name="context" type="StringName" default="&amp;&quot;&quot;" />
+ <description>
+ Returns the current locale's translation for the given message and context.
+ </description>
+ </method>
+ <method name="translate_plural" qualifiers="const">
+ <return type="StringName" />
+ <param index="0" name="message" type="StringName" />
+ <param index="1" name="message_plural" type="StringName" />
+ <param index="2" name="n" type="int" />
+ <param index="3" name="context" type="StringName" default="&amp;&quot;&quot;" />
+ <description>
+ Returns the current locale's translation for the given message, plural message and context.
+ The number [param n] is the number or quantity of the plural object. It will be used to guide the translation system to fetch the correct plural form for the selected language.
+ </description>
+ </method>
+ </methods>
+</class>
diff --git a/doc/classes/TranslationServer.xml b/doc/classes/TranslationServer.xml
index db1a65278c..0a4965c36c 100644
--- a/doc/classes/TranslationServer.xml
+++ b/doc/classes/TranslationServer.xml
@@ -4,7 +4,8 @@
The server responsible for language translations.
</brief_description>
<description>
- The server that manages all language translations. Translations can be added to or removed from it.
+ The translation server is the API backend that manages all language translations.
+ Translations are stored in [TranslationDomain]s, which can be accessed by name. The most commonly used translation domain is the main translation domain. It always exists and can be accessed using an empty [StringName]. The translation server provides wrapper methods for accessing the main translation domain directly, without having to fetch the translation domain first. Custom translation domains are mainly for advanced usages like editor plugins. Names starting with [code]godot.[/code] are reserved for engine internals.
</description>
<tutorials>
<link title="Internationalizing games">$DOCS_URL/tutorials/i18n/internationalizing_games.html</link>
@@ -15,13 +16,13 @@
<return type="void" />
<param index="0" name="translation" type="Translation" />
<description>
- Adds a [Translation] resource.
+ Adds a translation to the main translation domain.
</description>
</method>
<method name="clear">
<return type="void" />
<description>
- Clears the server from all translations.
+ Removes all translations from the main translation domain.
</description>
</method>
<method name="compare_locales" qualifiers="const">
@@ -84,6 +85,13 @@
Returns a locale's language and its variant (e.g. [code]"en_US"[/code] would return [code]"English (United States)"[/code]).
</description>
</method>
+ <method name="get_or_add_domain">
+ <return type="TranslationDomain" />
+ <param index="0" name="domain" type="StringName" />
+ <description>
+ Returns the translation domain with the specified name. An empty translation domain will be created and added if it does not exist.
+ </description>
+ </method>
<method name="get_script_name" qualifiers="const">
<return type="String" />
<param index="0" name="script" type="String" />
@@ -102,8 +110,14 @@
<return type="Translation" />
<param index="0" name="locale" type="String" />
<description>
- Returns the [Translation] instance based on the [param locale] passed in.
- It will return [code]null[/code] if there is no [Translation] instance that matches the [param locale].
+ Returns the [Translation] instance that best matches [param locale] in the main translation domain. Returns [code]null[/code] if there are no matches.
+ </description>
+ </method>
+ <method name="has_domain" qualifiers="const">
+ <return type="bool" />
+ <param index="0" name="domain" type="StringName" />
+ <description>
+ Returns [code]true[/code] if a translation domain with the specified name exists.
</description>
</method>
<method name="pseudolocalize" qualifiers="const">
@@ -119,11 +133,19 @@
Reparses the pseudolocalization options and reloads the translation.
</description>
</method>
+ <method name="remove_domain">
+ <return type="void" />
+ <param index="0" name="domain" type="StringName" />
+ <description>
+ Removes the translation domain with the specified name.
+ [b]Note:[/b] Trying to remove the main translation domain is an error.
+ </description>
+ </method>
<method name="remove_translation">
<return type="void" />
<param index="0" name="translation" type="Translation" />
<description>
- Removes the given translation from the server.
+ Removes the given translation from the main translation domain.
</description>
</method>
<method name="set_locale">
@@ -146,7 +168,8 @@
<param index="0" name="message" type="StringName" />
<param index="1" name="context" type="StringName" default="&amp;&quot;&quot;" />
<description>
- Returns the current locale's translation for the given message (key) and context.
+ Returns the current locale's translation for the given message and context.
+ [b]Note:[/b] This method always uses the main translation domain.
</description>
</method>
<method name="translate_plural" qualifiers="const">
@@ -156,8 +179,9 @@
<param index="2" name="n" type="int" />
<param index="3" name="context" type="StringName" default="&amp;&quot;&quot;" />
<description>
- Returns the current locale's translation for the given message (key), plural message and context.
+ Returns the current locale's translation for the given message, plural message and context.
The number [param n] is the number or quantity of the plural object. It will be used to guide the translation system to fetch the correct plural form for the selected language.
+ [b]Note:[/b] This method always uses the main translation domain.
</description>
</method>
</methods>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 85663e10b2..95a1d0f77e 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -33,6 +33,18 @@
Returns the first valid [World3D] for this viewport, searching the [member world_3d] property of itself and any Viewport ancestor.
</description>
</method>
+ <method name="get_audio_listener_2d" qualifiers="const">
+ <return type="AudioListener2D" />
+ <description>
+ Returns the currently active 2D audio listener. Returns [code]null[/code] if there are no active 2D audio listeners, in which case the active 2D camera will be treated as listener.
+ </description>
+ </method>
+ <method name="get_audio_listener_3d" qualifiers="const">
+ <return type="AudioListener3D" />
+ <description>
+ Returns the currently active 3D audio listener. Returns [code]null[/code] if there are no active 3D audio listeners, in which case the active 3D camera will be treated as listener.
+ </description>
+ </method>
<method name="get_camera_2d" qualifiers="const">
<return type="Camera2D" />
<description>
diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl
index f734e4b355..186b630bc8 100644
--- a/drivers/gles3/shaders/sky.glsl
+++ b/drivers/gles3/shaders/sky.glsl
@@ -212,9 +212,7 @@ void main() {
#endif
{
-
#CODE : SKY
-
}
color *= sky_energy_multiplier;
diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.h b/drivers/gles3/storage/render_scene_buffers_gles3.h
index a7a676ad33..9a2912f978 100644
--- a/drivers/gles3/storage/render_scene_buffers_gles3.h
+++ b/drivers/gles3/storage/render_scene_buffers_gles3.h
@@ -103,9 +103,9 @@ public:
virtual void configure(const RenderSceneBuffersConfiguration *p_config) override;
void configure_for_probe(Size2i p_size);
- virtual void set_fsr_sharpness(float p_fsr_sharpness) override{};
- virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override{};
- virtual void set_use_debanding(bool p_use_debanding) override{};
+ virtual void set_fsr_sharpness(float p_fsr_sharpness) override {}
+ virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override {}
+ virtual void set_use_debanding(bool p_use_debanding) override {}
void set_apply_color_adjustments_in_post(bool p_apply_in_post);
void free_render_buffer_data();
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 54012c20e9..bd824a076e 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -729,7 +729,7 @@ void TextureStorage::texture_free(RID p_texture) {
}
}
} else {
- must_free_data = t->tex_id != 0 && !t->is_external;
+ must_free_data = t->tex_id != 0 && !t->is_from_native_handle;
}
if (must_free_data) {
GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);
@@ -874,26 +874,28 @@ void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
texture_owner.initialize_rid(p_texture, proxy_tex);
}
-RID TextureStorage::texture_create_external(GLES3::Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {
+RID TextureStorage::texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {
Texture texture;
texture.active = true;
- texture.is_external = true;
- texture.type = p_type;
+ texture.is_from_native_handle = true;
switch (p_type) {
- case Texture::TYPE_2D: {
+ case RS::TEXTURE_TYPE_2D: {
+ texture.type = Texture::TYPE_2D;
texture.target = GL_TEXTURE_2D;
} break;
- case Texture::TYPE_3D: {
+ case RS::TEXTURE_TYPE_3D: {
+ texture.type = Texture::TYPE_3D;
texture.target = GL_TEXTURE_3D;
} break;
- case Texture::TYPE_LAYERED: {
+ case RS::TEXTURE_TYPE_LAYERED: {
+ texture.type = Texture::TYPE_LAYERED;
texture.target = GL_TEXTURE_2D_ARRAY;
} break;
}
texture.real_format = texture.format = p_format;
- texture.tex_id = p_image;
+ texture.tex_id = p_native_handle;
texture.alloc_width = texture.width = p_width;
texture.alloc_height = texture.height = p_height;
texture.depth = p_depth;
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 5569abcc73..b1d4630978 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -146,7 +146,7 @@ struct Texture {
RID self;
bool is_proxy = false;
- bool is_external = false;
+ bool is_from_native_handle = false;
bool is_render_target = false;
RID proxy_to;
@@ -209,7 +209,7 @@ struct Texture {
void copy_from(const Texture &o) {
proxy_to = o.proxy_to;
is_proxy = o.is_proxy;
- is_external = o.is_external;
+ is_from_native_handle = o.is_from_native_handle;
width = o.width;
height = o.height;
alloc_width = o.alloc_width;
@@ -514,7 +514,7 @@ public:
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent
- RID texture_create_external(Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY);
+ virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) override;
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override;
@@ -582,7 +582,7 @@ public:
virtual RID decal_allocate() override;
virtual void decal_initialize(RID p_rid) override;
- virtual void decal_free(RID p_rid) override{};
+ virtual void decal_free(RID p_rid) override {}
virtual void decal_set_size(RID p_decal, const Vector3 &p_size) override;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
diff --git a/drivers/metal/metal_objects.h b/drivers/metal/metal_objects.h
index 97f33bb1e8..030b353ee8 100644
--- a/drivers/metal/metal_objects.h
+++ b/drivers/metal/metal_objects.h
@@ -318,6 +318,13 @@ public:
dirty.set_flag(DirtyFlag::DIRTY_UNIFORMS);
}
+ _FORCE_INLINE_ void mark_blend_dirty() {
+ if (!blend_constants.has_value()) {
+ return;
+ }
+ dirty.set_flag(DirtyFlag::DIRTY_BLEND);
+ }
+
MTLScissorRect clip_to_render_area(MTLScissorRect p_rect) const {
uint32_t raLeft = render_area.position.x;
uint32_t raRight = raLeft + render_area.size.width;
diff --git a/drivers/metal/metal_objects.mm b/drivers/metal/metal_objects.mm
index d3c3d2b232..1d08a10781 100644
--- a/drivers/metal/metal_objects.mm
+++ b/drivers/metal/metal_objects.mm
@@ -143,6 +143,9 @@ void MDCommandBuffer::bind_pipeline(RDD::PipelineID p_pipeline) {
if (render.pipeline != nullptr && render.pipeline->depth_stencil != rp->depth_stencil) {
render.dirty.set_flag(RenderState::DIRTY_DEPTH);
}
+ if (rp->raster_state.blend.enabled) {
+ render.dirty.set_flag(RenderState::DIRTY_BLEND);
+ }
render.pipeline = rp;
}
} else if (p->type == MDPipelineType::Compute) {
@@ -301,6 +304,7 @@ void MDCommandBuffer::render_clear_attachments(VectorView<RDD::AttachmentClear>
render.mark_viewport_dirty();
render.mark_scissors_dirty();
render.mark_vertex_dirty();
+ render.mark_blend_dirty();
}
void MDCommandBuffer::_render_set_dirty_state() {
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index 16423fb111..0d89f37dd2 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -254,6 +254,7 @@ Variant ActionMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
Label *label = memnew(Label(name));
label->set_theme_type_variation("HeaderSmall");
label->set_modulate(Color(1, 1, 1, 1.0f));
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
action_tree->set_drag_preview(label);
Dictionary drag_data;
@@ -588,7 +589,7 @@ ActionMapEditor::ActionMapEditor() {
add_hbox->add_child(show_builtin_actions_checkbutton);
show_builtin_actions = EditorSettings::get_singleton()->get_project_metadata("project_settings", "show_builtin_actions", false);
- show_builtin_actions_checkbutton->set_pressed(show_builtin_actions);
+ show_builtin_actions_checkbutton->set_pressed_no_signal(show_builtin_actions);
main_vbox->add_child(add_hbox);
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index 66ebd07c2a..2e8c727849 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -1443,6 +1443,11 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
i++;
}
+ AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
+ if (ape) {
+ undo_redo->add_do_method(ape, "_animation_update_key_frame");
+ undo_redo->add_undo_method(ape, "_animation_update_key_frame");
+ }
undo_redo->commit_action();
} else if (select_single_attempt != IntPair(-1, -1)) {
@@ -1967,15 +1972,6 @@ void AnimationBezierTrackEdit::delete_selection() {
void AnimationBezierTrackEdit::_bezier_track_insert_key_at_anim(const Ref<Animation> &p_anim, int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle, const Animation::HandleMode p_handle_mode) {
int idx = p_anim->bezier_track_insert_key(p_track, p_time, p_value, p_in_handle, p_out_handle);
p_anim->bezier_track_set_key_handle_mode(p_track, idx, p_handle_mode);
-
- EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->create_action(TTR("Animation Bezier Curve Change Call"));
- AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
- if (ape) {
- undo_redo->add_do_method(ape, "_animation_update_key_frame");
- undo_redo->add_undo_method(ape, "_animation_update_key_frame");
- }
- undo_redo->commit_action();
}
void AnimationBezierTrackEdit::_bind_methods() {
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 07b7c34a10..d277ba2f6d 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -3241,6 +3241,7 @@ Variant AnimationTrackEdit::get_drag_data(const Point2 &p_point) {
tb->set_flat(true);
tb->set_text(path_cache);
tb->set_icon(icon_cache);
+ tb->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
tb->add_theme_constant_override("icon_max_width", get_theme_constant("class_icon_size", EditorStringName(Editor)));
set_drag_preview(tb);
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 59783c58b5..d97293329a 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -820,7 +820,7 @@ FindReplaceBar::FindReplaceBar() {
/*** CODE EDITOR ****/
-static constexpr float ZOOM_FACTOR_PRESETS[7] = { 0.25f, 0.5f, 0.75f, 1.0f, 1.5f, 2.0f, 3.0f };
+static constexpr float ZOOM_FACTOR_PRESETS[8] = { 0.5f, 0.75f, 0.9f, 1.0f, 1.1f, 1.25f, 1.5f, 2.0f };
// This function should be used to handle shortcuts that could otherwise
// be handled too late if they weren't handled here.
@@ -1716,8 +1716,7 @@ void CodeTextEditor::_zoom_to(float p_zoom_factor) {
}
void CodeTextEditor::set_zoom_factor(float p_zoom_factor) {
- int preset_count = sizeof(ZOOM_FACTOR_PRESETS) / sizeof(float);
- zoom_factor = CLAMP(p_zoom_factor, ZOOM_FACTOR_PRESETS[0], ZOOM_FACTOR_PRESETS[preset_count - 1]);
+ zoom_factor = CLAMP(p_zoom_factor, 0.25f, 3.0f);
int neutral_font_size = int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE;
int new_font_size = Math::round(zoom_factor * neutral_font_size);
@@ -1843,7 +1842,8 @@ CodeTextEditor::CodeTextEditor() {
status_bar->add_child(zoom_button);
zoom_button->set_flat(true);
zoom_button->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER);
- zoom_button->set_tooltip_text(TTR("Zoom factor"));
+ zoom_button->set_tooltip_text(
+ TTR("Zoom factor") + "\n" + vformat(TTR("%sMouse wheel, %s/%s: Finetune\n%s: Reset"), keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL), ED_GET_SHORTCUT("script_editor/zoom_in")->get_as_text(), ED_GET_SHORTCUT("script_editor/zoom_out")->get_as_text(), ED_GET_SHORTCUT("script_editor/reset_zoom")->get_as_text()));
zoom_button->set_text("100 %");
PopupMenu *zoom_menu = zoom_button->get_popup();
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 42346a0c0b..330ac3b437 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -615,6 +615,7 @@ Variant CreateDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
tb->set_flat(true);
tb->set_icon(ti->get_icon(0));
tb->set_text(ti->get_text(0));
+ tb->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
favorites->set_drag_preview(tb);
return d;
diff --git a/editor/directory_create_dialog.cpp b/editor/directory_create_dialog.cpp
index 604531f109..46baa2c6e1 100644
--- a/editor/directory_create_dialog.cpp
+++ b/editor/directory_create_dialog.cpp
@@ -31,6 +31,7 @@
#include "directory_create_dialog.h"
#include "core/io/dir_access.h"
+#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
#include "editor/gui/editor_validation_panel.h"
#include "editor/themes/editor_scale.h"
@@ -100,15 +101,7 @@ void DirectoryCreateDialog::ok_pressed() {
const String error = _validate_path(path);
ERR_FAIL_COND_MSG(!error.is_empty(), error);
- Error err;
- Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-
- err = da->change_dir(base_dir);
- ERR_FAIL_COND_MSG(err != OK, "Cannot open directory '" + base_dir + "'.");
-
- print_verbose("Making folder " + path + " in " + base_dir);
- err = da->make_dir_recursive(path);
-
+ Error err = EditorFileSystem::get_singleton()->make_dir_recursive(path, base_dir);
if (err == OK) {
emit_signal(SNAME("dir_created"), base_dir.path_join(path));
} else {
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index de4e9240f6..24fc7a9c2b 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -657,6 +657,7 @@ Variant EditorAudioBus::get_drag_data_fw(const Point2 &p_point, Control *p_from)
Label *l = memnew(Label);
l->set_text(item->get_text(0));
+ l->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
effects->set_drag_preview(l);
return fxd;
@@ -929,6 +930,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
hb->add_child(scale);
effects = memnew(Tree);
+ effects->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
effects->set_hide_root(true);
effects->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
effects->set_hide_folding(true);
@@ -954,6 +956,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
set_focus_mode(FOCUS_CLICK);
effect_options = memnew(PopupMenu);
+ effect_options->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate class names.
effect_options->connect("index_pressed", callable_mp(this, &EditorAudioBus::_effect_add));
add_child(effect_options);
List<StringName> effect_list;
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index fb007aee28..0eabe53360 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -644,6 +644,7 @@ Variant EditorAutoloadSettings::get_drag_data_fw(const Point2 &p_point, Control
for (int i = 0; i < max_size; i++) {
Label *label = memnew(Label(autoloads[i]));
label->set_self_modulate(Color(1, 1, 1, Math::lerp(1, 0, float(i) / PREVIEW_LIST_MAX_SIZE)));
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
preview->add_child(label);
}
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index cad615e6c5..adae6599c1 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/extension/gdextension_manager.h"
+#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/resource_saver.h"
#include "core/object/worker_thread_pool.h"
@@ -3075,33 +3076,51 @@ void EditorFileSystem::move_group_file(const String &p_path, const String &p_new
}
}
-void EditorFileSystem::add_new_directory(const String &p_path) {
- String path = p_path.get_base_dir();
- EditorFileSystemDirectory *parent = filesystem;
- int base = p_path.count("/");
- int max_bit = base + 1;
+Error EditorFileSystem::make_dir_recursive(const String &p_path, const String &p_base_path) {
+ Error err;
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (!p_base_path.is_empty()) {
+ err = da->change_dir(p_base_path);
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open base directory '" + p_base_path + "'.");
+ }
- while (path != "res://") {
- EditorFileSystemDirectory *dir = get_filesystem_path(path);
- if (dir) {
- parent = dir;
- break;
- }
- path = path.get_base_dir();
- base--;
+ if (da->dir_exists(p_path)) {
+ return ERR_ALREADY_EXISTS;
+ }
+
+ err = da->make_dir_recursive(p_path);
+ if (err != OK) {
+ return err;
}
- for (int i = base; i < max_bit; i++) {
+ const String path = da->get_current_dir();
+ EditorFileSystemDirectory *parent = get_filesystem_path(path);
+ ERR_FAIL_NULL_V(parent, ERR_FILE_NOT_FOUND);
+
+ const PackedStringArray folders = p_path.trim_prefix(path).trim_suffix("/").split("/");
+ bool first = true;
+
+ for (const String &folder : folders) {
+ const int current = parent->find_dir_index(folder);
+ if (current > -1) {
+ parent = parent->get_subdir(current);
+ continue;
+ }
+
EditorFileSystemDirectory *efd = memnew(EditorFileSystemDirectory);
efd->parent = parent;
- efd->name = p_path.get_slice("/", i);
+ efd->name = folder;
parent->subdirs.push_back(efd);
- if (i == base) {
+ if (first) {
parent->subdirs.sort_custom<DirectoryComparator>();
+ first = false;
}
parent = efd;
}
+
+ emit_signal(SNAME("filesystem_changed"));
+ return OK;
}
ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const String &p_path, bool p_generate) {
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index be299800d8..e02127cb13 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -370,7 +370,7 @@ public:
bool is_group_file(const String &p_path) const;
void move_group_file(const String &p_path, const String &p_new_path);
- void add_new_directory(const String &p_path);
+ Error make_dir_recursive(const String &p_path, const String &p_base_path = String());
static bool _should_skip_directory(const String &p_path);
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 4cd0761691..a215662f16 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -893,6 +893,7 @@ Variant EditorProperty::get_drag_data(const Point2 &p_point) {
Label *drag_label = memnew(Label);
drag_label->set_text(property);
+ drag_label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate raw property name.
set_drag_preview(drag_label);
return dp;
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 0c21f3c2cd..2b4b6a5b7e 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4113,7 +4113,9 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
_update_title();
scene_tabs->update_scene_tabs();
- _add_to_recent_scenes(lpath);
+ if (!restoring_scenes) {
+ _add_to_recent_scenes(lpath);
+ }
return OK;
}
@@ -5663,6 +5665,7 @@ Dictionary EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from
Control *drag_control = memnew(Control);
TextureRect *drag_preview = memnew(TextureRect);
Label *label = memnew(Label);
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
Ref<Texture2D> preview;
@@ -5715,6 +5718,7 @@ Dictionary EditorNode::drag_files_and_dirs(const Vector<String> &p_paths, Contro
HBoxContainer *hbox = memnew(HBoxContainer);
TextureRect *icon = memnew(TextureRect);
Label *label = memnew(Label);
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
if (p_paths[i].ends_with("/")) {
label->set_text(p_paths[i].substr(0, p_paths[i].length() - 1).get_file());
@@ -6673,6 +6677,8 @@ EditorNode::EditorNode() {
DEV_ASSERT(!singleton);
singleton = this;
+ set_translation_domain("godot.editor");
+
Resource::_get_local_scene_func = _resource_get_edited_scene;
{
@@ -7906,9 +7912,14 @@ EditorNode::EditorNode() {
title_bar->set_can_move_window(true);
}
- String exec = OS::get_singleton()->get_executable_path();
- // Save editor executable path for third-party tools.
- EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "executable_path", exec);
+ {
+ const String exec = OS::get_singleton()->get_executable_path();
+ const String old_exec = EditorSettings::get_singleton()->get_project_metadata("editor_metadata", "executable_path", "");
+ // Save editor executable path for third-party tools.
+ if (exec != old_exec) {
+ EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "executable_path", exec);
+ }
+ }
follow_system_theme = EDITOR_GET("interface/theme/follow_system_theme");
use_system_accent_color = EDITOR_GET("interface/theme/use_system_accent_color");
diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h
index 2870f9a201..57b6e4cedb 100644
--- a/editor/editor_resource_preview.h
+++ b/editor/editor_resource_preview.h
@@ -65,7 +65,7 @@ public:
virtual bool handles(const String &p_type) const;
virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size, Dictionary &p_metadata) const;
virtual Ref<Texture2D> generate_from_path(const String &p_path, const Size2 &p_size, Dictionary &p_metadata) const;
- virtual void abort(){};
+ virtual void abort() {}
virtual bool generate_small_preview_automatically() const;
virtual bool can_generate_small_preview() const;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 312140da67..963c45b573 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -1226,6 +1226,8 @@ fail:
void EditorSettings::setup_language() {
String lang = get("interface/editor/editor_language");
+ TranslationServer::get_singleton()->set_locale(lang);
+
if (lang == "en") {
return; // Default, nothing to do.
}
diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp
index 81bc9c8fbe..b133847823 100644
--- a/editor/editor_settings_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -697,7 +697,7 @@ Variant EditorSettingsDialog::get_drag_data_fw(const Point2 &p_point, Control *p
return Variant();
}
- String label_text = "Event " + itos(selected->get_meta("event_index"));
+ String label_text = vformat(TTRC("Event %d"), selected->get_meta("event_index"));
Label *label = memnew(Label(label_text));
label->set_modulate(Color(1, 1, 1, 1.0f));
shortcuts->set_drag_preview(label);
diff --git a/editor/editor_translation.cpp b/editor/editor_translation.cpp
index 4654d41082..6ccde3b696 100644
--- a/editor/editor_translation.cpp
+++ b/editor/editor_translation.cpp
@@ -54,6 +54,8 @@ Vector<String> get_editor_locales() {
}
void load_editor_translations(const String &p_locale) {
+ const Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_or_add_domain("godot.editor");
+
EditorTranslationList *etl = _editor_translations;
while (etl->data) {
if (etl->lang == p_locale) {
@@ -70,7 +72,7 @@ void load_editor_translations(const String &p_locale) {
if (tr.is_valid()) {
tr->set_locale(etl->lang);
- TranslationServer::get_singleton()->set_tool_translation(tr);
+ domain->add_translation(tr);
break;
}
}
@@ -80,6 +82,8 @@ void load_editor_translations(const String &p_locale) {
}
void load_property_translations(const String &p_locale) {
+ const Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_or_add_domain("godot.properties");
+
PropertyTranslationList *etl = _property_translations;
while (etl->data) {
if (etl->lang == p_locale) {
@@ -96,7 +100,7 @@ void load_property_translations(const String &p_locale) {
if (tr.is_valid()) {
tr->set_locale(etl->lang);
- TranslationServer::get_singleton()->set_property_translation(tr);
+ domain->add_translation(tr);
break;
}
}
@@ -106,6 +110,8 @@ void load_property_translations(const String &p_locale) {
}
void load_doc_translations(const String &p_locale) {
+ const Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_or_add_domain("godot.documentation");
+
DocTranslationList *dtl = _doc_translations;
while (dtl->data) {
if (dtl->lang == p_locale) {
@@ -122,7 +128,7 @@ void load_doc_translations(const String &p_locale) {
if (tr.is_valid()) {
tr->set_locale(dtl->lang);
- TranslationServer::get_singleton()->set_doc_translation(tr);
+ domain->add_translation(tr);
break;
}
}
@@ -132,6 +138,8 @@ void load_doc_translations(const String &p_locale) {
}
void load_extractable_translations(const String &p_locale) {
+ const Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_or_add_domain("godot.editor");
+
ExtractableTranslationList *etl = _extractable_translations;
while (etl->data) {
if (etl->lang == p_locale) {
@@ -148,7 +156,7 @@ void load_extractable_translations(const String &p_locale) {
if (tr.is_valid()) {
tr->set_locale(etl->lang);
- TranslationServer::get_singleton()->set_extractable_translation(tr);
+ domain->add_translation(tr);
break;
}
}
diff --git a/editor/export/editor_export_platform.h b/editor/export/editor_export_platform.h
index a800bb95e6..95f21ceafb 100644
--- a/editor/export/editor_export_platform.h
+++ b/editor/export/editor_export_platform.h
@@ -308,7 +308,7 @@ public:
virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0);
virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0);
virtual void get_platform_features(List<String> *r_features) const = 0;
- virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features){};
+ virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) {}
virtual String get_debug_protocol() const { return "tcp://"; }
EditorExportPlatform();
diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp
index 3ad8ab0b19..be9e0f78ec 100644
--- a/editor/export/project_export.cpp
+++ b/editor/export/project_export.cpp
@@ -713,6 +713,7 @@ Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_
drag->add_child(tr);
Label *label = memnew(Label);
label->set_text(presets->get_item_text(pos));
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate user input.
drag->add_child(label);
presets->set_drag_preview(drag);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 1082e4d0c2..dd2eec6893 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -649,8 +649,7 @@ void FileSystemDock::_notification(int p_what) {
}
if (do_redraw) {
- _update_file_list(true);
- _update_tree(get_uncollapsed_paths());
+ update_all();
}
if (EditorThemeManager::is_generated_theme_outdated()) {
@@ -1343,13 +1342,7 @@ void FileSystemDock::_fs_changed() {
scanning_vb->hide();
split_box->show();
- if (tree->is_visible()) {
- _update_tree(get_uncollapsed_paths());
- }
-
- if (file_list_vb->is_visible()) {
- _update_file_list(true);
- }
+ update_all();
if (!select_after_scan.is_empty()) {
_navigate_to_path(select_after_scan);
@@ -1361,15 +1354,6 @@ void FileSystemDock::_fs_changed() {
set_process(false);
}
-void FileSystemDock::_directory_created(const String &p_path) {
- if (!DirAccess::exists(p_path)) {
- return;
- }
- EditorFileSystem::get_singleton()->add_new_directory(p_path);
- _update_tree(get_uncollapsed_paths());
- _update_file_list(true);
-}
-
void FileSystemDock::_set_scanning_mode() {
button_hist_prev->set_disabled(true);
button_hist_next->set_disabled(true);
@@ -2678,8 +2662,11 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
default: {
- // Resource conversion commands:
- if (p_option >= CONVERT_BASE_ID) {
+ if (p_option >= EditorContextMenuPlugin::BASE_ID) {
+ if (!EditorContextMenuPluginManager::get_singleton()->activate_custom_option(EditorContextMenuPlugin::CONTEXT_SLOT_FILESYSTEM, p_option, p_selected)) {
+ EditorContextMenuPluginManager::get_singleton()->activate_custom_option(EditorContextMenuPlugin::CONTEXT_SLOT_FILESYSTEM_CREATE, p_option, p_selected);
+ }
+ } else if (p_option >= CONVERT_BASE_ID) {
selected_conversion_id = p_option - CONVERT_BASE_ID;
ERR_FAIL_INDEX(selected_conversion_id, (int)cached_valid_conversion_targets.size());
@@ -2697,10 +2684,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
}
conversion_id++;
}
- } else {
- if (!EditorContextMenuPluginManager::get_singleton()->activate_custom_option(EditorContextMenuPlugin::CONTEXT_SLOT_FILESYSTEM, p_option, p_selected)) {
- EditorContextMenuPluginManager::get_singleton()->activate_custom_option(EditorContextMenuPlugin::CONTEXT_SLOT_FILESYSTEM_CREATE, p_option, p_selected);
- }
}
break;
}
@@ -2820,6 +2803,16 @@ void FileSystemDock::fix_dependencies(const String &p_for_file) {
deps_editor->edit(p_for_file);
}
+void FileSystemDock::update_all() {
+ if (tree->is_visible()) {
+ _update_tree(get_uncollapsed_paths());
+ }
+
+ if (file_list_vb->is_visible()) {
+ _update_file_list(true);
+ }
+}
+
void FileSystemDock::focus_on_path() {
current_path_line_edit->grab_focus();
current_path_line_edit->select_all();
@@ -3241,9 +3234,7 @@ void FileSystemDock::_folder_color_index_pressed(int p_index, PopupMenu *p_menu)
}
_update_folder_colors_setting();
-
- _update_tree(get_uncollapsed_paths());
- _update_file_list(true);
+ update_all();
emit_signal(SNAME("folder_color_changed"));
}
@@ -3951,8 +3942,7 @@ void FileSystemDock::set_file_sort(FileSortOption p_file_sort) {
file_sort = p_file_sort;
// Update everything needed.
- _update_tree(get_uncollapsed_paths());
- _update_file_list(true);
+ update_all();
}
void FileSystemDock::_file_sort_popup(int p_id) {
@@ -4342,7 +4332,6 @@ FileSystemDock::FileSystemDock() {
make_dir_dialog = memnew(DirectoryCreateDialog);
add_child(make_dir_dialog);
- make_dir_dialog->connect("dir_created", callable_mp(this, &FileSystemDock::_directory_created));
make_scene_dialog = memnew(SceneCreateDialog);
add_child(make_scene_dialog);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 751fbed022..108b646029 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -270,7 +270,6 @@ private:
void _toggle_file_display();
void _set_file_display(bool p_active);
void _fs_changed();
- void _directory_created(const String &p_path);
void _select_file(const String &p_path, bool p_select_in_favorites = false);
void _tree_activate_file();
@@ -417,6 +416,7 @@ public:
ScriptCreateDialog *get_script_create_dialog() const;
void fix_dependencies(const String &p_for_file);
+ void update_all();
int get_h_split_offset() const { return split_box_offset_h; }
void set_h_split_offset(int p_offset) { split_box_offset_h = p_offset; }
diff --git a/editor/gui/editor_dir_dialog.cpp b/editor/gui/editor_dir_dialog.cpp
index e64761d5b5..b677ba1098 100644
--- a/editor/gui/editor_dir_dialog.cpp
+++ b/editor/gui/editor_dir_dialog.cpp
@@ -191,7 +191,6 @@ void EditorDirDialog::_make_dir_confirm(const String &p_path) {
}
new_dir_path = p_path + "/";
- EditorFileSystem::get_singleton()->scan_changes(); // We created a dir, so rescan changes.
}
void EditorDirDialog::_bind_methods() {
diff --git a/editor/gui/editor_file_dialog.cpp b/editor/gui/editor_file_dialog.cpp
index b6aa3c2215..18f1f6da0c 100644
--- a/editor/gui/editor_file_dialog.cpp
+++ b/editor/gui/editor_file_dialog.cpp
@@ -207,6 +207,10 @@ void EditorFileDialog::_update_theme_item_cache() {
void EditorFileDialog::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_POSTINITIALIZE: {
+ set_translation_domain(SNAME("godot.editor"));
+ } break;
+
case NOTIFICATION_THEME_CHANGED:
case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED: {
diff --git a/editor/gui/editor_title_bar.h b/editor/gui/editor_title_bar.h
index 4055476b82..13fd5d6cdb 100644
--- a/editor/gui/editor_title_bar.h
+++ b/editor/gui/editor_title_bar.h
@@ -43,7 +43,7 @@ class EditorTitleBar : public HBoxContainer {
protected:
virtual void gui_input(const Ref<InputEvent> &p_event) override;
- static void _bind_methods(){};
+ static void _bind_methods() {}
public:
void set_can_move_window(bool p_enabled);
diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp
index 6695abb70a..2e36b66025 100644
--- a/editor/gui/scene_tree_editor.cpp
+++ b/editor/gui/scene_tree_editor.cpp
@@ -1361,6 +1361,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
tf->set_texture(icons[i]);
hb->add_child(tf);
Label *label = memnew(Label(selected_nodes[i]->get_name()));
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
hb->add_child(label);
vb->add_child(hb);
hb->set_modulate(Color(1, 1, 1, opacity_item));
diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp
index 6bc3a27a95..3c07e85758 100644
--- a/editor/localization_editor.cpp
+++ b/editor/localization_editor.cpp
@@ -37,7 +37,6 @@
#include "editor/filesystem_dock.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/pot_generator.h"
-#include "editor/themes/editor_scale.h"
#include "scene/gui/control.h"
void LocalizationEditor::_notification(int p_what) {
@@ -49,6 +48,7 @@ void LocalizationEditor::_notification(int p_what) {
List<String> tfn;
ResourceLoader::get_recognized_extensions_for_type("Translation", &tfn);
+ tfn.erase("csv"); // CSV is recognized by the resource importer to generate translation files, but it's not a translation file itself.
for (const String &E : tfn) {
translation_file_open->add_filter("*." + E);
}
diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h
index 860d0ed35d..eb623a147d 100644
--- a/editor/plugins/animation_state_machine_editor.h
+++ b/editor/plugins/animation_state_machine_editor.h
@@ -322,7 +322,7 @@ protected:
public:
void add_transition(const StringName &p_from, const StringName &p_to, Ref<AnimationNodeStateMachineTransition> p_transition);
- EditorAnimationMultiTransitionEdit(){};
+ EditorAnimationMultiTransitionEdit() {}
};
#endif // ANIMATION_STATE_MACHINE_EDITOR_H
diff --git a/editor/plugins/font_config_plugin.h b/editor/plugins/font_config_plugin.h
index e83f29a77b..87fd3861dc 100644
--- a/editor/plugins/font_config_plugin.h
+++ b/editor/plugins/font_config_plugin.h
@@ -51,7 +51,7 @@ public:
void set_dict(const Dictionary &p_dict);
Dictionary get_dict();
- EditorPropertyFontMetaObject(){};
+ EditorPropertyFontMetaObject() {}
};
/*************************************************************************/
@@ -75,7 +75,7 @@ public:
void set_defaults(const Dictionary &p_dict);
Dictionary get_defaults();
- EditorPropertyFontOTObject(){};
+ EditorPropertyFontOTObject() {}
};
/*************************************************************************/
@@ -103,7 +103,7 @@ class EditorPropertyFontMetaOverride : public EditorProperty {
protected:
void _notification(int p_what);
- static void _bind_methods(){};
+ static void _bind_methods() {}
void _edit_pressed();
void _page_changed(int p_page);
@@ -138,7 +138,7 @@ class EditorPropertyOTVariation : public EditorProperty {
EditorPaginator *paginator = nullptr;
protected:
- static void _bind_methods(){};
+ static void _bind_methods() {}
void _edit_pressed();
void _page_changed(int p_page);
@@ -187,7 +187,7 @@ class EditorPropertyOTFeatures : public EditorProperty {
protected:
void _notification(int p_what);
- static void _bind_methods(){};
+ static void _bind_methods() {}
void _edit_pressed();
void _page_changed(int p_page);
@@ -256,7 +256,7 @@ protected:
virtual void _add_element() override;
void _add_font(int p_option);
- static void _bind_methods(){};
+ static void _bind_methods() {}
public:
EditorPropertyFontNamesArray();
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.h b/editor/plugins/gpu_particles_3d_editor_plugin.h
index 5f59f6dca7..1295836b5f 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.h
@@ -59,7 +59,7 @@ protected:
Vector<Face3> geometry;
bool _generate(Vector<Vector3> &points, Vector<Vector3> &normals);
- virtual void _generate_emission_points(){};
+ virtual void _generate_emission_points() {}
void _node_selected(const NodePath &p_path);
public:
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index ba9fd4e66c..dc86acd884 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -3997,7 +3997,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
xform.orthonormalize();
xform.basis.scale(scale);
RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[3], xform);
- RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], spatial_editor->is_gizmo_visible() && transform_gizmo_visible && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE));
+ RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], spatial_editor->is_gizmo_visible() && !_edit.instant && transform_gizmo_visible && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE));
}
void Node3DEditorViewport::set_state(const Dictionary &p_state) {
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index af401ee6a3..9579388d46 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -3101,6 +3101,7 @@ Variant ScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
drag_preview->add_child(tf);
}
Label *label = memnew(Label(preview_name));
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate script names and class names.
drag_preview->add_child(label);
set_drag_preview(drag_preview);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 6bfe78c216..6b00a2c9c5 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -614,6 +614,7 @@ Variant ShaderEditorPlugin::get_drag_data_fw(const Point2 &p_point, Control *p_f
drag_preview->add_child(tf);
}
Label *label = memnew(Label(preview_name));
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate script names.
drag_preview->add_child(label);
main_split->set_drag_preview(drag_preview);
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 64b9522864..81beaf6f91 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -689,6 +689,7 @@ Variant Skeleton3DEditor::get_drag_data_fw(const Point2 &p_point, Control *p_fro
tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
hb->add_child(tf);
Label *label = memnew(Label(selected->get_text(0)));
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
hb->add_child(label);
vb->add_child(hb);
hb->set_modulate(Color(1, 1, 1, 1));
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 1acec4e959..b6c203f2a2 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -127,8 +127,8 @@ public:
virtual Variant get_navigation_state() override;
virtual Vector<String> get_functions() override;
virtual PackedInt32Array get_breakpoints() override;
- virtual void set_breakpoint(int p_line, bool p_enabled) override{};
- virtual void clear_breakpoints() override{};
+ virtual void set_breakpoint(int p_line, bool p_enabled) override {}
+ virtual void clear_breakpoints() override {}
virtual void goto_line(int p_line, int p_column = 0) override;
void goto_line_selection(int p_line, int p_begin, int p_end);
virtual void set_executing_line(int p_line) override;
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 79915012a8..12b9761fd2 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -1097,7 +1097,7 @@ void TileDataDefaultEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas_
}
};
-void TileDataDefaultEditor::forward_draw_over_alternatives(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_set_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform){
+void TileDataDefaultEditor::forward_draw_over_alternatives(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_set_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) {
};
diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h
index 9b1eadf331..1426bb4c2f 100644
--- a/editor/plugins/tiles/tile_data_editors.h
+++ b/editor/plugins/tiles/tile_data_editors.h
@@ -54,7 +54,7 @@ private:
protected:
Ref<TileSet> tile_set;
TileData *_get_tile_data(TileMapCell p_cell);
- virtual void _tile_set_changed(){};
+ virtual void _tile_set_changed() {}
static void _bind_methods();
@@ -63,13 +63,13 @@ public:
// Input to handle painting.
virtual Control *get_toolbar() { return nullptr; };
- virtual void forward_draw_over_atlas(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform){};
- virtual void forward_draw_over_alternatives(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform){};
- virtual void forward_painting_atlas_gui_input(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, const Ref<InputEvent> &p_event){};
- virtual void forward_painting_alternatives_gui_input(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, const Ref<InputEvent> &p_event){};
+ virtual void forward_draw_over_atlas(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) {}
+ virtual void forward_draw_over_alternatives(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) {}
+ virtual void forward_painting_atlas_gui_input(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, const Ref<InputEvent> &p_event) {}
+ virtual void forward_painting_alternatives_gui_input(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, const Ref<InputEvent> &p_event) {}
// Used to draw the tile data property value over a tile.
- virtual void draw_over_tile(CanvasItem *p_canvas_item, Transform2D p_transform, TileMapCell p_cell, bool p_selected = false){};
+ virtual void draw_over_tile(CanvasItem *p_canvas_item, Transform2D p_transform, TileMapCell p_cell, bool p_selected = false) {}
};
class DummyObject : public Object {
diff --git a/editor/plugins/tiles/tile_map_layer_editor.h b/editor/plugins/tiles/tile_map_layer_editor.h
index 7d749be1ba..805af7b58e 100644
--- a/editor/plugins/tiles/tile_map_layer_editor.h
+++ b/editor/plugins/tiles/tile_map_layer_editor.h
@@ -66,9 +66,9 @@ public:
};
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return false; };
- virtual void forward_canvas_draw_over_viewport(Control *p_overlay){};
- virtual void tile_set_changed(){};
- virtual void edit(ObjectID p_tile_map_layer_id){};
+ virtual void forward_canvas_draw_over_viewport(Control *p_overlay) {}
+ virtual void tile_set_changed() {}
+ virtual void edit(ObjectID p_tile_map_layer_id) {}
};
class TileMapLayerEditorTilesPlugin : public TileMapLayerSubEditorPlugin {
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 412d58cf45..c378bf315b 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -5994,6 +5994,7 @@ Variant VisualShaderEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
Label *label = memnew(Label);
label->set_text(it->get_text(0));
+ label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
set_drag_preview(label);
return d;
}
@@ -6560,6 +6561,7 @@ VisualShaderEditor::VisualShaderEditor() {
parameters->set_hide_folding(false);
parameters->set_h_size_flags(SIZE_EXPAND_FILL);
parameters->set_v_size_flags(SIZE_EXPAND_FILL);
+ parameters->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
parameters->connect(SceneStringName(item_selected), callable_mp(this, &VisualShaderEditor::_param_selected));
parameters->connect("nothing_selected", callable_mp(this, &VisualShaderEditor::_param_unselected));
sc->add_child(parameters);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 279590563a..8411c0edea 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1081,6 +1081,8 @@ void ProjectManager::_titlebar_resized() {
ProjectManager::ProjectManager() {
singleton = this;
+ set_translation_domain("godot.editor");
+
// Turn off some servers we aren't going to be using in the Project Manager.
NavigationServer3D::get_singleton()->set_active(false);
PhysicsServer3D::get_singleton()->set_active(false);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 489fbb037f..d00fdc2123 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -267,7 +267,7 @@ void ProjectSettingsEditor::shortcut_input(const Ref<InputEvent> &p_event) {
String ProjectSettingsEditor::_get_setting_name() const {
String name = property_box->get_text().strip_edges();
- if (!name.contains("/")) {
+ if (!name.begins_with("_") && !name.contains("/")) {
name = "global/" + name;
}
return name;
@@ -771,7 +771,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
bool use_advanced = EditorSettings::get_singleton()->get_project_metadata("project_settings", "advanced_mode", false);
if (use_advanced) {
- advanced->set_pressed(true);
+ advanced->set_pressed_no_signal(true);
}
_update_advanced(use_advanced);
diff --git a/main/main.cpp b/main/main.cpp
index f1ee4bf2a6..fa50a3039f 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1977,6 +1977,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_vulkan", true);
GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_d3d12", true);
+ GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_opengl3", true);
}
{
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index 72b540496d..1804d73a69 100644
--- a/modules/bmp/image_loader_bmp.cpp
+++ b/modules/bmp/image_loader_bmp.cpp
@@ -59,30 +59,6 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
size_t height = (size_t)p_header.bmp_info_header.bmp_height;
size_t bits_per_pixel = (size_t)p_header.bmp_info_header.bmp_bit_count;
- // Check whether we can load it
-
- if (bits_per_pixel == 1) {
- // Requires bit unpacking...
- ERR_FAIL_COND_V_MSG(width % 8 != 0, ERR_UNAVAILABLE,
- vformat("1-bpp BMP images must have a width that is a multiple of 8, but the imported BMP is %d pixels wide.", int(width)));
- ERR_FAIL_COND_V_MSG(height % 8 != 0, ERR_UNAVAILABLE,
- vformat("1-bpp BMP images must have a height that is a multiple of 8, but the imported BMP is %d pixels tall.", int(height)));
-
- } else if (bits_per_pixel == 2) {
- // Requires bit unpacking...
- ERR_FAIL_COND_V_MSG(width % 4 != 0, ERR_UNAVAILABLE,
- vformat("2-bpp BMP images must have a width that is a multiple of 4, but the imported BMP is %d pixels wide.", int(width)));
- ERR_FAIL_COND_V_MSG(height % 4 != 0, ERR_UNAVAILABLE,
- vformat("2-bpp BMP images must have a height that is a multiple of 4, but the imported BMP is %d pixels tall.", int(height)));
-
- } else if (bits_per_pixel == 4) {
- // Requires bit unpacking...
- ERR_FAIL_COND_V_MSG(width % 2 != 0, ERR_UNAVAILABLE,
- vformat("4-bpp BMP images must have a width that is a multiple of 2, but the imported BMP is %d pixels wide.", int(width)));
- ERR_FAIL_COND_V_MSG(height % 2 != 0, ERR_UNAVAILABLE,
- vformat("4-bpp BMP images must have a height that is a multiple of 2, but the imported BMP is %d pixels tall.", int(height)));
- }
-
// Image data (might be indexed)
Vector<uint8_t> data;
int data_len = 0;
@@ -98,55 +74,32 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
uint8_t *data_w = data.ptrw();
uint8_t *write_buffer = data_w;
- const uint32_t width_bytes = width * bits_per_pixel / 8;
- const uint32_t line_width = (width_bytes + 3) & ~3;
+ const uint32_t width_bytes = (width * bits_per_pixel + 7) / 8;
+ const uint32_t line_width = (width_bytes + 3) & ~3; // Padded to 4 bytes.
- // The actual data traversal is determined by
- // the data width in case of 8/4/2/1 bit images
- const uint32_t w = bits_per_pixel >= 16 ? width : width_bytes;
const uint8_t *line = p_buffer + (line_width * (height - 1));
const uint8_t *end_buffer = p_buffer + p_header.bmp_file_header.bmp_file_size - p_header.bmp_file_header.bmp_file_offset;
+ ERR_FAIL_COND_V(line + line_width > end_buffer, ERR_FILE_CORRUPT);
for (uint64_t i = 0; i < height; i++) {
const uint8_t *line_ptr = line;
- for (unsigned int j = 0; j < w; j++) {
- ERR_FAIL_COND_V(line_ptr >= end_buffer, ERR_FILE_CORRUPT);
+ for (unsigned int j = 0; j < width; j++) {
switch (bits_per_pixel) {
case 1: {
- uint8_t color_index = *line_ptr;
+ write_buffer[index] = (line[(j * bits_per_pixel) / 8] >> (8 - bits_per_pixel * (1 + j % 8))) & 0x01;
- write_buffer[index + 0] = (color_index >> 7) & 1;
- write_buffer[index + 1] = (color_index >> 6) & 1;
- write_buffer[index + 2] = (color_index >> 5) & 1;
- write_buffer[index + 3] = (color_index >> 4) & 1;
- write_buffer[index + 4] = (color_index >> 3) & 1;
- write_buffer[index + 5] = (color_index >> 2) & 1;
- write_buffer[index + 6] = (color_index >> 1) & 1;
- write_buffer[index + 7] = (color_index >> 0) & 1;
-
- index += 8;
- line_ptr += 1;
+ index++;
} break;
case 2: {
- uint8_t color_index = *line_ptr;
+ write_buffer[index] = (line[(j * bits_per_pixel) / 8] >> (8 - bits_per_pixel * (1 + j % 4))) & 0x03;
- write_buffer[index + 0] = (color_index >> 6) & 3;
- write_buffer[index + 1] = (color_index >> 4) & 3;
- write_buffer[index + 2] = (color_index >> 2) & 3;
- write_buffer[index + 3] = color_index & 3;
-
- index += 4;
- line_ptr += 1;
+ index++;
} break;
case 4: {
- uint8_t color_index = *line_ptr;
-
- write_buffer[index + 0] = (color_index >> 4) & 0x0f;
- write_buffer[index + 1] = color_index & 0x0f;
+ write_buffer[index] = (line[(j * bits_per_pixel) / 8] >> (8 - bits_per_pixel * (1 + j % 2))) & 0x0f;
- index += 2;
- line_ptr += 1;
+ index++;
} break;
case 8: {
uint8_t color_index = *line_ptr;
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h
index a808f19e5b..239f7d9f43 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.h
+++ b/modules/gdscript/language_server/gdscript_extend_parser.h
@@ -37,10 +37,10 @@
#include "core/variant/variant.h"
#ifndef LINE_NUMBER_TO_INDEX
-#define LINE_NUMBER_TO_INDEX(p_line) ((p_line)-1)
+#define LINE_NUMBER_TO_INDEX(p_line) ((p_line) - 1)
#endif
#ifndef COLUMN_NUMBER_TO_INDEX
-#define COLUMN_NUMBER_TO_INDEX(p_column) ((p_column)-1)
+#define COLUMN_NUMBER_TO_INDEX(p_column) ((p_column) - 1)
#endif
#ifndef SYMBOL_SEPERATOR
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index f47e6d209a..3d12994469 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1497,11 +1497,23 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const {
void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
List<PropertyInfo> props;
- script->get_script_property_list(&props);
+ ERR_FAIL_COND(!script.is_valid());
+#ifdef TOOLS_ENABLED
+ for (const PropertyInfo &prop : script->exported_members_cache) {
+ props.push_back(prop);
+ }
+#else
+ for (const KeyValue<StringName, PropertyInfo> &E : script->member_info) {
+ props.push_front(E.value);
+ }
+#endif
- // Call _get_property_list
+ for (PropertyInfo &prop : props) {
+ validate_property(prop);
+ p_properties->push_back(prop);
+ }
- ERR_FAIL_COND(!script.is_valid());
+ // Call _get_property_list
StringName method = SNAME("_get_property_list");
@@ -1524,10 +1536,25 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
}
}
- props.reverse();
- for (PropertyInfo &prop : props) {
- validate_property(prop);
- p_properties->push_front(prop);
+ CSharpScript *top = script.ptr()->base_script.ptr();
+ while (top != nullptr) {
+ props.clear();
+#ifdef TOOLS_ENABLED
+ for (const PropertyInfo &prop : top->exported_members_cache) {
+ props.push_back(prop);
+ }
+#else
+ for (const KeyValue<StringName, PropertyInfo> &E : top->member_info) {
+ props.push_front(E.value);
+ }
+#endif
+
+ for (PropertyInfo &prop : props) {
+ validate_property(prop);
+ p_properties->push_back(prop);
+ }
+
+ top = top->base_script.ptr();
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.OpenVisualStudio/GodotTools.OpenVisualStudio.csproj b/modules/mono/editor/GodotTools/GodotTools.OpenVisualStudio/GodotTools.OpenVisualStudio.csproj
index f23f2b9a8c..208e6d8f41 100644
--- a/modules/mono/editor/GodotTools/GodotTools.OpenVisualStudio/GodotTools.OpenVisualStudio.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.OpenVisualStudio/GodotTools.OpenVisualStudio.csproj
@@ -5,7 +5,6 @@
<TargetFramework>net6.0-windows</TargetFramework>
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
- <RuntimeIdentifier>win-x86</RuntimeIdentifier>
<SelfContained>False</SelfContained>
<RollForward>LatestMajor</RollForward>
</PropertyGroup>
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index d3899c809a..e84b4e92c7 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -259,11 +259,12 @@ namespace GodotTools
var args = new List<string>
{
+ Path.Combine(GodotSharpDirs.DataEditorToolsDir, "GodotTools.OpenVisualStudio.dll"),
GodotSharpDirs.ProjectSlnPath,
line >= 0 ? $"{scriptPath};{line + 1};{col + 1}" : scriptPath
};
- string command = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "GodotTools.OpenVisualStudio.exe");
+ string command = DotNetFinder.FindDotNetExe() ?? "dotnet";
try
{
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 3222c58c4e..d0adf39fb2 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -1452,7 +1452,7 @@ Error BindingsGenerator::_populate_method_icalls_table(const TypeInterface &p_it
}
const TypeInterface *return_type = _get_type_or_null(imethod.return_type);
- ERR_FAIL_NULL_V(return_type, ERR_BUG); // Return type not found
+ ERR_FAIL_NULL_V_MSG(return_type, ERR_BUG, "Return type '" + imethod.return_type.cname + "' was not found.");
String im_unique_sig = get_ret_unique_sig(return_type) + ",CallMethodBind";
@@ -1463,7 +1463,7 @@ Error BindingsGenerator::_populate_method_icalls_table(const TypeInterface &p_it
// Get arguments information
for (const ArgumentInterface &iarg : imethod.arguments) {
const TypeInterface *arg_type = _get_type_or_null(iarg.type);
- ERR_FAIL_NULL_V(arg_type, ERR_BUG); // Argument type not found
+ ERR_FAIL_NULL_V_MSG(arg_type, ERR_BUG, "Argument type '" + iarg.type.cname + "' was not found.");
im_unique_sig += ",";
im_unique_sig += get_arg_unique_sig(*arg_type);
@@ -2313,7 +2313,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
const ArgumentInterface &iarg = *itr;
const TypeInterface *arg_type = _get_type_or_null(iarg.type);
- ERR_FAIL_NULL_V(arg_type, ERR_BUG); // Argument type not found
+ ERR_FAIL_NULL_V_MSG(arg_type, ERR_BUG, "Argument type '" + iarg.type.cname + "' was not found.");
if (i != 0) {
output << ", ";
@@ -2333,7 +2333,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
if (imethod.return_type.cname != name_cache.type_void) {
const TypeInterface *return_type = _get_type_or_null(imethod.return_type);
- ERR_FAIL_NULL_V(return_type, ERR_BUG); // Return type not found
+ ERR_FAIL_NULL_V_MSG(return_type, ERR_BUG, "Return type '" + imethod.return_type.cname + "' was not found.");
output << INDENT3 "ret = "
<< sformat(return_type->cs_managed_to_variant, "callRet", return_type->cs_type, return_type->name)
@@ -2552,7 +2552,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
const TypeReference &proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type;
const TypeInterface *prop_itype = _get_type_or_singleton_or_null(proptype_name);
- ERR_FAIL_NULL_V(prop_itype, ERR_BUG); // Property type not found
+ ERR_FAIL_NULL_V_MSG(prop_itype, ERR_BUG, "Property type '" + proptype_name.cname + "' was not found.");
ERR_FAIL_COND_V_MSG(prop_itype->is_singleton, ERR_BUG,
"Property type is a singleton: '" + p_itype.name + "." + String(p_iprop.cname) + "'.");
@@ -2651,7 +2651,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output) {
const TypeInterface *return_type = _get_type_or_singleton_or_null(p_imethod.return_type);
- ERR_FAIL_NULL_V(return_type, ERR_BUG); // Return type not found
+ ERR_FAIL_NULL_V_MSG(return_type, ERR_BUG, "Return type '" + p_imethod.return_type.cname + "' was not found.");
ERR_FAIL_COND_V_MSG(return_type->is_singleton, ERR_BUG,
"Method return type is a singleton: '" + p_itype.name + "." + p_imethod.name + "'.");
@@ -2690,7 +2690,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
const ArgumentInterface &first = p_imethod.arguments.front()->get();
for (const ArgumentInterface &iarg : p_imethod.arguments) {
const TypeInterface *arg_type = _get_type_or_singleton_or_null(iarg.type);
- ERR_FAIL_NULL_V(arg_type, ERR_BUG); // Argument type not found
+ ERR_FAIL_NULL_V_MSG(arg_type, ERR_BUG, "Argument type '" + iarg.type.cname + "' was not found.");
ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
"Argument type is a singleton: '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
@@ -2944,7 +2944,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
const ArgumentInterface &first = p_isignal.arguments.front()->get();
for (const ArgumentInterface &iarg : p_isignal.arguments) {
const TypeInterface *arg_type = _get_type_or_singleton_or_null(iarg.type);
- ERR_FAIL_NULL_V(arg_type, ERR_BUG); // Argument type not found
+ ERR_FAIL_NULL_V_MSG(arg_type, ERR_BUG, "Argument type '" + iarg.type.cname + "' was not found.");
ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
"Argument type is a singleton: '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "'.");
@@ -3013,7 +3013,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
int idx = 0;
for (const ArgumentInterface &iarg : p_isignal.arguments) {
const TypeInterface *arg_type = _get_type_or_null(iarg.type);
- ERR_FAIL_NULL_V(arg_type, ERR_BUG); // Argument type not found
+ ERR_FAIL_NULL_V_MSG(arg_type, ERR_BUG, "Argument type '" + iarg.type.cname + "' was not found.");
if (idx != 0) {
p_output << ", ";
@@ -3113,7 +3113,7 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
bool ret_void = p_icall.return_type.cname == name_cache.type_void;
const TypeInterface *return_type = _get_type_or_null(p_icall.return_type);
- ERR_FAIL_NULL_V(return_type, ERR_BUG); // Return type not found
+ ERR_FAIL_NULL_V_MSG(return_type, ERR_BUG, "Return type '" + p_icall.return_type.cname + "' was not found.");
StringBuilder c_func_sig;
StringBuilder c_in_statements;
@@ -3129,7 +3129,7 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
int i = 0;
for (const TypeReference &arg_type_ref : p_icall.argument_types) {
const TypeInterface *arg_type = _get_type_or_null(arg_type_ref);
- ERR_FAIL_NULL_V(arg_type, ERR_BUG); // Return type not found
+ ERR_FAIL_NULL_V_MSG(arg_type, ERR_BUG, "Argument type '" + arg_type_ref.cname + "' was not found.");
String c_param_name = "arg" + itos(i + 1);
@@ -3389,7 +3389,7 @@ const String BindingsGenerator::_get_generic_type_parameters(const TypeInterface
String params = "<";
for (const TypeReference &param_type : p_generic_type_parameters) {
const TypeInterface *param_itype = _get_type_or_singleton_or_null(param_type);
- ERR_FAIL_NULL_V(param_itype, ""); // Parameter type not found
+ ERR_FAIL_NULL_V_MSG(param_itype, "", "Parameter type '" + param_type.cname + "' was not found.");
ERR_FAIL_COND_V_MSG(param_itype->is_singleton, "",
"Generic type parameter is a singleton: '" + param_itype->name + "'.");
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
index 0f534d477f..0dc143edea 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
@@ -468,8 +468,8 @@ namespace Godot
{
for (int j = 0; j < 3; j++)
{
- real_t e = transform.Basis[i][j] * min[j];
- real_t f = transform.Basis[i][j] * max[j];
+ real_t e = transform.Basis[j][i] * min[j];
+ real_t f = transform.Basis[j][i] * max[j];
if (e < f)
{
tmin[i] += e;
diff --git a/modules/navigation/nav_base.h b/modules/navigation/nav_base.h
index c28392acf7..d2308abfaf 100644
--- a/modules/navigation/nav_base.h
+++ b/modules/navigation/nav_base.h
@@ -64,7 +64,7 @@ public:
void set_owner_id(ObjectID p_owner_id) { owner_id = p_owner_id; }
ObjectID get_owner_id() const { return owner_id; }
- virtual ~NavBase(){};
+ virtual ~NavBase() {}
};
#endif // NAV_BASE_H
diff --git a/modules/openxr/extensions/platform/openxr_opengl_extension.cpp b/modules/openxr/extensions/platform/openxr_opengl_extension.cpp
index de4a9e4b8e..caded14ca7 100644
--- a/modules/openxr/extensions/platform/openxr_opengl_extension.cpp
+++ b/modules/openxr/extensions/platform/openxr_opengl_extension.cpp
@@ -240,8 +240,8 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
Vector<RID> texture_rids;
for (uint64_t i = 0; i < swapchain_length; i++) {
- RID texture_rid = texture_storage->texture_create_external(
- p_array_size == 1 ? GLES3::Texture::TYPE_2D : GLES3::Texture::TYPE_LAYERED,
+ RID texture_rid = texture_storage->texture_create_from_native_handle(
+ p_array_size == 1 ? RS::TEXTURE_TYPE_2D : RS::TEXTURE_TYPE_LAYERED,
format,
images[i].image,
p_width,
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index 448be9ebe4..c63389b1c6 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -705,7 +705,7 @@ class TextServerAdvanced : public TextServerExtension {
};
protected:
- static void _bind_methods(){};
+ static void _bind_methods() {}
void full_copy(ShapedTextDataAdvanced *p_shaped);
void invalidate(ShapedTextDataAdvanced *p_shaped, bool p_text = false);
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index ee1f72401f..7f12ad593b 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -574,7 +574,7 @@ class TextServerFallback : public TextServerExtension {
Mutex ft_mutex;
protected:
- static void _bind_methods(){};
+ static void _bind_methods() {}
void full_copy(ShapedTextDataFallback *p_shaped);
void invalidate(ShapedTextDataFallback *p_shaped);
diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp
index 78a9db9b19..352d495dd4 100644
--- a/modules/webxr/webxr_interface_js.cpp
+++ b/modules/webxr/webxr_interface_js.cpp
@@ -561,8 +561,8 @@ RID WebXRInterfaceJS::_get_texture(unsigned int p_texture_id) {
uint32_t view_count = godot_webxr_get_view_count();
Size2 texture_size = get_render_target_size();
- RID texture = texture_storage->texture_create_external(
- view_count == 1 ? GLES3::Texture::TYPE_2D : GLES3::Texture::TYPE_LAYERED,
+ RID texture = texture_storage->texture_create_from_native_handle(
+ view_count == 1 ? RS::TEXTURE_TYPE_2D : RS::TEXTURE_TYPE_LAYERED,
Image::FORMAT_RGBA8,
p_texture_id,
(int)texture_size.width,
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index b88d887af5..c1053215c6 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -607,11 +607,19 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
if (rendering_context) {
if (rendering_context->initialize() != OK) {
- ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver));
memdelete(rendering_context);
rendering_context = nullptr;
- r_error = ERR_UNAVAILABLE;
- return;
+ bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
+ if (fallback_to_opengl3 && rendering_driver != "opengl3") {
+ WARN_PRINT("Your device seem not to support Vulkan, switching to OpenGL 3.");
+ rendering_driver = "opengl3";
+ OS::get_singleton()->set_current_rendering_method("gl_compatibility");
+ OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
+ } else {
+ ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver));
+ r_error = ERR_UNAVAILABLE;
+ return;
+ }
}
union {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
index 4a166112ab..be5a7a2962 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
@@ -50,7 +50,7 @@ public final class SignalInfo {
}
this.name = signalName;
- this.paramTypes = paramTypes == null ? new Class<?>[ 0 ] : paramTypes;
+ this.paramTypes = paramTypes == null ? new Class<?>[0] : paramTypes;
this.paramTypesNames = new String[this.paramTypes.length];
for (int i = 0; i < this.paramTypes.length; i++) {
this.paramTypesNames[i] = this.paramTypes[i].getName();
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index 5a027e0196..e51d43bd89 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -107,11 +107,19 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
#endif
if (rendering_context) {
if (rendering_context->initialize() != OK) {
- ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver));
memdelete(rendering_context);
rendering_context = nullptr;
- r_error = ERR_UNAVAILABLE;
- return;
+ bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
+ if (fallback_to_opengl3 && rendering_driver != "opengl3") {
+ WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3.");
+ rendering_driver = "opengl3";
+ OS::get_singleton()->set_current_rendering_method("gl_compatibility");
+ OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
+ } else {
+ ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver));
+ r_error = ERR_UNAVAILABLE;
+ return;
+ }
}
if (rendering_context->window_create(MAIN_WINDOW_ID, &wpd) != OK) {
diff --git a/platform/linuxbsd/export/export_plugin.h b/platform/linuxbsd/export/export_plugin.h
index 1d9ef01d1a..9e016bd4c3 100644
--- a/platform/linuxbsd/export/export_plugin.h
+++ b/platform/linuxbsd/export/export_plugin.h
@@ -48,7 +48,7 @@ class EditorExportPlatformLinuxBSD : public EditorExportPlatformPC {
String cmd_args;
bool wait = false;
- SSHCleanupCommand(){};
+ SSHCleanupCommand() {}
SSHCleanupCommand(const String &p_host, const String &p_port, const Vector<String> &p_ssh_arg, const String &p_cmd_args, bool p_wait = false) {
host = p_host;
port = p_port;
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index a67428b9a4..49f2690e61 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -50,7 +50,7 @@
#define LONG_BITS (sizeof(long) * 8)
#define test_bit(nr, addr) (((1UL << ((nr) % LONG_BITS)) & ((addr)[(nr) / LONG_BITS])) != 0)
-#define NBITS(x) ((((x)-1) / LONG_BITS) + 1)
+#define NBITS(x) ((((x) - 1) / LONG_BITS) + 1)
#ifdef UDEV_ENABLED
static const char *ignore_str = "/dev/input/js";
diff --git a/platform/linuxbsd/wayland/key_mapping_xkb.h b/platform/linuxbsd/wayland/key_mapping_xkb.h
index 306a8f25b5..9b8c90a445 100644
--- a/platform/linuxbsd/wayland/key_mapping_xkb.h
+++ b/platform/linuxbsd/wayland/key_mapping_xkb.h
@@ -51,7 +51,7 @@ class KeyMappingXKB {
static inline HashMap<Key, unsigned int, HashMapHasherKeys> scancode_map_inv;
static inline HashMap<unsigned int, KeyLocation, HashMapHasherKeys> location_map;
- KeyMappingXKB(){};
+ KeyMappingXKB() {}
public:
static void initialize();
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index a12c935273..7949f80f24 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -6160,20 +6160,28 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
if (rendering_context->initialize() != OK) {
memdelete(rendering_context);
rendering_context = nullptr;
- r_error = ERR_CANT_CREATE;
+ bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
+ if (fallback_to_opengl3 && rendering_driver != "opengl3") {
+ WARN_PRINT("Your video card drivers seem not to support the required Vulkan version, switching to OpenGL 3.");
+ rendering_driver = "opengl3";
+ OS::get_singleton()->set_current_rendering_method("gl_compatibility");
+ OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
+ } else {
+ r_error = ERR_CANT_CREATE;
+
+ if (p_rendering_driver == "vulkan") {
+ OS::get_singleton()->alert(
+ vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
+ "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
+ "You can enable the OpenGL 3 driver by starting the engine from the\n"
+ "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
+ "If you recently updated your video card drivers, try rebooting.",
+ executable_name),
+ "Unable to initialize Vulkan video driver");
+ }
- if (p_rendering_driver == "vulkan") {
- OS::get_singleton()->alert(
- vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
- "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
- "You can enable the OpenGL 3 driver by starting the engine from the\n"
- "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
- "If you recently updated your video card drivers, try rebooting.",
- executable_name),
- "Unable to initialize Vulkan video driver");
+ ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver));
}
-
- ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver));
}
driver_found = true;
}
diff --git a/platform/linuxbsd/x11/gl_manager_x11_egl.h b/platform/linuxbsd/x11/gl_manager_x11_egl.h
index b9c96619c4..405dda3d83 100644
--- a/platform/linuxbsd/x11/gl_manager_x11_egl.h
+++ b/platform/linuxbsd/x11/gl_manager_x11_egl.h
@@ -52,8 +52,8 @@ private:
public:
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {}
- GLManagerEGL_X11(){};
- ~GLManagerEGL_X11(){};
+ GLManagerEGL_X11() {}
+ ~GLManagerEGL_X11() {}
};
#endif // X11_ENABLED && GLES3_ENABLED
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 52dc51bc96..f6c1d11028 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -3649,8 +3649,16 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
if (rendering_context->initialize() != OK) {
memdelete(rendering_context);
rendering_context = nullptr;
- r_error = ERR_CANT_CREATE;
- ERR_FAIL_MSG("Could not initialize " + rendering_driver);
+ bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
+ if (fallback_to_opengl3 && rendering_driver != "opengl3") {
+ WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3.");
+ rendering_driver = "opengl3";
+ OS::get_singleton()->set_current_rendering_method("gl_compatibility");
+ OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
+ } else {
+ r_error = ERR_CANT_CREATE;
+ ERR_FAIL_MSG("Could not initialize " + rendering_driver);
+ }
}
}
#endif
diff --git a/platform/macos/export/export_plugin.h b/platform/macos/export/export_plugin.h
index 5457c687d3..d88d347359 100644
--- a/platform/macos/export/export_plugin.h
+++ b/platform/macos/export/export_plugin.h
@@ -68,7 +68,7 @@ class EditorExportPlatformMacOS : public EditorExportPlatform {
String cmd_args;
bool wait = false;
- SSHCleanupCommand(){};
+ SSHCleanupCommand() {}
SSHCleanupCommand(const String &p_host, const String &p_port, const Vector<String> &p_ssh_arg, const String &p_cmd_args, bool p_wait = false) {
host = p_host;
port = p_port;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 2db58172bf..db4c743595 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -704,6 +704,17 @@ def get_is_ar_thin_supported(env):
return False
+WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")
+
+
+def tempfile_arg_esc_func(arg):
+ from SCons.Subst import quote_spaces
+
+ arg = quote_spaces(arg)
+ # GCC requires double Windows slashes, let's use UNIX separator
+ return WINPATHSEP_RE.sub(r"/\1", arg)
+
+
def configure_mingw(env: "SConsEnvironment"):
# Workaround for MinGW. See:
# https://www.scons.org/wiki/LongCmdLinesOnWin32
@@ -713,6 +724,8 @@ def configure_mingw(env: "SConsEnvironment"):
env["ARCOM_ORIG"] = env["ARCOM"]
env["ARCOM"] = "${TEMPFILE('$ARCOM_ORIG', '$ARCOMSTR')}"
env["TEMPFILESUFFIX"] = ".rsp"
+ if os.name == "nt":
+ env["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func
## Build type
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 50ebe7077f..ed9d5244a3 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -381,7 +381,7 @@ public:
ctls[cid] = p_name;
}
- virtual ~FileDialogEventHandler(){};
+ virtual ~FileDialogEventHandler() {}
};
#if defined(__GNUC__) && !defined(__clang__)
@@ -6177,6 +6177,17 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
}
#endif
+ bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
+ if (failed && fallback_to_opengl3 && rendering_driver != "opengl3") {
+ memdelete(rendering_context);
+ rendering_context = nullptr;
+ tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3);
+ WARN_PRINT("Your video card drivers seem not to support Direct3D 12 or Vulkan, switching to OpenGL 3.");
+ rendering_driver = "opengl3";
+ OS::get_singleton()->set_current_rendering_method("gl_compatibility");
+ OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
+ failed = false;
+ }
if (failed) {
memdelete(rendering_context);
rendering_context = nullptr;
diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h
index e86aac83d4..1972b36845 100644
--- a/platform/windows/export/export_plugin.h
+++ b/platform/windows/export/export_plugin.h
@@ -52,7 +52,7 @@ class EditorExportPlatformWindows : public EditorExportPlatformPC {
String cmd_args;
bool wait = false;
- SSHCleanupCommand(){};
+ SSHCleanupCommand() {}
SSHCleanupCommand(const String &p_host, const String &p_port, const Vector<String> &p_ssh_arg, const String &p_cmd_args, bool p_wait = false) {
host = p_host;
port = p_port;
diff --git a/platform/windows/gl_manager_windows_angle.h b/platform/windows/gl_manager_windows_angle.h
index f43a6fbe02..9c02912b86 100644
--- a/platform/windows/gl_manager_windows_angle.h
+++ b/platform/windows/gl_manager_windows_angle.h
@@ -52,8 +52,8 @@ private:
public:
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
- GLManagerANGLE_Windows(){};
- ~GLManagerANGLE_Windows(){};
+ GLManagerANGLE_Windows() {}
+ ~GLManagerANGLE_Windows() {}
};
#endif // WINDOWS_ENABLED && GLES3_ENABLED
diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h
index cc0a5b49fb..6cb481849c 100644
--- a/scene/2d/tile_map_layer.h
+++ b/scene/2d/tile_map_layer.h
@@ -90,7 +90,7 @@ public:
TerrainConstraint(Ref<TileSet> p_tile_set, const Vector2i &p_position, int p_terrain); // For the center terrain bit
TerrainConstraint(Ref<TileSet> p_tile_set, const Vector2i &p_position, const TileSet::CellNeighbor &p_bit, int p_terrain); // For peering bits
- TerrainConstraint(){};
+ TerrainConstraint() {}
};
#ifdef DEBUG_ENABLED
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 591528b915..98bee2115c 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -401,10 +401,19 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
total_max = MAX(total_max, listener_area_pos.length());
}
- if (total_max > max_distance) {
+ if (dist > total_max || total_max > max_distance) {
+ if (!was_further_than_max_distance_last_frame) {
+ HashMap<StringName, Vector<AudioFrame>> bus_volumes;
+ for (Ref<AudioStreamPlayback> &playback : internal->stream_playbacks) {
+ // So the player gets muted and mostly stops mixing when out of range.
+ AudioServer::get_singleton()->set_playback_bus_volumes_linear(playback, bus_volumes);
+ }
+ was_further_than_max_distance_last_frame = true; // Cache so we don't set the volume over and over.
+ }
continue; //can't hear this sound in this listener
}
}
+ was_further_than_max_distance_last_frame = false;
float multiplier = Math::db_to_linear(_get_attenuation_db(dist));
if (max_distance > 0) {
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 72356faad7..91104a06c7 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -105,6 +105,7 @@ private:
float linear_attenuation = 0;
float max_distance = 0.0;
+ bool was_further_than_max_distance_last_frame = false;
Ref<VelocityTracker3D> velocity_tracker;
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index cdc85d2b2d..a96417738f 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -1139,7 +1139,11 @@ void AnimationNodeTransition::remove_input(int p_index) {
bool AnimationNodeTransition::set_input_name(int p_input, const String &p_name) {
pending_update = true;
- return AnimationNode::set_input_name(p_input, p_name);
+ if (!AnimationNode::set_input_name(p_input, p_name)) {
+ return false;
+ }
+ emit_signal(SNAME("tree_changed")); // For updating enum options.
+ return true;
}
void AnimationNodeTransition::set_input_as_auto_advance(int p_input, bool p_enable) {
diff --git a/scene/gui/color_mode.h b/scene/gui/color_mode.h
index 84e9d4542d..94193ccf74 100644
--- a/scene/gui/color_mode.h
+++ b/scene/gui/color_mode.h
@@ -50,14 +50,14 @@ public:
virtual Color get_color() const = 0;
- virtual void _value_changed(){};
+ virtual void _value_changed() {}
virtual void slider_draw(int p_which) = 0;
virtual bool apply_theme() const { return false; }
virtual ColorPicker::PickerShapeType get_shape_override() const { return ColorPicker::SHAPE_MAX; }
ColorMode(ColorPicker *p_color_picker);
- virtual ~ColorMode(){};
+ virtual ~ColorMode() {}
};
class ColorModeHSV : public ColorMode {
@@ -81,7 +81,7 @@ public:
virtual void slider_draw(int p_which) override;
ColorModeHSV(ColorPicker *p_color_picker) :
- ColorMode(p_color_picker){};
+ ColorMode(p_color_picker) {}
};
class ColorModeRGB : public ColorMode {
@@ -100,7 +100,7 @@ public:
virtual void slider_draw(int p_which) override;
ColorModeRGB(ColorPicker *p_color_picker) :
- ColorMode(p_color_picker){};
+ ColorMode(p_color_picker) {}
};
class ColorModeRAW : public ColorMode {
@@ -122,7 +122,7 @@ public:
virtual bool apply_theme() const override;
ColorModeRAW(ColorPicker *p_color_picker) :
- ColorMode(p_color_picker){};
+ ColorMode(p_color_picker) {}
};
class ColorModeOKHSL : public ColorMode {
@@ -147,9 +147,9 @@ public:
virtual ColorPicker::PickerShapeType get_shape_override() const override { return ColorPicker::SHAPE_OKHSL_CIRCLE; }
ColorModeOKHSL(ColorPicker *p_color_picker) :
- ColorMode(p_color_picker){};
+ ColorMode(p_color_picker) {}
- ~ColorModeOKHSL(){};
+ ~ColorModeOKHSL() {}
};
#endif // COLOR_MODE_H
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 756cb77c60..43782409a8 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -921,6 +921,7 @@ Variant LineEdit::get_drag_data(const Point2 &p_point) {
String t = get_selected_text();
Label *l = memnew(Label);
l->set_text(t);
+ l->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate user input.
set_drag_preview(l);
return t;
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 0c3c90d070..e302927692 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -5431,6 +5431,7 @@ Variant RichTextLabel::get_drag_data(const Point2 &p_point) {
String t = get_selected_text();
Label *l = memnew(Label);
l->set_text(t);
+ l->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Text is already translated.
set_drag_preview(l);
return t;
}
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index 3e0d6adf42..90bb0799b1 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -1250,6 +1250,7 @@ Variant TabBar::_handle_get_drag_data(const String &p_type, const Point2 &p_poin
}
Label *label = memnew(Label(get_tab_title(tab_over)));
+ label->set_auto_translate_mode(get_auto_translate_mode()); // Reflect how the title is displayed.
drag_preview->add_child(label);
set_drag_preview(drag_preview);
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 6e533aa5ab..eb9616c939 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -267,10 +267,14 @@ void TabContainer::_repaint() {
Vector<Control *> controls = _get_tab_controls();
int current = get_current_tab();
+ // Move the TabBar to the top or bottom.
+ // Don't change the left and right offsets since the TabBar will resize and may change tab offset.
if (tabs_position == POSITION_BOTTOM) {
- tab_bar->set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE);
+ tab_bar->set_anchor_and_offset(SIDE_BOTTOM, 1.0, 0.0);
+ tab_bar->set_anchor_and_offset(SIDE_TOP, 1.0, -_get_tab_height());
} else {
- tab_bar->set_anchors_and_offsets_preset(PRESET_TOP_WIDE);
+ tab_bar->set_anchor_and_offset(SIDE_BOTTOM, 0.0, _get_tab_height());
+ tab_bar->set_anchor_and_offset(SIDE_TOP, 0.0, 0.0);
}
updating_visibility = true;
@@ -299,7 +303,6 @@ void TabContainer::_repaint() {
}
updating_visibility = false;
- _update_margins();
update_minimum_size();
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index bf9c479c69..888e680219 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -3034,6 +3034,7 @@ Variant TextEdit::get_drag_data(const Point2 &p_point) {
if (has_selection() && selection_drag_attempt) {
String t = get_selected_text();
Label *l = memnew(Label);
+ l->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate user input.
l->set_text(t);
set_drag_preview(l);
return t;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 858fc2246b..eb3448e1a2 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -111,6 +111,7 @@ void Node::_notification(int p_notification) {
data.auto_translate_mode = AUTO_TRANSLATE_MODE_ALWAYS;
}
data.is_auto_translate_dirty = true;
+ data.is_translation_domain_dirty = true;
#ifdef TOOLS_ENABLED
// Don't translate UI elements when they're being edited.
@@ -1320,6 +1321,51 @@ bool Node::can_auto_translate() const {
return data.is_auto_translating;
}
+StringName Node::get_translation_domain() const {
+ ERR_READ_THREAD_GUARD_V(StringName());
+
+ if (data.is_translation_domain_inherited && data.is_translation_domain_dirty) {
+ const_cast<Node *>(this)->_translation_domain = data.parent ? data.parent->get_translation_domain() : StringName();
+ data.is_translation_domain_dirty = false;
+ }
+ return _translation_domain;
+}
+
+void Node::set_translation_domain(const StringName &p_domain) {
+ ERR_THREAD_GUARD
+
+ if (!data.is_translation_domain_inherited && _translation_domain == p_domain) {
+ return;
+ }
+
+ _translation_domain = p_domain;
+ data.is_translation_domain_inherited = false;
+ data.is_translation_domain_dirty = false;
+ _propagate_translation_domain_dirty();
+}
+
+void Node::set_translation_domain_inherited() {
+ ERR_THREAD_GUARD
+
+ if (data.is_translation_domain_inherited) {
+ return;
+ }
+ data.is_translation_domain_inherited = true;
+ data.is_translation_domain_dirty = true;
+ _propagate_translation_domain_dirty();
+}
+
+void Node::_propagate_translation_domain_dirty() {
+ for (KeyValue<StringName, Node *> &K : data.children) {
+ Node *child = K.value;
+ if (child->data.is_translation_domain_inherited) {
+ child->data.is_translation_domain_dirty = true;
+ child->_propagate_translation_domain_dirty();
+ }
+ }
+ notification(NOTIFICATION_TRANSLATION_CHANGED);
+}
+
StringName Node::get_name() const {
return data.name;
}
@@ -3610,6 +3656,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_auto_translate_mode", "mode"), &Node::set_auto_translate_mode);
ClassDB::bind_method(D_METHOD("get_auto_translate_mode"), &Node::get_auto_translate_mode);
+ ClassDB::bind_method(D_METHOD("set_translation_domain_inherited"), &Node::set_translation_domain_inherited);
ClassDB::bind_method(D_METHOD("get_window"), &Node::get_window);
ClassDB::bind_method(D_METHOD("get_last_exclusive_window"), &Node::get_last_exclusive_window);
diff --git a/scene/main/node.h b/scene/main/node.h
index dc65513fca..4560ed085c 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -255,6 +255,9 @@ private:
mutable bool is_auto_translating = true;
mutable bool is_auto_translate_dirty = true;
+ mutable bool is_translation_domain_inherited = true;
+ mutable bool is_translation_domain_dirty = true;
+
mutable NodePath *path_cache = nullptr;
} data;
@@ -281,6 +284,7 @@ private:
void _propagate_physics_interpolation_reset_requested(bool p_requested);
void _propagate_process_owner(Node *p_owner, int p_pause_notification, int p_enabled_notification);
void _propagate_groups_dirty();
+ void _propagate_translation_domain_dirty();
Array _get_node_and_resource(const NodePath &p_path);
void _duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const;
@@ -735,6 +739,10 @@ public:
AutoTranslateMode get_auto_translate_mode() const;
bool can_auto_translate() const;
+ virtual StringName get_translation_domain() const override;
+ virtual void set_translation_domain(const StringName &p_domain) override;
+ void set_translation_domain_inherited();
+
_FORCE_INLINE_ String atr(const String p_message, const StringName p_context = "") const { return can_auto_translate() ? tr(p_message, p_context) : p_message; }
_FORCE_INLINE_ String atr_n(const String p_message, const StringName &p_message_plural, int p_n, const StringName p_context = "") const { return can_auto_translate() ? tr_n(p_message, p_message_plural, p_n, p_context) : p_message; }
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index acf4f67673..ba69f8cc45 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -4671,6 +4671,7 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d);
ClassDB::bind_method(D_METHOD("is_audio_listener_2d"), &Viewport::is_audio_listener_2d);
+ ClassDB::bind_method(D_METHOD("get_audio_listener_2d"), &Viewport::get_audio_listener_2d);
ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d);
#ifndef _3D_DISABLED
@@ -4681,6 +4682,7 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d);
ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d);
+ ClassDB::bind_method(D_METHOD("get_audio_listener_3d"), &Viewport::get_audio_listener_3d);
ClassDB::bind_method(D_METHOD("get_camera_3d"), &Viewport::get_camera_3d);
ClassDB::bind_method(D_METHOD("set_as_audio_listener_3d", "enable"), &Viewport::set_as_audio_listener_3d);
ClassDB::bind_method(D_METHOD("is_audio_listener_3d"), &Viewport::is_audio_listener_3d);
diff --git a/scene/resources/2d/tile_set.h b/scene/resources/2d/tile_set.h
index 931495d020..15e1a16359 100644
--- a/scene/resources/2d/tile_set.h
+++ b/scene/resources/2d/tile_set.h
@@ -571,25 +571,25 @@ public:
// Not exposed.
virtual void set_tile_set(const TileSet *p_tile_set);
TileSet *get_tile_set() const;
- virtual void notify_tile_data_properties_should_change(){};
- virtual void add_occlusion_layer(int p_index){};
- virtual void move_occlusion_layer(int p_from_index, int p_to_pos){};
- virtual void remove_occlusion_layer(int p_index){};
- virtual void add_physics_layer(int p_index){};
- virtual void move_physics_layer(int p_from_index, int p_to_pos){};
- virtual void remove_physics_layer(int p_index){};
- virtual void add_terrain_set(int p_index){};
- virtual void move_terrain_set(int p_from_index, int p_to_pos){};
- virtual void remove_terrain_set(int p_index){};
- virtual void add_terrain(int p_terrain_set, int p_index){};
- virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos){};
- virtual void remove_terrain(int p_terrain_set, int p_index){};
- virtual void add_navigation_layer(int p_index){};
- virtual void move_navigation_layer(int p_from_index, int p_to_pos){};
- virtual void remove_navigation_layer(int p_index){};
- virtual void add_custom_data_layer(int p_index){};
- virtual void move_custom_data_layer(int p_from_index, int p_to_pos){};
- virtual void remove_custom_data_layer(int p_index){};
+ virtual void notify_tile_data_properties_should_change() {}
+ virtual void add_occlusion_layer(int p_index) {}
+ virtual void move_occlusion_layer(int p_from_index, int p_to_pos) {}
+ virtual void remove_occlusion_layer(int p_index) {}
+ virtual void add_physics_layer(int p_index) {}
+ virtual void move_physics_layer(int p_from_index, int p_to_pos) {}
+ virtual void remove_physics_layer(int p_index) {}
+ virtual void add_terrain_set(int p_index) {}
+ virtual void move_terrain_set(int p_from_index, int p_to_pos) {}
+ virtual void remove_terrain_set(int p_index) {}
+ virtual void add_terrain(int p_terrain_set, int p_index) {}
+ virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {}
+ virtual void remove_terrain(int p_terrain_set, int p_index) {}
+ virtual void add_navigation_layer(int p_index) {}
+ virtual void move_navigation_layer(int p_from_index, int p_to_pos) {}
+ virtual void remove_navigation_layer(int p_index) {}
+ virtual void add_custom_data_layer(int p_index) {}
+ virtual void move_custom_data_layer(int p_from_index, int p_to_pos) {}
+ virtual void remove_custom_data_layer(int p_index) {}
virtual void reset_state() override;
// Tiles.
diff --git a/scene/resources/3d/primitive_meshes.h b/scene/resources/3d/primitive_meshes.h
index fc2489923a..85f46a482a 100644
--- a/scene/resources/3d/primitive_meshes.h
+++ b/scene/resources/3d/primitive_meshes.h
@@ -77,7 +77,7 @@ protected:
Vector2 get_uv2_scale(Vector2 p_margin_scale = Vector2(1.0, 1.0)) const;
float get_lightmap_texel_size() const;
- virtual void _update_lightmap_size(){};
+ virtual void _update_lightmap_size() {}
void _on_settings_changed();
@@ -541,7 +541,7 @@ private:
Vector2 point;
bool sharp = false;
- ContourPoint(){};
+ ContourPoint() {}
ContourPoint(const Vector2 &p_pt, bool p_sharp) {
point = p_pt;
sharp = p_sharp;
@@ -551,7 +551,7 @@ private:
struct ContourInfo {
real_t length = 0.0;
bool ccw = true;
- ContourInfo(){};
+ ContourInfo() {}
ContourInfo(real_t p_len, bool p_ccw) {
length = p_len;
ccw = p_ccw;
diff --git a/scene/resources/camera_attributes.h b/scene/resources/camera_attributes.h
index 0f819134e2..de57b0ce8f 100644
--- a/scene/resources/camera_attributes.h
+++ b/scene/resources/camera_attributes.h
@@ -53,7 +53,7 @@ protected:
float auto_exposure_max = 64.0;
float auto_exposure_speed = 0.5;
float auto_exposure_scale = 0.4;
- virtual void _update_auto_exposure(){};
+ virtual void _update_auto_exposure() {}
public:
virtual RID get_rid() const override;
diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h
index 4a956cd25d..e4c58474e2 100644
--- a/servers/rendering/dummy/storage/material_storage.h
+++ b/servers/rendering/dummy/storage/material_storage.h
@@ -97,7 +97,7 @@ public:
/* MATERIAL API */
virtual RID material_allocate() override { return RID(); }
virtual void material_initialize(RID p_rid) override {}
- virtual void material_free(RID p_rid) override{};
+ virtual void material_free(RID p_rid) override {}
virtual void material_set_render_priority(RID p_material, int priority) override {}
virtual void material_set_shader(RID p_shader_material, RID p_shader) override {}
diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h
index 43572b65e0..1a566b518d 100644
--- a/servers/rendering/dummy/storage/texture_storage.h
+++ b/servers/rendering/dummy/storage/texture_storage.h
@@ -56,14 +56,14 @@ public:
/* Canvas Texture API */
virtual RID canvas_texture_allocate() override { return RID(); };
- virtual void canvas_texture_initialize(RID p_rid) override{};
- virtual void canvas_texture_free(RID p_rid) override{};
+ virtual void canvas_texture_initialize(RID p_rid) override {}
+ virtual void canvas_texture_free(RID p_rid) override {}
- virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override{};
- virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override{};
+ virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override {}
+ virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override {}
- virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override{};
- virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override{};
+ virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override {}
+ virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override {}
/* Texture API */
@@ -88,18 +88,20 @@ public:
ERR_FAIL_NULL(t);
t->image = p_image->duplicate();
};
- virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override{};
- virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override{};
- virtual void texture_proxy_initialize(RID p_texture, RID p_base) override{}; //all slices, then all the mipmaps, must be coherent
+ virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override {}
+ virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override {}
+ virtual void texture_proxy_initialize(RID p_texture, RID p_base) override {} //all slices, then all the mipmaps, must be coherent
- virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override{};
- virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override{};
- virtual void texture_proxy_update(RID p_proxy, RID p_base) override{};
+ virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) override { return RID(); }
+
+ virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {}
+ virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override {}
+ virtual void texture_proxy_update(RID p_proxy, RID p_base) override {}
//these two APIs can be used together or in combination with the others.
- virtual void texture_2d_placeholder_initialize(RID p_texture) override{};
- virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) override{};
- virtual void texture_3d_placeholder_initialize(RID p_texture) override{};
+ virtual void texture_2d_placeholder_initialize(RID p_texture) override {}
+ virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) override {}
+ virtual void texture_3d_placeholder_initialize(RID p_texture) override {}
virtual Ref<Image> texture_2d_get(RID p_texture) const override {
DummyTexture *t = texture_owner.get_or_null(p_texture);
@@ -110,31 +112,31 @@ public:
virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const override { return Vector<Ref<Image>>(); };
virtual void texture_replace(RID p_texture, RID p_by_texture) override { texture_free(p_by_texture); };
- virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) override{};
+ virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) override {}
- virtual void texture_set_path(RID p_texture, const String &p_path) override{};
+ virtual void texture_set_path(RID p_texture, const String &p_path) override {}
virtual String texture_get_path(RID p_texture) const override { return String(); };
virtual Image::Format texture_get_format(RID p_texture) const override { return Image::FORMAT_MAX; }
- virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override{};
- virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override{};
- virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) override{};
+ virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override {}
+ virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override {}
+ virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) override {}
- virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) override{};
+ virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) override {}
- virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override{};
+ virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override {}
virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); };
- virtual void texture_rd_initialize(RID p_texture, const RID &p_rd_texture, const RS::TextureLayeredType p_layer_type = RS::TEXTURE_LAYERED_2D_ARRAY) override{};
+ virtual void texture_rd_initialize(RID p_texture, const RID &p_rd_texture, const RS::TextureLayeredType p_layer_type = RS::TEXTURE_LAYERED_2D_ARRAY) override {}
virtual RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) const override { return RID(); };
virtual uint64_t texture_get_native_handle(RID p_texture, bool p_srgb = false) const override { return 0; };
/* DECAL API */
virtual RID decal_allocate() override { return RID(); }
virtual void decal_initialize(RID p_rid) override {}
- virtual void decal_free(RID p_rid) override{};
+ virtual void decal_free(RID p_rid) override {}
virtual void decal_set_size(RID p_decal, const Vector3 &p_size) override {}
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h
index 25fb190f44..75b9c563f7 100644
--- a/servers/rendering/renderer_rd/environment/fog.h
+++ b/servers/rendering/renderer_rd/environment/fog.h
@@ -316,8 +316,8 @@ public:
int last_shadow_filter = -1;
- virtual void configure(RenderSceneBuffersRD *p_render_buffers) override{};
- virtual void free_data() override{};
+ virtual void configure(RenderSceneBuffersRD *p_render_buffers) override {}
+ virtual void free_data() override {}
bool sync_gi_dependent_sets_validity(bool p_ensure_freed = false);
diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h
index 6169d386b5..f6f9ab4f75 100644
--- a/servers/rendering/renderer_rd/environment/gi.h
+++ b/servers/rendering/renderer_rd/environment/gi.h
@@ -461,7 +461,7 @@ public:
RID get_voxel_gi_buffer();
- virtual void configure(RenderSceneBuffersRD *p_render_buffers) override{};
+ virtual void configure(RenderSceneBuffersRD *p_render_buffers) override {}
virtual void free_data() override;
};
@@ -675,7 +675,7 @@ public:
int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically
RID integrate_sky_uniform_set;
- virtual void configure(RenderSceneBuffersRD *p_render_buffers) override{};
+ virtual void configure(RenderSceneBuffersRD *p_render_buffers) override {}
virtual void free_data() override;
~SDFGI();
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index fc60c770e8..9e429d598a 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -366,12 +366,12 @@ protected:
virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
- virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override{};
- virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override{};
- virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override{};
+ virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {}
+ virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {}
+ virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {}
- virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override{};
- virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override{};
+ virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override {}
+ virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override {}
/* Geometry instance */
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 738bcd4832..57497eb207 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -2479,6 +2479,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
r_current_batch = _new_batch(r_batch_broken);
r_current_batch->command_type = Item::Command::TYPE_NINEPATCH;
r_current_batch->command = c;
+ r_current_batch->has_blend = false;
r_current_batch->pipeline_variant = PipelineVariant::PIPELINE_VARIANT_NINEPATCH;
}
@@ -2548,6 +2549,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
r_current_batch = _new_batch(r_batch_broken);
r_current_batch->command_type = Item::Command::TYPE_POLYGON;
+ r_current_batch->has_blend = false;
r_current_batch->command = c;
TextureState tex_state(polygon->texture, texture_filter, texture_repeat, false, use_linear_colors);
@@ -2585,6 +2587,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
if (primitive->point_count != r_current_batch->primitive_points || r_current_batch->command_type != Item::Command::TYPE_PRIMITIVE) {
r_current_batch = _new_batch(r_batch_broken);
r_current_batch->command_type = Item::Command::TYPE_PRIMITIVE;
+ r_current_batch->has_blend = false;
r_current_batch->command = c;
r_current_batch->primitive_points = primitive->point_count;
@@ -2646,6 +2649,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
r_current_batch = _new_batch(r_batch_broken);
r_current_batch->command = c;
r_current_batch->command_type = c->type;
+ r_current_batch->has_blend = false;
InstanceData *instance_data = nullptr;
@@ -2799,6 +2803,7 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV
RID pipeline = p_pipeline_variants->variants[p_batch->light_mode][p_batch->pipeline_variant].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
if (p_batch->has_blend) {
+ DEV_ASSERT(p_batch->pipeline_variant == PIPELINE_VARIANT_QUAD_LCD_BLEND);
RD::get_singleton()->draw_list_set_blend_constants(p_draw_list, p_batch->modulate);
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 022a4560f8..b82d50378e 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -165,9 +165,9 @@ public:
/* LIGHTING */
- virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_size){};
- virtual void setup_added_light(const RS::LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture){};
- virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_size){};
+ virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_size) {}
+ virtual void setup_added_light(const RS::LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) {}
+ virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_size) {}
/* GI */
diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h
index 22a21086af..688092d604 100644
--- a/servers/rendering/renderer_rd/shader_rd.h
+++ b/servers/rendering/renderer_rd/shader_rd.h
@@ -46,7 +46,7 @@ public:
int group = 0;
CharString text;
bool default_enabled = true;
- VariantDefine(){};
+ VariantDefine() {}
VariantDefine(int p_group, const String &p_text, bool p_default_enabled) {
group = p_group;
default_enabled = p_default_enabled;
diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index 2154d56faf..5e19c24246 100644
--- a/servers/rendering/renderer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -41,11 +41,11 @@ layout(location = 3) out vec2 pixel_size_interp;
#endif
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = 1, binding = 0, std140) uniform MaterialUniforms{
-
+/* clang-format off */
+layout(set = 1, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
-
} material;
+/* clang-format on */
#endif
#GLOBALS
@@ -258,11 +258,11 @@ layout(location = 3) in vec2 pixel_size_interp;
layout(location = 0) out vec4 frag_color;
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = 1, binding = 0, std140) uniform MaterialUniforms{
-
+/* clang-format off */
+layout(set = 1, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
-
} material;
+/* clang-format on */
#endif
vec2 screen_uv_to_sdf(vec2 p_uv) {
diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl
index 5aa3735494..cc1c40cad1 100644
--- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl
@@ -106,9 +106,11 @@ layout(set = 0, binding = 3, std140) uniform DirectionalLights {
directional_lights;
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = 1, binding = 0, std140) uniform MaterialUniforms{
+/* clang-format off */
+layout(set = 1, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
} material;
+/* clang-format on */
#endif
layout(set = 2, binding = 0) uniform textureCube radiance;
@@ -247,9 +249,7 @@ void main() {
#endif //USE_CUBEMAP_PASS
{
-
#CODE : SKY
-
}
frag_color.rgb = color;
diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl
index 2360375c23..929f1e34df 100644
--- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl
@@ -77,9 +77,11 @@ layout(r32ui, set = 1, binding = 4) uniform volatile uimage3D light_only_map;
#endif
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = 2, binding = 0, std140) uniform MaterialUniforms{
+/* clang-format off */
+layout(set = 2, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
} material;
+/* clang-format on */
#endif
#GLOBALS
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
index cfde97af95..a441b1667d 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
@@ -116,9 +116,11 @@ layout(location = 8) out vec4 prev_screen_position;
#endif
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{
+/* clang-format off */
+layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
} material;
+/* clang-format on */
#endif
float global_time;
@@ -808,11 +810,11 @@ ivec2 multiview_uv(ivec2 uv) {
#endif
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{
-
+/* clang-format off */
+layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
-
} material;
+/* clang-format on */
#endif
#GLOBALS
diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
index b21769f207..92a8e2be32 100644
--- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
@@ -107,11 +107,11 @@ layout(location = 6) mediump out vec3 binormal_interp;
#endif
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{
-
+/* clang-format off */
+layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
-
} material;
+/* clang-format on */
#endif
#ifdef MODE_DUAL_PARABOLOID
@@ -671,11 +671,11 @@ ivec2 multiview_uv(ivec2 uv) {
#endif
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{
-
+/* clang-format off */
+layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
-
} material;
+/* clang-format on */
#endif
#GLOBALS
diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl
index 7c5291038f..a8f27ba726 100644
--- a/servers/rendering/renderer_rd/shaders/particles.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles.glsl
@@ -168,11 +168,11 @@ layout(set = 2, binding = 1) uniform texture2D height_field_texture;
/* SET 3: MATERIAL */
#ifdef MATERIAL_UNIFORMS_USED
-layout(set = 3, binding = 0, std140) uniform MaterialUniforms{
-
+/* clang-format off */
+layout(set = 3, binding = 0, std140) uniform MaterialUniforms {
#MATERIAL_UNIFORMS
-
} material;
+/* clang-format on */
#endif
layout(push_constant, std430) uniform Params {
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index be29716f45..81ab384edc 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -1108,6 +1108,195 @@ void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
tex->proxies.push_back(p_texture);
}
+// Note: We make some big assumptions about format and usage. If developers need more control,
+// they should use RD::texture_create_from_extension() instead.
+RID TextureStorage::texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {
+ RD::TextureType type;
+ switch (p_type) {
+ case RS::TEXTURE_TYPE_2D:
+ type = RD::TEXTURE_TYPE_2D;
+ break;
+
+ case RS::TEXTURE_TYPE_3D:
+ type = RD::TEXTURE_TYPE_3D;
+ break;
+
+ case RS::TEXTURE_TYPE_LAYERED:
+ if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {
+ type = RD::TEXTURE_TYPE_2D_ARRAY;
+ } else if (p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP) {
+ type = RD::TEXTURE_TYPE_CUBE;
+ } else if (p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {
+ type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+ } else {
+ // Arbitrary fallback.
+ type = RD::TEXTURE_TYPE_2D_ARRAY;
+ }
+ break;
+
+ default:
+ // Arbitrary fallback.
+ type = RD::TEXTURE_TYPE_2D;
+ }
+
+ // Only a rough conversion - see note above.
+ RD::DataFormat format;
+ switch (p_format) {
+ case Image::FORMAT_L8:
+ case Image::FORMAT_R8:
+ format = RD::DATA_FORMAT_R8_UNORM;
+ break;
+
+ case Image::FORMAT_LA8:
+ case Image::FORMAT_RG8:
+ format = RD::DATA_FORMAT_R8G8_UNORM;
+ break;
+
+ case Image::FORMAT_RGB8:
+ format = RD::DATA_FORMAT_R8G8B8_UNORM;
+ break;
+
+ case Image::FORMAT_RGBA8:
+ format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ break;
+
+ case Image::FORMAT_RGBA4444:
+ format = RD::DATA_FORMAT_B4G4R4A4_UNORM_PACK16;
+ break;
+
+ case Image::FORMAT_RGB565:
+ format = RD::DATA_FORMAT_B5G6R5_UNORM_PACK16;
+ break;
+
+ case Image::FORMAT_RF:
+ format = RD::DATA_FORMAT_R32_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGF:
+ format = RD::DATA_FORMAT_R32G32_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBF:
+ format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBAF:
+ format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
+ break;
+
+ case Image::FORMAT_RH:
+ format = RD::DATA_FORMAT_R16_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGH:
+ format = RD::DATA_FORMAT_R16G16_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBH:
+ format = RD::DATA_FORMAT_R16G16B16_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBAH:
+ format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBE9995:
+ format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
+ break;
+
+ case Image::FORMAT_DXT1:
+ format = RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_DXT3:
+ format = RD::DATA_FORMAT_BC2_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_DXT5:
+ format = RD::DATA_FORMAT_BC3_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_RGTC_R:
+ format = RD::DATA_FORMAT_BC4_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_RGTC_RG:
+ format = RD::DATA_FORMAT_BC5_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_BPTC_RGBA:
+ format = RD::DATA_FORMAT_BC7_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_BPTC_RGBF:
+ format = RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK;
+ break;
+
+ case Image::FORMAT_BPTC_RGBFU:
+ format = RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_R11:
+ format = RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_R11S:
+ format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RG11:
+ format = RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RG11S:
+ format = RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RGB8:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RGBA8:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RGB8A1:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RA_AS_RG:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_DXT5_RA_AS_RG:
+ format = RD::DATA_FORMAT_BC3_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ASTC_4x4:
+ case Image::FORMAT_ASTC_4x4_HDR:
+ format = RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ASTC_8x8:
+ case Image::FORMAT_ASTC_8x8_HDR:
+ format = RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK;
+ break;
+
+ default:
+ // Arbitrary fallback.
+ format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ }
+
+ // Assumed to be a color attachment - see note above.
+ uint64_t usage_flags = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+
+ return RD::get_singleton()->texture_create_from_extension(type, format, RD::TEXTURE_SAMPLES_1, usage_flags, p_native_handle, p_width, p_height, p_depth, p_layers);
+}
+
void TextureStorage::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) {
ERR_FAIL_COND(p_image.is_null() || p_image->is_empty());
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 704f5fb1bd..d352690fff 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -493,6 +493,8 @@ public:
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent
+ virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) override;
+
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override;
virtual void texture_proxy_update(RID p_proxy, RID p_base) override;
diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h
index a848c86bd2..df403c5484 100644
--- a/servers/rendering/renderer_scene_occlusion_cull.h
+++ b/servers/rendering/renderer_scene_occlusion_cull.h
@@ -192,7 +192,7 @@ public:
RID get_debug_texture();
const Size2i &get_occlusion_buffer_size() const { return occlusion_buffer_size; }
- virtual ~HZBuffer(){};
+ virtual ~HZBuffer() {}
};
static RendererSceneOcclusionCull *get_singleton() { return singleton; }
diff --git a/servers/rendering/rendering_device_commons.h b/servers/rendering/rendering_device_commons.h
index 8c3996bd80..d72265958c 100644
--- a/servers/rendering/rendering_device_commons.h
+++ b/servers/rendering/rendering_device_commons.h
@@ -34,7 +34,7 @@
#include "core/object/object.h"
#include "core/variant/type_info.h"
-#define STEPIFY(m_number, m_alignment) ((((m_number) + ((m_alignment)-1)) / (m_alignment)) * (m_alignment))
+#define STEPIFY(m_number, m_alignment) ((((m_number) + ((m_alignment) - 1)) / (m_alignment)) * (m_alignment))
class RenderingDeviceCommons : public Object {
////////////////////////////////////////////
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 60fa546e16..fb4f4aa756 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -179,6 +179,11 @@ public:
FUNCRIDTEX6(texture_3d, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &)
FUNCRIDTEX1(texture_proxy, RID)
+ // Called directly, not through the command queue.
+ virtual RID texture_create_from_native_handle(TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, TextureLayeredType p_layered_type = TEXTURE_LAYERED_2D_ARRAY) override {
+ return RSG::texture_storage->texture_create_from_native_handle(p_type, p_format, p_native_handle, p_width, p_height, p_depth, p_layers, p_layered_type);
+ }
+
//these go through command queue if they are in another thread
FUNC3(texture_2d_update, RID, const Ref<Image> &, int)
FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &)
diff --git a/servers/rendering/storage/material_storage.h b/servers/rendering/storage/material_storage.h
index 03feda8abb..a5935cc90f 100644
--- a/servers/rendering/storage/material_storage.h
+++ b/servers/rendering/storage/material_storage.h
@@ -36,7 +36,7 @@
class RendererMaterialStorage {
public:
- virtual ~RendererMaterialStorage(){};
+ virtual ~RendererMaterialStorage() {}
/* GLOBAL SHADER UNIFORM API */
virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) = 0;
diff --git a/servers/rendering/storage/render_scene_buffers.h b/servers/rendering/storage/render_scene_buffers.h
index 6c82d47799..b860af7640 100644
--- a/servers/rendering/storage/render_scene_buffers.h
+++ b/servers/rendering/storage/render_scene_buffers.h
@@ -91,7 +91,7 @@ public:
void set_use_debanding(bool p_use_debanding) { use_debanding = p_use_debanding; }
RenderSceneBuffersConfiguration() {}
- virtual ~RenderSceneBuffersConfiguration(){};
+ virtual ~RenderSceneBuffersConfiguration() {}
};
class RenderSceneBuffers : public RefCounted {
@@ -101,8 +101,8 @@ protected:
static void _bind_methods();
public:
- RenderSceneBuffers(){};
- virtual ~RenderSceneBuffers(){};
+ RenderSceneBuffers() {}
+ virtual ~RenderSceneBuffers() {}
virtual void configure(const RenderSceneBuffersConfiguration *p_config) = 0;
@@ -124,7 +124,7 @@ protected:
GDVIRTUAL1(_set_use_debanding, bool)
public:
- virtual ~RenderSceneBuffersExtension(){};
+ virtual ~RenderSceneBuffersExtension() {}
virtual void configure(const RenderSceneBuffersConfiguration *p_config) override;
diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h
index 72c4dd305b..6e1cb9eb7f 100644
--- a/servers/rendering/storage/texture_storage.h
+++ b/servers/rendering/storage/texture_storage.h
@@ -61,7 +61,7 @@ public:
/* Texture API */
virtual bool can_create_resources_async() const = 0;
- virtual ~RendererTextureStorage(){};
+ virtual ~RendererTextureStorage() {}
virtual RID texture_allocate() = 0;
virtual void texture_free(RID p_rid) = 0;
@@ -71,6 +71,8 @@ public:
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) = 0; //all slices, then all the mipmaps, must be coherent
+ virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) = 0;
+
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 020fa94e9d..a1c05fa2e7 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2239,6 +2239,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_2d_layered_create", "layers", "layered_type"), &RenderingServer::_texture_2d_layered_create);
ClassDB::bind_method(D_METHOD("texture_3d_create", "format", "width", "height", "depth", "mipmaps", "data"), &RenderingServer::_texture_3d_create);
ClassDB::bind_method(D_METHOD("texture_proxy_create", "base"), &RenderingServer::texture_proxy_create);
+ ClassDB::bind_method(D_METHOD("texture_create_from_native_handle", "type", "format", "native_handle", "width", "height", "depth", "layers", "layered_type"), &RenderingServer::texture_create_from_native_handle, DEFVAL(1), DEFVAL(TEXTURE_LAYERED_2D_ARRAY));
ClassDB::bind_method(D_METHOD("texture_2d_update", "texture", "image", "layer"), &RenderingServer::texture_2d_update);
ClassDB::bind_method(D_METHOD("texture_3d_update", "texture", "data"), &RenderingServer::_texture_3d_update);
@@ -2265,6 +2266,10 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_get_rd_texture", "texture", "srgb"), &RenderingServer::texture_get_rd_texture, DEFVAL(false));
ClassDB::bind_method(D_METHOD("texture_get_native_handle", "texture", "srgb"), &RenderingServer::texture_get_native_handle, DEFVAL(false));
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_LAYERED);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D);
+
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY);
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP);
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP_ARRAY);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 62ca6b3b6d..2b45b73f09 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -113,6 +113,12 @@ public:
/* TEXTURE API */
+ enum TextureType {
+ TEXTURE_TYPE_2D,
+ TEXTURE_TYPE_LAYERED,
+ TEXTURE_TYPE_3D,
+ };
+
enum TextureLayeredType {
TEXTURE_LAYERED_2D_ARRAY,
TEXTURE_LAYERED_CUBEMAP,
@@ -133,6 +139,8 @@ public:
virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; //all slices, then all the mipmaps, must be coherent
virtual RID texture_proxy_create(RID p_base) = 0;
+ virtual RID texture_create_from_native_handle(TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, TextureLayeredType p_layered_type = TEXTURE_LAYERED_2D_ARRAY) = 0;
+
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to) = 0;
@@ -1793,6 +1801,7 @@ private:
};
// Make variant understand the enums.
+VARIANT_ENUM_CAST(RenderingServer::TextureType);
VARIANT_ENUM_CAST(RenderingServer::TextureLayeredType);
VARIANT_ENUM_CAST(RenderingServer::CubeMapLayer);
VARIANT_ENUM_CAST(RenderingServer::ShaderMode);
diff --git a/servers/xr/xr_controller_tracker.cpp b/servers/xr/xr_controller_tracker.cpp
index df85e86b7e..2d6cf44ce8 100644
--- a/servers/xr/xr_controller_tracker.cpp
+++ b/servers/xr/xr_controller_tracker.cpp
@@ -32,7 +32,7 @@
#include "core/input/input.h"
-void XRControllerTracker::_bind_methods(){};
+void XRControllerTracker::_bind_methods() {}
XRControllerTracker::XRControllerTracker() {
type = XRServer::TRACKER_CONTROLLER;
diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h
index 6b6a67a04c..55495731c5 100644
--- a/servers/xr/xr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -137,10 +137,10 @@ public:
virtual RID get_color_texture(); /* obtain color output texture (if applicable) */
virtual RID get_depth_texture(); /* obtain depth output texture (if applicable, used for reprojection) */
virtual RID get_velocity_texture(); /* obtain velocity output texture (if applicable, used for spacewarp) */
- virtual void pre_render(){};
+ virtual void pre_render() {}
virtual bool pre_draw_viewport(RID p_render_target) { return true; }; /* inform XR interface we are about to start our viewport draw process */
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) = 0; /* inform XR interface we finished our viewport draw process */
- virtual void end_frame(){};
+ virtual void end_frame() {}
/** passthrough **/
diff --git a/tests/core/variant/test_array.h b/tests/core/variant/test_array.h
index 787b8f39d9..15e2cebe09 100644
--- a/tests/core/variant/test_array.h
+++ b/tests/core/variant/test_array.h
@@ -634,6 +634,24 @@ TEST_CASE("[Array] Typed copying") {
a6.clear();
}
+static bool _find_custom_callable(const Variant &p_val) {
+ return (int)p_val % 2 == 0;
+}
+
+TEST_CASE("[Array] Test find_custom") {
+ Array a1 = build_array(1, 3, 4, 5, 8, 9);
+ // Find first even number.
+ int index = a1.find_custom(callable_mp_static(_find_custom_callable));
+ CHECK_EQ(index, 2);
+}
+
+TEST_CASE("[Array] Test rfind_custom") {
+ Array a1 = build_array(1, 3, 4, 5, 8, 9);
+ // Find last even number.
+ int index = a1.rfind_custom(callable_mp_static(_find_custom_callable));
+ CHECK_EQ(index, 4);
+}
+
} // namespace TestArray
#endif // TEST_ARRAY_H