Compare commits

...

108 Commits

Author SHA1 Message Date
Allen Pestaluky
ba513dc5c8 Exposed EditorExport through the EditorInterface singleton.
Also exposed functions relating to feature tags of platforms and presets.
2024-10-22 13:41:53 -04:00
Thaddeus Crews
b3bcb2dc14
Merge pull request #98299 from timothyqiu/tree-coordinate
Some checks are pending
🔗 GHA / 📊 Static checks (push) Waiting to run
🔗 GHA / 🤖 Android (push) Blocked by required conditions
🔗 GHA / 🍏 iOS (push) Blocked by required conditions
🔗 GHA / 🐧 Linux (push) Blocked by required conditions
🔗 GHA / 🍎 macOS (push) Blocked by required conditions
🔗 GHA / 🏁 Windows (push) Blocked by required conditions
🔗 GHA / 🌐 Web (push) Blocked by required conditions
🔗 GHA / 🪲 Godot CPP (push) Blocked by required conditions
Fix button click detection when `Tree` is rotated
2024-10-21 16:39:31 -05:00
Thaddeus Crews
a4ed24acef
Merge pull request #98041 from Hilderin/fix-lost-gdextensions-on-startup
Fix loss of gdextension on editor startup
2024-10-21 16:39:30 -05:00
Thaddeus Crews
7815ccbdd5
Merge pull request #98294 from Calinou/texture-placeholders-use-shared-copy
Use a shared copy of placeholder textures, tweak placeholder appearance
2024-10-21 16:39:29 -05:00
Thaddeus Crews
66d19abdfa
Merge pull request #96629 from ditiem-games/path2d
Fix Animated Path2D doesn't update PathFollow2D progress when scene is running.
2024-10-21 16:39:28 -05:00
Thaddeus Crews
22822f71ac
Merge pull request #97905 from 0x53A/patch-1
Update Node.xml: specify that normal processing happens in tree order
2024-10-21 16:39:27 -05:00
Thaddeus Crews
6ec3dc1fb5
Merge pull request #97649 from ohboh/literally-unusable-on-mobile-without-this
Fix `emulate_mouse_from_touch` setting affecting editor
2024-10-21 16:39:26 -05:00
Thaddeus Crews
7dbea98c49
Merge pull request #97005 from Repiteo/core/window-corner-style
Core: Add `DisplayServer` flag for sharp corners
2024-10-21 16:39:25 -05:00
Thaddeus Crews
8b5c20e2b0
Merge pull request #98283 from tetrapod00/canvasmodulate-link
Docs: Add link to 2D lights and shadows from CanvasModulate
2024-10-21 16:39:24 -05:00
Thaddeus Crews
55aeff19dc
Merge pull request #98146 from HolonProduction/this-error-does-not-apply-to-unrecognized-annotations
GDScript: Fix annotation parsing adding new annotation entries
2024-10-21 16:39:24 -05:00
Thaddeus Crews
1a9628f937
Merge pull request #98267 from Chaosus/shader_pp_error
Add `#error` preprocessor directive to shading language
2024-10-21 16:39:23 -05:00
Thaddeus Crews
677ebad7fc
Merge pull request #97626 from Repiteo/scons/c17
SCons: Bump C standard: `C11`→`C17`
2024-10-21 16:39:22 -05:00
Thaddeus Crews
a14e9e99e5
Merge pull request #98388 from DarioSamo/sync-fixes
Improve synchronization of rendering after changes from transfer queues.
2024-10-21 16:39:21 -05:00
Thaddeus Crews
178342b058
Merge pull request #98258 from LainAmongYou/fix-bgra
Add support for BGRA textures with Texture*RD
2024-10-21 16:39:20 -05:00
Thaddeus Crews
77da16ce69
Merge pull request #88530 from davthedev/tree-hover-items
Add hover state to Tree items display
2024-10-21 16:39:16 -05:00
Thaddeus Crews
291e4b78e2
Merge pull request #98237 from dustdfg/os_transitive_image_headers_refactor
Don't include `core/io/image.h` in `core/os/os.h`
2024-10-21 16:39:15 -05:00
Thaddeus Crews
b6547b0d06
Merge pull request #98236 from timothyqiu/locale-compare-cache-4.x
Cache results for `TranslationServer.compare_locales()`
2024-10-21 16:39:14 -05:00
Thaddeus Crews
7a438dc72e
Merge pull request #97205 from tetrapod00/inspect-native-shader-code
Add "Inspect Native Shader Code" to shader inspector and shader editor
2024-10-21 16:39:13 -05:00
Thaddeus Crews
cb3c01a5fe
Merge pull request #97588 from TML233/generated-raise-signal
[C#] Change generated On{SignalName} to EmitSignal{SignalName}
2024-10-21 16:39:12 -05:00
Thaddeus Crews
c145e85011
Merge pull request #98226 from m-pranav-r/fix-volumetric-shadows
Fix incorrect depth comparison used to calculate volumetric fog shadowing
2024-10-21 16:39:11 -05:00
Thaddeus Crews
ecc2eb73fc
Merge pull request #97707 from Sauermann/fix-input-device-clash
Fix `InputEvent` device id clash
2024-10-21 16:39:10 -05:00
Thaddeus Crews
975f42227f
Merge pull request #97706 from lalitshankarchowdhury/fix-create-folder
Display proper message on invalid folder path
2024-10-21 16:39:10 -05:00
Thaddeus Crews
4630cbc487
Merge pull request #98212 from stuartcarnie/sgc/metal_improvements
Metal: Performance improvements and bug fixes
2024-10-21 16:39:09 -05:00
Thaddeus Crews
8be0061458
Merge pull request #98340 from juanjp600/dotnet-typed-dictionary-hint-fix
Fix exported typed dictionaries in .NET having an incorrect hint
2024-10-21 16:39:08 -05:00
Thaddeus Crews
4ce5235fbd
Merge pull request #98203 from timothyqiu/layout-dir-created-equal
Add System Locale layout direction for `Control` and `Window`
2024-10-21 16:39:07 -05:00
Thaddeus Crews
16d68c6be4
Merge pull request #98201 from AThousandShips/lightmap_compile_fix
Fix unreachable code in `lightmap_gi.cpp`
2024-10-21 16:39:06 -05:00
Thaddeus Crews
29fa4b18f1
Merge pull request #97807 from syntaxerror247/colorPicker_kb_fix
Fix `ColorPicker` virtual keyboard popup on mobile
2024-10-21 16:39:06 -05:00
Thaddeus Crews
5fb22327ee
Merge pull request #97542 from AThousandShips/dict_sort_fix
[Core] Fix sorting of `Dictionary` keys
2024-10-21 16:39:05 -05:00
Thaddeus Crews
5e65747d90
Merge pull request #97925 from huwpascoe/lightmap_dynamic_bugfix
Fix updating dynamic objects in LightmapGI
2024-10-21 16:39:04 -05:00
Dario
4ad424234f Improve synchronization of rendering commands after changes from transfer queues.
Fix an error where barriers are expected to be inserted for the swap chain textures.
Add the relevant synchronization stages and accesses to resources between frames.
Fix an error where debug labels weren't finished correctly between frames.
Breadcrumbs are now behind an optional macro as they currently lead to synchronization errors which are harmless.
2024-10-21 11:27:56 -03:00
Hilderin
fbd1643176 Fix lost of gdextension on editor startup.
Co-authored-by: NetroScript <noreply@enostrion.com>"
2024-10-20 18:39:31 -04:00
Markus Sauermann
916d480686 Fix InputEvent device id clash
`InputMap::ALL_DEVICES` and `InputEvent::DEVICE_ID_EMULATION` have the
same value `-1`.

Change value of `InputMap::All_DEVICES` so that it's different from
`InputEvent::DEVICE_ID_EMULATION`. `InputEvent::DEVICE_ID_EMULATION`
is part of the API and can't be changed without potentially breaking
projects.

Gather all special device constants in a single location inside
`InputEvent`.

Add a converter to project settings, that takes care of adjusting
project files during loading.
2024-10-20 21:56:41 +02:00
Lukas Rieger
5c65f80199 Update Node.xml: specify that normal processing happens in tree order 2024-10-20 18:41:54 +02:00
Stuart Carnie
83ac274e25
Metal: Performance improvements and bug fixes 2024-10-20 11:15:13 +11:00
Clay John
44fa552343
Merge pull request #83863 from Calinou/editor-lightmap-probe-gizmo-improve-display
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
🔗 GHA / 🪲 Godot CPP (push) Has been cancelled
Improve display for lightmap probes in the editor
2024-10-18 16:57:45 -07:00
Clay John
80f0b33313
Merge pull request #97977 from syntaxerror247/menu_bar_refresh_bug
Refresh `MenuBar` scene after child renamed in editor
2024-10-18 13:54:27 -07:00
Hugo Locurcio
8e0c0d7837 Improve display for lightmap probes in the editor
- Use the default Back cull mode to improve performance slightly
  and prevent obstructing the camera.
- Fade probes when the camera gets close as to be less intrusive.
2024-10-18 22:52:50 +02:00
Clay John
58a7f9b4d8
Merge pull request #98271 from DarioSamo/d3d12-enhanced-barrier-fix
Some checks are pending
🔗 GHA / 📊 Static checks (push) Waiting to run
🔗 GHA / 🤖 Android (push) Blocked by required conditions
🔗 GHA / 🍏 iOS (push) Blocked by required conditions
🔗 GHA / 🐧 Linux (push) Blocked by required conditions
🔗 GHA / 🍎 macOS (push) Blocked by required conditions
🔗 GHA / 🏁 Windows (push) Blocked by required conditions
🔗 GHA / 🌐 Web (push) Blocked by required conditions
🔗 GHA / 🪲 Godot CPP (push) Blocked by required conditions
Move transitions of textures from transfer workers to the graphics queue.
2024-10-18 12:03:50 -07:00
Thaddeus Crews
f8c4a683d7
Core: Add DisplayServer flag for sharp corners 2024-10-18 11:20:21 -05:00
Yevhen Babiichuk (DustDFG)
af6d260c17 Don't include core/io/image.h in core/os/os.h
`core/os/os.h` doesn't use `core/io/image.h`. It just brings
transitive dependencies. Lots of dependencies because `core/os/os.h`
is transitively included in almost every file of godot

Also added `core/io/image.h` into files^1 where `Ref<Image>` and `core/os/os.h`
were used to prevent obscure errors involving `Ref<Image>`

^1 except those which include `core/io/image_loader.h` or `core/io/image.h` by
corresponding .h file with the same name

Signed-off-by: Yevhen Babiichuk (DustDFG) <dfgdust@gmail.com>
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
2024-10-18 19:04:19 +03:00
Haoyu Qiu
17642692c5 Fix button click detection when Tree is rotated 2024-10-18 22:43:48 +08:00
Hugo Locurcio
35a20fa96a Use a shared copy of placeholder textures, tweak placeholder appearance
This reduces memory usage a bit in case multiple placeholders were
requested, e.g. when using multiple NoiseTextures with no noise property
defined.

The placeholder texture's appearance was also changed from a plain magenta
color to a checkerboard alternating between magenta and black pixels.
This makes it easier to spot when the placeholder texture ends up
being used in a complex scene (usually by accident).
The texture's dimensions remain identical to keep the physical size
identical in 2D.
2024-10-18 14:51:51 +02:00
Dario
8c3e46b13b Move transitions of textures initialized by transfer workers to the main graphics queue.
Also adds a new possible texture layout and API trait to support a particular behavior in D3D12 where only the COMMON layout is supported in copy queues. Fixes #98158.
2024-10-18 09:15:25 -03:00
Chaosus
155cf6a5b6 Add #error preprocessor directive to shading language 2024-10-18 10:56:58 +03:00
A Thousand Ships
610635e1c8
Add test 2024-10-18 08:47:29 +02:00
A Thousand Ships
79f654ced5
[Core] Fix sorting of Dictionary keys
`StringName` keys were sorted as `StringName` which is unstable.
2024-10-18 08:47:05 +02:00
Clay John
4631a617e5
Merge pull request #98255 from timothyqiu/form-is-indeed-emptiness
Some checks are pending
🔗 GHA / 📊 Static checks (push) Waiting to run
🔗 GHA / 🤖 Android (push) Blocked by required conditions
🔗 GHA / 🍏 iOS (push) Blocked by required conditions
🔗 GHA / 🐧 Linux (push) Blocked by required conditions
🔗 GHA / 🍎 macOS (push) Blocked by required conditions
🔗 GHA / 🏁 Windows (push) Blocked by required conditions
🔗 GHA / 🌐 Web (push) Blocked by required conditions
🔗 GHA / 🪲 Godot CPP (push) Blocked by required conditions
Don't pseudolocalize empty strings
2024-10-17 21:27:30 -07:00
Clay John
14fc9a545c
Merge pull request #98230 from and-rad/android_permissions
Fix Android app permissions for SDK levels earlier than 28
2024-10-17 21:26:27 -07:00
Clay John
4dd0b67ec9
Merge pull request #98254 from timothyqiu/marker-typos
Fix typos in `AnimationMarkerEdit`
2024-10-17 21:24:11 -07:00
Juan Pablo Arce
e3790de461 Fix exported typed dictionaries in .NET having an incorrect hint, which led to incorrect scene serialization 2024-10-18 00:55:24 -03:00
tetrapod00
4b37fb3f88 Docs: Add link to 2D lights and shadows from CanvasModulate 2024-10-17 19:53:41 -07:00
Clay John
1435247de0
Merge pull request #98222 from timothyqiu/media-control-rtl
Some checks are pending
🔗 GHA / 📊 Static checks (push) Waiting to run
🔗 GHA / 🤖 Android (push) Blocked by required conditions
🔗 GHA / 🍏 iOS (push) Blocked by required conditions
🔗 GHA / 🐧 Linux (push) Blocked by required conditions
🔗 GHA / 🍎 macOS (push) Blocked by required conditions
🔗 GHA / 🏁 Windows (push) Blocked by required conditions
🔗 GHA / 🌐 Web (push) Blocked by required conditions
🔗 GHA / 🪲 Godot CPP (push) Blocked by required conditions
Don't flip playback control buttons in RTL layout
2024-10-17 16:58:23 -07:00
Clay John
0ce4d8fcd3
Merge pull request #98086 from DarioSamo/transfer-queues-semaphores
Rewrite semaphore handling for transfer workers.
2024-10-17 16:54:43 -07:00
Clay John
cdf45f73ab
Merge pull request #96893 from tetrapod00/docs-crosslink-antialiasing
Docs: Add cross-links to antialiasing project settings
2024-10-17 16:54:19 -07:00
Clay John
f6279ffd56
Merge pull request #97885 from timothyqiu/useful-tooltip
Make `EditorFileDialog`'s Recent and Fav list show full path in tooltip
2024-10-17 16:53:55 -07:00
Clay John
e50b864b64
Merge pull request #98085 from dalexeev/gds-fix-typed-dict-static-default-init
GDScript: Add missing static default initialization for typed dictionaries
2024-10-17 16:53:11 -07:00
Clay John
acc3786db2
Merge pull request #98009 from TokageItLab/init-skel-skin
Fix initial skin update timing in Skeleton3D
2024-10-17 16:51:05 -07:00
Clay John
be9e42c6a4
Merge pull request #97888 from Gamemap/Itemlist-fix-right-padding
ItemList - Fix right padding missing
2024-10-17 16:47:11 -07:00
Clay John
c6b94ca9b4
Merge pull request #93005 from CozyCubeGames/sqr-dist-optimization
Replace some distance checks with square distance checks in NavMap
2024-10-17 16:41:02 -07:00
Clay John
a2117f5796
Merge pull request #98187 from EnlightenedOne/98102
Fix Mobile Renderer - Shadow Disabled and User Vertex Lighting flags
2024-10-17 16:37:09 -07:00
Dario
7a936e8bac Rewrite semaphore handling for transfer workers. 2024-10-17 14:07:08 -03:00
yesfish
274076c5be Lightmap Dynamic Bugfix 2024-10-17 16:27:30 +01:00
Lalit Shankar Chowdhury
25687c5b99
Display proper message on invalid folder path 2024-10-17 13:06:48 +05:30
Lain
4e6d9813b2 Add support for BGRA textures with Texture*RD
This adds the ability to use BGRA textures created with RenderingDevice
with classes such as Texture2DRD.
2024-10-16 22:31:43 -07:00
Haoyu Qiu
f61fe2799c Don't pseudolocalize empty strings 2024-10-17 10:30:17 +08:00
Haoyu Qiu
3d07fced0c Fix typos in AnimationMarkerEdit 2024-10-17 08:12:00 +08:00
Haoyu Qiu
009446a277 Add System Locale layout direction for Control and Window 2024-10-17 07:52:07 +08:00
David Giardi
ebe1a2d7ec Add hover state to Tree items display 2024-10-17 00:21:52 +02:00
Thaddeus Crews
04692d83cb
Merge pull request #98238 from timothyqiu/not-append
Some checks are pending
🔗 GHA / 📊 Static checks (push) Waiting to run
🔗 GHA / 🤖 Android (push) Blocked by required conditions
🔗 GHA / 🍏 iOS (push) Blocked by required conditions
🔗 GHA / 🐧 Linux (push) Blocked by required conditions
🔗 GHA / 🍎 macOS (push) Blocked by required conditions
🔗 GHA / 🏁 Windows (push) Blocked by required conditions
🔗 GHA / 🌐 Web (push) Blocked by required conditions
🔗 GHA / 🪲 Godot CPP (push) Blocked by required conditions
Fix wording in description of `store_line` and `store_string`
2024-10-16 14:16:05 -05:00
Thaddeus Crews
324659f0ca
Merge pull request #97564 from kitbdev/animation-bezier-editor-fix-box-select-mouse
Fix mouse clamping in Animation Bezier Editor box select
2024-10-16 14:16:04 -05:00
Thaddeus Crews
e4093b558a
Merge pull request #98202 from syntaxerror247/patch-1
Update `use_native_dialog` description in `FileDialog`
2024-10-16 14:16:04 -05:00
Thaddeus Crews
78dbd39d1e
Merge pull request #98196 from bruvzg/u16_list
[Font Importer] Update Unicode block list to Unicode 16.0
2024-10-16 14:16:03 -05:00
Thaddeus Crews
74328ac38e
Merge pull request #98195 from kleonc/2d_transform_snapping_revert_incorrect_rounding
Revert unintentional rounding change when 2D transform snapping
2024-10-16 14:16:02 -05:00
Thaddeus Crews
30a2a800dd
Merge pull request #98127 from darksylinc/matias-wayland-build-error
Fix wrong Wayland path if building with opengl3=no
2024-10-16 14:16:02 -05:00
Thaddeus Crews
6ccff9b009
Merge pull request #98126 from TCROC/macos-codesign-additional-entitlements
Additional macOS codesign entitlements and print verbose
2024-10-16 14:16:01 -05:00
Thaddeus Crews
c032acb865
Merge pull request #98156 from jaydensipe/show-custom-icons-in-remote-scene-view
Show correct icons in remote object inspector (EditorDebuggerRemoteObject)
2024-10-16 14:16:00 -05:00
Thaddeus Crews
7f108cfa12
Merge pull request #88427 from CrayolaEater/fix-no-icons-on-remote-nodes
Fix Remote Nodes missing custom icons
2024-10-16 14:15:59 -05:00
Thaddeus Crews
e64662cb63
Merge pull request #98210 from allenwp/fix-CONTAINER_PROJECT_SETTING_TAB_RIGHT
Fix `CONTAINER_PROJECT_SETTING_TAB_RIGHT` option of `EditorPlugin`
2024-10-16 14:15:59 -05:00
Haoyu Qiu
e7e0e65159 Fix wording in description of store_line and store_string 2024-10-16 23:41:50 +08:00
Haoyu Qiu
acab2d6c1c Cache results for TranslationServer.compare_locales() 2024-10-16 20:54:56 +08:00
Andreas Raddau
90c35f3978 Fix Android app permissions for SDK levels earlier than 28 2024-10-16 12:47:18 +02:00
Anish Mishra
7ee72d2f81 Update use_native_dialog description in FileDialog 2024-10-16 15:33:47 +05:30
m-pranav-r
c12001a9dc Fix incorrect depth comparison used to calculate volumetric fog shadowing 2024-10-16 14:55:41 +05:30
Haoyu Qiu
9ed655d0eb Don't flip playback control buttons in RTL layout 2024-10-16 16:28:11 +08:00
Zi Ye
db194f06e1 Replaced some distance checks with square distance checks in NavMap, wherever the purpose is only to find the nearest element. 2024-10-15 22:06:35 -05:00
Jayden Sipe
7261321d34 Show correct icons in EditorDebuggerRemoteObject 2024-10-15 16:40:16 -04:00
Silc Lizard (Tokage) Renew
d29e7b6953 Fix initial skin update timing in Skeleton3D 2024-10-16 05:13:13 +09:00
Allen Pestaluky
920fd47fa3 Fix CONTAINER_PROJECT_SETTING_TAB_RIGHT option of EditorPlugin to add to the right of all other tabs. 2024-10-15 15:32:14 -04:00
Bogdan Inculet
fb58ea6c89 Fixed Remote Nodes missing custom icons 2024-10-15 22:28:53 +03:00
A Thousand Ships
de128812f3
Fix unreachable code in lightmap_gi.cpp 2024-10-15 13:17:15 +02:00
bruvzg
e4b8cd2948
[Font Importer] Update Unicode block list to Unicode 16.0 2024-10-15 12:40:30 +03:00
kleonc
8d3e9aa7ae Revert incorrect rounding when 2D transform snapping 2024-10-15 10:43:42 +02:00
EnlightenedOne
cef515506b Move preprocessor to end of line for iterator, remove redeclaration incompatible with ubershader method definitions 2024-10-14 22:19:16 +01:00
HolonProduction
140c6a612e GDScript: Fix annotation parsing adding new annotation entries 2024-10-13 22:43:06 +02:00
Travis Lange
5777a3fed5 added ability to add extra codesign entitlements for macos from godot editor 2024-10-13 09:33:42 -04:00
Matias N. Goldberg
0818408db5 Fix wrong Wayland path if building with opengl3=no
Godot checks if there's Vulkan or GLES3 support.
If no support is found, it shows an error message.

However the code for this error message is left out when building with
opengl3=no
2024-10-12 20:20:12 -03:00
Danil Alexeev
0bc59c78de
GDScript: Add missing static default initialization for typed dictionaries 2024-10-11 13:23:34 +03:00
tetrapod00
12d2c05936 Add "Inspect Native Shader Code" to shader resource and shader editor 2024-10-08 11:02:45 -07:00
Anish Mishra
9f6c88de89 update MenuBar after child renamed in editor 2024-10-08 20:19:02 +05:30
Gamemap
84b15a2ea4 ItemList - Fix right padding missing 2024-10-06 17:34:33 +02:00
Haoyu Qiu
ecb56fca26 Make EditorFileDialog's Recent and Fav list show full path in tooltip 2024-10-06 21:32:31 +08:00
Anish Mishra
8f9ed35f8b Fix ColorPicker virtual keyboard popup on mobile 2024-10-05 19:03:29 +05:30
obo
4ef07cb9a5 Fix "emulate mouse from touch" setting affecting editor
Make "emulate mouse from touch" always true in the editor
2024-10-01 02:23:32 +08:00
Thaddeus Crews
705f51f97e
SCons: Bump C standard: C11C17 2024-09-29 11:23:24 -05:00
TML
fa48ed9945 Change generated On{SignalName} to EmitSignal{SignalName} 2024-09-28 22:10:33 +08:00
kit
5af917e763 Fix mouse clamping in Animation Bezier box select 2024-09-27 22:25:41 -04:00
tetrapod00
461283887f Docs: Add cross-links to antialiasing project settings 2024-09-11 20:17:55 -07:00
David Trallero
1b376b32cd Update FollowPath2D children of Path2D when a curve_changed event occurs 2024-09-06 07:54:22 +08:00
141 changed files with 1382 additions and 472 deletions

View File

@ -799,8 +799,8 @@ if env["lto"] != "none":
# This needs to come after `configure`, otherwise we don't have env.msvc.
if not env.msvc:
# Specifying GNU extensions support explicitly, which are supported by
# both GCC and Clang. Both currently default to gnu11 and gnu++17.
env.Prepend(CFLAGS=["-std=gnu11"])
# both GCC and Clang. Both currently default to gnu17 and gnu++17.
env.Prepend(CFLAGS=["-std=gnu17"])
env.Prepend(CXXFLAGS=["-std=gnu++17"])
else:
# MSVC started offering C standard support with Visual Studio 2019 16.8, which covers all
@ -809,7 +809,7 @@ else:
if cc_version_major < 16:
print_warning("Visual Studio 2017 cannot specify a C-Standard.")
else:
env.Prepend(CFLAGS=["/std:c11"])
env.Prepend(CFLAGS=["/std:c17"])
# MSVC is non-conforming with the C++ standard by default, so we enable more conformance.
# Note that this is still not complete conformance, as certain Windows-related headers
# don't compile under complete conformance.

View File

@ -494,6 +494,7 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_f
}
void ProjectSettings::_convert_to_last_version(int p_from_version) {
#ifndef DISABLE_DEPRECATED
if (p_from_version <= 3) {
// Converts the actions from array to dictionary (array of events to dictionary with deadzone + events)
for (KeyValue<StringName, ProjectSettings::VariantContainer> &E : props) {
@ -507,6 +508,22 @@ void ProjectSettings::_convert_to_last_version(int p_from_version) {
}
}
}
if (p_from_version <= 5) {
// Converts the device in events from -1 (emulated events) to -3 (all events).
for (KeyValue<StringName, ProjectSettings::VariantContainer> &E : props) {
if (String(E.key).begins_with("input/")) {
Dictionary action = E.value.variant;
Array events = action["events"];
for (int i = 0; i < events.size(); i++) {
Ref<InputEvent> x = events[i];
if (x->get_device() == -1) { // -1 was the previous value (GH-97707).
x->set_device(InputEvent::DEVICE_ID_ALL_DEVICES);
}
}
}
}
}
#endif // DISABLE_DEPRECATED
}
/*
@ -1460,6 +1477,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("display/window/size/transparent", false);
GLOBAL_DEF("display/window/size/extend_to_title", false);
GLOBAL_DEF("display/window/size/no_focus", false);
GLOBAL_DEF("display/window/size/sharp_corners", false);
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution

View File

@ -32,7 +32,6 @@
#define CORE_BIND_H
#include "core/debugger/engine_profiler.h"
#include "core/io/image.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/object/script_language.h"

View File

@ -34,6 +34,7 @@
#include "core/extension/gdextension.h"
#include "core/extension/gdextension_compat_hashes.h"
#include "core/io/file_access.h"
#include "core/io/image.h"
#include "core/io/xml_parser.h"
#include "core/object/class_db.h"
#include "core/object/script_language_extension.h"

View File

@ -35,9 +35,6 @@
#include "core/os/keyboard.h"
#include "core/os/os.h"
const int InputEvent::DEVICE_ID_EMULATION = -1;
const int InputEvent::DEVICE_ID_INTERNAL = -2;
void InputEvent::set_device(int p_device) {
device = p_device;
emit_changed();

View File

@ -62,8 +62,9 @@ protected:
static void _bind_methods();
public:
static const int DEVICE_ID_EMULATION;
static const int DEVICE_ID_INTERNAL;
inline static constexpr int DEVICE_ID_EMULATION = -1;
inline static constexpr int DEVICE_ID_INTERNAL = -2;
inline static constexpr int DEVICE_ID_ALL_DEVICES = -3; // Signify that a given Action can be triggered by any device.
void set_device(int p_device);
int get_device() const;

View File

@ -39,8 +39,6 @@
InputMap *InputMap::singleton = nullptr;
int InputMap::ALL_DEVICES = -1;
void InputMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions);
@ -163,7 +161,7 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re
int i = 0;
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
int device = E->get()->get_device();
if (device == ALL_DEVICES || device == p_event->get_device()) {
if (device == InputEvent::DEVICE_ID_ALL_DEVICES || device == p_event->get_device()) {
if (E->get()->action_match(p_event, p_exact_match, p_action.deadzone, r_pressed, r_strength, r_raw_strength)) {
if (r_event_index) {
*r_event_index = i;

View File

@ -43,11 +43,6 @@ class InputMap : public Object {
GDCLASS(InputMap, Object);
public:
/**
* A special value used to signify that a given Action can be triggered by any device
*/
static int ALL_DEVICES;
struct Action {
int id;
float deadzone;

View File

@ -121,7 +121,7 @@ String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_
d.get_key_list(&keys);
if (p_sort_keys) {
keys.sort();
keys.sort_custom<StringLikeVariantOrder>();
}
bool first_key = true;

View File

@ -1268,6 +1268,11 @@ void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String
return;
}
// res files not supported for GDExtension.
if (p_type == "GDExtension") {
return;
}
List<String> extensions;
ClassDB::get_extensions_for_type(p_type, &extensions);

View File

@ -32,7 +32,6 @@
#define OS_H
#include "core/config/engine.h"
#include "core/io/image.h"
#include "core/io/logger.h"
#include "core/io/remote_filesystem_client.h"
#include "core/os/time_enums.h"

View File

@ -389,6 +389,10 @@ void TranslationDomain::set_pseudolocalization_suffix(const String &p_suffix) {
}
StringName TranslationDomain::pseudolocalize(const StringName &p_message) const {
if (p_message.is_empty()) {
return p_message;
}
String message = p_message;
int length = message.length();
if (pseudolocalization.override_enabled) {

View File

@ -228,32 +228,41 @@ int TranslationServer::compare_locales(const String &p_locale_a, const String &p
return 10;
}
const String cache_key = p_locale_a + "|" + p_locale_b;
const int *cached_result = locale_compare_cache.getptr(cache_key);
if (cached_result) {
return *cached_result;
}
String locale_a = _standardize_locale(p_locale_a, true);
String locale_b = _standardize_locale(p_locale_b, true);
if (locale_a == locale_b) {
// Exact match.
locale_compare_cache.insert(cache_key, 10);
return 10;
}
Vector<String> locale_a_elements = locale_a.split("_");
Vector<String> locale_b_elements = locale_b.split("_");
if (locale_a_elements[0] == locale_b_elements[0]) {
// Matching language, both locales have extra parts.
// Return number of matching elements.
int matching_elements = 1;
for (int i = 1; i < locale_a_elements.size(); i++) {
for (int j = 1; j < locale_b_elements.size(); j++) {
if (locale_a_elements[i] == locale_b_elements[j]) {
matching_elements++;
}
}
}
return matching_elements;
} else {
if (locale_a_elements[0] != locale_b_elements[0]) {
// No match.
locale_compare_cache.insert(cache_key, 0);
return 0;
}
// Matching language, both locales have extra parts.
// Return number of matching elements.
int matching_elements = 1;
for (int i = 1; i < locale_a_elements.size(); i++) {
for (int j = 1; j < locale_b_elements.size(); j++) {
if (locale_a_elements[i] == locale_b_elements[j]) {
matching_elements++;
}
}
}
locale_compare_cache.insert(cache_key, matching_elements);
return matching_elements;
}
String TranslationServer::get_locale_name(const String &p_locale) const {

View File

@ -46,6 +46,8 @@ class TranslationServer : public Object {
Ref<TranslationDomain> doc_domain;
HashMap<StringName, Ref<TranslationDomain>> custom_domains;
mutable HashMap<String, int> locale_compare_cache;
bool enabled = true;
static TranslationServer *singleton;

View File

@ -854,6 +854,19 @@ struct StringLikeVariantComparator {
static bool compare(const Variant &p_lhs, const Variant &p_rhs);
};
struct StringLikeVariantOrder {
static _ALWAYS_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) {
if (p_lhs.is_string() && p_rhs.is_string()) {
return p_lhs.operator String() < p_rhs.operator String();
}
return p_lhs < p_rhs;
}
_ALWAYS_INLINE_ bool operator()(const Variant &p_lhs, const Variant &p_rhs) const {
return compare(p_lhs, p_rhs);
}
};
Variant::ObjData &Variant::_get_obj() {
return *reinterpret_cast<ObjData *>(&_data._mem[0]);
}

View File

@ -2245,7 +2245,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} else {
List<Variant> keys;
dict.get_key_list(&keys);
keys.sort();
keys.sort_custom<StringLikeVariantOrder>();
if (keys.is_empty()) {
// Avoid unnecessary line break.

View File

@ -7,6 +7,7 @@
[CanvasModulate] applies a color tint to all nodes on a canvas. Only one can be used to tint a canvas, but [CanvasLayer]s can be used to render things independently.
</description>
<tutorials>
<link title="2D lights and shadows">$DOCS_URL/tutorials/2d/2d_lights_and_shadows.html</link>
</tutorials>
<members>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)" keywords="colour">

View File

@ -1365,7 +1365,7 @@
<constant name="LAYOUT_DIRECTION_INHERITED" value="0" enum="LayoutDirection">
Automatic layout direction, determined from the parent control layout direction.
</constant>
<constant name="LAYOUT_DIRECTION_LOCALE" value="1" enum="LayoutDirection">
<constant name="LAYOUT_DIRECTION_APPLICATION_LOCALE" value="1" enum="LayoutDirection">
Automatic layout direction, determined from the current locale.
</constant>
<constant name="LAYOUT_DIRECTION_LTR" value="2" enum="LayoutDirection">
@ -1374,6 +1374,14 @@
<constant name="LAYOUT_DIRECTION_RTL" value="3" enum="LayoutDirection">
Right-to-left layout direction.
</constant>
<constant name="LAYOUT_DIRECTION_SYSTEM_LOCALE" value="4" enum="LayoutDirection">
Automatic layout direction, determined from the system locale.
</constant>
<constant name="LAYOUT_DIRECTION_MAX" value="5" enum="LayoutDirection">
Represents the size of the [enum LayoutDirection] enum.
</constant>
<constant name="LAYOUT_DIRECTION_LOCALE" value="1" enum="LayoutDirection" deprecated="Use [constant LAYOUT_DIRECTION_APPLICATION_LOCALE] instead.">
</constant>
<constant name="TEXT_DIRECTION_INHERITED" value="3" enum="TextDirection">
Text writing direction is the same as layout direction.
</constant>

View File

@ -2099,7 +2099,11 @@
<constant name="WINDOW_FLAG_MOUSE_PASSTHROUGH" value="7" enum="WindowFlags">
All mouse events are passed to the underlying window of the same application.
</constant>
<constant name="WINDOW_FLAG_MAX" value="8" enum="WindowFlags">
<constant name="WINDOW_FLAG_SHARP_CORNERS" value="8" enum="WindowFlags">
Window style is overridden, forcing sharp corners.
[b]Note:[/b] This flag is implemented only on Windows (11).
</constant>
<constant name="WINDOW_FLAG_MAX" value="9" enum="WindowFlags">
Max value of the [enum WindowFlags].
</constant>
<constant name="WINDOW_EVENT_MOUSE_ENTER" value="0" enum="WindowEvent">

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorExport" inherits="Node" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Hosts data related to a project's export configuration.
</brief_description>
<description>
Editor-only singleton that hosts a project's [EditorExportPlatform], [EditorExportPreset], and [EditorExportPlugin] objects. Use this class to retrieve information about a project's export configuration.
</description>
<tutorials>
<link title="Export">$DOCS_URL/tutorials/export/index.html</link>
</tutorials>
<methods>
<method name="get_export_platform">
<return type="EditorExportPlatform" />
<param index="0" name="idx" type="int" />
<description>
Returns the [EditorExportPlatform] at index [param idx]. [param idx] must be equal to or greater than [code]0[/code] and less than the result of [method get_export_platform_count].
</description>
</method>
<method name="get_export_platform_count" qualifiers="const">
<return type="int" />
<description>
Returns the number of unique platforms available for export. This includes platforms that do not have an export preset in the current project.
</description>
</method>
<method name="get_export_preset">
<return type="EditorExportPreset" />
<param index="0" name="idx" type="int" />
<description>
Returns the [EditorExportPreset] at index [param idx]. [param idx] must be equal to or greater than [code]0[/code] and less than the result of [method get_export_preset_count].
</description>
</method>
<method name="get_export_preset_count" qualifiers="const">
<return type="int" />
<description>
Returns the number of export presets in the project.
</description>
</method>
</methods>
<signals>
<signal name="export_presets_runnable_updated">
<description>
Emitted when the [code]runnable[/code] property of an [EditorExportPreset] has been updated or when an [EditorExportPreset] has been added to or removed from the project.
</description>
</signal>
<signal name="export_presets_updated">
<description>
Emitted when the properties of an [EditorExportPreset] have been updated.
</description>
</signal>
</signals>
</class>

View File

@ -158,6 +158,20 @@
Returns the name of the export operating system handled by this [EditorExportPlatform] class, as a friendly string. Possible return values are [code]Windows[/code], [code]Linux[/code], [code]macOS[/code], [code]Android[/code], [code]iOS[/code], and [code]Web[/code].
</description>
</method>
<method name="get_platform_features" qualifiers="const">
<return type="String[]" />
<description>
Returns feature tags that are specific to the export platform. Some feature tags that may be included in this list are [code]mobile[/code], [code]pc[/code], [code]web[/code], [code]android[/code], [code]ios[/code], [code]linux[/code], [code]macos[/code], and [code]windows[/code].
</description>
</method>
<method name="get_preset_features" qualifiers="const">
<return type="String[]" />
<param index="0" name="preset" type="EditorExportPreset" />
<description>
Returns feature tags that are specific to [param preset], excluding custom features. Some feature tags that may be included in this list are texture formats ([code]etc2[/code], [code]bptc[/code], [code]s3tc[/code]), architectures ([code]x86_64[/code], [code]x86_32[/code], [code]arm64[/code], [code]arm32[/code], [code]rv64[/code], [code]riscv[/code], [code]ppc64[/code], [code]ppc[/code], [code]wasm32[/code], [code]wasm64[/code], [code]universal[/code]), and other features ([code]threads[/code], [code]nothreads[/code]).
Use [method EditorExportPreset.get_custom_features] to get the custom features of an export preset.
</description>
</method>
<method name="get_worst_message_type" qualifiers="const">
<return type="int" enum="EditorExportPlatform.ExportMessageType" />
<description>

View File

@ -115,6 +115,12 @@
Returns the list of packs on which to base a patch export on.
</description>
</method>
<method name="get_platform" qualifiers="const">
<return type="EditorExportPlatform" />
<description>
Returns the [EditorExportPlatform] for this export preset.
</description>
</method>
<method name="get_preset_name" qualifiers="const">
<return type="String" />
<description>

View File

@ -83,6 +83,12 @@
Returns the edited (current) scene's root [Node].
</description>
</method>
<method name="get_editor_export" qualifiers="const">
<return type="EditorExport" />
<description>
Returns the [EditorExport] singleton.
</description>
</method>
<method name="get_editor_main_screen" qualifiers="const">
<return type="VBoxContainer" />
<description>

View File

@ -474,7 +474,7 @@
<return type="void" />
<param index="0" name="line" type="String" />
<description>
Appends [param line] to the file followed by a line return character ([code]\n[/code]), encoding the text as UTF-8.
Stores [param line] in the file followed by a newline character ([code]\n[/code]), encoding the text as UTF-8.
</description>
</method>
<method name="store_pascal_string">
@ -496,7 +496,7 @@
<return type="void" />
<param index="0" name="string" type="String" />
<description>
Appends [param string] to the file without a line return, encoding the text as UTF-8.
Stores [param string] in the file without a newline character ([code]\n[/code]), encoding the text as UTF-8.
[b]Note:[/b] This method is intended to be used to write text files. The string is stored as a UTF-8 encoded buffer without string length or terminating zero, which means that it can't be loaded back easily. If you want to store a retrievable string in a binary file, consider using [method store_pascal_string] instead. For retrieving strings from a text file, you can use [code]get_buffer(length).get_string_from_utf8()[/code] (if you know the length) or [method get_as_text].
</description>
</method>

View File

@ -164,7 +164,7 @@
<member name="size" type="Vector2i" setter="set_size" getter="get_size" overrides="Window" default="Vector2i(640, 360)" />
<member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Save a File&quot;" />
<member name="use_native_dialog" type="bool" setter="set_use_native_dialog" getter="get_use_native_dialog" default="false">
If [code]true[/code], [member access] is set to [constant ACCESS_FILESYSTEM], and it is supported by the current [DisplayServer], OS native dialog will be used instead of custom one.
If [code]true[/code], and if supported by the current [DisplayServer], OS native dialog will be used instead of custom one.
[b]Note:[/b] On Linux and macOS, sandboxed apps always use native dialogs to access the host file system.
[b]Note:[/b] On macOS, sandboxed apps will save security-scoped bookmarks to retain access to the opened folders across multiple sessions. Use [method OS.get_granted_permissions] to get a list of saved bookmarks.
[b]Note:[/b] Native dialogs are isolated from the base process, file dialog properties can't be modified once the dialog is shown.

View File

@ -45,7 +45,7 @@
<method name="inspect_native_shader_code">
<return type="void" />
<description>
Only available when running in the editor. Opens a popup that visualizes the generated shader code, including all variants and internal shader code.
Only available when running in the editor. Opens a popup that visualizes the generated shader code, including all variants and internal shader code. See also [method Shader.inspect_native_shader_code].
</description>
</method>
</methods>

View File

@ -73,6 +73,7 @@
<description>
Called during the physics processing step of the main loop. Physics processing means that the frame rate is synced to the physics, i.e. the [param delta] variable should be constant. [param delta] is in seconds.
It is only called if physics processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_physics_process].
Processing happens in order of [member process_physics_priority], lower priority values are called first. Nodes with the same priority are processed in tree order, or top to bottom as seen in the editor (also known as pre-order traversal).
Corresponds to the [constant NOTIFICATION_PHYSICS_PROCESS] notification in [method Object._notification].
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not an orphan).
</description>
@ -83,6 +84,7 @@
<description>
Called during the processing step of the main loop. Processing happens at every frame and as fast as possible, so the [param delta] time since the previous frame is not constant. [param delta] is in seconds.
It is only called if processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process].
Processing happens in order of [member process_priority], lower priority values are called first. Nodes with the same priority are processed in tree order, or top to bottom as seen in the editor (also known as pre-order traversal).
Corresponds to the [constant NOTIFICATION_PROCESS] notification in [method Object._notification].
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not an orphan).
</description>
@ -1015,10 +1017,10 @@
The node's processing behavior (see [enum ProcessMode]). To check if the node can process in its current mode, use [method can_process].
</member>
<member name="process_physics_priority" type="int" setter="set_physics_process_priority" getter="get_physics_process_priority" default="0">
Similar to [member process_priority] but for [constant NOTIFICATION_PHYSICS_PROCESS], [method _physics_process] or the internal version.
Similar to [member process_priority] but for [constant NOTIFICATION_PHYSICS_PROCESS], [method _physics_process], or [constant NOTIFICATION_INTERNAL_PHYSICS_PROCESS].
</member>
<member name="process_priority" type="int" setter="set_process_priority" getter="get_process_priority" default="0">
The node's execution order of the process callbacks ([method _process], [method _physics_process], and internal processing). Nodes whose priority value is [i]lower[/i] call their process callbacks first, regardless of tree order.
The node's execution order of the process callbacks ([method _process], [constant NOTIFICATION_PROCESS], and [constant NOTIFICATION_INTERNAL_PROCESS]). Nodes whose priority value is [i]lower[/i] call their process callbacks first, regardless of tree order.
</member>
<member name="process_thread_group" type="int" setter="set_process_thread_group" getter="get_process_thread_group" enum="Node.ProcessThreadGroup" default="0">
Set the process thread group for this node (basically, whether it receives [constant NOTIFICATION_PROCESS], [constant NOTIFICATION_PHYSICS_PROCESS], [method _process] or [method _physics_process] (and the internal versions) on the main thread or in a sub-thread.

View File

@ -875,6 +875,10 @@
[b]Note:[/b] Certain window managers can be configured to ignore the non-resizable status of a window. Do not rely on this setting as a guarantee that the window will [i]never[/i] be resizable.
[b]Note:[/b] This setting is ignored on iOS.
</member>
<member name="display/window/size/sharp_corners" type="bool" setter="" getter="" default="false">
If [code]true[/code], the main window uses sharp corners by default.
[b]Note:[/b] This property is implemented only on Windows (11).
</member>
<member name="display/window/size/transparent" type="bool" setter="" getter="" default="false">
If [code]true[/code], enables a window manager hint that the main window background [i]can[/i] be transparent. This does not make the background actually transparent. For the background to be transparent, the root viewport must also be made transparent by enabling [member rendering/viewport/transparent_background].
[b]Note:[/b] To use a transparent splash screen, set [member application/boot_splash/bg_color] to [code]Color(0, 0, 0, 0)[/code].
@ -2376,26 +2380,30 @@
[b]Note:[/b] It is not recommended to use this setting together with [member rendering/2d/snap/snap_2d_transforms_to_pixel], as movement may appear even less smooth. Prefer only enabling that setting instead.
</member>
<member name="rendering/anti_aliasing/quality/msaa_2d" type="int" setter="" getter="" default="0">
Sets the number of MSAA samples to use for 2D/Canvas rendering (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware, especially integrated graphics due to their limited memory bandwidth. This has no effect on shader-induced aliasing or texture aliasing.
Sets the number of multisample antialiasing (MSAA) samples to use for 2D/Canvas rendering (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware, especially integrated graphics due to their limited memory bandwidth. This has no effect on shader-induced aliasing or texture aliasing.
[b]Note:[/b] MSAA is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
[b]Note:[/b] This property is only read when the project starts. To set the number of 2D MSAA samples at runtime, set [member Viewport.msaa_2d] or use [method RenderingServer.viewport_set_msaa_2d].
</member>
<member name="rendering/anti_aliasing/quality/msaa_3d" type="int" setter="" getter="" default="0">
Sets the number of MSAA samples to use for 3D rendering (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware, especially integrated graphics due to their limited memory bandwidth. See also [member rendering/scaling_3d/mode] for supersampling, which provides higher quality but is much more expensive. This has no effect on shader-induced aliasing or texture aliasing.
Sets the number of multisample antialiasing (MSAA) samples to use for 3D rendering (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware, especially integrated graphics due to their limited memory bandwidth. See also [member rendering/scaling_3d/mode] for supersampling, which provides higher quality but is much more expensive. This has no effect on shader-induced aliasing or texture aliasing.
[b]Note:[/b] This property is only read when the project starts. To set the number of 3D MSAA samples at runtime, set [member Viewport.msaa_3d] or use [method RenderingServer.viewport_set_msaa_3d].
</member>
<member name="rendering/anti_aliasing/quality/screen_space_aa" type="int" setter="" getter="" default="0">
Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. The blurriness is partially counteracted by automatically using a negative mipmap LOD bias (see [member rendering/textures/default_filters/texture_mipmap_bias]).
Another way to combat specular aliasing is to enable [member rendering/anti_aliasing/screen_space_roughness_limiter/enabled].
[b]Note:[/b] Screen-space antialiasing is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
[b]Note:[/b] This property is only read when the project starts. To set the screen-space antialiasing mode at runtime, set [member Viewport.screen_space_aa] on the root [Viewport] instead, or use [method RenderingServer.viewport_set_screen_space_aa].
</member>
<member name="rendering/anti_aliasing/quality/use_debanding" type="bool" setter="" getter="" default="false">
If [code]true[/code], uses a fast post-processing filter to make banding significantly less visible in 3D. 2D rendering is [i]not[/i] affected by debanding unless the [member Environment.background_mode] is [constant Environment.BG_CANVAS].
In some cases, debanding may introduce a slightly noticeable dithering pattern. It's recommended to enable debanding only when actually needed since the dithering pattern will make lossless-compressed screenshots larger.
[b]Note:[/b] This property is only read when the project starts. To set debanding at run-time, set [member Viewport.use_debanding] on the root [Viewport] instead.
[b]Note:[/b] This property is only read when the project starts. To set debanding at runtime, set [member Viewport.use_debanding] on the root [Viewport] instead, or use [method RenderingServer.viewport_set_use_debanding].
</member>
<member name="rendering/anti_aliasing/quality/use_taa" type="bool" setter="" getter="" default="false">
Enables Temporal Anti-Aliasing for the default screen [Viewport]. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion. Enabling TAA can make the image blurrier, which is partially counteracted by automatically using a negative mipmap LOD bias (see [member rendering/textures/default_filters/texture_mipmap_bias]).
Enables temporal antialiasing for the default screen [Viewport]. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion. Enabling TAA can make the image blurrier, which is partially counteracted by automatically using a negative mipmap LOD bias (see [member rendering/textures/default_filters/texture_mipmap_bias]).
[b]Note:[/b] The implementation is not complete yet. Some visual instances such as particles and skinned meshes may show ghosting artifacts in motion.
[b]Note:[/b] TAA is only supported in the Forward+ rendering method, not Mobile or Compatibility.
[b]Note:[/b] This property is only read when the project starts. To set TAA at runtime, set [member Viewport.use_taa] on the root [Viewport] instead, or use [method RenderingServer.viewport_set_use_taa].
</member>
<member name="rendering/anti_aliasing/screen_space_roughness_limiter/amount" type="float" setter="" getter="" default="0.25">
[b]Note:[/b] This property is only read when the project starts. To control the screen-space roughness limiter at runtime, call [method RenderingServer.screen_space_roughness_limiter_set_active] instead.

View File

@ -3917,7 +3917,7 @@
<param index="0" name="viewport" type="RID" />
<param index="1" name="msaa" type="int" enum="RenderingServer.ViewportMSAA" />
<description>
Sets the multisample anti-aliasing mode for 2D/Canvas on the specified [param viewport] RID. See [enum ViewportMSAA] for options.
Sets the multisample antialiasing mode for 2D/Canvas on the specified [param viewport] RID. See [enum ViewportMSAA] for options. Equivalent to [member ProjectSettings.rendering/anti_aliasing/quality/msaa_2d] or [member Viewport.msaa_2d].
</description>
</method>
<method name="viewport_set_msaa_3d">
@ -3925,7 +3925,7 @@
<param index="0" name="viewport" type="RID" />
<param index="1" name="msaa" type="int" enum="RenderingServer.ViewportMSAA" />
<description>
Sets the multisample anti-aliasing mode for 3D on the specified [param viewport] RID. See [enum ViewportMSAA] for options.
Sets the multisample antialiasing mode for 3D on the specified [param viewport] RID. See [enum ViewportMSAA] for options. Equivalent to [member ProjectSettings.rendering/anti_aliasing/quality/msaa_3d] or [member Viewport.msaa_3d].
</description>
</method>
<method name="viewport_set_occlusion_culling_build_quality">
@ -4007,7 +4007,7 @@
<param index="0" name="viewport" type="RID" />
<param index="1" name="mode" type="int" enum="RenderingServer.ViewportScreenSpaceAA" />
<description>
Sets the viewport's screen-space antialiasing mode.
Sets the viewport's screen-space antialiasing mode. Equivalent to [member ProjectSettings.rendering/anti_aliasing/quality/screen_space_aa] or [member Viewport.screen_space_aa].
</description>
</method>
<method name="viewport_set_sdf_oversize_and_scale">
@ -4074,7 +4074,7 @@
<param index="0" name="viewport" type="RID" />
<param index="1" name="enable" type="bool" />
<description>
If [code]true[/code], enables debanding on the specified viewport. Equivalent to [member ProjectSettings.rendering/anti_aliasing/quality/use_debanding].
If [code]true[/code], enables debanding on the specified viewport. Equivalent to [member ProjectSettings.rendering/anti_aliasing/quality/use_debanding] or [member Viewport.use_debanding].
</description>
</method>
<method name="viewport_set_use_hdr_2d">
@ -4099,7 +4099,7 @@
<param index="0" name="viewport" type="RID" />
<param index="1" name="enable" type="bool" />
<description>
If [code]true[/code], use Temporal Anti-Aliasing. Equivalent to [member ProjectSettings.rendering/anti_aliasing/quality/use_taa].
If [code]true[/code], use temporal antialiasing. Equivalent to [member ProjectSettings.rendering/anti_aliasing/quality/use_taa] or [member Viewport.use_taa].
</description>
</method>
<method name="viewport_set_use_xr">

View File

@ -35,6 +35,12 @@
If argument [param get_groups] is true, parameter grouping hints will be provided.
</description>
</method>
<method name="inspect_native_shader_code">
<return type="void" />
<description>
Only available when running in the editor. Opens a popup that visualizes the generated shader code, including all variants and internal shader code. See also [method Material.inspect_native_shader_code].
</description>
</method>
<method name="set_default_texture_parameter">
<return type="void" />
<param index="0" name="name" type="StringName" />

View File

@ -509,6 +509,12 @@
<theme_item name="font_disabled_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 0.5)">
Text [Color] for a [constant TreeItem.CELL_MODE_CHECK] mode cell when it's non-editable (see [method TreeItem.set_editable]).
</theme_item>
<theme_item name="font_hovered_color" data_type="color" type="Color" default="Color(0.95, 0.95, 0.95, 1)">
Text [Color] used when the item is hovered.
</theme_item>
<theme_item name="font_hovered_dimmed_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 1)">
Text [Color] used when the item is hovered, while a button of the same item is hovered as the same time.
</theme_item>
<theme_item name="font_outline_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
The tint of text outline of the item.
</theme_item>
@ -645,6 +651,9 @@
<theme_item name="updown" data_type="icon" type="Texture2D">
The updown arrow icon to display for the [constant TreeItem.CELL_MODE_RANGE] mode cell.
</theme_item>
<theme_item name="button_hover" data_type="style" type="StyleBox">
[StyleBox] used when a button in the tree is hovered.
</theme_item>
<theme_item name="button_pressed" data_type="style" type="StyleBox">
[StyleBox] used when a button in the tree is pressed.
</theme_item>
@ -666,6 +675,12 @@
<theme_item name="focus" data_type="style" type="StyleBox">
The focused style for the [Tree], drawn on top of everything.
</theme_item>
<theme_item name="hovered" data_type="style" type="StyleBox">
[StyleBox] for the item being hovered.
</theme_item>
<theme_item name="hovered_dimmed" data_type="style" type="StyleBox">
[StyleBox] for the item being hovered, while a button of the same item is hovered as the same time.
</theme_item>
<theme_item name="panel" data_type="style" type="StyleBox">
The background style for the [Tree].
</theme_item>

View File

@ -312,10 +312,12 @@
[b]Note:[/b] [member mesh_lod_threshold] does not affect [GeometryInstance3D] visibility ranges (also known as "manual" LOD or hierarchical LOD).
</member>
<member name="msaa_2d" type="int" setter="set_msaa_2d" getter="get_msaa_2d" enum="Viewport.MSAA" default="0">
The multisample anti-aliasing mode for 2D/Canvas rendering. A higher number results in smoother edges at the cost of significantly worse performance. A value of 2 or 4 is best unless targeting very high-end systems. This has no effect on shader-induced aliasing or texture aliasing.
The multisample antialiasing mode for 2D/Canvas rendering. A higher number results in smoother edges at the cost of significantly worse performance. A value of [constant Viewport.MSAA_2X] or [constant Viewport.MSAA_4X] is best unless targeting very high-end systems. This has no effect on shader-induced aliasing or texture aliasing.
See also [member ProjectSettings.rendering/anti_aliasing/quality/msaa_2d] and [method RenderingServer.viewport_set_msaa_2d].
</member>
<member name="msaa_3d" type="int" setter="set_msaa_3d" getter="get_msaa_3d" enum="Viewport.MSAA" default="0">
The multisample anti-aliasing mode for 3D rendering. A higher number results in smoother edges at the cost of significantly worse performance. A value of 2 or 4 is best unless targeting very high-end systems. See also bilinear scaling 3d [member scaling_3d_mode] for supersampling, which provides higher quality but is much more expensive. This has no effect on shader-induced aliasing or texture aliasing.
The multisample antialiasing mode for 3D rendering. A higher number results in smoother edges at the cost of significantly worse performance. A value of [constant Viewport.MSAA_2X] or [constant Viewport.MSAA_4X] is best unless targeting very high-end systems. See also bilinear scaling 3d [member scaling_3d_mode] for supersampling, which provides higher quality but is much more expensive. This has no effect on shader-induced aliasing or texture aliasing.
See also [member ProjectSettings.rendering/anti_aliasing/quality/msaa_3d] and [method RenderingServer.viewport_set_msaa_3d].
</member>
<member name="own_world_3d" type="bool" setter="set_use_own_world_3d" getter="is_using_own_world_3d" default="false">
If [code]true[/code], the viewport will use a unique copy of the [World3D] defined in [member world_3d].
@ -365,6 +367,7 @@
</member>
<member name="screen_space_aa" type="int" setter="set_screen_space_aa" getter="get_screen_space_aa" enum="Viewport.ScreenSpaceAA" default="0">
Sets the screen-space antialiasing method used. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry.
See also [member ProjectSettings.rendering/anti_aliasing/quality/screen_space_aa] and [method RenderingServer.viewport_set_screen_space_aa].
</member>
<member name="sdf_oversize" type="int" setter="set_sdf_oversize" getter="get_sdf_oversize" enum="Viewport.SDFOversize" default="1">
Controls how much of the original viewport's size should be covered by the 2D signed distance field. This SDF can be sampled in [CanvasItem] shaders and is also used for [GPUParticles2D] collision. Higher values allow portions of occluders located outside the viewport to still be taken into account in the generated signed distance field, at the cost of performance. If you notice particles falling through [LightOccluder2D]s as the occluders leave the viewport, increase this setting.
@ -389,8 +392,9 @@
If [code]true[/code], the viewport should render its background as transparent.
</member>
<member name="use_debanding" type="bool" setter="set_use_debanding" getter="is_using_debanding" default="false">
If [code]true[/code], uses a fast post-processing filter to make banding significantly less visible in 3D. 2D rendering is [i]not[/i] affected by debanding unless the [member Environment.background_mode] is [constant Environment.BG_CANVAS]. See also [member ProjectSettings.rendering/anti_aliasing/quality/use_debanding].
If [code]true[/code], uses a fast post-processing filter to make banding significantly less visible in 3D. 2D rendering is [i]not[/i] affected by debanding unless the [member Environment.background_mode] is [constant Environment.BG_CANVAS].
In some cases, debanding may introduce a slightly noticeable dithering pattern. It's recommended to enable debanding only when actually needed since the dithering pattern will make lossless-compressed screenshots larger.
See also [member ProjectSettings.rendering/anti_aliasing/quality/use_debanding] and [method RenderingServer.viewport_set_use_debanding].
</member>
<member name="use_hdr_2d" type="bool" setter="set_use_hdr_2d" getter="is_using_hdr_2d" default="false">
If [code]true[/code], 2D rendering will use an high dynamic range (HDR) format framebuffer matching the bit depth of the 3D framebuffer. When using the Forward+ renderer this will be an [code]RGBA16[/code] framebuffer, while when using the Mobile renderer it will be an [code]RGB10_A2[/code] framebuffer. Additionally, 2D rendering will take place in linear color space and will be converted to sRGB space immediately before blitting to the screen (if the Viewport is attached to the screen). Practically speaking, this means that the end result of the Viewport will not be clamped into the [code]0-1[/code] range and can be used in 3D rendering without color space adjustments. This allows 2D rendering to take advantage of effects requiring high dynamic range (e.g. 2D glow) as well as substantially improves the appearance of effects requiring highly detailed gradients.
@ -402,8 +406,9 @@
[b]Note:[/b] Due to memory constraints, occlusion culling is not supported by default in Web export templates. It can be enabled by compiling custom Web export templates with [code]module_raycast_enabled=yes[/code].
</member>
<member name="use_taa" type="bool" setter="set_use_taa" getter="is_using_taa" default="false">
Enables Temporal Anti-Aliasing for this viewport. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion.
Enables temporal antialiasing for this viewport. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion.
[b]Note:[/b] The implementation is not complete yet, some visual instances such as particles and skinned meshes may show artifacts.
See also [member ProjectSettings.rendering/anti_aliasing/quality/use_taa] and [method RenderingServer.viewport_set_use_taa].
</member>
<member name="use_xr" type="bool" setter="set_use_xr" getter="is_using_xr" default="false">
If [code]true[/code], the viewport will use the primary XR interface to render XR output. When applicable this can result in a stereoscopic image and the resulting render being output to a headset.

View File

@ -659,6 +659,11 @@
If [member ProjectSettings.display/window/subwindows/embed_subwindows] is [code]false[/code], the position is in absolute screen coordinates. This typically applies to editor plugins. If the setting is [code]true[/code], the window's position is in the coordinates of its parent [Viewport].
[b]Note:[/b] This property only works if [member initial_position] is set to [constant WINDOW_INITIAL_POSITION_ABSOLUTE].
</member>
<member name="sharp_corners" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window] will override the OS window style to display sharp corners.
[b]Note:[/b] This property is implemented only on Windows (11).
[b]Note:[/b] This property only works with native windows.
</member>
<member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i(100, 100)">
The window's size in pixels.
</member>
@ -842,7 +847,12 @@
All mouse events are passed to the underlying window of the same application.
[b]Note:[/b] This flag has no effect in embedded windows.
</constant>
<constant name="FLAG_MAX" value="8" enum="Flags">
<constant name="FLAG_SHARP_CORNERS" value="8" enum="Flags">
Window style is overridden, forcing sharp corners.
[b]Note:[/b] This flag has no effect in embedded windows.
[b]Note:[/b] This flag is implemented only on Windows (11).
</constant>
<constant name="FLAG_MAX" value="9" enum="Flags">
Max value of the [enum Flags].
</constant>
<constant name="CONTENT_SCALE_MODE_DISABLED" value="0" enum="ContentScaleMode">
@ -878,7 +888,7 @@
<constant name="LAYOUT_DIRECTION_INHERITED" value="0" enum="LayoutDirection">
Automatic layout direction, determined from the parent window layout direction.
</constant>
<constant name="LAYOUT_DIRECTION_LOCALE" value="1" enum="LayoutDirection">
<constant name="LAYOUT_DIRECTION_APPLICATION_LOCALE" value="1" enum="LayoutDirection">
Automatic layout direction, determined from the current locale.
</constant>
<constant name="LAYOUT_DIRECTION_LTR" value="2" enum="LayoutDirection">
@ -887,6 +897,14 @@
<constant name="LAYOUT_DIRECTION_RTL" value="3" enum="LayoutDirection">
Right-to-left layout direction.
</constant>
<constant name="LAYOUT_DIRECTION_SYSTEM_LOCALE" value="4" enum="LayoutDirection">
Automatic layout direction, determined from the system locale.
</constant>
<constant name="LAYOUT_DIRECTION_MAX" value="5" enum="LayoutDirection">
Represents the size of the [enum LayoutDirection] enum.
</constant>
<constant name="LAYOUT_DIRECTION_LOCALE" value="1" enum="LayoutDirection" deprecated="Use [constant LAYOUT_DIRECTION_APPLICATION_LOCALE] instead.">
</constant>
<constant name="WINDOW_INITIAL_POSITION_ABSOLUTE" value="0" enum="WindowInitialPosition">
Initial window position is determined by [member position].
</constant>

View File

@ -2003,6 +2003,8 @@ static D3D12_BARRIER_LAYOUT _rd_texture_layout_to_d3d12_barrier_layout(RDD::Text
switch (p_texture_layout) {
case RDD::TEXTURE_LAYOUT_UNDEFINED:
return D3D12_BARRIER_LAYOUT_UNDEFINED;
case RDD::TEXTURE_LAYOUT_GENERAL:
return D3D12_BARRIER_LAYOUT_COMMON;
case RDD::TEXTURE_LAYOUT_STORAGE_OPTIMAL:
return D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS;
case RDD::TEXTURE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
@ -6175,6 +6177,8 @@ uint64_t RenderingDeviceDriverD3D12::api_trait_get(ApiTrait p_trait) {
return false;
case API_TRAIT_CLEARS_WITH_COPY_ENGINE:
return false;
case API_TRAIT_USE_GENERAL_IN_COPY_QUEUES:
return true;
default:
return RenderingDeviceDriver::api_trait_get(p_trait);
}

View File

@ -35,6 +35,7 @@
#include "core/config/project_settings.h"
#include "core/io/dir_access.h"
#include "core/io/image.h"
#include "core/os/os.h"
#include "storage/texture_storage.h"

View File

@ -230,6 +230,32 @@ TextureStorage::TextureStorage() {
sdf_shader.shader_version = sdf_shader.shader.version_create();
}
// Initialize texture placeholder data for the `texture_*_placeholder_initialize()` methods.
constexpr int placeholder_size = 4;
texture_2d_placeholder = Image::create_empty(placeholder_size, placeholder_size, false, Image::FORMAT_RGBA8);
// Draw a magenta/black checkerboard pattern.
for (int i = 0; i < placeholder_size * placeholder_size; i++) {
const int x = i % placeholder_size;
const int y = i / placeholder_size;
texture_2d_placeholder->set_pixel(x, y, (x + y) % 2 == 0 ? Color(1, 0, 1) : Color(0, 0, 0));
}
texture_2d_array_placeholder.push_back(texture_2d_placeholder);
for (int i = 0; i < 6; i++) {
cubemap_placeholder.push_back(texture_2d_placeholder);
}
Ref<Image> texture_2d_placeholder_rotated;
texture_2d_placeholder_rotated.instantiate();
texture_2d_placeholder_rotated->copy_from(texture_2d_placeholder);
texture_2d_placeholder_rotated->rotate_90(CLOCKWISE);
for (int i = 0; i < 4; i++) {
// Alternate checkerboard pattern on odd layers (by using a copy that is rotated 90 degrees).
texture_3d_placeholder.push_back(i % 2 == 0 ? texture_2d_placeholder : texture_2d_placeholder_rotated);
}
#ifdef GL_API_ENABLED
if (RasterizerGLES3::is_gles_over_gl()) {
glEnable(GL_PROGRAM_POINT_SIZE);
@ -1014,46 +1040,19 @@ void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {
}
void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
image->fill(Color(1, 0, 1, 1));
texture_2d_initialize(p_texture, image);
texture_2d_initialize(p_texture, texture_2d_placeholder);
}
void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
image->fill(Color(1, 0, 1, 1));
Vector<Ref<Image>> images;
void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) {
if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {
images.push_back(image);
texture_2d_layered_initialize(p_texture, texture_2d_array_placeholder, p_layered_type);
} else {
//cube
for (int i = 0; i < 6; i++) {
images.push_back(image);
}
texture_2d_layered_initialize(p_texture, cubemap_placeholder, p_layered_type);
}
texture_2d_layered_initialize(p_texture, images, p_layered_type);
}
void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
image->fill(Color(1, 0, 1, 1));
Vector<Ref<Image>> images;
//cube
for (int i = 0; i < 4; i++) {
images.push_back(image);
}
texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, images);
texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, texture_3d_placeholder);
}
Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {

View File

@ -36,6 +36,7 @@
#include "platform_gl.h"
#include "config.h"
#include "core/io/image.h"
#include "core/os/os.h"
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_compositor.h"
@ -521,6 +522,11 @@ public:
virtual void texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override;
virtual void texture_proxy_update(RID p_proxy, RID p_base) override;
Ref<Image> texture_2d_placeholder;
Vector<Ref<Image>> texture_2d_array_placeholder;
Vector<Ref<Image>> cubemap_placeholder;
Vector<Ref<Image>> texture_3d_placeholder;
//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;

View File

@ -96,6 +96,22 @@ _FORCE_INLINE_ ShaderStageUsage &operator|=(ShaderStageUsage &p_a, int p_b) {
return p_a;
}
enum StageResourceUsage : uint32_t {
VertexRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_VERTEX * 2),
VertexWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_VERTEX * 2),
FragmentRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_FRAGMENT * 2),
FragmentWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_FRAGMENT * 2),
TesselationControlRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_TESSELATION_CONTROL * 2),
TesselationControlWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_TESSELATION_CONTROL * 2),
TesselationEvaluationRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_TESSELATION_EVALUATION * 2),
TesselationEvaluationWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_TESSELATION_EVALUATION * 2),
ComputeRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_COMPUTE * 2),
ComputeWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_COMPUTE * 2),
};
typedef LocalVector<__unsafe_unretained id<MTLResource>> ResourceVector;
typedef HashMap<StageResourceUsage, ResourceVector> ResourceUsageMap;
enum class MDCommandBufferStateType {
None,
Render,
@ -230,6 +246,7 @@ public:
uint32_t index_offset = 0;
LocalVector<id<MTLBuffer> __unsafe_unretained> vertex_buffers;
LocalVector<NSUInteger> vertex_offsets;
ResourceUsageMap resource_usage;
// clang-format off
enum DirtyFlag: uint8_t {
DIRTY_NONE = 0b0000'0000,
@ -271,8 +288,14 @@ public:
blend_constants.reset();
vertex_buffers.clear();
vertex_offsets.clear();
// Keep the keys, as they are likely to be used again.
for (KeyValue<StageResourceUsage, LocalVector<__unsafe_unretained id<MTLResource>>> &kv : resource_usage) {
kv.value.clear();
}
}
void end_encoding();
_FORCE_INLINE_ void mark_viewport_dirty() {
if (viewports.is_empty()) {
return;
@ -356,13 +379,20 @@ public:
} render;
// State specific for a compute pass.
struct {
struct ComputeState {
MDComputePipeline *pipeline = nullptr;
id<MTLComputeCommandEncoder> encoder = nil;
ResourceUsageMap resource_usage;
_FORCE_INLINE_ void reset() {
pipeline = nil;
encoder = nil;
// Keep the keys, as they are likely to be used again.
for (KeyValue<StageResourceUsage, LocalVector<__unsafe_unretained id<MTLResource>>> &kv : resource_usage) {
kv.value.clear();
}
}
void end_encoding();
} compute;
// State specific to a blit pass.
@ -632,19 +662,6 @@ public:
MDRenderShader(CharString p_name, Vector<UniformSet> p_sets, MDLibrary *p_vert, MDLibrary *p_frag);
};
enum StageResourceUsage : uint32_t {
VertexRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_VERTEX * 2),
VertexWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_VERTEX * 2),
FragmentRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_FRAGMENT * 2),
FragmentWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_FRAGMENT * 2),
TesselationControlRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_TESSELATION_CONTROL * 2),
TesselationControlWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_TESSELATION_CONTROL * 2),
TesselationEvaluationRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_TESSELATION_EVALUATION * 2),
TesselationEvaluationWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_TESSELATION_EVALUATION * 2),
ComputeRead = (MTLResourceUsageRead << RDD::SHADER_STAGE_COMPUTE * 2),
ComputeWrite = (MTLResourceUsageWrite << RDD::SHADER_STAGE_COMPUTE * 2),
};
_FORCE_INLINE_ StageResourceUsage &operator|=(StageResourceUsage &p_a, uint32_t p_b) {
p_a = StageResourceUsage(uint32_t(p_a) | p_b);
return p_a;
@ -667,7 +684,13 @@ struct HashMapComparatorDefault<RDD::ShaderID> {
struct BoundUniformSet {
id<MTLBuffer> buffer;
HashMap<id<MTLResource>, StageResourceUsage> bound_resources;
ResourceUsageMap usage_to_resources;
/// Perform a 2-way merge each key of `ResourceVector` resources from this set into the
/// destination set.
///
/// Assumes the vectors of resources are sorted.
void merge_into(ResourceUsageMap &p_dst) const;
};
class API_AVAILABLE(macos(11.0), ios(14.0)) MDUniformSet {

View File

@ -58,7 +58,7 @@
void MDCommandBuffer::begin() {
DEV_ASSERT(commandBuffer == nil);
commandBuffer = queue.commandBuffer;
commandBuffer = queue.commandBufferWithUnretainedReferences;
}
void MDCommandBuffer::end() {
@ -390,6 +390,38 @@ void MDCommandBuffer::render_set_blend_constants(const Color &p_constants) {
}
}
void BoundUniformSet::merge_into(ResourceUsageMap &p_dst) const {
for (KeyValue<StageResourceUsage, ResourceVector> const &keyval : usage_to_resources) {
ResourceVector *resources = p_dst.getptr(keyval.key);
if (resources == nullptr) {
resources = &p_dst.insert(keyval.key, ResourceVector())->value;
}
// Reserve space for the new resources, assuming they are all added.
resources->reserve(resources->size() + keyval.value.size());
uint32_t i = 0, j = 0;
__unsafe_unretained id<MTLResource> *resources_ptr = resources->ptr();
const __unsafe_unretained id<MTLResource> *keyval_ptr = keyval.value.ptr();
// 2-way merge.
while (i < resources->size() && j < keyval.value.size()) {
if (resources_ptr[i] < keyval_ptr[j]) {
i++;
} else if (resources_ptr[i] > keyval_ptr[j]) {
resources->insert(i, keyval_ptr[j]);
i++;
j++;
} else {
i++;
j++;
}
}
// Append the remaining resources.
for (; j < keyval.value.size(); j++) {
resources->push_back(keyval_ptr[j]);
}
}
}
void MDCommandBuffer::_render_bind_uniform_sets() {
DEV_ASSERT(type == MDCommandBufferStateType::Render);
if (!render.dirty.has_flag(RenderState::DIRTY_UNIFORMS)) {
@ -408,7 +440,7 @@ void MDCommandBuffer::_render_bind_uniform_sets() {
// Find the index of the next set bit.
int index = __builtin_ctzll(set_uniforms);
// Clear the set bit.
set_uniforms &= ~(1ULL << index);
set_uniforms &= (set_uniforms - 1);
MDUniformSet *set = render.uniform_sets[index];
if (set == nullptr || set->index >= (uint32_t)shader->sets.size()) {
continue;
@ -416,17 +448,7 @@ void MDCommandBuffer::_render_bind_uniform_sets() {
UniformSet const &set_info = shader->sets[set->index];
BoundUniformSet &bus = set->boundUniformSetForShader(shader, device);
for (KeyValue<id<MTLResource>, StageResourceUsage> const &keyval : bus.bound_resources) {
MTLResourceUsage usage = resource_usage_for_stage(keyval.value, RDD::ShaderStage::SHADER_STAGE_VERTEX);
if (usage != 0) {
[enc useResource:keyval.key usage:usage stages:MTLRenderStageVertex];
}
usage = resource_usage_for_stage(keyval.value, RDD::ShaderStage::SHADER_STAGE_FRAGMENT);
if (usage != 0) {
[enc useResource:keyval.key usage:usage stages:MTLRenderStageFragment];
}
}
bus.merge_into(render.resource_usage);
// Set the buffer for the vertex stage.
{
@ -545,8 +567,7 @@ void MDCommandBuffer::_end_render_pass() {
// see: https://github.com/KhronosGroup/MoltenVK/blob/d20d13fe2735adb845636a81522df1b9d89c0fba/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm#L407
}
[render.encoder endEncoding];
render.encoder = nil;
render.end_encoding();
}
void MDCommandBuffer::_render_clear_render_area() {
@ -792,10 +813,59 @@ void MDCommandBuffer::render_draw_indirect_count(RDD::BufferID p_indirect_buffer
ERR_FAIL_MSG("not implemented");
}
void MDCommandBuffer::RenderState::end_encoding() {
if (encoder == nil) {
return;
}
// Bind all resources.
for (KeyValue<StageResourceUsage, ResourceVector> const &keyval : resource_usage) {
if (keyval.value.is_empty()) {
continue;
}
MTLResourceUsage vert_usage = resource_usage_for_stage(keyval.key, RDD::ShaderStage::SHADER_STAGE_VERTEX);
MTLResourceUsage frag_usage = resource_usage_for_stage(keyval.key, RDD::ShaderStage::SHADER_STAGE_FRAGMENT);
if (vert_usage == frag_usage) {
[encoder useResources:keyval.value.ptr() count:keyval.value.size() usage:vert_usage stages:MTLRenderStageVertex | MTLRenderStageFragment];
} else {
if (vert_usage != 0) {
[encoder useResources:keyval.value.ptr() count:keyval.value.size() usage:vert_usage stages:MTLRenderStageVertex];
}
if (frag_usage != 0) {
[encoder useResources:keyval.value.ptr() count:keyval.value.size() usage:frag_usage stages:MTLRenderStageFragment];
}
}
}
[encoder endEncoding];
encoder = nil;
}
void MDCommandBuffer::ComputeState::end_encoding() {
if (encoder == nil) {
return;
}
// Bind all resources.
for (KeyValue<StageResourceUsage, ResourceVector> const &keyval : resource_usage) {
if (keyval.value.is_empty()) {
continue;
}
MTLResourceUsage usage = resource_usage_for_stage(keyval.key, RDD::ShaderStage::SHADER_STAGE_COMPUTE);
if (usage != 0) {
[encoder useResources:keyval.value.ptr() count:keyval.value.size() usage:usage];
}
}
[encoder endEncoding];
encoder = nil;
}
void MDCommandBuffer::render_end_pass() {
DEV_ASSERT(type == MDCommandBufferStateType::Render);
[render.encoder endEncoding];
render.end_encoding();
render.reset();
type = MDCommandBufferStateType::None;
}
@ -813,13 +883,7 @@ void MDCommandBuffer::compute_bind_uniform_set(RDD::UniformSetID p_uniform_set,
MDUniformSet *set = (MDUniformSet *)(p_uniform_set.id);
BoundUniformSet &bus = set->boundUniformSetForShader(shader, device);
for (KeyValue<id<MTLResource>, StageResourceUsage> &keyval : bus.bound_resources) {
MTLResourceUsage usage = resource_usage_for_stage(keyval.value, RDD::ShaderStage::SHADER_STAGE_COMPUTE);
if (usage != 0) {
[enc useResource:keyval.key usage:usage];
}
}
bus.merge_into(compute.resource_usage);
uint32_t const *offset = set_info.offsets.getptr(RDD::SHADER_STAGE_COMPUTE);
if (offset) {
@ -848,7 +912,7 @@ void MDCommandBuffer::compute_dispatch_indirect(RDD::BufferID p_indirect_buffer,
void MDCommandBuffer::_end_compute_dispatch() {
DEV_ASSERT(type == MDCommandBufferStateType::Compute);
[compute.encoder endEncoding];
compute.end_encoding();
compute.reset();
type = MDCommandBufferStateType::None;
}
@ -1052,7 +1116,20 @@ BoundUniformSet &MDUniformSet::boundUniformSetForShader(MDShader *p_shader, id<M
}
}
BoundUniformSet bs = { .buffer = enc_buffer, .bound_resources = bound_resources };
SearchArray<__unsafe_unretained id<MTLResource>> search;
ResourceUsageMap usage_to_resources;
for (KeyValue<id<MTLResource>, StageResourceUsage> const &keyval : bound_resources) {
ResourceVector *resources = usage_to_resources.getptr(keyval.value);
if (resources == nullptr) {
resources = &usage_to_resources.insert(keyval.value, ResourceVector())->value;
}
int64_t pos = search.bisect(resources->ptr(), resources->size(), keyval.key, true);
if (pos == resources->size() || (*resources)[pos] != keyval.key) {
resources->insert(pos, keyval.key);
}
}
BoundUniformSet bs = { .buffer = enc_buffer, .usage_to_resources = usage_to_resources };
bound_uniforms.insert(p_shader, bs);
return bound_uniforms.get(p_shader);
}
@ -1211,8 +1288,7 @@ vertex VaryingsPos vertClear(AttributesPos attributes [[stage_in]], constant Cle
varyings.layer = uint(attributes.a_position.w);
return varyings;
}
)",
ClearAttKey::DEPTH_INDEX];
)", ClearAttKey::DEPTH_INDEX];
return new_func(msl, @"vertClear", nil);
}

View File

@ -2060,6 +2060,10 @@ Vector<uint8_t> RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec
case BT::Sampler: {
primary.dataType = MTLDataTypeSampler;
primary.arrayLength = 1;
for (uint32_t const &a : a_type.array) {
primary.arrayLength *= a;
}
} break;
default: {
@ -2067,7 +2071,7 @@ Vector<uint8_t> RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec
} break;
}
// Find array length.
// Find array length of image.
if (basetype == BT::Image || basetype == BT::SampledImage) {
primary.arrayLength = 1;
for (uint32_t const &a : a_type.array) {

View File

@ -266,6 +266,7 @@ static const VkFormat RD_TO_VK_FORMAT[RDD::DATA_FORMAT_MAX] = {
static VkImageLayout RD_TO_VK_LAYOUT[RDD::TEXTURE_LAYOUT_MAX] = {
VK_IMAGE_LAYOUT_UNDEFINED, // TEXTURE_LAYOUT_UNDEFINED
VK_IMAGE_LAYOUT_GENERAL, // TEXTURE_LAYOUT_GENERAL
VK_IMAGE_LAYOUT_GENERAL, // TEXTURE_LAYOUT_STORAGE_OPTIMAL
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // TEXTURE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
@ -2636,11 +2637,13 @@ bool RenderingDeviceDriverVulkan::command_buffer_begin(CommandBufferID p_cmd_buf
bool RenderingDeviceDriverVulkan::command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) {
// Reset is implicit (VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT).
Framebuffer *framebuffer = (Framebuffer *)(p_framebuffer.id);
VkCommandBufferInheritanceInfo inheritance_info = {};
inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
inheritance_info.renderPass = (VkRenderPass)p_render_pass.id;
inheritance_info.subpass = p_subpass;
inheritance_info.framebuffer = (VkFramebuffer)p_framebuffer.id;
inheritance_info.framebuffer = framebuffer->vk_framebuffer;
VkCommandBufferBeginInfo cmd_buf_begin_info = {};
cmd_buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@ -2950,12 +2953,16 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
fb_create_info.height = surface->height;
fb_create_info.layers = 1;
VkFramebuffer framebuffer;
VkFramebuffer vk_framebuffer;
for (uint32_t i = 0; i < image_count; i++) {
fb_create_info.pAttachments = &swap_chain->image_views[i];
err = vkCreateFramebuffer(vk_device, &fb_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER), &framebuffer);
err = vkCreateFramebuffer(vk_device, &fb_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER), &vk_framebuffer);
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
Framebuffer *framebuffer = memnew(Framebuffer);
framebuffer->vk_framebuffer = vk_framebuffer;
framebuffer->swap_chain_image = swap_chain->images[i];
framebuffer->swap_chain_image_subresource_range = view_create_info.subresourceRange;
swap_chain->framebuffers.push_back(RDD::FramebufferID(framebuffer));
}
@ -3024,7 +3031,10 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::swap_chain_acquire_framebuffer(C
command_queue->pending_semaphores_for_fence.push_back(semaphore_index);
// Return the corresponding framebuffer to the new current image.
return swap_chain->framebuffers[swap_chain->image_index];
FramebufferID framebuffer_id = swap_chain->framebuffers[swap_chain->image_index];
Framebuffer *framebuffer = (Framebuffer *)(framebuffer_id.id);
framebuffer->swap_chain_acquired = true;
return framebuffer_id;
}
RDD::RenderPassID RenderingDeviceDriverVulkan::swap_chain_get_render_pass(SwapChainID p_swap_chain) {
@ -3093,11 +3103,15 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::framebuffer_create(RenderPassID
}
#endif
return FramebufferID(vk_framebuffer);
Framebuffer *framebuffer = memnew(Framebuffer);
framebuffer->vk_framebuffer = vk_framebuffer;
return FramebufferID(framebuffer);
}
void RenderingDeviceDriverVulkan::framebuffer_free(FramebufferID p_framebuffer) {
vkDestroyFramebuffer(vk_device, (VkFramebuffer)p_framebuffer.id, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER));
Framebuffer *framebuffer = (Framebuffer *)(p_framebuffer.id);
vkDestroyFramebuffer(vk_device, framebuffer->vk_framebuffer, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER));
memdelete(framebuffer);
}
/****************/
@ -4315,10 +4329,25 @@ void RenderingDeviceDriverVulkan::render_pass_free(RenderPassID p_render_pass) {
static_assert(ARRAYS_COMPATIBLE_FIELDWISE(RDD::RenderPassClearValue, VkClearValue));
void RenderingDeviceDriverVulkan::command_begin_render_pass(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, FramebufferID p_framebuffer, CommandBufferType p_cmd_buffer_type, const Rect2i &p_rect, VectorView<RenderPassClearValue> p_clear_values) {
Framebuffer *framebuffer = (Framebuffer *)(p_framebuffer.id);
if (framebuffer->swap_chain_acquired) {
// Insert a barrier to wait for the acquisition of the framebuffer before the render pass begins.
VkImageMemoryBarrier image_barrier = {};
image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
image_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_barrier.image = framebuffer->swap_chain_image;
image_barrier.subresourceRange = framebuffer->swap_chain_image_subresource_range;
vkCmdPipelineBarrier((VkCommandBuffer)p_cmd_buffer.id, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_barrier);
framebuffer->swap_chain_acquired = false;
}
VkRenderPassBeginInfo render_pass_begin = {};
render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
render_pass_begin.renderPass = (VkRenderPass)p_render_pass.id;
render_pass_begin.framebuffer = (VkFramebuffer)p_framebuffer.id;
render_pass_begin.framebuffer = framebuffer->vk_framebuffer;
render_pass_begin.renderArea.offset.x = p_rect.position.x;
render_pass_begin.renderArea.offset.y = p_rect.position.y;

View File

@ -366,6 +366,15 @@ public:
/**** FRAMEBUFFER ****/
/*********************/
struct Framebuffer {
VkFramebuffer vk_framebuffer = VK_NULL_HANDLE;
// Only filled in by a framebuffer created by a swap chain. Unused otherwise.
VkImage swap_chain_image = VK_NULL_HANDLE;
VkImageSubresourceRange swap_chain_image_subresource_range = {};
bool swap_chain_acquired = false;
};
virtual FramebufferID framebuffer_create(RenderPassID p_render_pass, VectorView<TextureID> p_attachments, uint32_t p_width, uint32_t p_height) override final;
virtual void framebuffer_free(FramebufferID p_framebuffer) override final;

View File

@ -1501,11 +1501,6 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
box_selection_to = mm->get_position();
if (get_local_mouse_position().y < 0) {
// Avoid cursor from going too above, so it does not lose focus with viewport.
warp_mouse(Vector2(get_local_mouse_position().x, 0));
}
queue_redraw();
}

View File

@ -8763,7 +8763,7 @@ void AnimationMarkerEdit::_move_selection_commit() {
void AnimationMarkerEdit::_delete_selected_markers() {
if (selection.size()) {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Animation Delete Keys"));
undo_redo->create_action(TTR("Animation Delete Markers"));
for (const StringName &name : selection) {
double time = animation->get_marker_time(name);
undo_redo->add_do_method(animation.ptr(), "remove_marker", name);
@ -8967,7 +8967,7 @@ AnimationMarkerEdit::AnimationMarkerEdit() {
add_child(menu);
menu->connect(SceneStringName(id_pressed), callable_mp(this, &AnimationMarkerEdit::_menu_selected));
menu->add_shortcut(ED_SHORTCUT("animation_marker_edit/rename_marker", TTR("Rename Marker"), Key::R), MENU_KEY_RENAME);
menu->add_shortcut(ED_SHORTCUT("animation_marker_edit/delete_selection", TTR("Delete Markers (s)"), Key::KEY_DELETE), MENU_KEY_DELETE);
menu->add_shortcut(ED_SHORTCUT("animation_marker_edit/delete_selection", TTR("Delete Marker(s)"), Key::KEY_DELETE), MENU_KEY_DELETE);
menu->add_shortcut(ED_SHORTCUT("animation_marker_edit/toggle_marker_names", TTR("Show All Marker Names"), Key::M), MENU_KEY_TOGGLE_MARKER_NAMES);
marker_insert_confirm = memnew(ConfirmationDialog);

View File

@ -277,11 +277,14 @@ Variant EditorDebuggerTree::get_drag_data(const Point2 &p_point) {
}
String path = selected->get_text(0);
const int icon_size = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));
HBoxContainer *hb = memnew(HBoxContainer);
TextureRect *tf = memnew(TextureRect);
tf->set_texture(selected->get_icon(0));
tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
tf->set_custom_minimum_size(Size2(icon_size, icon_size));
tf->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
tf->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE);
hb->add_child(tf);
Label *label = memnew(Label(path));
hb->add_child(label);

View File

@ -30,6 +30,7 @@
#include "editor_profiler.h"
#include "core/io/image.h"
#include "core/os/os.h"
#include "editor/editor_settings.h"
#include "editor/editor_string_names.h"

View File

@ -30,6 +30,7 @@
#include "editor_visual_profiler.h"
#include "core/io/image.h"
#include "core/os/os.h"
#include "editor/editor_settings.h"
#include "editor/editor_string_names.h"
@ -437,11 +438,7 @@ void EditorVisualProfiler::_notification(int p_what) {
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED: {
if (is_layout_rtl()) {
activate->set_icon(get_editor_theme_icon(SNAME("PlayBackwards")));
} else {
activate->set_icon(get_editor_theme_icon(SNAME("Play")));
}
activate->set_icon(get_editor_theme_icon(SNAME("Play")));
clear_button->set_icon(get_editor_theme_icon(SNAME("Clear")));
} break;
}

View File

@ -248,11 +248,16 @@ void EditorFileSystem::_first_scan_filesystem() {
ep.step(TTR("Scanning file structure..."), 0, true);
nb_files_total = _scan_new_dir(first_scan_root_dir, d);
// Preloading GDExtensions file extensions to prevent looping on all the resource loaders
// for each files in _first_scan_process_scripts.
List<String> gdextension_extensions;
ResourceLoader::get_recognized_extensions_for_type("GDExtension", &gdextension_extensions);
// This loads the global class names from the scripts and ensures that even if the
// global_script_class_cache.cfg was missing or invalid, the global class names are valid in ScriptServer.
// At the same time, to prevent looping multiple times in all files, it looks for extensions.
ep.step(TTR("Loading global class names..."), 1, true);
_first_scan_process_scripts(first_scan_root_dir, existing_class_names, extensions);
_first_scan_process_scripts(first_scan_root_dir, gdextension_extensions, existing_class_names, extensions);
// Removing invalid global class to prevent having invalid paths in ScriptServer.
_remove_invalid_global_class_names(existing_class_names);
@ -276,16 +281,16 @@ void EditorFileSystem::_first_scan_filesystem() {
ep.step(TTR("Starting file scan..."), 5, true);
}
void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_scan_dir, HashSet<String> &p_existing_class_names, HashSet<String> &p_extensions) {
void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_scan_dir, List<String> &p_gdextension_extensions, HashSet<String> &p_existing_class_names, HashSet<String> &p_extensions) {
for (ScannedDirectory *scan_sub_dir : p_scan_dir->subdirs) {
_first_scan_process_scripts(scan_sub_dir, p_existing_class_names, p_extensions);
_first_scan_process_scripts(scan_sub_dir, p_gdextension_extensions, p_existing_class_names, p_extensions);
}
for (const String &scan_file : p_scan_dir->files) {
// Optimization to skip the ResourceLoader::get_resource_type for files
// that are not scripts. Some loader get_resource_type methods read the file
// which can be very slow on large projects.
String ext = scan_file.get_extension().to_lower();
const String ext = scan_file.get_extension().to_lower();
bool is_script = false;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
if (ScriptServer::get_language(i)->get_extension() == ext) {
@ -293,24 +298,29 @@ void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_sca
break;
}
}
if (!is_script) {
continue; // Not a script.
if (is_script) {
const String path = p_scan_dir->full_path.path_join(scan_file);
const String type = ResourceLoader::get_resource_type(path);
if (ClassDB::is_parent_class(type, SNAME("Script"))) {
String script_class_extends;
String script_class_icon_path;
String script_class_name = _get_global_script_class(type, path, &script_class_extends, &script_class_icon_path);
_register_global_class_script(path, path, type, script_class_name, script_class_extends, script_class_icon_path);
if (!script_class_name.is_empty()) {
p_existing_class_names.insert(script_class_name);
}
}
}
String path = p_scan_dir->full_path.path_join(scan_file);
String type = ResourceLoader::get_resource_type(path);
if (ClassDB::is_parent_class(type, SNAME("Script"))) {
String script_class_extends;
String script_class_icon_path;
String script_class_name = _get_global_script_class(type, path, &script_class_extends, &script_class_icon_path);
_register_global_class_script(path, path, type, script_class_name, script_class_extends, script_class_icon_path);
if (!script_class_name.is_empty()) {
p_existing_class_names.insert(script_class_name);
// Check for GDExtensions.
if (p_gdextension_extensions.find(ext)) {
const String path = p_scan_dir->full_path.path_join(scan_file);
const String type = ResourceLoader::get_resource_type(path);
if (type == SNAME("GDExtension")) {
p_extensions.insert(path);
}
} else if (type == SNAME("GDExtension")) {
p_extensions.insert(path);
}
}
}

View File

@ -191,7 +191,7 @@ class EditorFileSystem : public Node {
void _scan_filesystem();
void _first_scan_filesystem();
void _first_scan_process_scripts(const ScannedDirectory *p_scan_dir, HashSet<String> &p_existing_class_names, HashSet<String> &p_extensions);
void _first_scan_process_scripts(const ScannedDirectory *p_scan_dir, List<String> &p_gdextension_extensions, HashSet<String> &p_existing_class_names, HashSet<String> &p_extensions);
HashSet<String> late_update_files;

View File

@ -93,6 +93,10 @@ EditorUndoRedoManager *EditorInterface::get_editor_undo_redo() const {
return EditorUndoRedoManager::get_singleton();
}
EditorExport *EditorInterface::get_editor_export() const {
return EditorExport::get_singleton();
}
TypedArray<Texture2D> EditorInterface::_make_mesh_previews(const TypedArray<Mesh> &p_meshes, int p_preview_size) {
Vector<Ref<Mesh>> meshes;
@ -557,6 +561,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_selection"), &EditorInterface::get_selection);
ClassDB::bind_method(D_METHOD("get_editor_settings"), &EditorInterface::get_editor_settings);
ClassDB::bind_method(D_METHOD("get_editor_undo_redo"), &EditorInterface::get_editor_undo_redo);
ClassDB::bind_method(D_METHOD("get_editor_export"), &EditorInterface::get_editor_export);
ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews);

View File

@ -46,6 +46,7 @@ class EditorResourcePreview;
class EditorSelection;
class EditorSettings;
class EditorUndoRedoManager;
class EditorExport;
class FileSystemDock;
class Mesh;
class Node;
@ -103,6 +104,7 @@ public:
EditorSelection *get_selection() const;
Ref<EditorSettings> get_editor_settings() const;
EditorUndoRedoManager *get_editor_undo_redo() const;
EditorExport *get_editor_export() const;
Vector<Ref<Texture2D>> make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform3D> *p_transforms, int p_preview_size);

View File

@ -35,6 +35,7 @@
#include "core/input/input.h"
#include "core/io/config_file.h"
#include "core/io/file_access.h"
#include "core/io/image.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/object/class_db.h"
@ -4771,7 +4772,13 @@ Ref<Texture2D> EditorNode::_get_class_or_script_icon(const String &p_class, cons
// Look for the native base type in the editor theme. This is relevant for
// scripts extending other scripts and for built-in classes.
String script_class_name = p_script->get_language()->get_global_class_name(p_script->get_path());
String base_type = ScriptServer::get_global_class_native_base(script_class_name);
String base_type;
if (script_class_name.is_empty()) {
base_type = p_script->get_instance_base_type();
} else {
base_type = ScriptServer::get_global_class_native_base(script_class_name);
}
if (theme.is_valid() && theme->has_icon(base_type, EditorStringName(EditorIcons))) {
return theme->get_icon(base_type, EditorStringName(EditorIcons));
}
@ -4836,6 +4843,8 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p
Ref<Script> scr;
if (ScriptServer::is_global_class(p_class)) {
scr = EditorNode::get_editor_data().script_class_load_script(p_class);
} else if (ResourceLoader::exists(p_class)) { // If the script is not a class_name we check if the script resource exists.
scr = ResourceLoader::load(p_class);
}
return _get_class_or_script_icon(p_class, scr, p_fallback, true);

View File

@ -121,7 +121,7 @@ String EventListenerLineEdit::get_event_text(const Ref<InputEvent> &p_event, boo
}
String EventListenerLineEdit::get_device_string(int p_device) {
if (p_device == InputMap::ALL_DEVICES) {
if (p_device == InputEvent::DEVICE_ID_ALL_DEVICES) {
return TTR("All Devices");
}
return TTR("Device") + " " + itos(p_device);

View File

@ -120,8 +120,16 @@ void EditorExport::emit_presets_runnable_changed() {
}
void EditorExport::_bind_methods() {
_export_presets_updated = StringName("export_presets_updated", true);
_export_presets_runnable_updated = StringName("export_presets_runnable_updated", true);
ADD_SIGNAL(MethodInfo(_export_presets_updated));
ADD_SIGNAL(MethodInfo(_export_presets_runnable_updated));
ClassDB::bind_method(D_METHOD("get_export_platform_count"), &EditorExport::get_export_platform_count);
ClassDB::bind_method(D_METHOD("get_export_platform", "idx"), &EditorExport::get_export_platform);
ClassDB::bind_method(D_METHOD("get_export_preset_count"), &EditorExport::get_export_preset_count);
ClassDB::bind_method(D_METHOD("get_export_preset", "idx"), &EditorExport::get_export_preset);
}
void EditorExport::add_export_platform(const Ref<EditorExportPlatform> &p_platform) {
@ -139,7 +147,7 @@ void EditorExport::remove_export_platform(const Ref<EditorExportPlatform> &p_pla
should_reload_presets = true;
}
int EditorExport::get_export_platform_count() {
int EditorExport::get_export_platform_count() const {
return export_platforms.size();
}
@ -442,9 +450,6 @@ EditorExport::EditorExport() {
save_timer->set_one_shot(true);
save_timer->connect("timeout", callable_mp(this, &EditorExport::_save));
_export_presets_updated = StringName("export_presets_updated", true);
_export_presets_runnable_updated = StringName("export_presets_runnable_updated", true);
singleton = this;
set_process(true);
}

View File

@ -65,7 +65,7 @@ public:
static EditorExport *get_singleton() { return singleton; }
void add_export_platform(const Ref<EditorExportPlatform> &p_platform);
int get_export_platform_count();
int get_export_platform_count() const;
Ref<EditorExportPlatform> get_export_platform(int p_idx);
void remove_export_platform(const Ref<EditorExportPlatform> &p_platform);

View File

@ -326,11 +326,7 @@ Error EditorExportPlatform::_save_zip_patch_file(void *p_userdata, const String
Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const {
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
ERR_FAIL_COND_V(theme.is_null(), Ref<ImageTexture>());
if (EditorNode::get_singleton()->get_gui_base()->is_layout_rtl()) {
return theme->get_icon(SNAME("PlayBackwards"), EditorStringName(EditorIcons));
} else {
return theme->get_icon(SNAME("Play"), EditorStringName(EditorIcons));
}
return theme->get_icon(SNAME("Play"), EditorStringName(EditorIcons));
}
String EditorExportPlatform::find_export_template(const String &template_file_name, String *err) const {
@ -534,6 +530,26 @@ HashSet<String> EditorExportPlatform::get_features(const Ref<EditorExportPreset>
return result;
}
TypedArray<String> EditorExportPlatform::get_platform_features_as_array() const {
List<String> feature_list;
get_platform_features(&feature_list);
TypedArray<String> result;
for (const String &E : feature_list) {
result.push_back(E);
}
return result;
}
TypedArray<String> EditorExportPlatform::get_preset_features_as_array(const Ref<EditorExportPreset> &p_preset) const {
List<String> feature_list;
get_preset_features(p_preset, &feature_list);
TypedArray<String> result;
for (const String &E : feature_list) {
result.push_back(E);
}
return result;
}
EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
HashSet<String> features = p_platform.get_features(p_preset, p_debug);
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
@ -2299,6 +2315,9 @@ void EditorExportPlatform::_bind_methods() {
ClassDB::bind_method(D_METHOD("ssh_run_on_remote_no_wait", "host", "port", "ssh_args", "cmd_args", "port_fwd"), &EditorExportPlatform::_ssh_run_on_remote_no_wait, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("ssh_push_to_remote", "host", "port", "scp_args", "src_file", "dst_file"), &EditorExportPlatform::ssh_push_to_remote);
ClassDB::bind_method(D_METHOD("get_platform_features"), &EditorExportPlatform::get_platform_features_as_array);
ClassDB::bind_method(D_METHOD("get_preset_features", "preset"), &EditorExportPlatform::get_preset_features_as_array);
ClassDB::bind_static_method("EditorExportPlatform", D_METHOD("get_forced_export_files"), &EditorExportPlatform::get_forced_export_files);
BIND_ENUM_CONSTANT(EXPORT_MESSAGE_NONE);

View File

@ -197,6 +197,8 @@ protected:
void _unload_patches();
public:
TypedArray<String> get_platform_features_as_array() const;
TypedArray<String> get_preset_features_as_array(const Ref<EditorExportPreset> &p_preset) const;
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const = 0;
struct ExportOption {

View File

@ -65,6 +65,8 @@ void EditorExportPreset::_bind_methods() {
ClassDB::bind_method(D_METHOD("has", "property"), &EditorExportPreset::has);
ClassDB::bind_method(D_METHOD("get_platform"), &EditorExportPreset::get_platform);
ClassDB::bind_method(D_METHOD("get_files_to_export"), &EditorExportPreset::get_files_to_export);
ClassDB::bind_method(D_METHOD("get_customized_files"), &EditorExportPreset::get_customized_files);
ClassDB::bind_method(D_METHOD("get_customized_files_count"), &EditorExportPreset::get_customized_files_count);

View File

@ -1355,6 +1355,13 @@ EditorFileDialog::Access EditorFileDialog::get_access() const {
void EditorFileDialog::_make_dir_confirm() {
const String stripped_dirname = makedirname->get_text().strip_edges();
if (stripped_dirname.is_empty()) {
error_dialog->set_text(TTR("The path specified is invalid."));
error_dialog->popup_centered(Size2(250, 50) * EDSCALE);
makedirname->set_text(""); // Reset label.
return;
}
if (dir_access->dir_exists(stripped_dirname)) {
error_dialog->set_text(TTR("Could not create folder. File with that name already exists."));
error_dialog->popup_centered(Size2(250, 50) * EDSCALE);
@ -1638,6 +1645,7 @@ void EditorFileDialog::_update_favorites() {
for (int i = 0; i < favorited_paths.size(); i++) {
favorites->add_item(favorited_names[i], theme_cache.folder);
favorites->set_item_tooltip(-1, favorited_paths[i]);
favorites->set_item_metadata(-1, favorited_paths[i]);
favorites->set_item_icon_modulate(-1, get_dir_icon_color(favorited_paths[i]));
@ -1719,6 +1727,7 @@ void EditorFileDialog::_update_recent() {
for (int i = 0; i < recentd_paths.size(); i++) {
recent->add_item(recentd_names[i], theme_cache.folder);
recent->set_item_tooltip(-1, recentd_paths[i]);
recent->set_item_metadata(-1, recentd_paths[i]);
recent->set_item_icon_modulate(-1, get_dir_icon_color(recentd_paths[i]));
}

View File

@ -30,6 +30,7 @@
#include "editor_object_selector.h"
#include "editor/debugger/editor_debugger_inspector.h"
#include "editor/editor_data.h"
#include "editor/editor_node.h"
#include "editor/editor_string_names.h"
@ -131,6 +132,19 @@ void EditorObjectSelector::update_path() {
Ref<Texture2D> obj_icon;
if (Object::cast_to<MultiNodeEdit>(obj)) {
obj_icon = EditorNode::get_singleton()->get_class_icon(Object::cast_to<MultiNodeEdit>(obj)->get_edited_class_name());
} else if (Object::cast_to<EditorDebuggerRemoteObject>(obj)) {
String class_name;
Ref<Script> base_script = obj->get_script();
if (base_script.is_valid()) {
class_name = base_script->get_global_name();
if (class_name.is_empty()) {
// If there is no class_name in this script we just take the script path.
class_name = base_script->get_path();
}
}
obj_icon = EditorNode::get_singleton()->get_class_icon(class_name.is_empty() ? Object::cast_to<EditorDebuggerRemoteObject>(obj)->type_name : class_name);
} else {
obj_icon = EditorNode::get_singleton()->get_object_icon(obj);
}

View File

@ -96,7 +96,7 @@ struct UniRange {
};
// Unicode Character Blocks
// Source: https://www.unicode.org/Public/14.0.0/ucd/Blocks.txt
// Source: https://www.unicode.org/Public/16.0.0/ucd/Blocks.txt
static UniRange unicode_ranges[] = {
{ 0x0000, 0x007F, U"Basic Latin" },
{ 0x0080, 0x00FF, U"Latin-1 Supplement" },
@ -283,6 +283,7 @@ static UniRange unicode_ranges[] = {
{ 0x10500, 0x1052F, U"Elbasan" },
{ 0x10530, 0x1056F, U"Caucasian Albanian" },
{ 0x10570, 0x105BF, U"Vithkuqi" },
{ 0x105C0, 0x105FF, U"Todhri" },
{ 0x10600, 0x1077F, U"Linear A" },
{ 0x10780, 0x107BF, U"Latin Extended-F" },
{ 0x10800, 0x1083F, U"Cypriot Syllabary" },
@ -305,6 +306,7 @@ static UniRange unicode_ranges[] = {
{ 0x10C00, 0x10C4F, U"Old Turkic" },
{ 0x10C80, 0x10CFF, U"Old Hungarian" },
{ 0x10D00, 0x10D3F, U"Hanifi Rohingya" },
{ 0x10D40, 0x10D8F, U"Garay" },
{ 0x10E60, 0x10E7F, U"Rumi Numeral Symbols" },
{ 0x10E80, 0x10EBF, U"Yezidi" },
{ 0x10EC0, 0x10EFF, U"Arabic Extended-C" },
@ -324,12 +326,14 @@ static UniRange unicode_ranges[] = {
{ 0x11280, 0x112AF, U"Multani" },
{ 0x112B0, 0x112FF, U"Khudawadi" },
{ 0x11300, 0x1137F, U"Grantha" },
{ 0x11380, 0x113FF, U"Tulu-Tigalari" },
{ 0x11400, 0x1147F, U"Newa" },
{ 0x11480, 0x114DF, U"Tirhuta" },
{ 0x11580, 0x115FF, U"Siddham" },
{ 0x11600, 0x1165F, U"Modi" },
{ 0x11660, 0x1167F, U"Mongolian Supplement" },
{ 0x11680, 0x116CF, U"Takri" },
{ 0x116D0, 0x116FF, U"Myanmar Extended-C" },
{ 0x11700, 0x1174F, U"Ahom" },
{ 0x11800, 0x1184F, U"Dogra" },
{ 0x118A0, 0x118FF, U"Warang Citi" },
@ -340,6 +344,7 @@ static UniRange unicode_ranges[] = {
{ 0x11AB0, 0x11ABF, U"Unified Canadian Aboriginal Syllabics Extended-A" },
{ 0x11AC0, 0x11AFF, U"Pau Cin Hau" },
{ 0x11B00, 0x11B5F, U"Devanagari Extended-A" },
{ 0x11BC0, 0x11BFF, U"Sunuwar" },
{ 0x11C00, 0x11C6F, U"Bhaiksuki" },
{ 0x11C70, 0x11CBF, U"Marchen" },
{ 0x11D00, 0x11D5F, U"Masaram Gondi" },
@ -354,12 +359,15 @@ static UniRange unicode_ranges[] = {
{ 0x12F90, 0x12FFF, U"Cypro-Minoan" },
{ 0x13000, 0x1342F, U"Egyptian Hieroglyphs" },
{ 0x13430, 0x1343F, U"Egyptian Hieroglyph Format Controls" },
{ 0x13460, 0x143FF, U"Egyptian Hieroglyphs Extended-A" },
{ 0x14400, 0x1467F, U"Anatolian Hieroglyphs" },
{ 0x16100, 0x1613F, U"Gurung Khema" },
{ 0x16800, 0x16A3F, U"Bamum Supplement" },
{ 0x16A40, 0x16A6F, U"Mro" },
{ 0x16A70, 0x16ACF, U"Tangsa" },
{ 0x16AD0, 0x16AFF, U"Bassa Vah" },
{ 0x16B00, 0x16B8F, U"Pahawh Hmong" },
{ 0x16D40, 0x16D7F, U"Kirat Rai" },
{ 0x16E40, 0x16E9F, U"Medefaidrin" },
{ 0x16F00, 0x16F9F, U"Miao" },
{ 0x16FE0, 0x16FFF, U"Ideographic Symbols and Punctuation" },
@ -374,6 +382,7 @@ static UniRange unicode_ranges[] = {
{ 0x1B170, 0x1B2FF, U"Nushu" },
{ 0x1BC00, 0x1BC9F, U"Duployan" },
{ 0x1BCA0, 0x1BCAF, U"Shorthand Format Controls" },
{ 0x1CC00, 0x1CEBF, U"Symbols for Legacy Computing Supplement" },
{ 0x1CF00, 0x1CFCF, U"Znamenny Musical Notation" },
{ 0x1D000, 0x1D0FF, U"Byzantine Musical Symbols" },
{ 0x1D100, 0x1D1FF, U"Musical Symbols" },
@ -391,6 +400,7 @@ static UniRange unicode_ranges[] = {
{ 0x1E290, 0x1E2BF, U"Toto" },
{ 0x1E2C0, 0x1E2FF, U"Wancho" },
{ 0x1E4D0, 0x1E4FF, U"Nag Mundari" },
{ 0x1E5D0, 0x1E5FF, U"Ol Onal" },
{ 0x1E7E0, 0x1E7FF, U"Ethiopic Extended-B" },
{ 0x1E800, 0x1E8DF, U"Mende Kikakui" },
{ 0x1E900, 0x1E95F, U"Adlam" },
@ -418,6 +428,7 @@ static UniRange unicode_ranges[] = {
{ 0x2B740, 0x2B81F, U"CJK Unified Ideographs Extension D" },
{ 0x2B820, 0x2CEAF, U"CJK Unified Ideographs Extension E" },
{ 0x2CEB0, 0x2EBEF, U"CJK Unified Ideographs Extension F" },
{ 0x2EBF0, 0x2EE5F, U"CJK Unified Ideographs Extension I" },
{ 0x2F800, 0x2FA1F, U"CJK Compatibility Ideographs Supplement" },
{ 0x30000, 0x3134F, U"CJK Unified Ideographs Extension G" },
{ 0x31350, 0x323AF, U"CJK Unified Ideographs Extension H" },

View File

@ -551,18 +551,18 @@ void InputEventConfigurationDialog::_input_list_item_selected() {
}
void InputEventConfigurationDialog::_device_selection_changed(int p_option_button_index) {
// Subtract 1 as option index 0 corresponds to "All Devices" (value of -1)
// and option index 1 corresponds to device 0, etc...
event->set_device(p_option_button_index - 1);
// Option index 0 corresponds to "All Devices" (value of -3).
// Otherwise subtract 1 as option index 1 corresponds to device 0, etc...
event->set_device(p_option_button_index == 0 ? InputEvent::DEVICE_ID_ALL_DEVICES : p_option_button_index - 1);
event_as_text->set_text(EventListenerLineEdit::get_event_text(event, true));
}
void InputEventConfigurationDialog::_set_current_device(int p_device) {
device_id_option->select(p_device + 1);
device_id_option->select(p_device == InputEvent::DEVICE_ID_ALL_DEVICES ? 0 : p_device + 1);
}
int InputEventConfigurationDialog::_get_current_device() const {
return device_id_option->get_selected() - 1;
return device_id_option->get_selected() == 0 ? InputEvent::DEVICE_ID_ALL_DEVICES : device_id_option->get_selected() - 1;
}
void InputEventConfigurationDialog::_notification(int p_what) {
@ -705,11 +705,12 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
device_id_option = memnew(OptionButton);
device_id_option->set_h_size_flags(Control::SIZE_EXPAND_FILL);
for (int i = -1; i < 8; i++) {
device_id_option->add_item(EventListenerLineEdit::get_device_string(InputEvent::DEVICE_ID_ALL_DEVICES));
for (int i = 0; i < 8; i++) {
device_id_option->add_item(EventListenerLineEdit::get_device_string(i));
}
device_id_option->connect(SceneStringName(item_selected), callable_mp(this, &InputEventConfigurationDialog::_device_selection_changed));
_set_current_device(InputMap::ALL_DEVICES);
_set_current_device(InputEvent::DEVICE_ID_ALL_DEVICES);
device_container->add_child(device_id_option);
device_container->hide();

View File

@ -2006,30 +2006,34 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
HBoxContainer *playback_container = memnew(HBoxContainer);
playback_container->set_layout_direction(LAYOUT_DIRECTION_LTR);
hb->add_child(playback_container);
play_bw_from = memnew(Button);
play_bw_from->set_theme_type_variation("FlatButton");
play_bw_from->set_tooltip_text(TTR("Play Animation Backwards"));
hb->add_child(play_bw_from);
playback_container->add_child(play_bw_from);
play_bw = memnew(Button);
play_bw->set_theme_type_variation("FlatButton");
play_bw->set_tooltip_text(TTR("Play Animation Backwards from End"));
hb->add_child(play_bw);
playback_container->add_child(play_bw);
stop = memnew(Button);
stop->set_theme_type_variation("FlatButton");
stop->set_tooltip_text(TTR("Pause/Stop Animation"));
hb->add_child(stop);
playback_container->add_child(stop);
play = memnew(Button);
play->set_theme_type_variation("FlatButton");
play->set_tooltip_text(TTR("Play Animation from Start"));
hb->add_child(play);
playback_container->add_child(play);
play_from = memnew(Button);
play_from->set_theme_type_variation("FlatButton");
play_from->set_tooltip_text(TTR("Play Animation"));
hb->add_child(play_from);
playback_container->add_child(play_from);
frame = memnew(SpinBox);
hb->add_child(frame);

View File

@ -153,7 +153,6 @@ void EditorPlugin::add_control_to_container(CustomControlContainer p_location, C
} break;
case CONTAINER_PROJECT_SETTING_TAB_RIGHT: {
ProjectSettingsEditor::get_singleton()->get_tabs()->add_child(p_control);
ProjectSettingsEditor::get_singleton()->get_tabs()->move_child(p_control, 1);
} break;
}

View File

@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/io/file_access_memory.h"
#include "core/io/image.h"
#include "core/io/resource_loader.h"
#include "core/object/script_language.h"
#include "core/os/os.h"

View File

@ -44,7 +44,10 @@ LightmapGIGizmoPlugin::LightmapGIGizmoPlugin() {
Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D);
mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED);
// Fade out probes when camera gets too close to them.
mat->set_distance_fade(StandardMaterial3D::DISTANCE_FADE_PIXEL_DITHER);
mat->set_distance_fade_min_distance(0.5);
mat->set_distance_fade_max_distance(1.5);
mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, false);
mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true);

View File

@ -396,6 +396,7 @@ void ShaderEditorPlugin::_setup_popup_menu(PopupMenuType p_type, PopupMenu *p_me
if (p_type == FILE) {
p_menu->add_separator();
p_menu->add_item(TTR("Open File in Inspector"), FILE_INSPECT);
p_menu->add_item(TTR("Inspect Native Shader Code..."), FILE_INSPECT_NATIVE_SHADER_CODE);
p_menu->add_separator();
p_menu->add_shortcut(ED_SHORTCUT("shader_editor/close_file", TTR("Close File"), KeyModifierMask::CMD_OR_CTRL | Key::W), FILE_CLOSE);
} else {
@ -554,6 +555,12 @@ void ShaderEditorPlugin::_menu_item_pressed(int p_index) {
EditorNode::get_singleton()->push_item(edited_shaders[index].shader_inc.ptr());
}
} break;
case FILE_INSPECT_NATIVE_SHADER_CODE: {
int index = shader_tabs->get_current_tab();
if (edited_shaders[index].shader.is_valid()) {
edited_shaders[index].shader->inspect_native_shader_code();
}
} break;
case FILE_CLOSE: {
_close_shader(shader_tabs->get_current_tab());
} break;
@ -754,6 +761,7 @@ void ShaderEditorPlugin::_set_file_specific_items_disabled(bool p_disabled) {
file_popup_menu->set_item_disabled(file_popup_menu->get_item_index(FILE_SAVE), p_disabled);
file_popup_menu->set_item_disabled(file_popup_menu->get_item_index(FILE_SAVE_AS), p_disabled);
file_popup_menu->set_item_disabled(file_popup_menu->get_item_index(FILE_INSPECT), p_disabled);
file_popup_menu->set_item_disabled(file_popup_menu->get_item_index(FILE_INSPECT_NATIVE_SHADER_CODE), p_disabled);
file_popup_menu->set_item_disabled(file_popup_menu->get_item_index(FILE_CLOSE), p_disabled);
}

View File

@ -69,6 +69,7 @@ class ShaderEditorPlugin : public EditorPlugin {
FILE_SAVE,
FILE_SAVE_AS,
FILE_INSPECT,
FILE_INSPECT_NATIVE_SHADER_CODE,
FILE_CLOSE,
CLOSE_ALL,
CLOSE_OTHER_TABS,

View File

@ -1986,6 +1986,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
sub_vb->add_child(hfc);
playback_container = memnew(HBoxContainer);
playback_container->set_layout_direction(LAYOUT_DIRECTION_LTR);
hfc->add_child(playback_container);
play_bw_from = memnew(Button);
@ -2013,7 +2014,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
play_from->set_tooltip_text(TTR("Play selected animation from current pos. (D)"));
playback_container->add_child(play_from);
playback_container->add_child(memnew(VSeparator));
hfc->add_child(memnew(VSeparator));
autoplay->connect(SceneStringName(pressed), callable_mp(this, &SpriteFramesEditor::_autoplay_pressed));
autoplay->set_toggle_mode(true);

View File

@ -2128,12 +2128,11 @@ void VisualShaderEditor::_update_nodes() {
}
}
Array keys = added.keys();
keys.sort();
for (int i = 0; i < keys.size(); i++) {
const Variant &key = keys.get(i);
List<Variant> keys;
added.get_key_list(&keys);
keys.sort_custom<StringLikeVariantOrder>();
for (const Variant &key : keys) {
const Dictionary &value = (Dictionary)added[key];
add_custom_type(value["name"], value["type"], value["script"], value["description"], value["return_icon_type"], value["category"], value["highend"]);

View File

@ -88,7 +88,7 @@ void ProjectListItemControl::_notification(int p_what) {
draw_style_box(get_theme_stylebox(SNAME("selected"), SNAME("Tree")), Rect2(Point2(), get_size()));
}
if (is_hovering) {
draw_style_box(get_theme_stylebox(SNAME("hover"), SNAME("Tree")), Rect2(Point2(), get_size()));
draw_style_box(get_theme_stylebox(SNAME("hovered"), SNAME("Tree")), Rect2(Point2(), get_size()));
}
draw_line(Point2(0, get_size().y + 1), Point2(get_size().x, get_size().y + 1), get_theme_color(SNAME("guide_color"), SNAME("Tree")));

View File

@ -45,6 +45,7 @@
#include "editor/editor_string_names.h"
#include "editor/editor_translation_parser.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/export/editor_export.h"
#include "editor/export/editor_export_platform.h"
#include "editor/export/editor_export_platform_extension.h"
#include "editor/export/editor_export_platform_pc.h"
@ -158,6 +159,7 @@ void register_editor_types() {
GDREGISTER_ABSTRACT_CLASS(ScriptEditorBase);
GDREGISTER_CLASS(EditorSyntaxHighlighter);
GDREGISTER_ABSTRACT_CLASS(EditorInterface);
GDREGISTER_ABSTRACT_CLASS(EditorExport);
GDREGISTER_CLASS(EditorExportPlugin);
GDREGISTER_ABSTRACT_CLASS(EditorExportPlatform);
GDREGISTER_ABSTRACT_CLASS(EditorExportPlatformPC);

View File

@ -945,6 +945,8 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
p_theme->set_color("custom_button_font_highlight", "Tree", p_config.font_hover_color);
p_theme->set_color(SceneStringName(font_color), "Tree", p_config.font_color);
p_theme->set_color("font_hovered_color", "Tree", p_config.mono_color);
p_theme->set_color("font_hovered_dimmed_color", "Tree", p_config.font_color);
p_theme->set_color("font_selected_color", "Tree", p_config.mono_color);
p_theme->set_color("font_disabled_color", "Tree", p_config.font_disabled_color);
p_theme->set_color("font_outline_color", "Tree", p_config.font_outline_color);
@ -997,7 +999,13 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
Ref<StyleBoxFlat> style_tree_hover = p_config.base_style->duplicate();
style_tree_hover->set_bg_color(p_config.highlight_color * Color(1, 1, 1, 0.4));
style_tree_hover->set_border_width_all(0);
p_theme->set_stylebox("hover", "Tree", style_tree_hover);
p_theme->set_stylebox("hovered", "Tree", style_tree_hover);
p_theme->set_stylebox("button_hover", "Tree", style_tree_hover);
Ref<StyleBoxFlat> style_tree_hover_dimmed = p_config.base_style->duplicate();
style_tree_hover_dimmed->set_bg_color(p_config.highlight_color * Color(1, 1, 1, 0.2));
style_tree_hover_dimmed->set_border_width_all(0);
p_theme->set_stylebox("hovered_dimmed", "Tree", style_tree_hover_dimmed);
p_theme->set_stylebox("selected_focus", "Tree", style_tree_focus);
p_theme->set_stylebox("selected", "Tree", style_tree_selected);

View File

@ -42,6 +42,7 @@
#include "core/io/dir_access.h"
#include "core/io/file_access_pack.h"
#include "core/io/file_access_zip.h"
#include "core/io/image.h"
#include "core/io/image_loader.h"
#include "core/io/ip.h"
#include "core/io/resource_loader.h"
@ -2412,6 +2413,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (bool(GLOBAL_GET("display/window/size/no_focus"))) {
window_flags |= DisplayServer::WINDOW_FLAG_NO_FOCUS_BIT;
}
if (bool(GLOBAL_GET("display/window/size/sharp_corners"))) {
window_flags |= DisplayServer::WINDOW_FLAG_SHARP_CORNERS_BIT;
}
window_mode = (DisplayServer::WindowMode)(GLOBAL_GET("display/window/size/mode").operator int());
int initial_position_type = GLOBAL_GET("display/window/size/initial_position_type").operator int();
if (initial_position_type == 0) { // Absolute.
@ -3197,6 +3201,10 @@ Error Main::setup2(bool p_show_boot_logo) {
}
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF_BASIC("input_devices/pointing/emulate_mouse_from_touch", true)));
if (editor) {
id->set_emulate_mouse_from_touch(true);
}
}
OS::get_singleton()->benchmark_end_measure("Startup", "Setup Window and Boot");

View File

@ -30,6 +30,7 @@
#include "image_compress_basisu.h"
#include "core/io/image.h"
#include "core/os/os.h"
#include "core/string/print_string.h"
#include "servers/rendering_server.h"

View File

@ -217,7 +217,7 @@ String GDScriptDocGen::_docvalue_from_variant(const Variant &p_variant, int p_re
List<Variant> keys;
dict.get_key_list(&keys);
keys.sort();
keys.sort_custom<StringLikeVariantOrder>();
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
if (E->prev()) {

View File

@ -693,10 +693,16 @@ void GDScript::_static_default_init() {
continue;
}
if (type.builtin_type == Variant::ARRAY && type.has_container_element_type(0)) {
const GDScriptDataType element_type = type.get_container_element_type(0);
Array default_value;
const GDScriptDataType &element_type = type.get_container_element_type(0);
default_value.set_typed(element_type.builtin_type, element_type.native_type, element_type.script_type);
static_variables.write[E.value.index] = default_value;
} else if (type.builtin_type == Variant::DICTIONARY && type.has_container_element_types()) {
const GDScriptDataType key_type = type.get_container_element_type_or_variant(0);
const GDScriptDataType value_type = type.get_container_element_type_or_variant(1);
Dictionary default_value;
default_value.set_typed(key_type.builtin_type, key_type.native_type, key_type.script_type, value_type.builtin_type, value_type.native_type, value_type.script_type);
static_variables.write[E.value.index] = default_value;
} else {
Variant default_value;
Callable::CallError err;

View File

@ -1624,15 +1624,17 @@ GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_vali
valid = false;
}
annotation->info = &valid_annotations[annotation->name];
if (valid) {
annotation->info = &valid_annotations[annotation->name];
if (!annotation->applies_to(p_valid_targets)) {
if (annotation->applies_to(AnnotationInfo::SCRIPT)) {
push_error(vformat(R"(Annotation "%s" must be at the top of the script, before "extends" and "class_name".)", annotation->name));
} else {
push_error(vformat(R"(Annotation "%s" is not allowed in this level.)", annotation->name));
if (!annotation->applies_to(p_valid_targets)) {
if (annotation->applies_to(AnnotationInfo::SCRIPT)) {
push_error(vformat(R"(Annotation "%s" must be at the top of the script, before "extends" and "class_name".)", annotation->name));
} else {
push_error(vformat(R"(Annotation "%s" is not allowed in this level.)", annotation->name));
}
valid = false;
}
valid = false;
}
if (check(GDScriptTokenizer::Token::PARENTHESIS_OPEN)) {

View File

@ -0,0 +1,3 @@
@export
func test():
pass

View File

@ -0,0 +1,2 @@
GDTEST_PARSER_ERROR
Annotation "@export" cannot be applied to a function.

View File

@ -0,0 +1,3 @@
@hello_world
func test():
pass

View File

@ -0,0 +1,2 @@
GDTEST_PARSER_ERROR
Unrecognized annotation: "@hello_world".

View File

@ -32,7 +32,7 @@ partial class EventSignals
add => backing_MySignal += value;
remove => backing_MySignal -= value;
}
protected void OnMySignal(string str, int num)
protected void EmitSignalMySignal(string str, int num)
{
EmitSignal(SignalName.MySignal, str, num);
}

View File

@ -807,7 +807,7 @@ partial class ExportedFields
properties.Add(new(type: (global::Godot.Variant.Type)23, name: PropertyName.@_fieldRid, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.@_fieldGodotDictionary, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.@_fieldGodotArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.@_fieldGodotGenericDictionary, hint: (global::Godot.PropertyHint)38, hintString: "4/0:;1/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.@_fieldGodotGenericDictionary, hint: (global::Godot.PropertyHint)23, hintString: "4/0:;1/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.@_fieldGodotGenericArray, hint: (global::Godot.PropertyHint)23, hintString: "2/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)31, name: PropertyName.@_fieldEmptyInt64Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
return properties;

View File

@ -925,7 +925,7 @@ partial class ExportedProperties
properties.Add(new(type: (global::Godot.Variant.Type)23, name: PropertyName.@PropertyRid, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.@PropertyGodotDictionary, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.@PropertyGodotArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.@PropertyGodotGenericDictionary, hint: (global::Godot.PropertyHint)38, hintString: "4/0:;1/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.@PropertyGodotGenericDictionary, hint: (global::Godot.PropertyHint)23, hintString: "4/0:;1/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.@PropertyGodotGenericArray, hint: (global::Godot.PropertyHint)23, hintString: "2/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
return properties;
}

View File

@ -791,7 +791,7 @@ namespace Godot.SourceGenerators
}
}
hint = PropertyHint.DictionaryType;
hint = PropertyHint.TypeString;
hintString = keyHintString != null && valueHintString != null ? $"{keyHintString};{valueHintString}" : null;
return hintString != null;

View File

@ -282,7 +282,7 @@ namespace Godot.SourceGenerators
.Append(" -= value;\n")
.Append("}\n");
// Generate On{EventName} method to raise the event
// Generate EmitSignal{EventName} method to raise the event
var invokeMethodSymbol = signalDelegate.InvokeMethodData.Method;
int paramCount = invokeMethodSymbol.Parameters.Length;
@ -291,7 +291,7 @@ namespace Godot.SourceGenerators
"private" :
"protected";
source.Append($" {raiseMethodModifiers} void On{signalName}(");
source.Append($" {raiseMethodModifiers} void EmitSignal{signalName}(");
for (int i = 0; i < paramCount; i++)
{
var paramSymbol = invokeMethodSymbol.Parameters[i];

View File

@ -3275,10 +3275,10 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append(CLOSE_BLOCK_L1);
// Generate On{EventName} method to raise the event.
// Generate EmitSignal{EventName} method to raise the event.
if (!p_itype.is_singleton) {
p_output.append(MEMBER_BEGIN "protected void ");
p_output << "On" << p_isignal.proxy_name;
p_output << "EmitSignal" << p_isignal.proxy_name;
if (is_parameterless) {
p_output.append("()\n" OPEN_BLOCK_L1 INDENT2);
p_output << "EmitSignal(SignalName." << p_isignal.proxy_name << ");\n";

View File

@ -480,6 +480,8 @@ void NavMap::sync() {
// connection, integration and path finding.
_new_pm_edge_free_count = free_edges.size();
real_t sqr_edge_connection_margin = edge_connection_margin * edge_connection_margin;
for (int i = 0; i < free_edges.size(); i++) {
const gd::Edge::Connection &free_edge = free_edges[i];
Vector3 edge_p1 = free_edge.polygon->points[free_edge.edge].pos;
@ -510,7 +512,7 @@ void NavMap::sync() {
} else {
other1 = other_edge_p1.lerp(other_edge_p2, (1.0 - projected_p1_ratio) / (projected_p2_ratio - projected_p1_ratio));
}
if (other1.distance_to(self1) > edge_connection_margin) {
if (other1.distance_squared_to(self1) > sqr_edge_connection_margin) {
continue;
}
@ -521,7 +523,7 @@ void NavMap::sync() {
} else {
other2 = other_edge_p1.lerp(other_edge_p2, (0.0 - projected_p1_ratio) / (projected_p2_ratio - projected_p1_ratio));
}
if (other2.distance_to(self2) > edge_connection_margin) {
if (other2.distance_squared_to(self2) > sqr_edge_connection_margin) {
continue;
}
@ -549,11 +551,11 @@ void NavMap::sync() {
const Vector3 end = link->get_end_position();
gd::Polygon *closest_start_polygon = nullptr;
real_t closest_start_distance = link_connection_radius;
real_t closest_start_sqr_dist = link_connection_radius * link_connection_radius;
Vector3 closest_start_point;
gd::Polygon *closest_end_polygon = nullptr;
real_t closest_end_distance = link_connection_radius;
real_t closest_end_sqr_dist = link_connection_radius * link_connection_radius;
Vector3 closest_end_point;
// Create link to any polygons within the search radius of the start point.
@ -564,11 +566,11 @@ void NavMap::sync() {
for (uint32_t start_point_id = 2; start_point_id < start_poly.points.size(); start_point_id += 1) {
const Face3 start_face(start_poly.points[0].pos, start_poly.points[start_point_id - 1].pos, start_poly.points[start_point_id].pos);
const Vector3 start_point = start_face.get_closest_point_to(start);
const real_t start_distance = start_point.distance_to(start);
const real_t sqr_dist = start_point.distance_squared_to(start);
// Pick the polygon that is within our radius and is closer than anything we've seen yet.
if (start_distance <= link_connection_radius && start_distance < closest_start_distance) {
closest_start_distance = start_distance;
if (sqr_dist < closest_start_sqr_dist) {
closest_start_sqr_dist = sqr_dist;
closest_start_point = start_point;
closest_start_polygon = &start_poly;
}
@ -581,11 +583,11 @@ void NavMap::sync() {
for (uint32_t end_point_id = 2; end_point_id < end_poly.points.size(); end_point_id += 1) {
const Face3 end_face(end_poly.points[0].pos, end_poly.points[end_point_id - 1].pos, end_poly.points[end_point_id].pos);
const Vector3 end_point = end_face.get_closest_point_to(end);
const real_t end_distance = end_point.distance_to(end);
const real_t sqr_dist = end_point.distance_squared_to(end);
// Pick the polygon that is within our radius and is closer than anything we've seen yet.
if (end_distance <= link_connection_radius && end_distance < closest_end_distance) {
closest_end_distance = end_distance;
if (sqr_dist < closest_end_sqr_dist) {
closest_end_sqr_dist = sqr_dist;
closest_end_point = end_point;
closest_end_polygon = &end_poly;
}

View File

@ -32,6 +32,7 @@
#include "core/error/error_macros.h"
#include "core/io/file_access_memory.h"
#include "core/io/image.h"
#include "core/os/os.h"
#include "core/string/print_string.h"

View File

@ -31,6 +31,7 @@
#include "video_stream_theora.h"
#include "core/config/project_settings.h"
#include "core/io/image.h"
#include "core/os/os.h"
#include "scene/resources/image_texture.h"

View File

@ -31,6 +31,7 @@
#include "image_saver_tinyexr.h"
#include "core/math/math_funcs.h"
#include "core/os/os.h"
#include <zlib.h> // Should come before including tinyexr.

View File

@ -31,7 +31,7 @@
#ifndef IMAGE_SAVER_TINYEXR_H
#define IMAGE_SAVER_TINYEXR_H
#include "core/os/os.h"
#include "core/io/image.h"
Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
Vector<uint8_t> save_exr_buffer(const Ref<Image> &p_img, bool p_grayscale);

View File

@ -35,6 +35,7 @@
#include "godot_plugin_config.h"
#endif // DISABLE_DEPRECATED
#include "core/io/image.h"
#include "core/io/zip_io.h"
#include "core/os/os.h"
#include "editor/export/editor_export_platform.h"

View File

@ -108,7 +108,7 @@ public final class PermissionsUtil {
} else {
PermissionInfo permissionInfo = getPermissionInfo(activity, permission);
int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
if ((protectionLevel & PermissionInfo.PROTECTION_DANGEROUS) == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Requesting permission " + permission);
requestedPermissions.add(permission);
}
@ -174,7 +174,7 @@ public final class PermissionsUtil {
try {
PermissionInfo permissionInfo = getPermissionInfo(activity, permissionName);
int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, permissionName) != PackageManager.PERMISSION_GRANTED) {
if ((protectionLevel & PermissionInfo.PROTECTION_DANGEROUS) == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, permissionName) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[] { permissionName }, REQUEST_SINGLE_PERMISSION_REQ_CODE);
return false;
}
@ -259,7 +259,7 @@ public final class PermissionsUtil {
} else {
PermissionInfo permissionInfo = getPermissionInfo(context, manifestPermission);
int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(context, manifestPermission) == PackageManager.PERMISSION_GRANTED) {
if ((protectionLevel & PermissionInfo.PROTECTION_DANGEROUS) == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(context, manifestPermission) == PackageManager.PERMISSION_GRANTED) {
grantedPermissions.add(manifestPermission);
}
}

View File

@ -1479,12 +1479,12 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
driver_found = true;
}
}
#endif // GLES3_ENABLED
if (!driver_found) {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Video driver not found.");
}
#endif // GLES3_ENABLED
cursor_set_shape(CURSOR_BUSY);

View File

@ -75,6 +75,13 @@
<member name="codesign/custom_options" type="PackedStringArray" setter="" getter="">
Array of the additional command line arguments passed to the code signing tool.
</member>
<member name="codesign/entitlements/additional" type="String" setter="" getter="">
Additional data added to the root [code]&lt;dict&gt;[/code] section of the [url=https://developer.apple.com/documentation/bundleresources/entitlements].entitlements[/url] file. The value should be an XML section with pairs of key-value elements, e.g.:
[codeblock lang=text]
&lt;key&gt;key_name&lt;/key&gt;
&lt;string&gt;value&lt;/string&gt;
[/codeblock]
</member>
<member name="codesign/entitlements/address_book" type="bool" setter="" getter="">
Enable to allow access to contacts in the user's address book, if it's enabled you should also provide usage message in the [member privacy/address_book_usage_description] option. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_personal-information_addressbook]com.apple.security.personal-information.addressbook[/url].
</member>

View File

@ -327,7 +327,7 @@ bool EditorExportPlatformMacOS::get_export_option_visibility(const EditorExportP
}
bool advanced_options_enabled = p_preset->are_advanced_options_enabled();
if (p_option.begins_with("privacy")) {
if (p_option.begins_with("privacy") || p_option == "codesign/entitlements/additional") {
return advanced_options_enabled;
}
}
@ -501,6 +501,7 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/entitlements/app_sandbox/files_movies", PROPERTY_HINT_ENUM, "No,Read-only,Read-write"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/entitlements/app_sandbox/files_user_selected", PROPERTY_HINT_ENUM, "No,Read-only,Read-write"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::ARRAY, "codesign/entitlements/app_sandbox/helper_executables", PROPERTY_HINT_ARRAY_TYPE, itos(Variant::STRING) + "/" + itos(PROPERTY_HINT_GLOBAL_FILE) + ":"), Array()));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements/additional", PROPERTY_HINT_MULTILINE_TEXT), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray()));
#ifdef MACOS_ENABLED
@ -2126,6 +2127,11 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
}
}
const String &additional_entitlements = p_preset->get("codesign/entitlements/additional");
if (!additional_entitlements.is_empty()) {
ent_f->store_line(additional_entitlements);
}
ent_f->store_line("</dict>");
ent_f->store_line("</plist>");
} else {
@ -2288,6 +2294,14 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
}
}
if (FileAccess::exists(ent_path)) {
print_verbose("entitlements:\n" + FileAccess::get_file_as_string(ent_path));
}
if (FileAccess::exists(hlp_ent_path)) {
print_verbose("helper entitlements:\n" + FileAccess::get_file_as_string(hlp_ent_path));
}
// Clean up temporary entitlements files.
if (FileAccess::exists(hlp_ent_path)) {
DirAccess::remove_file_or_error(hlp_ent_path);

View File

@ -34,6 +34,7 @@
#include "core/config/project_settings.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/image.h"
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
#include "core/os/os.h"

View File

@ -67,6 +67,18 @@
#define DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 19
#endif
#ifndef DWMWA_WINDOW_CORNER_PREFERENCE
#define DWMWA_WINDOW_CORNER_PREFERENCE 33
#endif
#ifndef DWMWCP_DEFAULT
#define DWMWCP_DEFAULT 0
#endif
#ifndef DWMWCP_DONOTROUND
#define DWMWCP_DONOTROUND 1
#endif
#define WM_INDICATOR_CALLBACK_MESSAGE (WM_USER + 1)
#if defined(__GNUC__)
@ -1483,6 +1495,9 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
if (p_flags & WINDOW_FLAG_ALWAYS_ON_TOP_BIT && p_mode != WINDOW_MODE_FULLSCREEN && p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
wd.always_on_top = true;
}
if (p_flags & WINDOW_FLAG_SHARP_CORNERS_BIT) {
wd.sharp_corners = true;
}
if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) {
wd.no_focus = true;
}
@ -2297,6 +2312,12 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
wd.always_on_top = p_enabled;
_update_window_style(p_window);
} break;
case WINDOW_FLAG_SHARP_CORNERS: {
wd.sharp_corners = p_enabled;
DWORD value = wd.sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
::DwmSetWindowAttribute(wd.hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
_update_window_style(p_window);
} break;
case WINDOW_FLAG_TRANSPARENT: {
if (p_enabled) {
// Enable per-pixel alpha.
@ -3994,6 +4015,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
native_menu->_menu_activate(HMENU(lParam), (int)wParam);
} break;
case WM_CREATE: {
{
DWORD value = windows[window_id].sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
::DwmSetWindowAttribute(windows[window_id].hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
}
if (is_dark_mode_supported() && dark_title_available) {
BOOL value = is_dark_mode();
@ -5645,6 +5670,12 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
wd_transient_parent->transient_children.insert(id);
}
wd.sharp_corners = p_flags & WINDOW_FLAG_SHARP_CORNERS_BIT;
{
DWORD value = wd.sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
::DwmSetWindowAttribute(wd.hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
}
if (is_dark_mode_supported() && dark_title_available) {
BOOL value = is_dark_mode();
::DwmSetWindowAttribute(wd.hWnd, use_legacy_dark_mode_before_20H1 ? DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 : DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));

Some files were not shown because too many files have changed in this diff Show More