summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.mailmap2
-rw-r--r--.travis.yml35
-rw-r--r--AUTHORS.md4
-rw-r--r--DONORS.md38
-rw-r--r--SConstruct4
-rw-r--r--core/array.cpp90
-rw-r--r--core/array.h5
-rw-r--r--core/callable_method_pointer.h1
-rw-r--r--core/class_db.cpp9
-rw-r--r--core/class_db.h1
-rw-r--r--core/container_type_validate.h98
-rw-r--r--core/crypto/crypto.cpp2
-rw-r--r--core/crypto/crypto.h6
-rw-r--r--core/debugger/remote_debugger.cpp2
-rw-r--r--core/engine.cpp2
-rw-r--r--core/engine.h2
-rw-r--r--core/global_constants.cpp4
-rw-r--r--core/hashfuncs.h3
-rw-r--r--core/image.cpp3
-rw-r--r--core/io/image_loader.cpp2
-rw-r--r--core/io/image_loader.h2
-rw-r--r--core/io/resource_format_binary.cpp52
-rw-r--r--core/io/resource_format_binary.h5
-rw-r--r--core/io/resource_importer.cpp4
-rw-r--r--core/io/resource_importer.h2
-rw-r--r--core/io/resource_loader.cpp4
-rw-r--r--core/io/resource_loader.h2
-rw-r--r--core/io/translation_loader_po.cpp2
-rw-r--r--core/io/translation_loader_po.h2
-rw-r--r--core/math/basis.cpp4
-rw-r--r--core/method_bind.h1
-rw-r--r--core/object.h8
-rw-r--r--core/resource.cpp3
-rw-r--r--core/rid.h5
-rw-r--r--core/rid_owner.h5
-rw-r--r--core/script_language.h2
-rw-r--r--core/typed_array.cpp1
-rw-r--r--core/typed_array.h202
-rw-r--r--core/undo_redo.cpp3
-rw-r--r--doc/classes/@GlobalScope.xml44
-rw-r--r--doc/classes/AudioStreamSample.xml12
-rw-r--r--doc/classes/BackBufferCopy.xml1
-rw-r--r--doc/classes/BaseButton.xml1
-rw-r--r--doc/classes/BaseMaterial3D.xml78
-rw-r--r--doc/classes/Camera2D.xml3
-rw-r--r--doc/classes/CameraFeed.xml2
-rw-r--r--doc/classes/CameraServer.xml13
-rw-r--r--doc/classes/CanvasItem.xml1
-rw-r--r--doc/classes/Control.xml2
-rw-r--r--doc/classes/Decal.xml111
-rw-r--r--doc/classes/Dictionary.xml28
-rw-r--r--doc/classes/DirectionalLight3D.xml9
-rw-r--r--doc/classes/DynamicFont.xml1
-rw-r--r--doc/classes/EditorFeatureProfile.xml2
-rw-r--r--doc/classes/EditorInspector.xml6
-rw-r--r--doc/classes/EditorProperty.xml8
-rw-r--r--doc/classes/Environment.xml10
-rw-r--r--doc/classes/File.xml4
-rw-r--r--doc/classes/GeometryInstance3D.xml18
-rw-r--r--doc/classes/GraphEdit.xml6
-rw-r--r--doc/classes/HSlider.xml2
-rw-r--r--doc/classes/IP_Unix.xml15
-rw-r--r--doc/classes/Image.xml1
-rw-r--r--doc/classes/ImageTexture.xml1
-rw-r--r--doc/classes/JNISingleton.xml (renamed from doc/classes/MonoGCHandle.xml)2
-rw-r--r--doc/classes/Light3D.xml49
-rw-r--r--doc/classes/Node3D.xml1
-rw-r--r--doc/classes/OptionButton.xml4
-rw-r--r--doc/classes/PackedScene.xml12
-rw-r--r--doc/classes/PhysicalBone3D.xml59
-rw-r--r--doc/classes/PhysicsDirectBodyState2DSW.xml15
-rw-r--r--doc/classes/PhysicsDirectSpaceState3D.xml2
-rw-r--r--doc/classes/PhysicsServer2DSW.xml15
-rw-r--r--doc/classes/ProceduralSkyMaterial.xml5
-rw-r--r--doc/classes/ProjectSettings.xml91
-rw-r--r--doc/classes/RDAttachmentFormat.xml21
-rw-r--r--doc/classes/RDPipelineColorBlendState.xml53
-rw-r--r--doc/classes/RDPipelineColorBlendStateAttachment.xml37
-rw-r--r--doc/classes/RDPipelineDepthStencilState.xml57
-rw-r--r--doc/classes/RDPipelineMultisampleState.xml45
-rw-r--r--doc/classes/RDPipelineRasterizationState.xml37
-rw-r--r--doc/classes/RDSamplerState.xml45
-rw-r--r--doc/classes/RDShaderBytecode.xml71
-rw-r--r--doc/classes/RDShaderFile.xml41
-rw-r--r--doc/classes/RDShaderSource.xml45
-rw-r--r--doc/classes/RDTextureFormat.xml49
-rw-r--r--doc/classes/RDTextureView.xml25
-rw-r--r--doc/classes/RDUniform.xml39
-rw-r--r--doc/classes/RDVertexDescription.xml25
-rw-r--r--doc/classes/RenderingDevice.xml1586
-rw-r--r--doc/classes/RenderingServer.xml291
-rw-r--r--doc/classes/ResourceFormatLoaderCrypto.xml13
-rw-r--r--doc/classes/ResourceFormatSaverCrypto.xml13
-rw-r--r--doc/classes/RigidBody3D.xml7
-rw-r--r--doc/classes/ShaderGlobalsOverride.xml (renamed from modules/bullet/doc_classes/BulletPhysicsServer3D.xml)2
-rw-r--r--doc/classes/Sky.xml2
-rw-r--r--doc/classes/SubViewport.xml24
-rw-r--r--doc/classes/TabContainer.xml4
-rw-r--r--doc/classes/TextEdit.xml2
-rw-r--r--doc/classes/TileMap.xml4
-rw-r--r--doc/classes/UndoRedo.xml2
-rw-r--r--doc/classes/VSlider.xml2
-rw-r--r--doc/classes/Viewport.xml71
-rw-r--r--doc/classes/VisibilityEnabler2D.xml5
-rw-r--r--doc/classes/VisibilityEnabler3D.xml5
-rw-r--r--doc/classes/VisibilityNotifier2D.xml3
-rw-r--r--doc/classes/VisibilityNotifier3D.xml3
-rw-r--r--doc/classes/XRAnchor3D.xml (renamed from doc/classes/ARVRAnchor.xml)6
-rw-r--r--doc/classes/XRCamera3D.xml (renamed from doc/classes/ARVRCamera.xml)4
-rw-r--r--doc/classes/XRController3D.xml (renamed from doc/classes/ARVRController.xml)20
-rw-r--r--doc/classes/XRInterface.xml (renamed from doc/classes/ARVRInterface.xml)30
-rw-r--r--doc/classes/XROrigin3D.xml (renamed from doc/classes/ARVROrigin.xml)8
-rw-r--r--doc/classes/XRPositionalTracker.xml (renamed from doc/classes/ARVRPositionalTracker.xml)12
-rw-r--r--doc/classes/XRServer.xml (renamed from doc/classes/ARVRServer.xml)22
-rwxr-xr-xdoc/tools/makerst.py2
-rw-r--r--drivers/dummy/texture_loader_dummy.cpp2
-rw-r--r--drivers/dummy/texture_loader_dummy.h2
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp2
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp2
-rw-r--r--drivers/vulkan/SCsub20
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp550
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h44
-rw-r--r--drivers/vulkan/vulkan_context.cpp92
-rw-r--r--drivers/vulkan/vulkan_context.h20
-rw-r--r--editor/animation_track_editor.cpp2
-rw-r--r--editor/doc_data.cpp34
-rw-r--r--editor/editor_data.cpp4
-rw-r--r--editor/editor_data.h2
-rw-r--r--editor/editor_help.cpp14
-rw-r--r--editor/editor_inspector.cpp127
-rw-r--r--editor/editor_inspector.h15
-rw-r--r--editor/editor_node.cpp25
-rw-r--r--editor/editor_properties.cpp334
-rw-r--r--editor/editor_properties.h58
-rw-r--r--editor/editor_properties_array_dict.cpp21
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--editor/editor_themes.cpp2
-rw-r--r--editor/icons/AcceptDialog.svg2
-rw-r--r--editor/icons/ConfirmationDialog.svg2
-rw-r--r--editor/icons/EditorFileDialog.svg (renamed from editor/icons/PopupDialog.svg)2
-rw-r--r--editor/icons/FileDialog.svg2
-rw-r--r--editor/icons/Popup.svg2
-rw-r--r--editor/icons/PopupMenu.svg2
-rw-r--r--editor/icons/PopupPanel.svg2
-rw-r--r--editor/icons/ScriptCreateDialog.svg2
-rw-r--r--editor/icons/Window.svg (renamed from editor/icons/WindowDialog.svg)2
-rw-r--r--editor/icons/XRAnchor3D.svg (renamed from editor/icons/ARVRAnchor.svg)0
-rw-r--r--editor/icons/XRCamera3D.svg (renamed from editor/icons/ARVRCamera.svg)0
-rw-r--r--editor/icons/XRController3D.svg (renamed from editor/icons/ARVRController.svg)0
-rw-r--r--editor/icons/XROrigin3D.svg (renamed from editor/icons/ARVROrigin.svg)0
-rw-r--r--editor/import/resource_importer_shader_file.cpp90
-rw-r--r--editor/import/resource_importer_shader_file.h27
-rw-r--r--editor/node_3d_editor_gizmos.cpp152
-rw-r--r--editor/node_3d_editor_gizmos.h23
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp21
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp3
-rw-r--r--editor/plugins/cpu_particles_3d_editor_plugin.cpp3
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp5
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.cpp5
-rw-r--r--editor/plugins/material_editor_plugin.cpp12
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp105
-rw-r--r--editor/plugins/node_3d_editor_plugin.h22
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp2
-rw-r--r--editor/plugins/root_motion_editor_plugin.h2
-rw-r--r--editor/plugins/script_editor_plugin.cpp6
-rw-r--r--editor/plugins/script_text_editor.cpp2
-rw-r--r--editor/plugins/shader_editor_plugin.cpp10
-rw-r--r--editor/plugins/shader_file_editor_plugin.cpp303
-rw-r--r--editor/plugins/shader_file_editor_plugin.h64
-rw-r--r--editor/plugins/style_box_editor_plugin.cpp2
-rw-r--r--editor/plugins/style_box_editor_plugin.h2
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp11
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp10
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h2
-rw-r--r--editor/project_settings_editor.cpp5
-rw-r--r--editor/project_settings_editor.h2
-rw-r--r--editor/scene_tree_dock.cpp1
-rw-r--r--editor/script_create_dialog.cpp9
-rw-r--r--editor/script_create_dialog.h1
-rw-r--r--editor/shader_globals_editor.cpp452
-rw-r--r--editor/shader_globals_editor.h38
-rw-r--r--editor/translations/af.po40
-rw-r--r--editor/translations/ar.po100
-rw-r--r--editor/translations/bg.po75
-rw-r--r--editor/translations/bn.po49
-rw-r--r--editor/translations/ca.po56
-rw-r--r--editor/translations/cs.po52
-rw-r--r--editor/translations/da.po46
-rw-r--r--editor/translations/de.po56
-rw-r--r--editor/translations/de_CH.po40
-rw-r--r--editor/translations/editor.pot40
-rw-r--r--editor/translations/el.po61
-rw-r--r--editor/translations/eo.po45
-rw-r--r--editor/translations/es.po91
-rw-r--r--editor/translations/es_AR.po54
-rw-r--r--editor/translations/et.po40
-rw-r--r--editor/translations/eu.po40
-rw-r--r--editor/translations/fa.po52
-rw-r--r--editor/translations/fi.po54
-rw-r--r--editor/translations/fil.po40
-rw-r--r--editor/translations/fr.po67
-rw-r--r--editor/translations/ga.po40
-rw-r--r--editor/translations/he.po48
-rw-r--r--editor/translations/hi.po1128
-rw-r--r--editor/translations/hr.po40
-rw-r--r--editor/translations/hu.po46
-rw-r--r--editor/translations/id.po155
-rw-r--r--editor/translations/is.po58
-rw-r--r--editor/translations/it.po60
-rw-r--r--editor/translations/ja.po296
-rw-r--r--editor/translations/ka.po40
-rw-r--r--editor/translations/ko.po70
-rw-r--r--editor/translations/lt.po40
-rw-r--r--editor/translations/lv.po40
-rw-r--r--editor/translations/mi.po40
-rw-r--r--editor/translations/ml.po40
-rw-r--r--editor/translations/mr.po40
-rw-r--r--editor/translations/ms.po40
-rw-r--r--editor/translations/nb.po252
-rw-r--r--editor/translations/nl.po84
-rw-r--r--editor/translations/or.po40
-rw-r--r--editor/translations/pl.po58
-rw-r--r--editor/translations/pr.po40
-rw-r--r--editor/translations/pt_BR.po64
-rw-r--r--editor/translations/pt_PT.po65
-rw-r--r--editor/translations/ro.po48
-rw-r--r--editor/translations/ru.po163
-rw-r--r--editor/translations/si.po40
-rw-r--r--editor/translations/sk.po580
-rw-r--r--editor/translations/sl.po46
-rw-r--r--editor/translations/sq.po47
-rw-r--r--editor/translations/sr_Cyrl.po49
-rw-r--r--editor/translations/sr_Latn.po40
-rw-r--r--editor/translations/sv.po43
-rw-r--r--editor/translations/ta.po40
-rw-r--r--editor/translations/te.po40
-rw-r--r--editor/translations/th.po2344
-rw-r--r--editor/translations/tr.po54
-rw-r--r--editor/translations/uk.po63
-rw-r--r--editor/translations/ur_PK.po40
-rw-r--r--editor/translations/vi.po47
-rw-r--r--editor/translations/zh_CN.po60
-rw-r--r--editor/translations/zh_HK.po43
-rw-r--r--editor/translations/zh_TW.po56
-rw-r--r--main/main.cpp56
-rw-r--r--main/tests/test_shader_lang.cpp2
-rwxr-xr-xmisc/travis/android-tools-linux.sh6
-rw-r--r--modules/SCsub5
-rw-r--r--modules/arkit/arkit_interface.h18
-rw-r--r--modules/arkit/arkit_interface.mm54
-rw-r--r--modules/arkit/register_types.cpp2
-rw-r--r--modules/bullet/config.py11
-rw-r--r--modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml13
-rw-r--r--modules/bullet/rigid_body_bullet.cpp4
-rw-r--r--modules/bullet/rigid_body_bullet.h2
-rw-r--r--modules/dds/texture_loader_dds.cpp2
-rw-r--r--modules/dds/texture_loader_dds.h2
-rw-r--r--modules/etc/texture_loader_pkm.cpp2
-rw-r--r--modules/etc/texture_loader_pkm.h2
-rw-r--r--modules/gdnative/SCsub2
-rw-r--r--modules/gdnative/config.py2
-rw-r--r--modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml15
-rw-r--r--modules/gdnative/doc_classes/GDNativeLibrary.xml2
-rw-r--r--modules/gdnative/doc_classes/XRInterfaceGDNative.xml15
-rw-r--r--modules/gdnative/gdnative.cpp2
-rw-r--r--modules/gdnative/gdnative.h2
-rw-r--r--modules/gdnative/gdnative_api.json28
-rw-r--r--modules/gdnative/gdnative_builders.py2
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h4
-rw-r--r--modules/gdnative/include/xr/godot_xr.h (renamed from modules/gdnative/include/arvr/godot_arvr.h)37
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp9
-rw-r--r--modules/gdnative/nativescript/nativescript.h4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.cpp2
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.h2
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp7
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.h2
-rw-r--r--modules/gdnative/register_types.cpp6
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.cpp2
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.h2
-rw-r--r--modules/gdnative/xr/SCsub (renamed from modules/gdnative/arvr/SCsub)0
-rw-r--r--modules/gdnative/xr/config.py (renamed from modules/gdnative/arvr/config.py)0
-rw-r--r--modules/gdnative/xr/register_types.cpp (renamed from modules/gdnative/arvr/register_types.cpp)9
-rw-r--r--modules/gdnative/xr/register_types.h (renamed from modules/gdnative/arvr/register_types.h)10
-rw-r--r--modules/gdnative/xr/xr_interface_gdnative.cpp (renamed from modules/gdnative/arvr/arvr_interface_gdnative.cpp)173
-rw-r--r--modules/gdnative/xr/xr_interface_gdnative.h (renamed from modules/gdnative/arvr/arvr_interface_gdnative.h)34
-rw-r--r--modules/gdscript/config.py1
-rw-r--r--modules/gdscript/doc_classes/GDScriptNativeClass.xml19
-rw-r--r--modules/gdscript/gdscript.cpp20
-rw-r--r--modules/gdscript/gdscript.h4
-rw-r--r--modules/gdscript/gdscript_editor.cpp13
-rw-r--r--modules/gdscript/gdscript_function.cpp13
-rw-r--r--modules/gdscript/gdscript_parser.cpp30
-rw-r--r--modules/gdscript/gdscript_tokenizer.h1
-rw-r--r--modules/mobile_vr/doc_classes/MobileVRInterface.xml8
-rw-r--r--modules/mobile_vr/mobile_vr_interface.cpp44
-rw-r--r--modules/mobile_vr/mobile_vr_interface.h14
-rw-r--r--modules/mobile_vr/register_types.cpp2
-rw-r--r--modules/mono/csharp_script.cpp14
-rw-r--r--modules/mono/csharp_script.h4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs27
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj1
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs65
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs54
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs21
-rw-r--r--modules/mono/editor/bindings_generator.cpp2
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp10
-rw-r--r--modules/mono/editor/godotsharp_export.cpp18
-rw-r--r--modules/mono/editor/godotsharp_export.h4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs28
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs31
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs178
-rw-r--r--modules/mono/godotsharp_dirs.cpp2
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp17
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp30
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h23
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp16
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h6
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp107
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp307
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h9
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp5
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp60
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h17
-rw-r--r--modules/opensimplex/noise_texture.cpp11
-rw-r--r--modules/pvr/texture_loader_pvr.cpp2
-rw-r--r--modules/pvr/texture_loader_pvr.h2
-rw-r--r--modules/theora/video_stream_theora.cpp2
-rw-r--r--modules/theora/video_stream_theora.h2
-rw-r--r--modules/upnp/upnp.cpp7
-rw-r--r--modules/upnp/upnp_device.cpp22
-rw-r--r--modules/visual_script/visual_script.cpp24
-rw-r--r--modules/visual_script/visual_script.h2
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp6
-rw-r--r--modules/visual_script/visual_script_editor.cpp21
-rw-r--r--modules/visual_script/visual_script_nodes.cpp3
-rw-r--r--modules/webm/video_stream_webm.cpp2
-rw-r--r--modules/webm/video_stream_webm.h2
-rw-r--r--platform/android/SCsub4
-rw-r--r--platform/android/api/api.cpp5
-rw-r--r--platform/android/api/jni_singleton.h242
-rw-r--r--platform/android/detect.py8
-rw-r--r--platform/android/display_server_android.cpp655
-rw-r--r--platform/android/display_server_android.h174
-rw-r--r--platform/android/export/export.cpp9
-rw-r--r--platform/android/java/app/build.gradle9
-rw-r--r--platform/android/java/app/config.gradle2
-rw-r--r--platform/android/java/app/settings.gradle2
-rw-r--r--platform/android/java/lib/AndroidManifest.xml2
-rw-r--r--platform/android/java/lib/build.gradle6
-rw-r--r--platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.pngbin1116 -> 0 bytes
-rw-r--r--platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.pngbin388 -> 0 bytes
-rw-r--r--platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.pngbin462 -> 0 bytes
-rw-r--r--platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.pngbin1556 -> 0 bytes
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java59
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java (renamed from platform/android/java/lib/src/org/godotengine/godot/GodotView.java)39
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java40
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java7
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java (renamed from platform/android/vulkan/vk_renderer_jni.h)29
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java142
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java32
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java12
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java42
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java85
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java98
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt43
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java1
-rw-r--r--platform/android/java/plugins/godotpayment/build.gradle1
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java4
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java (renamed from platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java)3
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java (renamed from platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java)3
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java (renamed from platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java)3
-rw-r--r--platform/android/java_godot_io_wrapper.cpp41
-rw-r--r--platform/android/java_godot_io_wrapper.h10
-rw-r--r--platform/android/java_godot_lib_jni.cpp90
-rw-r--r--platform/android/java_godot_lib_jni.h2
-rw-r--r--platform/android/jni_utils.h186
-rw-r--r--platform/android/os_android.cpp521
-rw-r--r--platform/android/os_android.h115
-rw-r--r--platform/android/plugin/godot_plugin_jni.cpp48
-rw-r--r--platform/android/plugin/godot_plugin_jni.h2
-rw-r--r--platform/android/vulkan/vulkan_context_android.cpp60
-rw-r--r--platform/android/vulkan/vulkan_context_android.h (renamed from platform/android/vulkan/vk_renderer_jni.cpp)35
-rw-r--r--platform/linuxbsd/display_server_x11.cpp13
-rw-r--r--scene/2d/area_2d.cpp8
-rw-r--r--scene/2d/area_2d.h4
-rw-r--r--scene/2d/navigation_region_2d.cpp4
-rw-r--r--scene/2d/navigation_region_2d.h4
-rw-r--r--scene/2d/path_2d.cpp12
-rw-r--r--scene/2d/physics_body_2d.cpp6
-rw-r--r--scene/2d/physics_body_2d.h4
-rw-r--r--scene/2d/tile_map.cpp12
-rw-r--r--scene/2d/tile_map.h4
-rw-r--r--scene/3d/area_3d.cpp4
-rw-r--r--scene/3d/area_3d.h4
-rw-r--r--scene/3d/decal.cpp235
-rw-r--r--scene/3d/decal.h114
-rw-r--r--scene/3d/light_3d.cpp79
-rw-r--r--scene/3d/light_3d.h12
-rw-r--r--scene/3d/path_3d.cpp12
-rw-r--r--scene/3d/physics_body_3d.cpp132
-rw-r--r--scene/3d/physics_body_3d.h24
-rw-r--r--scene/3d/skeleton_3d.cpp12
-rw-r--r--scene/3d/skeleton_3d.h2
-rw-r--r--scene/3d/spring_arm_3d.cpp6
-rw-r--r--scene/3d/visual_instance_3d.cpp75
-rw-r--r--scene/3d/visual_instance_3d.h12
-rw-r--r--scene/3d/voxelizer.cpp18
-rw-r--r--scene/3d/xr_nodes.cpp (renamed from scene/3d/arvr_nodes.cpp)320
-rw-r--r--scene/3d/xr_nodes.h (renamed from scene/3d/arvr_nodes.h)64
-rw-r--r--scene/animation/animation_player.cpp4
-rw-r--r--scene/gui/graph_edit.cpp25
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/gui/option_button.cpp4
-rw-r--r--scene/gui/rich_text_label.cpp4
-rw-r--r--scene/gui/slider.cpp5
-rw-r--r--scene/gui/tab_container.cpp2
-rw-r--r--scene/gui/tree.cpp7
-rw-r--r--scene/main/node.cpp4
-rw-r--r--scene/main/node.h3
-rw-r--r--scene/main/scene_tree.cpp8
-rw-r--r--scene/main/shader_globals_override.cpp257
-rw-r--r--scene/main/shader_globals_override.h37
-rw-r--r--scene/main/viewport.cpp73
-rw-r--r--scene/main/viewport.h23
-rw-r--r--scene/register_scene_types.cpp28
-rw-r--r--scene/resources/default_theme/default_theme.cpp2
-rw-r--r--scene/resources/dynamic_font.cpp2
-rw-r--r--scene/resources/dynamic_font.h2
-rw-r--r--scene/resources/font.cpp2
-rw-r--r--scene/resources/font.h2
-rw-r--r--scene/resources/material.cpp169
-rw-r--r--scene/resources/material.h51
-rw-r--r--scene/resources/resource_format_text.cpp47
-rw-r--r--scene/resources/resource_format_text.h6
-rw-r--r--scene/resources/shader.cpp2
-rw-r--r--scene/resources/shader.h2
-rw-r--r--scene/resources/sky_material.cpp39
-rw-r--r--scene/resources/sky_material.h4
-rw-r--r--scene/resources/texture.cpp4
-rw-r--r--scene/resources/texture.h4
-rw-r--r--scene/scene_string_names.cpp3
-rw-r--r--scene/scene_string_names.h2
-rw-r--r--servers/SCsub2
-rw-r--r--servers/display_server.h2
-rw-r--r--servers/physics_2d/shape_2d_sw.h6
-rw-r--r--servers/physics_3d/body_3d_sw.h4
-rw-r--r--servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp44
-rw-r--r--servers/physics_3d/physics_server_3d_sw.cpp4
-rw-r--r--servers/physics_server_3d.h2
-rw-r--r--servers/register_server_types.cpp49
-rw-r--r--servers/rendering/rasterizer.h67
-rw-r--r--servers/rendering/rasterizer_rd/light_cluster_builder.cpp1
-rw-r--r--servers/rendering/rasterizer_rd/light_cluster_builder.h46
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp50
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h2
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp375
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.h150
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp824
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h88
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp315
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.h142
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp1290
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.h281
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.cpp149
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.h6
-rw-r--r--servers/rendering/rasterizer_rd/shaders/SCsub5
-rw-r--r--servers/rendering/rasterizer_rd/shaders/blur.glsl294
-rw-r--r--servers/rendering/rasterizer_rd/shaders/blur_inc.glsl35
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl5
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy.glsl234
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl104
-rw-r--r--servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl72
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl993
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl96
-rw-r--r--servers/rendering/rasterizer_rd/shaders/sky.glsl16
-rw-r--r--servers/rendering/rasterizer_rd/shaders/tonemap.glsl58
-rw-r--r--servers/rendering/rendering_device.cpp751
-rw-r--r--servers/rendering/rendering_device.h98
-rw-r--r--servers/rendering/rendering_device_binds.cpp167
-rw-r--r--servers/rendering/rendering_device_binds.h579
-rw-r--r--servers/rendering/rendering_server_raster.cpp23
-rw-r--r--servers/rendering/rendering_server_raster.h52
-rw-r--r--servers/rendering/rendering_server_scene.cpp448
-rw-r--r--servers/rendering/rendering_server_scene.h37
-rw-r--r--servers/rendering/rendering_server_viewport.cpp133
-rw-r--r--servers/rendering/rendering_server_viewport.h42
-rw-r--r--servers/rendering/rendering_server_wrap_mt.cpp22
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h45
-rw-r--r--servers/rendering/shader_language.cpp123
-rw-r--r--servers/rendering/shader_language.h27
-rw-r--r--servers/rendering/shader_types.cpp12
-rw-r--r--servers/rendering_server.cpp159
-rw-r--r--servers/rendering_server.h150
-rw-r--r--servers/xr/SCsub (renamed from servers/arvr/SCsub)0
-rw-r--r--servers/xr/xr_interface.cpp (renamed from servers/arvr/arvr_interface.cpp)92
-rw-r--r--servers/xr/xr_interface.h (renamed from servers/arvr/arvr_interface.h)52
-rw-r--r--servers/xr/xr_positional_tracker.cpp (renamed from servers/arvr/arvr_positional_tracker.cpp)134
-rw-r--r--servers/xr/xr_positional_tracker.h (renamed from servers/arvr/arvr_positional_tracker.h)30
-rw-r--r--servers/xr_server.cpp (renamed from servers/arvr_server.cpp)118
-rw-r--r--servers/xr_server.h (renamed from servers/arvr_server.h)64
-rw-r--r--thirdparty/README.md8
-rw-r--r--thirdparty/jpeg-compressor/jpgd.cpp6254
-rw-r--r--thirdparty/jpeg-compressor/jpgd.h634
-rw-r--r--thirdparty/jpeg-compressor/jpgd_idct.h462
-rw-r--r--thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/check_config.h21
-rw-r--r--thirdparty/mbedtls/include/mbedtls/version.h8
-rw-r--r--thirdparty/mbedtls/library/ecp.c28
-rw-r--r--thirdparty/mbedtls/library/ssl_cli.c16
-rw-r--r--thirdparty/mbedtls/library/ssl_tls.c34
-rw-r--r--thirdparty/mbedtls/library/x509.c2
-rw-r--r--thirdparty/vulkan/android/vk_mem_alloc.cpp8
518 files changed, 26303 insertions, 11733 deletions
diff --git a/.gitignore b/.gitignore
index 9096ff228a..19490b9878 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@ project.properties
platform/android/java/lib/.cxx/
platform/android/java/libs/*
platform/android/java/app/libs/*
+platform/android/java/lib/.cxx/*
# General c++ generated files
*.lib
diff --git a/.mailmap b/.mailmap
index 1baddb9c58..1ff1ffb0ee 100644
--- a/.mailmap
+++ b/.mailmap
@@ -26,6 +26,7 @@ Clay John <claynjohn@gmail.com> <clayjohn@shaw.ca>
Dana Olson <dana@shineuponthee.com> <adolson@gmail.com>
dankan1890 <mewuidev2@gmail.com>
Daniel J. Ramirez <djrmuv@gmail.com>
+Dominik 'dreamsComeTrue' Jasiński <dominikjasinski@o2.pl>
Emmanuel Barroga <emmanuelbarroga@gmail.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com>
@@ -75,6 +76,7 @@ Mariano Javier Suligoy <marianognu.easyrpg@gmail.com>
Mario Schlack <m4r10.5ch14ck@gmail.com>
marxin <mliska@suse.cz>
marynate <mary.w.nate@gmail.com> <marynate@github.com>
+Mateo Kuruk Miccino <mateomiccino@gmail.com>
Max Hilbrunner <m.hilbrunner@gmail.com>
Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com>
Michael Alexsander <michaelalexsander@protonmail.com>
diff --git a/.travis.yml b/.travis.yml
index 14ee95e77e..8cfd7a1a7f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -55,17 +55,15 @@ matrix:
packages:
- *linux_deps
-# TODO: Android support
-
-# - name: Android export template (release_debug, Clang)
-# stage: build
-# env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
-# os: linux
-# compiler: clang
-# addons:
-# apt:
-# packages:
-# - openjdk-8-jdk
+ - name: Android export template (release_debug, Clang)
+ stage: build
+ env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
+ os: linux
+ compiler: clang
+ addons:
+ apt:
+ packages:
+ - openjdk-8-jdk
- name: macOS editor (debug, Clang)
stage: build
@@ -92,21 +90,6 @@ matrix:
# packages:
# - scons
-# TODO: Dummy/Offscreen rasterizer
-
-# - name: Linux headless editor (release_debug, GCC 9, testing project exporting and script running)
-# stage: build
-# env: PLATFORM=server TOOLS=yes TARGET=release_debug CACHE_NAME=${PLATFORM}-tools-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="warnings=extra werror=yes" TEST_PROJECT=yes
-# os: linux
-# compiler: gcc-9
-# addons:
-# apt:
-# sources:
-# - sourceline: "ppa:ubuntu-toolchain-r/test"
-# packages:
-# - *gcc9_deps
-# - *linux_deps
-
- name: Linux export template (release_debug, GCC 7, without 3D support)
stage: build
env: PLATFORM=linuxbsd TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-gcc-7 EXTRA_ARGS="disable_3d=yes"
diff --git a/AUTHORS.md b/AUTHORS.md
index a3269a73f7..0f002cfaed 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -61,6 +61,7 @@ name is available.
David Sichma (DavidSichma)
Dharkael (lupoDharkael)
Dmitry Koteroff (Krakean)
+ Dominik Jasiński (dreamsComeTrue)
DualMatrix
Emmanuel Barroga (codecustard)
Emmanuel Leblond (touilleMan)
@@ -104,6 +105,7 @@ name is available.
Kelly Thomas (KellyThomas)
Kostadin Damyanov (Max-Might)
K. S. Ernest (iFire) Lee (fire)
+ lawnjelly
Leon Krause (eska014)
Lucien Menassol (Kanabenki)
m4nu3lf
@@ -118,6 +120,7 @@ name is available.
Martin Sjursen (binbitten)
marynate
Masoud BH (masoudbh3)
+ Mateo Kuruk Miccino (kuruk-mm)
Matthias Hölzl (hoelzl)
Max Hilbrunner (mhilbrunner)
merumelu
@@ -157,6 +160,7 @@ name is available.
Shiqing (kawa-yoiko)
Simon Wenner (swenner)
Swarnim Arun (minraws)
+ Thakee Nathees (ThakeeNathees)
Theo Hallenius (TheoXD)
Thomas Herzog (karroffel)
Timo Schwarzer (timoschwarzer)
diff --git a/DONORS.md b/DONORS.md
index 0b7829c55d..f11cb85822 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -40,6 +40,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Grady
Hein-Pieter van Braam
Jacob McKenney
+ Jasper Brooks
Javary Co.
Jeffery Chiu
Justin Arnold
@@ -62,6 +63,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Andrei
Dave
David Gehrig
+ David Graham
David Snopek
Ed Morley
Florian Krick
@@ -69,7 +71,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Jakub Grzesik
Manuele Finocchiaro
Officine Pixel S.n.c.
- Retro Village
Ronan Zeegers
Sofox
Taylor Ritenour
@@ -99,6 +100,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Matthew Hillier
Mohamed Ikbel Boulabiar
Mored4u
+ Retro Village
Rob Messick
Ryan Badour
Sandro Jenny
@@ -106,10 +108,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Sergey
thechris
Tom Langwaldt
+ Tricky Fat Cat
tukon
William Wold
Alex Khayrullin
+ alice gambrell
Chris Goddard
Chris Serino
Christian Padilla
@@ -151,6 +155,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Charlie Whitfield
Chase Taranto
Chris Petrich
+ Christian Alexander Bjørklund Bøhler
Christian Leth Jeppesen
Christoph Schröder
Cody Parker
@@ -186,6 +191,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Joshua Lesperance
Juan Velandia
Juraj Móza
+ Kelteseth
kinfox
Marcelo Dornbusch Lopes
Markus Fehr
@@ -193,9 +199,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Martin Eigel
Matt Eunson
Max Bulai
+ m kaersten
MuffinManKen
Nick Nikitin
Oliver Dick
+ Oscar Campos
Patrick Ting
Paul Hocker
Paul Von Zimmerman
@@ -205,9 +213,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Robert Larnach
Rocknight Studios
Romildo Franco
+ Ryan
Samuel Judd
Scott Pilet
Sean Morgan
+ Serban Serafimescu
+ Sindre Sømme
SleepCircle
spilldata
Steve Hyatt
@@ -216,7 +227,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Thomas Krampl
Thomas Kurz
Tobias Bocanegra
- Tricky Fat Cat
Urho
William Foster
Zhou Tuizhi
@@ -232,6 +242,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Adam Carr
Adam Long
Adam McCurdy
+ Adam Netzel
Adam N Webber
Adam Smeltzer
Adam Szymański
@@ -244,6 +255,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Alan Stice
Albin Jonasson Svärdsby
Alder Stefano
+ AleMax
Alessandro Senese
Alexander Erlemann
alex clavelle
@@ -253,6 +265,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Andreas Krampitz
André Simões
Andrew Thomas
+ Anthony Avina
Anthony Staunton
AP Condomines
Arda Erol
@@ -260,6 +273,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Arseniy M
Arthur S. Muszynski
Asger
+ Ashley Claymore
Aubrey Falconer
Avencherus
B A
@@ -269,6 +283,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Ben Phelan
Ben Vercammen
Bernd Jänichen
+ Bjarne
Black Block
Blair Allen
Bobby CC Wong
@@ -276,6 +291,7 @@ generous deed immortalized in the next stable release of Godot Engine.
bugcaptor
Burney Waring
Cameron Meyer
+ Carlo Sitaro
Carl van der Geest
Carwyn Edwards
Cassidy James
@@ -284,11 +300,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Christian Winter
Christoffer Sundbom
Christoph Brodmann
+ Christophe Gagnier
Christopher Schmitt
Christoph Woinke
Clay Heaton
Curt King
- Dancin Liao
Daniel Johnson
Daniel Kimblad
Daniel Pontillo
@@ -328,7 +344,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Gary Thomas
George Marques
GiulianoB
- Gordian Arragon
Greg Olson
GREGORY C FEIN
Greg P
@@ -337,13 +352,13 @@ generous deed immortalized in the next stable release of Godot Engine.
Guldoman
Hal A
Heribert Hirth
- Hudson Thorpe-Doubble
Hunter Jones
Hylpher
Ichiro Dohi
Iiari
iKlem
IndustrialRobot
+ Jacob
Jaiden Gerig
Jaime Ruiz-Borau Vizárraga
Jako Danar
@@ -351,7 +366,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Janders
Jannik Gröger
JARKKO PARVIAINEN
- Jarrod Davis
Jeff Hungerford
Jennifer Graves
Jeremy Kahn
@@ -362,8 +376,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Johannes Wuensch
John Gabriel
Jomei Jackson
+ Jonas Bernemann
Jonas Rudlang
Jonas Yamazaki
+ Jonatan R
Jonathan G
Jonathon
Jon Bonazza
@@ -376,6 +392,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Judd
Julian Murgia
JungleRobba
+ Justin Hamilton
Justin Spedding
KaDokta
Kauzig
@@ -383,6 +400,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Keith Bradner
Kevin McPhillips
kickmaniac
+ Kiri Jolly
Kiyohiro Kawamura (kyorohiro)
Kjetil Haugland
Klagsam
@@ -394,6 +412,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Laurent Tréguier
Leonardo Dimano
Levi Lindsey
+ Lin Chear
Linus Lind Lundgren
Lionel Gaillard
Luigi Renna
@@ -418,8 +437,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Melissa Mears
mewin
mhilbrunner
+ Michael Dürwald
Michael Haney
Michael Labbe
+ Michał Skwarek
Mikael Olsson
Mikayla
Mike Birkhead
@@ -479,6 +500,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Scott D. Yelich
Scott Longley
Sebastian Michailidis
+ Sebastian Vetter
Sergio Mello-Grand
sgnsajgon
Shane
@@ -489,6 +511,7 @@ generous deed immortalized in the next stable release of Godot Engine.
SK
smbe19
smo1704
+ Stefano Caronia
Svenne Krap
Terry
tezuvholovdr
@@ -498,7 +521,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Thomas Kelly
Tim Drumheller
Timothy B. MacDonald
+ tinyBigGames LLC
+ Title Plinsut
Tobbun
+ Tom Glenn
Torgeir Lilleskog
Torsten Crass
Travis O'Brien
diff --git a/SConstruct b/SConstruct
index 8fc333a8fa..e866a4c998 100644
--- a/SConstruct
+++ b/SConstruct
@@ -12,6 +12,7 @@ import sys
# Local
import methods
import gles_builders
+import version
from platform_methods import run_in_subprocess
# Scan possible build platforms
@@ -72,6 +73,7 @@ env_base.disabled_modules = []
env_base.use_ptrcall = False
env_base.module_version_string = ""
env_base.msvc = False
+env_base.stable_release = version.status == "stable"
env_base.__class__.disable_module = methods.disable_module
@@ -126,7 +128,7 @@ opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True))
opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extra", "all", "moderate", "no")))
-opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", True))
+opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", not env_base.stable_release))
opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False))
opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "")
opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False))
diff --git a/core/array.cpp b/core/array.cpp
index d65bddae61..cd4e0fb4c8 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -30,8 +30,10 @@
#include "array.h"
+#include "container_type_validate.h"
#include "core/hashfuncs.h"
#include "core/object.h"
+#include "core/script_language.h"
#include "core/variant.h"
#include "core/vector.h"
@@ -39,6 +41,8 @@ class ArrayPrivate {
public:
SafeRefCount refcount;
Vector<Variant> array;
+
+ ContainerTypeValidate typed;
};
void Array::_ref(const Array &p_from) const {
@@ -108,12 +112,59 @@ uint32_t Array::hash() const {
}
return h;
}
-void Array::operator=(const Array &p_array) {
- _ref(p_array);
+void Array::_assign(const Array &p_array) {
+
+ if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) {
+ //same type or untyped, just reference, shuold be fine
+ _ref(p_array);
+ } else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway
+ _p->array = p_array._p->array;
+ } else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid
+ if (_p->typed.type == Variant::OBJECT) {
+ //for objects, it needs full validation, either can be converted or fail
+ for (int i = 0; i < p_array._p->array.size(); i++) {
+ if (!_p->typed.validate(p_array._p->array[i], "assign")) {
+ return;
+ }
+ }
+ _p->array = p_array._p->array; //then just copy, which is cheap anyway
+
+ } else {
+ //for non objects, we need to check if there is a valid conversion, which needs to happen one by one, so this is the worst case.
+ Vector<Variant> new_array;
+ new_array.resize(p_array._p->array.size());
+ for (int i = 0; i < p_array._p->array.size(); i++) {
+ Variant src_val = p_array._p->array[i];
+ if (src_val.get_type() == _p->typed.type) {
+ new_array.write[i] = src_val;
+ } else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) {
+ Variant *ptr = &src_val;
+ Callable::CallError ce;
+ new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
+ }
+ } else {
+ ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
+ }
+ }
+
+ _p->array = new_array;
+ }
+ } else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible
+ _ref(p_array);
+ } else {
+ ERR_FAIL_MSG("Assignment of arrays of incompatible types.");
+ }
+}
+
+void Array::operator=(const Array &p_array) {
+ _assign(p_array);
}
void Array::push_back(const Variant &p_value) {
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "push_back"));
_p->array.push_back(p_value);
}
@@ -124,11 +175,13 @@ Error Array::resize(int p_new_size) {
void Array::insert(int p_pos, const Variant &p_value) {
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "insert"));
_p->array.insert(p_pos, p_value);
}
void Array::erase(const Variant &p_value) {
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "erase"));
_p->array.erase(p_value);
}
@@ -144,6 +197,7 @@ Variant Array::back() const {
int Array::find(const Variant &p_value, int p_from) const {
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find"), -1);
return _p->array.find(p_value, p_from);
}
@@ -151,6 +205,7 @@ int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array.size() == 0)
return -1;
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1);
if (p_from < 0) {
// Relative offset from the end
@@ -173,11 +228,13 @@ int Array::rfind(const Variant &p_value, int p_from) const {
int Array::find_last(const Variant &p_value) const {
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find_last"), -1);
return rfind(p_value);
}
int Array::count(const Variant &p_value) const {
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0);
if (_p->array.size() == 0)
return 0;
@@ -193,6 +250,8 @@ int Array::count(const Variant &p_value) const {
}
bool Array::has(const Variant &p_value) const {
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "use 'has'"), false);
+
return _p->array.find(p_value, 0) != -1;
}
@@ -203,6 +262,8 @@ void Array::remove(int p_pos) {
void Array::set(int p_idx, const Variant &p_value) {
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "set"));
+
operator[](p_idx) = p_value;
}
@@ -216,6 +277,7 @@ Array Array::duplicate(bool p_deep) const {
Array new_arr;
int element_count = size();
new_arr.resize(element_count);
+ new_arr._p->typed = _p->typed;
for (int i = 0; i < element_count; i++) {
new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i);
}
@@ -369,11 +431,13 @@ _FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value
int Array::bsearch(const Variant &p_value, bool p_before) {
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1);
return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
}
int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1);
ERR_FAIL_NULL_V(p_obj, 0);
_ArrayVariantSortCustom less;
@@ -391,6 +455,7 @@ Array &Array::invert() {
void Array::push_front(const Variant &p_value) {
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "push_front"));
_p->array.insert(0, p_value);
}
@@ -465,6 +530,27 @@ const void *Array::id() const {
return _p->array.ptr();
}
+Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
+ _p = memnew(ArrayPrivate);
+ _p->refcount.init();
+ set_typed(p_type, p_class_name, p_script);
+ _assign(p_from);
+}
+
+void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
+ ERR_FAIL_COND_MSG(_p->array.size() > 0, "Type can only be set when array is empty.");
+ ERR_FAIL_COND_MSG(_p->refcount.get() > 1, "Type can only be set when array has no more than one user.");
+ ERR_FAIL_COND_MSG(_p->typed.type != Variant::NIL, "Type can only be set once.");
+ ERR_FAIL_COND_MSG(p_class_name != StringName() && p_type != Variant::OBJECT, "Class names can only be set for type OBJECT");
+ Ref<Script> script = p_script;
+ ERR_FAIL_COND_MSG(script.is_valid() && p_class_name == StringName(), "Script class can only be set together with base class name");
+
+ _p->typed.type = Variant::Type(p_type);
+ _p->typed.class_name = p_class_name;
+ _p->typed.script = script;
+ _p->typed.where = "TypedArray";
+}
+
Array::Array(const Array &p_from) {
_p = nullptr;
diff --git a/core/array.h b/core/array.h
index 3b14bdb9fe..2840ce199c 100644
--- a/core/array.h
+++ b/core/array.h
@@ -47,6 +47,10 @@ class Array {
int _clamp_index(int p_index) const;
static int _fix_slice_index(int p_index, int p_arr_len, int p_top_mod);
+protected:
+ Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
+ void _assign(const Array &p_array);
+
public:
Variant &operator[](int p_idx);
const Variant &operator[](int p_idx) const;
@@ -101,6 +105,7 @@ public:
const void *id() const;
+ void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
Array(const Array &p_from);
Array();
~Array();
diff --git a/core/callable_method_pointer.h b/core/callable_method_pointer.h
index a931a344e6..fb809c2b44 100644
--- a/core/callable_method_pointer.h
+++ b/core/callable_method_pointer.h
@@ -34,6 +34,7 @@
#include "core/callable.h"
#include "core/hashfuncs.h"
#include "core/object.h"
+#include "core/os/copymem.h"
#include "core/simple_type.h"
class CallableCustomMethodPointerBase : public CallableCustom {
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 691b5a20fd..5e49688e9b 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -930,6 +930,15 @@ void ClassDB::add_property_group(StringName p_class, const String &p_name, const
type->property_list.push_back(PropertyInfo(Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_GROUP));
}
+void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix) {
+
+ OBJTYPE_WLOCK;
+ ClassInfo *type = classes.getptr(p_class);
+ ERR_FAIL_COND(!type);
+
+ type->property_list.push_back(PropertyInfo(Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_SUBGROUP));
+}
+
void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
lock->read_lock();
diff --git a/core/class_db.h b/core/class_db.h
index 1cbff34ea1..f760aa1738 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -349,6 +349,7 @@ public:
static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false);
static void add_property_group(StringName p_class, const String &p_name, const String &p_prefix = "");
+ static void add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix = "");
static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default);
static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr);
diff --git a/core/container_type_validate.h b/core/container_type_validate.h
new file mode 100644
index 0000000000..3721668033
--- /dev/null
+++ b/core/container_type_validate.h
@@ -0,0 +1,98 @@
+#ifndef CONTAINER_TYPE_VALIDATE_H
+#define CONTAINER_TYPE_VALIDATE_H
+
+#include "core/script_language.h"
+#include "core/variant.h"
+
+struct ContainerTypeValidate {
+
+ Variant::Type type = Variant::NIL;
+ StringName class_name;
+ Ref<Script> script;
+ const char *where = "conatiner";
+
+ _FORCE_INLINE_ bool can_reference(const ContainerTypeValidate &p_type) const {
+ if (type == p_type.type) {
+ if (type != Variant::OBJECT) {
+ return true; //nothing else to check
+ }
+ } else {
+ return false;
+ }
+
+ //both are object
+
+ if ((class_name != StringName()) != (p_type.class_name != StringName())) {
+ return false; //both need to have class or none
+ }
+
+ if (class_name != p_type.class_name) {
+ if (!ClassDB::is_parent_class(p_type.class_name, class_name)) {
+ return false;
+ }
+ }
+
+ if (script.is_null() != p_type.script.is_null()) {
+ return false;
+ }
+
+ if (script != p_type.script) {
+ if (!p_type.script->inherits_script(script)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ _FORCE_INLINE_ bool validate(const Variant &p_variant, const char *p_operation = "use") {
+
+ if (type == Variant::NIL) {
+ return true;
+ }
+
+ ERR_FAIL_COND_V_MSG(type != p_variant.get_type(), false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(p_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'.");
+ if (type != p_variant.get_type()) {
+ return false;
+ }
+
+ if (type != Variant::OBJECT) {
+ return true;
+ }
+#ifdef DEBUG_ENABLED
+ ObjectID object_id = p_variant;
+ if (object_id == ObjectID()) {
+ return true; //fine its null;
+ }
+ Object *object = ObjectDB::get_instance(object_id);
+ ERR_FAIL_COND_V_MSG(object == nullptr, false, "Attempted to " + String(p_operation) + " an invalid (previously freed?) object instance into a '" + String(where) + ".");
+#else
+ Object *object = p_variant;
+ if (object == nullptr) {
+ return true; //fine
+ }
+#endif
+ if (class_name == StringName()) {
+ return true; //all good, no class type requested
+ }
+
+ StringName obj_class = object->get_class_name();
+ if (obj_class != class_name) {
+ ERR_FAIL_COND_V_MSG(!ClassDB::is_parent_class(object->get_class_name(), class_name), false, "Attempted to " + String(p_operation) + " an object of type '" + object->get_class() + "' into a " + where + ", which does not inherit from '" + String(class_name) + "'.");
+ }
+
+ if (script.is_null()) {
+ return true; //all good
+ }
+
+ Ref<Script> other_script = object->get_script();
+
+ //check base script..
+ ERR_FAIL_COND_V_MSG(other_script.is_null(), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'.");
+ ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'.");
+
+ return true;
+ }
+};
+
+#endif // CONTAINER_TYPE_VALIDATE_H
diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp
index ab8548e3ba..233f62bd15 100644
--- a/core/crypto/crypto.cpp
+++ b/core/crypto/crypto.cpp
@@ -99,7 +99,7 @@ Crypto::Crypto() {
/// Resource loader/saver
-RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
String el = p_path.get_extension().to_lower();
if (el == "crt") {
diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h
index e515367de5..d9becab958 100644
--- a/core/crypto/crypto.h
+++ b/core/crypto/crypto.h
@@ -84,18 +84,14 @@ public:
};
class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
- GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader);
-
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
class ResourceFormatSaverCrypto : public ResourceFormatSaver {
- GDCLASS(ResourceFormatSaverCrypto, ResourceFormatSaver);
-
public:
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp
index c2996e552f..e6bcc5f77e 100644
--- a/core/debugger/remote_debugger.cpp
+++ b/core/debugger/remote_debugger.cpp
@@ -318,7 +318,7 @@ struct RemoteDebugger::ServersProfiler {
void _send_frame_data(bool p_final) {
DebuggerMarshalls::ServersProfilerFrame frame;
- frame.frame_number = Engine::get_singleton()->get_frames_drawn();
+ frame.frame_number = Engine::get_singleton()->get_idle_frames();
frame.frame_time = frame_time;
frame.idle_time = idle_time;
frame.physics_time = physics_time;
diff --git a/core/engine.cpp b/core/engine.cpp
index 36987eab31..5361e09a8a 100644
--- a/core/engine.cpp
+++ b/core/engine.cpp
@@ -60,7 +60,7 @@ void Engine::set_target_fps(int p_fps) {
_target_fps = p_fps > 0 ? p_fps : 0;
}
-float Engine::get_target_fps() const {
+int Engine::get_target_fps() const {
return _target_fps;
}
diff --git a/core/engine.h b/core/engine.h
index 4cfdeffa82..8512779d4c 100644
--- a/core/engine.h
+++ b/core/engine.h
@@ -86,7 +86,7 @@ public:
float get_physics_jitter_fix() const;
virtual void set_target_fps(int p_fps);
- virtual float get_target_fps() const;
+ virtual int get_target_fps() const;
virtual float get_frames_per_second() const { return _fps; }
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index 8706a38453..afcb283e05 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -568,9 +568,7 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_GROUP);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY);
- //deprecated, replaced by ClassDB function to check default value
- //BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONZERO);
- //BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONONE);
+ BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE);
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index 219b8b2658..a41a034843 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -35,10 +35,10 @@
#include "core/math/math_funcs.h"
#include "core/node_path.h"
#include "core/object_id.h"
+#include "core/rid.h"
#include "core/string_name.h"
#include "core/typedefs.h"
#include "core/ustring.h"
-
/**
* Hashing functions
*/
@@ -150,6 +150,7 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
+ static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); }
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
diff --git a/core/image.cpp b/core/image.cpp
index 2097f27b01..58351ae2e5 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -879,6 +879,9 @@ void Image::resize_to_po2(bool p_square) {
int w = next_power_of_2(width);
int h = next_power_of_2(height);
+ if (p_square) {
+ w = h = MAX(w, h);
+ }
if (w == width && h == height) {
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index 2770adbd36..01e6bb5618 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -129,7 +129,7 @@ void ImageLoader::cleanup() {
/////////////////
-RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index 18b4df98f7..15ce6031d7 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -73,7 +73,7 @@ public:
class ResourceFormatLoaderImage : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index a640565ecf..8c7559479b 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -337,12 +337,16 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case OBJECT_INTERNAL_RESOURCE: {
uint32_t index = f->get_32();
- String path = res_path + "::" + itos(index);
- RES res = ResourceLoader::load(path);
- if (res.is_null()) {
- WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
+ if (use_nocache) {
+ r_v = internal_resources[index].cache;
+ } else {
+ String path = res_path + "::" + itos(index);
+ RES res = ResourceLoader::load(path);
+ if (res.is_null()) {
+ WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
+ }
+ r_v = res;
}
- r_v = res;
} break;
case OBJECT_EXTERNAL_RESOURCE: {
@@ -716,22 +720,24 @@ Error ResourceLoaderBinary::load() {
if (!main) {
- path = internal_resources[i].path;
- if (path.begins_with("local://")) {
- path = path.replace_first("local://", "");
- subindex = path.to_int();
- path = res_path + "::" + path;
- }
+ if (!use_nocache) {
+ path = internal_resources[i].path;
+ if (path.begins_with("local://")) {
+ path = path.replace_first("local://", "");
+ subindex = path.to_int();
+ path = res_path + "::" + path;
+ }
- if (ResourceCache::has(path)) {
- //already loaded, don't do anything
- stage++;
- error = OK;
- continue;
+ if (ResourceCache::has(path)) {
+ //already loaded, don't do anything
+ stage++;
+ error = OK;
+ continue;
+ }
}
} else {
- if (!ResourceCache::has(res_path))
+ if (!use_nocache && !ResourceCache::has(res_path))
path = res_path;
}
@@ -757,9 +763,15 @@ Error ResourceLoaderBinary::load() {
RES res = RES(r);
- r->set_path(path);
+ if (path != String()) {
+ r->set_path(path);
+ }
r->set_subindex(subindex);
+ if (!main) {
+ internal_resources.write[i].cache = res;
+ }
+
int pc = f->get_32();
//set properties
@@ -1013,6 +1025,7 @@ ResourceLoaderBinary::ResourceLoaderBinary() :
importmd_ofs(0),
error(OK) {
+ use_nocache = false;
progress = nullptr;
use_sub_threads = false;
}
@@ -1023,7 +1036,7 @@ ResourceLoaderBinary::~ResourceLoaderBinary() {
memdelete(f);
}
-RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
@@ -1034,6 +1047,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'.");
ResourceLoaderBinary loader;
+ loader.use_nocache = p_no_cache;
loader.use_sub_threads = p_use_sub_threads;
loader.progress = r_progress;
String path = p_original_path != "" ? p_original_path : p_path;
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index da67e1e648..0f8fc9445b 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -68,6 +68,7 @@ class ResourceLoaderBinary {
struct IntResource {
String path;
uint64_t offset;
+ RES cache;
};
Vector<IntResource> internal_resources;
@@ -78,6 +79,8 @@ class ResourceLoaderBinary {
Map<String, String> remaps;
Error error;
+ bool use_nocache;
+
friend class ResourceFormatLoaderBinary;
Error parse_variant(Variant &r_v);
@@ -101,7 +104,7 @@ public:
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index ceb73cab77..643df53f8c 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -117,7 +117,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
return OK;
}
-RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);
@@ -130,7 +130,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_
return RES();
}
- RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error, p_use_sub_threads, r_progress);
+ RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_no_cache, r_error, p_use_sub_threads, r_progress);
#ifdef TOOLS_ENABLED
if (res.is_valid()) {
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index dbac80599a..6b76912494 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -58,7 +58,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
public:
static ResourceFormatImporter *get_singleton() { return singleton; }
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 05a41013c2..d90802d7e2 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -119,7 +119,7 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions)
}
}
-RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (get_script_instance() && get_script_instance()->has_method("load")) {
Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads);
@@ -200,7 +200,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
continue;
}
found = true;
- RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress);
+ RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_no_cache);
if (res.is_null()) {
continue;
}
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index be4adf9091..2d95d5545f 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -43,7 +43,7 @@ protected:
static void _bind_methods();
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual bool exists(const String &p_path) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 5da236d029..bce5361c76 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -185,7 +185,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
return translation;
}
-RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_CANT_OPEN;
diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h
index 9d3117b630..137dfd1768 100644
--- a/core/io/translation_loader_po.h
+++ b/core/io/translation_loader_po.h
@@ -38,7 +38,7 @@
class TranslationLoaderPO : public ResourceFormatLoader {
public:
static RES load_translation(FileAccess *f, Error *r_error = nullptr);
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 14079f811d..0f519a20d8 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -77,10 +77,6 @@ void Basis::invert() {
void Basis::orthonormalize() {
-#ifdef MATH_CHECKS
- ERR_FAIL_COND(determinant() == 0);
-#endif
-
// Gram-Schmidt Process
Vector3 x = get_axis(0);
diff --git a/core/method_bind.h b/core/method_bind.h
index 588b472b62..d39f107ba6 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -39,6 +39,7 @@
#include "core/method_ptrcall.h"
#include "core/object.h"
#include "core/type_info.h"
+#include "core/typedefs.h"
#include "core/variant.h"
#include <stdio.h>
diff --git a/core/object.h b/core/object.h
index 40032de271..b40aef2a42 100644
--- a/core/object.h
+++ b/core/object.h
@@ -60,7 +60,6 @@ enum PropertyHint {
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout")
PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
- PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat. Keeping now for GDNative compat.
PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
PROPERTY_HINT_LAYERS_2D_RENDER,
@@ -92,6 +91,7 @@ enum PropertyHint {
PROPERTY_HINT_NODE_PATH_VALID_TYPES,
PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
PROPERTY_HINT_INT_IS_OBJECTID,
+ PROPERTY_HINT_ARRAY_TYPE,
PROPERTY_HINT_MAX,
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
};
@@ -107,10 +107,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
PROPERTY_USAGE_CATEGORY = 256,
- // FIXME: Drop in 4.0, possibly reorder other flags?
- // Those below are deprecated thanks to ClassDB's now class value cache
- //PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero
- //PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false
+ PROPERTY_USAGE_SUBGROUP = 512,
PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
@@ -138,6 +135,7 @@ enum PropertyUsageFlags {
#define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index)
#define ADD_PROPERTY_DEFAULT(m_property, m_default) ClassDB::set_property_default_value(get_class_static(), m_property, m_default)
#define ADD_GROUP(m_name, m_prefix) ClassDB::add_property_group(get_class_static(), m_name, m_prefix)
+#define ADD_SUBGROUP(m_name, m_prefix) ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix)
struct PropertyInfo {
diff --git a/core/resource.cpp b/core/resource.cpp
index d1883d8043..8d5c441b21 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -477,6 +477,9 @@ void ResourceCache::clear() {
resources.clear();
memdelete(lock);
+#ifdef TOOLS_ENABLED
+ memdelete(path_cache_lock);
+#endif
}
void ResourceCache::reload_externals() {
diff --git a/core/rid.h b/core/rid.h
index 3cc0ee3084..a2f73423a3 100644
--- a/core/rid.h
+++ b/core/rid.h
@@ -31,11 +31,6 @@
#ifndef RID_H
#define RID_H
-#include "core/list.h"
-#include "core/oa_hash_map.h"
-#include "core/os/memory.h"
-#include "core/safe_refcount.h"
-#include "core/set.h"
#include "core/typedefs.h"
class RID_AllocBase;
diff --git a/core/rid_owner.h b/core/rid_owner.h
index 946b2e396c..ad6996b9a7 100644
--- a/core/rid_owner.h
+++ b/core/rid_owner.h
@@ -31,8 +31,13 @@
#ifndef RID_OWNER_H
#define RID_OWNER_H
+#include "core/list.h"
+#include "core/oa_hash_map.h"
+#include "core/os/memory.h"
#include "core/print_string.h"
#include "core/rid.h"
+#include "core/safe_refcount.h"
+#include "core/set.h"
#include "core/spin_lock.h"
#include <stdio.h>
#include <typeinfo>
diff --git a/core/script_language.h b/core/script_language.h
index 2d86c5166d..5cc240efcb 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -135,6 +135,8 @@ public:
virtual Ref<Script> get_base_script() const = 0; //for script inheritance
+ virtual bool inherits_script(const Ref<Script> &p_script) const = 0;
+
virtual StringName get_instance_base_type() const = 0; // this may not work in all scripts, will return empty if so
virtual ScriptInstance *instance_create(Object *p_this) = 0;
virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) { return nullptr; }
diff --git a/core/typed_array.cpp b/core/typed_array.cpp
new file mode 100644
index 0000000000..55e45f0b3f
--- /dev/null
+++ b/core/typed_array.cpp
@@ -0,0 +1 @@
+#include "typed_array.h"
diff --git a/core/typed_array.h b/core/typed_array.h
new file mode 100644
index 0000000000..5e95e81ea3
--- /dev/null
+++ b/core/typed_array.h
@@ -0,0 +1,202 @@
+#ifndef TYPED_ARRAY_H
+#define TYPED_ARRAY_H
+
+#include "core/array.h"
+#include "core/method_ptrcall.h"
+#include "core/variant.h"
+
+template <class T>
+class TypedArray : public Array {
+public:
+ template <class U>
+ _FORCE_INLINE_ void operator=(const TypedArray<U> &p_array) {
+ static_assert(__is_base_of(T, U));
+ _assign(p_array);
+ }
+
+ _FORCE_INLINE_ void operator=(const Array &p_array) {
+ _assign(p_array);
+ }
+ _FORCE_INLINE_ TypedArray(const Variant &p_variant) :
+ Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) {
+ }
+ _FORCE_INLINE_ TypedArray(const Array &p_array) :
+ Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) {
+ }
+ _FORCE_INLINE_ TypedArray() {
+ set_typed(Variant::OBJECT, T::get_class_static(), Variant());
+ }
+};
+
+//specialization for the rest of variant types
+
+#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \
+ template <> \
+ class TypedArray<m_type> : public Array { \
+ public: \
+ _FORCE_INLINE_ void operator=(const Array &p_array) { \
+ _assign(p_array); \
+ } \
+ _FORCE_INLINE_ TypedArray(const Variant &p_variant) : \
+ Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \
+ } \
+ _FORCE_INLINE_ TypedArray(const Array &p_array) : \
+ Array(p_array, m_variant_type, StringName(), Variant()) { \
+ } \
+ _FORCE_INLINE_ TypedArray() { \
+ set_typed(m_variant_type, StringName(), Variant()); \
+ } \
+ };
+
+MAKE_TYPED_ARRAY(bool, Variant::BOOL)
+MAKE_TYPED_ARRAY(uint8_t, Variant::INT)
+MAKE_TYPED_ARRAY(int8_t, Variant::INT)
+MAKE_TYPED_ARRAY(uint16_t, Variant::INT)
+MAKE_TYPED_ARRAY(int16_t, Variant::INT)
+MAKE_TYPED_ARRAY(uint32_t, Variant::INT)
+MAKE_TYPED_ARRAY(int32_t, Variant::INT)
+MAKE_TYPED_ARRAY(uint64_t, Variant::INT)
+MAKE_TYPED_ARRAY(int64_t, Variant::INT)
+MAKE_TYPED_ARRAY(float, Variant::FLOAT)
+MAKE_TYPED_ARRAY(double, Variant::FLOAT)
+MAKE_TYPED_ARRAY(String, Variant::STRING)
+MAKE_TYPED_ARRAY(Vector2, Variant::VECTOR2)
+MAKE_TYPED_ARRAY(Vector2i, Variant::VECTOR2I)
+MAKE_TYPED_ARRAY(Rect2, Variant::RECT2)
+MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I)
+MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3)
+MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I)
+MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D)
+MAKE_TYPED_ARRAY(Plane, Variant::PLANE)
+MAKE_TYPED_ARRAY(Quat, Variant::QUAT)
+MAKE_TYPED_ARRAY(AABB, Variant::AABB)
+MAKE_TYPED_ARRAY(Basis, Variant::BASIS)
+MAKE_TYPED_ARRAY(Transform, Variant::TRANSFORM)
+MAKE_TYPED_ARRAY(Color, Variant::COLOR)
+MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME)
+MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH)
+MAKE_TYPED_ARRAY(RID, Variant::_RID)
+MAKE_TYPED_ARRAY(Callable, Variant::CALLABLE)
+MAKE_TYPED_ARRAY(Signal, Variant::SIGNAL)
+MAKE_TYPED_ARRAY(Dictionary, Variant::DICTIONARY)
+MAKE_TYPED_ARRAY(Array, Variant::ARRAY)
+MAKE_TYPED_ARRAY(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY(Vector<String>, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
+
+#ifdef PTRCALL_ENABLED
+
+template <class T>
+struct PtrToArg<TypedArray<T>> {
+
+ _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
+
+ return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
+ }
+
+ _FORCE_INLINE_ static void encode(TypedArray<T> p_val, void *p_ptr) {
+
+ *(Array *)p_ptr = p_val;
+ }
+};
+
+template <class T>
+struct PtrToArg<const TypedArray<T> &> {
+
+ _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
+
+ return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
+ }
+};
+
+#endif // PTRCALL_ENABLED
+
+#ifdef DEBUG_METHODS_ENABLED
+
+template <class T>
+struct GetTypeInfo<TypedArray<T>> {
+ static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static());
+ }
+};
+
+template <class T>
+struct GetTypeInfo<const TypedArray<T> &> {
+ static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static());
+ }
+};
+
+#define MAKE_TYPED_ARRAY_INFO(m_type, m_variant_type) \
+ template <> \
+ struct GetTypeInfo<TypedArray<m_type>> { \
+ static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<const TypedArray<m_type> &> { \
+ static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \
+ } \
+ };
+
+MAKE_TYPED_ARRAY_INFO(bool, Variant::BOOL)
+MAKE_TYPED_ARRAY_INFO(uint8_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(int8_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(uint16_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(int16_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(uint32_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(int32_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(uint64_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(int64_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(float, Variant::FLOAT)
+MAKE_TYPED_ARRAY_INFO(double, Variant::FLOAT)
+MAKE_TYPED_ARRAY_INFO(String, Variant::STRING)
+MAKE_TYPED_ARRAY_INFO(Vector2, Variant::VECTOR2)
+MAKE_TYPED_ARRAY_INFO(Vector2i, Variant::VECTOR2I)
+MAKE_TYPED_ARRAY_INFO(Rect2, Variant::RECT2)
+MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I)
+MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3)
+MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I)
+MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D)
+MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE)
+MAKE_TYPED_ARRAY_INFO(Quat, Variant::QUAT)
+MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB)
+MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS)
+MAKE_TYPED_ARRAY_INFO(Transform, Variant::TRANSFORM)
+MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR)
+MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME)
+MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH)
+MAKE_TYPED_ARRAY_INFO(RID, Variant::_RID)
+MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE)
+MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL)
+MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY)
+MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
+
+#endif
+
+#endif // TYPED_ARRAY_H
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index 8bd5a4915d..62ad3e9f98 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -511,8 +511,7 @@ void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE));
ClassDB::bind_method(D_METHOD("commit_action"), &UndoRedo::commit_action);
- // FIXME: Typo in "commiting", fix in 4.0 when breaking compat.
- ClassDB::bind_method(D_METHOD("is_commiting_action"), &UndoRedo::is_committing_action);
+ ClassDB::bind_method(D_METHOD("is_committing_action"), &UndoRedo::is_committing_action);
{
MethodInfo mi;
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 8c6821eaac..71bbc271e2 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -12,9 +12,6 @@
<methods>
</methods>
<members>
- <member name="ARVRServer" type="ARVRServer" setter="" getter="">
- The [ARVRServer] singleton.
- </member>
<member name="AudioServer" type="AudioServer" setter="" getter="">
The [AudioServer] singleton.
</member>
@@ -30,9 +27,6 @@
<member name="Geometry" type="Geometry" setter="" getter="">
The [Geometry] singleton.
</member>
- <member name="GodotSharp" type="GodotSharp" setter="" getter="">
- The [GodotSharp] singleton. Only available when using Godot's Mono build.
- </member>
<member name="IP" type="IP" setter="" getter="">
The [IP] singleton.
</member>
@@ -95,6 +89,9 @@
<member name="VisualScriptEditor" type="VisualScriptEditor" setter="" getter="">
The [VisualScriptEditor] singleton.
</member>
+ <member name="XRServer" type="XRServer" setter="" getter="">
+ The [XRServer] singleton.
+ </member>
</members>
<constants>
<constant name="MARGIN_LEFT" value="0" enum="Margin">
@@ -1345,52 +1342,52 @@
<constant name="PROPERTY_HINT_LENGTH" value="5" enum="PropertyHint">
Deprecated hint, unused.
</constant>
- <constant name="PROPERTY_HINT_KEY_ACCEL" value="7" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_KEY_ACCEL" value="6" enum="PropertyHint">
Deprecated hint, unused.
</constant>
- <constant name="PROPERTY_HINT_FLAGS" value="8" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_FLAGS" value="7" enum="PropertyHint">
Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code].
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="9" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="8" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="10" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="9" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D physics layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="11" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="10" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="12" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="11" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D physics layers.
</constant>
- <constant name="PROPERTY_HINT_FILE" value="13" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_FILE" value="12" enum="PropertyHint">
Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_DIR" value="14" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_DIR" value="13" enum="PropertyHint">
Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_FILE" value="15" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_FILE" value="14" enum="PropertyHint">
Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_DIR" value="16" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_DIR" value="15" enum="PropertyHint">
Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="17" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="16" enum="PropertyHint">
Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate.
</constant>
- <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="18" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="17" enum="PropertyHint">
Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed.
</constant>
- <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="19" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="18" enum="PropertyHint">
Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use.
</constant>
- <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="20" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="19" enum="PropertyHint">
Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="21" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="20" enum="PropertyHint">
Hints that an image is compressed using lossy compression.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="22" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="21" enum="PropertyHint">
Hints that an image is compressed using lossless compression.
</constant>
<constant name="PROPERTY_USAGE_STORAGE" value="1" enum="PropertyUsageFlags">
@@ -1420,6 +1417,9 @@
<constant name="PROPERTY_USAGE_CATEGORY" value="256" enum="PropertyUsageFlags">
Used to categorize properties together in the editor.
</constant>
+ <constant name="PROPERTY_USAGE_SUBGROUP" value="512" enum="PropertyUsageFlags">
+ Used to group properties together in the editor in a subgroup (under a group).
+ </constant>
<constant name="PROPERTY_USAGE_NO_INSTANCE_STATE" value="2048" enum="PropertyUsageFlags">
The property does not save its state in [PackedScene].
</constant>
diff --git a/doc/classes/AudioStreamSample.xml b/doc/classes/AudioStreamSample.xml
index 6d99433c90..c12e1bd05c 100644
--- a/doc/classes/AudioStreamSample.xml
+++ b/doc/classes/AudioStreamSample.xml
@@ -30,13 +30,13 @@
Audio format. See [enum Format] constants for values.
</member>
<member name="loop_begin" type="int" setter="set_loop_begin" getter="get_loop_begin" default="0">
- Loop start in bytes.
+ The loop start point (in number of samples, relative to the beginning of the sample). This information will be imported automatically from the WAV file if present.
</member>
<member name="loop_end" type="int" setter="set_loop_end" getter="get_loop_end" default="0">
- Loop end in bytes.
+ The loop end point (in number of samples, relative to the beginning of the sample). This information will be imported automatically from the WAV file if present.
</member>
<member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" enum="AudioStreamSample.LoopMode" default="0">
- Loop mode. See [enum LoopMode] constants for values.
+ The loop mode. This information will be imported automatically from the WAV file if present. See [enum LoopMode] constants for values.
</member>
<member name="mix_rate" type="int" setter="set_mix_rate" getter="get_mix_rate" default="44100">
The sample rate for mixing this audio.
@@ -59,13 +59,13 @@
Audio does not loop.
</constant>
<constant name="LOOP_FORWARD" value="1" enum="LoopMode">
- Audio loops the data between [member loop_begin] and [member loop_end] playing forward only.
+ Audio loops the data between [member loop_begin] and [member loop_end], playing forward only.
</constant>
<constant name="LOOP_PING_PONG" value="2" enum="LoopMode">
- Audio loops the data between [member loop_begin] and [member loop_end] playing back and forth.
+ Audio loops the data between [member loop_begin] and [member loop_end], playing back and forth.
</constant>
<constant name="LOOP_BACKWARD" value="3" enum="LoopMode">
- Audio loops the data between [member loop_begin] and [member loop_end] playing backward only.
+ Audio loops the data between [member loop_begin] and [member loop_end], playing backward only.
</constant>
</constants>
</class>
diff --git a/doc/classes/BackBufferCopy.xml b/doc/classes/BackBufferCopy.xml
index 1f7554f978..7cc6a5613b 100644
--- a/doc/classes/BackBufferCopy.xml
+++ b/doc/classes/BackBufferCopy.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Node for back-buffering the currently-displayed screen. The region defined in the BackBufferCopy node is bufferized with the content of the screen it covers, or the entire screen according to the copy mode set. Use the [code]texture(SCREEN_TEXTURE, ...)[/code] function in your shader scripts to access the buffer.
+ [b]Note:[/b] Since this node inherits from [Node2D] (and not [Control]), anchors and margins won't apply to child [Control]-derived nodes. This can be problematic when resizing the window. To avoid this, add [Control]-derived nodes as [i]siblings[/i] to the BackBufferCopy node instead of adding them as children.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml
index 2147b2b4b0..5e908b0e53 100644
--- a/doc/classes/BaseButton.xml
+++ b/doc/classes/BaseButton.xml
@@ -60,6 +60,7 @@
</member>
<member name="keep_pressed_outside" type="bool" setter="set_keep_pressed_outside" getter="is_keep_pressed_outside" default="false">
If [code]true[/code], the button stays pressed when moving the cursor outside the button while pressing it.
+ [b]Note:[/b] This property only affects the button's visual appearance. Signals will be emitted at the same moment regardless of this property's value.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" default="false">
If [code]true[/code], the button's state is pressed. Means the button is pressed down or toggled (if [member toggle_mode] is active).
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index 5bb94d2858..76abc31451 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -108,6 +108,15 @@
<member name="ao_texture_channel" type="int" setter="set_ao_texture_channel" getter="get_ao_texture_channel" enum="BaseMaterial3D.TextureChannel">
Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
</member>
+ <member name="backlight" type="Color" setter="set_backlight" getter="get_backlight">
+ The color used by the backlight effect. Represents the light passing through an object.
+ </member>
+ <member name="backlight_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
+ If [code]true[/code], the backlight effect is enabled.
+ </member>
+ <member name="backlight_texture" type="Texture2D" setter="set_texture" getter="get_texture">
+ Texture used to control the backlight effect per-pixel. Added to [member backlight].
+ </member>
<member name="billboard_keep_scale" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the shader will keep the scale set for the mesh. Otherwise the scale is lost when billboarding. Only applies when [member billboard_mode] is [constant BILLBOARD_ENABLED].
</member>
@@ -296,6 +305,7 @@
Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
</member>
<member name="shading_mode" type="int" setter="set_shading_mode" getter="get_shading_mode" enum="BaseMaterial3D.ShadingMode" default="1">
+ Sets whether the shading takes place per-pixel or per-vertex. Per-vertex lighting is faster, making it the best choice for mobile applications, however it looks considerably worse than per-pixel.
</member>
<member name="shadow_to_opacity" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], enables the "shadow to opacity" render mode where lighting modifies the alpha so shadowed areas are opaque and non-shadowed areas are transparent. Useful for overlaying shadows onto a camera feed in AR.
@@ -307,6 +317,7 @@
If [code]true[/code], subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges.
</member>
<member name="subsurf_scatter_skin_mode" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code], subsurface scattering will use a special mode optimized for the color and density of human skin.
</member>
<member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength">
The strength of the subsurface scattering effect.
@@ -314,21 +325,24 @@
<member name="subsurf_scatter_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to control the subsurface scattering strength. Stored in the red texture channel. Multiplied by [member subsurf_scatter_strength].
</member>
+ <member name="subsurf_scatter_transmittance_boost" type="float" setter="set_transmittance_boost" getter="get_transmittance_boost">
+ </member>
+ <member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color">
+ </member>
+ <member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve">
+ </member>
+ <member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth">
+ </member>
+ <member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature">
+ </member>
+ <member name="subsurf_scatter_transmittance_texture" type="Texture2D" setter="set_texture" getter="get_texture">
+ </member>
<member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="BaseMaterial3D.TextureFilter" default="3">
Filter flags for the texture. See [enum TextureFilter] for options.
</member>
<member name="texture_repeat" type="bool" setter="set_flag" getter="get_flag" default="true">
Repeat flags for the texture. See [enum TextureFilter] for options.
</member>
- <member name="transmission" type="Color" setter="set_transmission" getter="get_transmission">
- The color used by the transmission effect. Represents the light passing through an object.
- </member>
- <member name="transmission_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
- If [code]true[/code], the transmission effect is enabled.
- </member>
- <member name="transmission_texture" type="Texture2D" setter="set_texture" getter="get_texture">
- Texture used to control the transmission effect per-pixel. Added to [member transmission].
- </member>
<member name="transparency" type="int" setter="set_transparency" getter="get_transparency" enum="BaseMaterial3D.Transparency" default="0">
If [code]true[/code], transparency is enabled on the body. See also [member blend_mode].
</member>
@@ -407,39 +421,47 @@
<constant name="TEXTURE_SUBSURFACE_SCATTERING" value="10" enum="TextureParam">
Texture specifying per-pixel subsurface scattering.
</constant>
- <constant name="TEXTURE_TRANSMISSION" value="11" enum="TextureParam">
- Texture specifying per-pixel transmission color.
+ <constant name="TEXTURE_SUBSURFACE_TRANSMITTANCE" value="11" enum="TextureParam">
+ Texture specifying per-pixel transmittance for subsurface scattering.
+ </constant>
+ <constant name="TEXTURE_BACKLIGHT" value="12" enum="TextureParam">
+ Texture specifying per-pixel backlight color.
</constant>
- <constant name="TEXTURE_REFRACTION" value="12" enum="TextureParam">
+ <constant name="TEXTURE_REFRACTION" value="13" enum="TextureParam">
Texture specifying per-pixel refraction strength.
</constant>
- <constant name="TEXTURE_DETAIL_MASK" value="13" enum="TextureParam">
+ <constant name="TEXTURE_DETAIL_MASK" value="14" enum="TextureParam">
Texture specifying per-pixel detail mask blending value.
</constant>
- <constant name="TEXTURE_DETAIL_ALBEDO" value="14" enum="TextureParam">
+ <constant name="TEXTURE_DETAIL_ALBEDO" value="15" enum="TextureParam">
Texture specifying per-pixel detail color.
</constant>
- <constant name="TEXTURE_DETAIL_NORMAL" value="15" enum="TextureParam">
+ <constant name="TEXTURE_DETAIL_NORMAL" value="16" enum="TextureParam">
Texture specifying per-pixel detail normal.
</constant>
- <constant name="TEXTURE_ORM" value="16" enum="TextureParam">
+ <constant name="TEXTURE_ORM" value="17" enum="TextureParam">
+ Texture holding ambient occlusion, roughness, and metallic.
</constant>
- <constant name="TEXTURE_MAX" value="17" enum="TextureParam">
+ <constant name="TEXTURE_MAX" value="18" enum="TextureParam">
Represents the size of the [enum TextureParam] enum.
</constant>
<constant name="TEXTURE_FILTER_NEAREST" value="0" enum="TextureFilter">
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
</constant>
<constant name="TEXTURE_FILTER_LINEAR" value="1" enum="TextureFilter">
- The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style.
+ The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="2" enum="TextureFilter">
+ The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="3" enum="TextureFilter">
+ The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for most cases as mipmaps are important to smooth out pixels that are far from the camera.
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="4" enum="TextureFilter">
+ The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
+ The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing.
</constant>
<constant name="TEXTURE_FILTER_MAX" value="6" enum="TextureFilter">
Represents the size of the [enum TextureFilter] enum.
@@ -457,8 +479,10 @@
The material will use the texture's alpha values for transparency.
</constant>
<constant name="TRANSPARENCY_ALPHA_SCISSOR" value="2" enum="Transparency">
+ The material will cut off all values below a threshold, the rest will remain opaque.
</constant>
<constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="3" enum="Transparency">
+ The material will use the texture's alpha value for transparency, but will still be rendered in the pre-pass.
</constant>
<constant name="TRANSPARENCY_MAX" value="4" enum="Transparency">
Represents the size of the [enum Transparency] enum.
@@ -494,20 +518,24 @@
Constant for setting [member ao_enabled].
</constant>
<constant name="FEATURE_HEIGHT_MAPPING" value="6" enum="Feature">
+ Constant for setting [member heightmap_enabled].
</constant>
- <constant name="FEATURE_SUBSURACE_SCATTERING" value="7" enum="Feature">
+ <constant name="FEATURE_SUBSURFACE_SCATTERING" value="7" enum="Feature">
Constant for setting [member subsurf_scatter_enabled].
</constant>
- <constant name="FEATURE_TRANSMISSION" value="8" enum="Feature">
- Constant for setting [member transmission_enabled].
+ <constant name="FEATURE_SUBSURFACE_TRANSMITTANCE" value="8" enum="Feature">
+ Constant for setting [member subsurf_scatter_transmittance_enabled].
+ </constant>
+ <constant name="FEATURE_BACKLIGHT" value="9" enum="Feature">
+ Constant for setting [member backlight_enabled].
</constant>
- <constant name="FEATURE_REFRACTION" value="9" enum="Feature">
+ <constant name="FEATURE_REFRACTION" value="10" enum="Feature">
Constant for setting [member refraction_enabled].
</constant>
- <constant name="FEATURE_DETAIL" value="10" enum="Feature">
+ <constant name="FEATURE_DETAIL" value="11" enum="Feature">
Constant for setting [member detail_enabled].
</constant>
- <constant name="FEATURE_MAX" value="11" enum="Feature">
+ <constant name="FEATURE_MAX" value="12" enum="Feature">
Represents the size of the [enum Feature] enum.
</constant>
<constant name="BLEND_MODE_MIX" value="0" enum="BlendMode">
@@ -589,11 +617,13 @@
Enables the shadow to opacity feature.
</constant>
<constant name="FLAG_USE_TEXTURE_REPEAT" value="16" enum="Flags">
+ Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture.
</constant>
<constant name="FLAG_INVERT_HEIGHTMAP" value="17" enum="Flags">
Invert values read from a depth texture to convert them to height values (heightmap).
</constant>
<constant name="FLAG_SUBSURFACE_MODE_SKIN" value="18" enum="Flags">
+ Enables the skin mode for subsurface scattering which is used to improve the look of subsurface scattering when used for human skin.
</constant>
<constant name="FLAG_MAX" value="19" enum="Flags">
Represents the size of the [enum Flags] enum.
diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml
index 73892481e6..ad49216b34 100644
--- a/doc/classes/Camera2D.xml
+++ b/doc/classes/Camera2D.xml
@@ -5,7 +5,8 @@
</brief_description>
<description>
Camera node for 2D scenes. It forces the screen (current layer) to scroll following this node. This makes it easier (and faster) to program scrollable scenes than manually changing the position of [CanvasItem]-based nodes.
- This node is intended to be a simple helper to get things going quickly and it may happen that more functionality is desired to change how the camera works. To make your own custom camera node, simply inherit from [Node2D] and change the transform of the canvas by calling get_viewport().set_canvas_transform(m) in [Viewport].
+ This node is intended to be a simple helper to get things going quickly and it may happen that more functionality is desired to change how the camera works. To make your own custom camera node, inherit from [Node2D] and change the transform of the canvas by setting [member Viewport.canvas_transform] in [Viewport] (you can obtain the current [Viewport] by using [method Node.get_viewport]).
+ Note that the [Camera2D] node's [code]position[/code] doesn't represent the actual position of the screen, which may differ due to applied smoothing or limits. You can use [method get_camera_screen_center] to get the real position.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CameraFeed.xml b/doc/classes/CameraFeed.xml
index 3232f5970c..4fc124592f 100644
--- a/doc/classes/CameraFeed.xml
+++ b/doc/classes/CameraFeed.xml
@@ -4,7 +4,7 @@
A camera feed gives you access to a single physical camera attached to your device.
</brief_description>
<description>
- A camera feed gives you access to a single physical camera attached to your device. When enabled, Godot will start capturing frames from the camera which can then be used.
+ A camera feed gives you access to a single physical camera attached to your device. When enabled, Godot will start capturing frames from the camera which can then be used. See also [CameraServer].
[b]Note:[/b] Many cameras will return YCbCr images which are split into two textures and need to be combined in a shader. Godot does this automatically for you if you set the environment to show the camera image in the background.
</description>
<tutorials>
diff --git a/doc/classes/CameraServer.xml b/doc/classes/CameraServer.xml
index 82d1faf716..e00dc031dc 100644
--- a/doc/classes/CameraServer.xml
+++ b/doc/classes/CameraServer.xml
@@ -6,6 +6,7 @@
<description>
The [CameraServer] keeps track of different cameras accessible in Godot. These are external cameras such as webcams or the cameras on your phone.
It is notably used to provide AR modules with a video feed from the camera.
+ [b]Note:[/b] This class is currently only implemented on macOS and iOS. On other platforms, no [CameraFeed]s will be available.
</description>
<tutorials>
</tutorials>
@@ -16,7 +17,7 @@
<argument index="0" name="feed" type="CameraFeed">
</argument>
<description>
- Adds a camera feed to the camera server.
+ Adds the camera [code]feed[/code] to the camera server.
</description>
</method>
<method name="feeds">
@@ -32,7 +33,7 @@
<argument index="0" name="index" type="int">
</argument>
<description>
- Returns the [CameraFeed] with this id.
+ Returns the [CameraFeed] corresponding to the camera with the given [code]index[/code].
</description>
</method>
<method name="get_feed_count">
@@ -48,7 +49,7 @@
<argument index="0" name="feed" type="CameraFeed">
</argument>
<description>
- Removes a [CameraFeed].
+ Removes the specified camera [code]feed[/code].
</description>
</method>
</methods>
@@ -57,14 +58,14 @@
<argument index="0" name="id" type="int">
</argument>
<description>
- Emitted when a [CameraFeed] is added (e.g. webcam is plugged in).
+ Emitted when a [CameraFeed] is added (e.g. a webcam is plugged in).
</description>
</signal>
<signal name="camera_feed_removed">
<argument index="0" name="id" type="int">
</argument>
<description>
- Emitted when a [CameraFeed] is removed (e.g. webcam is unplugged).
+ Emitted when a [CameraFeed] is removed (e.g. a webcam is unplugged).
</description>
</signal>
</signals>
@@ -73,7 +74,7 @@
The RGBA camera image.
</constant>
<constant name="FEED_YCBCR_IMAGE" value="0" enum="FeedImage">
- The YCbCr camera image.
+ The [url=https://en.wikipedia.org/wiki/YCbCr]YCbCr[/url] camera image.
</constant>
<constant name="FEED_Y_IMAGE" value="0" enum="FeedImage">
The Y component camera image.
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index f2ce2a6fb9..38e4453cf2 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -9,6 +9,7 @@
Canvas items are drawn in tree order. By default, children are on top of their parents so a root [CanvasItem] will be drawn behind everything. This behavior can be changed on a per-item basis.
A [CanvasItem] can also be hidden, which will also hide its children. It provides many ways to change parameters such as modulation (for itself and its children) and self modulation (only for itself), as well as its blend mode.
Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed.
+ [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad].
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 85a75fda37..0c8d42021a 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -838,7 +838,7 @@
Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. Also controls whether the control can receive the [signal mouse_entered], and [signal mouse_exited] signals. See the constants to learn what each does.
</member>
<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" default="false">
- Enables whether rendering of children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered.
+ Enables whether rendering of [CanvasItem] based children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered.
</member>
<member name="rect_global_position" type="Vector2" setter="_set_global_position" getter="get_global_position">
The node's global position, relative to the world (usually to the top-left corner of the window).
diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml
new file mode 100644
index 0000000000..f7329d1537
--- /dev/null
+++ b/doc/classes/Decal.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="Decal" inherits="VisualInstance3D" version="4.0">
+ <brief_description>
+ Node that projects a texture onto a [MeshInstance3D].
+ </brief_description>
+ <description>
+ [Decal]s are used to project a texture onto a [Mesh] in the scene. Use Decals to add detail to a scene without affecting the underlying [Mesh]. They are often used to add weathering to building, add dirt or mud to the ground, or add variety to props. Decals can be moved at any time, making them suitable for things like blob shadows or laser sight dots.
+ They are made of an [AABB] and a group of [Texture2D]s specifying [Color], normal, ORM (ambient occlusion, roughness, metallic), and emission. Decals are projected within their [AABB] so altering the orientation of the Decal affects the direction in which they are projected. By default, Decals are projected down (i.e. from positive Y to negative Y).
+ The [Texture2D]s associated with the Decal are automatically stored in a texture atlas which is used for drawing the decals so all decals can be drawn at once. Godot uses clustered decals, meaning they are stored in cluster data and drawn when the mesh is drawn, they are not drawn as a postprocessing effect after.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_texture" qualifiers="const">
+ <return type="Texture2D">
+ </return>
+ <argument index="0" name="type" type="int" enum="Decal.DecalTexture">
+ </argument>
+ <description>
+ Returns the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly.
+ For example, instead of [code]albedo_tex = $Decal.get_texture(Decal.TEXTURE_ALBEDO)[/code], use [code]albedo_tex = $Decal.texture_albedo[/code].
+ One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example:
+ [codeblock]
+ for i in Decal.TEXTURE_MAX:
+ $NewDecal.set_texture(i, $OldDecal.get_texture(i))
+ [/codeblock]
+ </description>
+ </method>
+ <method name="set_texture">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Decal.DecalTexture">
+ </argument>
+ <argument index="1" name="texture" type="Texture2D">
+ </argument>
+ <description>
+ Sets the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly.
+ For example, instead of [code]$Decal.set_texture(Decal.TEXTURE_ALBEDO, albedo_tex)[/code], use [code]$Decal.texture_albedo = albedo_tex[/code].
+ One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example:
+ [codeblock]
+ for i in Decal.TEXTURE_MAX:
+ $NewDecal.set_texture(i, $OldDecal.get_texture(i))
+ [/codeblock]
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="albedo_mix" type="float" setter="set_albedo_mix" getter="get_albedo_mix" default="1.0">
+ Blends the albedo [Color] of the decal with albedo [Color] of the underlying mesh.
+ </member>
+ <member name="cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask" default="1048575">
+ Specifies which [member VisualInstance3D.layers] this decal will project on. By default, Decals affect all layers. This is used so you can specify which types of objects receive the Decal and which do not. This is especially useful so you an ensure that dynamic objects don't accidentally receive a Decal intended for the terrain under them.
+ </member>
+ <member name="distance_fade_begin" type="float" setter="set_distance_fade_begin" getter="get_distance_fade_begin" default="10.0">
+ Distance from the camera at which the Decal begins to fade away.
+ </member>
+ <member name="distance_fade_enabled" type="bool" setter="set_enable_distance_fade" getter="is_distance_fade_enabled" default="false">
+ If [code]true[/code], decals will smoothly fade away when far from the active [Camera3D] starting at [member distance_fade_begin]. The Decal will fade out over [member distance_fade_length], after which it will be culled and not sent to the shader at all. Use this to reduce the number of active Decals in a scene and thus improve performance.
+ </member>
+ <member name="distance_fade_length" type="float" setter="set_distance_fade_length" getter="get_distance_fade_length" default="1.0">
+ Distance over which the Decal fades. The Decal becomes slowly more transparent over this distance and is completely invisible at the end.
+ </member>
+ <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy" default="1.0">
+ Energy multiplier for the emission texture. This will make the decal emit light at a higher intensity.
+ </member>
+ <member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3( 1, 1, 1 )">
+ Sets the size of the [AABB] used by the decal. The AABB goes from [code]-extents[/code] to [code]extents[/code].
+ </member>
+ <member name="lower_fade" type="float" setter="set_lower_fade" getter="get_lower_fade" default="0.3">
+ Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB].
+ </member>
+ <member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" default="Color( 1, 1, 1, 1 )">
+ Changes the [Color] of the Decal by multiplying it with this value.
+ </member>
+ <member name="normal_fade" type="float" setter="set_normal_fade" getter="get_normal_fade" default="0.0">
+ Fades the Decal if the angle between the Decal's [AABB] and the target surface becomes too large. A value of [code]0[/code] projects the Decal regardless of angle, a value of [code]1[/code] limits the Decal to surfaces that are nearly perpendicular.
+ </member>
+ <member name="texture_albedo" type="Texture2D" setter="set_texture" getter="get_texture">
+ [Texture2D] with the base [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object.
+ </member>
+ <member name="texture_emission" type="Texture2D" setter="set_texture" getter="get_texture">
+ [Texture2D] with the emission [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object.
+ </member>
+ <member name="texture_normal" type="Texture2D" setter="set_texture" getter="get_texture">
+ [Texture2D] with the per-pixel normalmap for the decal. Use this to add extra detail to decals.
+ </member>
+ <member name="texture_orm" type="Texture2D" setter="set_texture" getter="get_texture">
+ [Texture2D] storing ambient occlusion, roughness, and metallic for the decal. Use this to add extra detail to decals.
+ </member>
+ <member name="upper_fade" type="float" setter="set_upper_fade" getter="get_upper_fade" default="0.3">
+ Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB].
+ </member>
+ </members>
+ <constants>
+ <constant name="TEXTURE_ALBEDO" value="0" enum="DecalTexture">
+ [Texture2D] corresponding to [member texture_albedo].
+ </constant>
+ <constant name="TEXTURE_NORMAL" value="1" enum="DecalTexture">
+ [Texture2D] corresponding to [member texture_normal].
+ </constant>
+ <constant name="TEXTURE_ORM" value="2" enum="DecalTexture">
+ [Texture2D] corresponding to [member texture_orm].
+ </constant>
+ <constant name="TEXTURE_EMISSION" value="3" enum="DecalTexture">
+ [Texture2D] corresponding to [member texture_emission].
+ </constant>
+ <constant name="TEXTURE_MAX" value="4" enum="DecalTexture">
+ Max size of [enum DecalTexture] enum.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml
index 540ebf3931..e982e00d6d 100644
--- a/doc/classes/Dictionary.xml
+++ b/doc/classes/Dictionary.xml
@@ -4,27 +4,29 @@
Dictionary type.
</brief_description>
<description>
- Dictionary type. Associative container which contains values referenced by unique keys. Dictionary are composed of pairs of keys (which must be unique) and values. You can define a dictionary by placing a comma separated list of [code]key: value[/code] pairs in curly braces [code]{}[/code].
- Erasing elements while iterating over them [b]is not supported[/b].
+ Dictionary type. Associative container which contains values referenced by unique keys. Dictionaries are composed of pairs of keys (which must be unique) and values. Dictionaries will preserve the insertion order when adding elements, even though this may not be reflected when printing the dictionary. In other programming languages, this data structure is sometimes referred to as an hash map or associative array.
+ You can define a dictionary by placing a comma-separated list of [code]key: value[/code] pairs in curly braces [code]{}[/code].
+ Erasing elements while iterating over them [b]is not supported[/b] and will result in undefined behavior.
Creating a dictionary:
[codeblock]
var my_dir = {} # Creates an empty dictionary.
var points_dir = {"White": 50, "Yellow": 75, "Orange": 100}
- var my_dir = {
+ var another_dir = {
key1: value1,
key2: value2,
key3: value3,
}
[/codeblock]
- You can access values of a dictionary by referencing appropriate key in above example [code]points_dir["White"][/code] would return value of 50.
+ You can access a dictionary's values by referencing the appropriate key. In the above example, [code]points_dir["White"][/code] will return [code]50[/code]. You can also write [code]points_dir.White[/code], which is equivalent. However, you'll have to use the bracket syntax if the key you're accessing the dictionary with isn't a fixed string (such as a number or variable).
[codeblock]
export(String, "White", "Yellow", "Orange") var my_color
var points_dir = {"White": 50, "Yellow": 75, "Orange": 100}
func _ready():
+ # We can't use dot syntax here as `my_color` is a variable.
var points = points_dir[my_color]
[/codeblock]
- In the above code [code]points[/code] will be assigned the value that is paired with the appropriate color selected in [code]my_color[/code].
+ In the above code, [code]points[/code] will be assigned the value that is paired with the appropriate color selected in [code]my_color[/code].
Dictionaries can contain more complex data:
[codeblock]
my_dir = {"First Array": [1, 2, 3, 4]} # Assigns an Array to a String key.
@@ -32,13 +34,21 @@
To add a key to an existing dictionary, access it like an existing key and assign to it:
[codeblock]
var points_dir = {"White": 50, "Yellow": 75, "Orange": 100}
- var points_dir["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value.
+ points_dir["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value.
[/codeblock]
Finally, dictionaries can contain different types of keys and values in the same dictionary:
[codeblock]
- var my_dir = {"String Key": 5, 4: [1, 2, 3], 7: "Hello"} # This is a valid dictionary.
+ # This is a valid dictionary.
+ # To access the string "Nested value" below, use `my_dir.sub_dir.sub_key` or `my_dir["sub_dir"]["sub_key"]`.
+ # Indexing styles can be mixed and matched depending on your needs.
+ var my_dir = {
+ "String Key": 5,
+ 4: [1, 2, 3],
+ 7: "Hello",
+ "sub_dir": {"sub_key": "Nested value"},
+ }
[/codeblock]
- [b]Note:[/b] Unlike [Array]s you can't compare dictionaries directly:
+ [b]Note:[/b] Unlike [Array]s, you can't compare dictionaries directly:
[codeblock]
array1 = [1, 2, 3]
array2 = [1, 2, 3]
@@ -78,7 +88,7 @@
<argument index="0" name="deep" type="bool" default="false">
</argument>
<description>
- Creates a copy of the dictionary, and returns it.
+ Creates a copy of the dictionary, and returns it. The [code]deep[/code] parameter causes inner dictionaries and arrays to be copied recursively, but does not apply to objects.
</description>
</method>
<method name="empty">
diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml
index a5d476f5c8..6c88dcf42e 100644
--- a/doc/classes/DirectionalLight3D.xml
+++ b/doc/classes/DirectionalLight3D.xml
@@ -12,9 +12,6 @@
<methods>
</methods>
<members>
- <member name="directional_shadow_bias_split_scale" type="float" setter="set_param" getter="get_param" default="0.25">
- Amount of extra bias for shadow splits that are far away. If self-shadowing occurs only on the splits far away, increasing this value can fix them.
- </member>
<member name="directional_shadow_blend_splits" type="bool" setter="set_blend_splits" getter="is_blend_splits_enabled" default="false">
If [code]true[/code], shadow detail is sacrificed in exchange for smoother transitions between splits.
</member>
@@ -22,6 +19,7 @@
Optimizes shadow rendering for detail versus movement. See [enum ShadowDepthRange].
</member>
<member name="directional_shadow_fade_start" type="float" setter="set_param" getter="get_param" default="0.8">
+ Proportion of [member directional_shadow_max_distance] at which point the shadow starts to fade. At [member directional_shadow_max_distance] the shadow will disappear.
</member>
<member name="directional_shadow_max_distance" type="float" setter="set_param" getter="get_param" default="100.0">
The maximum distance for shadow splits.
@@ -29,8 +27,8 @@
<member name="directional_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" enum="DirectionalLight3D.ShadowMode" default="2">
The light's shadow rendering algorithm. See [enum ShadowMode].
</member>
- <member name="directional_shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="0.8">
- Can be used to fix special cases of self shadowing when objects are perpendicular to the light.
+ <member name="directional_shadow_pancake_size" type="float" setter="set_param" getter="get_param" default="20.0">
+ Sets the size of the directional shadow pancake. The pancake offsets the start of the shadow's camera frustum to provide a higher effective depth resolution for the shadow. However, a high pancake size can cause artifacts in the shadows of large objects that are close to the edge of the frustum. Reducing the pancake size can help. Setting the size to [code]0[/code] turns off the pancaking effect.
</member>
<member name="directional_shadow_split_1" type="float" setter="set_param" getter="get_param" default="0.1">
The distance from camera to shadow split 1. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or [code]SHADOW_PARALLEL_4_SPLITS[/code].
@@ -41,7 +39,6 @@
<member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5">
The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code].
</member>
- <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.1" />
</members>
<constants>
<constant name="SHADOW_ORTHOGONAL" value="0" enum="ShadowMode">
diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml
index 29e430b14d..0864c3ba36 100644
--- a/doc/classes/DynamicFont.xml
+++ b/doc/classes/DynamicFont.xml
@@ -12,6 +12,7 @@
dynamic_font.size = 64
$"Label".set("custom_fonts/font", dynamic_font)
[/codeblock]
+ [b]Note:[/b] DynamicFont doesn't support features such as right-to-left typesetting, ligatures, text shaping, variable fonts and optional font features yet. If you wish to "bake" an optional font feature into a TTF font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. In FontForge, use [b]File &gt; Generate Fonts[/b], click [b]Options[/b], choose the desired features then generate the font.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/EditorFeatureProfile.xml b/doc/classes/EditorFeatureProfile.xml
index 53db8dd293..eb03d3010f 100644
--- a/doc/classes/EditorFeatureProfile.xml
+++ b/doc/classes/EditorFeatureProfile.xml
@@ -72,7 +72,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
- Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] button.
+ Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] button.
</description>
</method>
<method name="set_disable_class">
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
index 61d240c1dc..99a78d147c 100644
--- a/doc/classes/EditorInspector.xml
+++ b/doc/classes/EditorInspector.xml
@@ -26,6 +26,12 @@
<description>
</description>
</signal>
+ <signal name="property_deleted">
+ <argument index="0" name="property" type="String">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="property_edited">
<argument index="0" name="property" type="String">
</argument>
diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml
index 3216541b20..4da3b58b94 100644
--- a/doc/classes/EditorProperty.xml
+++ b/doc/classes/EditorProperty.xml
@@ -78,6 +78,8 @@
<member name="checked" type="bool" setter="set_checked" getter="is_checked" default="false">
Used by the inspector, when the property is checked.
</member>
+ <member name="deletable" type="bool" setter="set_deletable" getter="is_deletable" default="false">
+ </member>
<member name="draw_red" type="bool" setter="set_draw_red" getter="is_draw_red" default="false">
Used by the inspector, when the property must draw with error color.
</member>
@@ -128,6 +130,12 @@
Emitted when a property was checked. Used internally.
</description>
</signal>
+ <signal name="property_deleted">
+ <argument index="0" name="property" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="property_keyed">
<argument index="0" name="property" type="StringName">
</argument>
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 6f55bfc229..3642d92771 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -265,18 +265,25 @@
Represents the size of the [enum BGMode] enum.
</constant>
<constant name="AMBIENT_SOURCE_BG" value="0" enum="AmbientSource">
+ Gather ambient light from whichever source is specified as the background.
</constant>
<constant name="AMBIENT_SOURCE_DISABLED" value="1" enum="AmbientSource">
+ Disable ambient light.
</constant>
<constant name="AMBIENT_SOURCE_COLOR" value="2" enum="AmbientSource">
+ Specify a specific [Color] for ambient light.
</constant>
<constant name="AMBIENT_SOURCE_SKY" value="3" enum="AmbientSource">
+ Gather ambient light from the [Sky] regardless of what the background is.
</constant>
<constant name="REFLECTION_SOURCE_BG" value="0" enum="ReflectionSource">
+ Use the background for reflections.
</constant>
<constant name="REFLECTION_SOURCE_DISABLED" value="1" enum="ReflectionSource">
+ Disable reflections.
</constant>
<constant name="REFLECTION_SOURCE_SKY" value="2" enum="ReflectionSource">
+ Use the [Sky] for reflections regardless of what the background is.
</constant>
<constant name="GLOW_BLEND_MODE_ADDITIVE" value="0" enum="GlowBlendMode">
Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources.
@@ -291,6 +298,7 @@
Replace glow blending mode. Replaces all pixels' color by the glow value. This can be used to simulate a full-screen blur effect by tweaking the glow parameters to match the original image's brightness.
</constant>
<constant name="GLOW_BLEND_MODE_MIX" value="4" enum="GlowBlendMode">
+ Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect.
</constant>
<constant name="TONE_MAPPER_LINEAR" value="0" enum="ToneMapper">
Linear tonemapper operator. Reads the linear data and passes it on unmodified.
@@ -314,7 +322,7 @@
2×2 blur for the screen-space ambient occlusion effect.
</constant>
<constant name="SSAO_BLUR_3x3" value="3" enum="SSAOBlur">
- 3×3 blur for the screen-space ambient occlusion effect (slowest).
+ 3×3 blur for the screen-space ambient occlusion effect. Increases the radius of the blur for a smoother look, but can result in checkerboard-like artifacts.
</constant>
</constants>
</class>
diff --git a/doc/classes/File.xml b/doc/classes/File.xml
index e9477517cf..17c65731ff 100644
--- a/doc/classes/File.xml
+++ b/doc/classes/File.xml
@@ -297,6 +297,7 @@
</argument>
<description>
Stores an integer as 16 bits in the file.
+ [b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, 2^16 - 1][/code].
</description>
</method>
<method name="store_32">
@@ -306,6 +307,7 @@
</argument>
<description>
Stores an integer as 32 bits in the file.
+ [b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, 2^32 - 1][/code].
</description>
</method>
<method name="store_64">
@@ -315,6 +317,7 @@
</argument>
<description>
Stores an integer as 64 bits in the file.
+ [b]Note:[/b] The [code]value[/code] must lie in the interval [code][-2^63, 2^63 - 1][/code] (i.e. be a valid [int] value).
</description>
</method>
<method name="store_8">
@@ -324,6 +327,7 @@
</argument>
<description>
Stores an integer as 8 bits in the file.
+ [b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, 255][/code].
</description>
</method>
<method name="store_buffer">
diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml
index 7df5f0ea50..518a172973 100644
--- a/doc/classes/GeometryInstance3D.xml
+++ b/doc/classes/GeometryInstance3D.xml
@@ -18,6 +18,14 @@
Returns the [enum GeometryInstance3D.Flags] that have been set for this object.
</description>
</method>
+ <method name="get_shader_instance_uniform" qualifiers="const">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="uniform" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_custom_aabb">
<return type="void">
</return>
@@ -38,6 +46,16 @@
Sets the [enum GeometryInstance3D.Flags] specified. See [enum GeometryInstance3D.Flags] for options.
</description>
</method>
+ <method name="set_shader_instance_uniform">
+ <return type="void">
+ </return>
+ <argument index="0" name="uniform" type="StringName">
+ </argument>
+ <argument index="1" name="value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="cast_shadow" type="int" setter="set_cast_shadows_setting" getter="get_cast_shadows_setting" enum="GeometryInstance3D.ShadowCastingSetting" default="1">
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index c41ffd4bff..750ac8085c 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -273,6 +273,12 @@
Emitted when a GraphNode is selected.
</description>
</signal>
+ <signal name="node_unselected">
+ <argument index="0" name="node" type="Node">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="paste_nodes_request">
<description>
Emitted when the user presses [code]Ctrl + V[/code].
diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml
index 2738958058..afe9d10d2e 100644
--- a/doc/classes/HSlider.xml
+++ b/doc/classes/HSlider.xml
@@ -19,6 +19,8 @@
<theme_item name="grabber_area" type="StyleBox">
The background of the area to the left of the grabber.
</theme_item>
+ <theme_item name="grabber_area_highlight" type="StyleBox">
+ </theme_item>
<theme_item name="grabber_disabled" type="Texture2D">
The texture for the grabber when it's disabled.
</theme_item>
diff --git a/doc/classes/IP_Unix.xml b/doc/classes/IP_Unix.xml
deleted file mode 100644
index 79cdf2ce08..0000000000
--- a/doc/classes/IP_Unix.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="IP_Unix" inherits="IP" version="4.0">
- <brief_description>
- UNIX IP support. See [IP].
- </brief_description>
- <description>
- UNIX-specific implementation of IP support functions. See [IP].
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index f541b0ae66..8cffe07fc0 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Native image datatype. Contains image data, which can be converted to a [Texture2D], and several functions to interact with it. The maximum width and height for an [Image] are [constant MAX_WIDTH] and [constant MAX_HEIGHT].
+ [b]Note:[/b] The maximum image size is 16384×16384 pixels due to graphics hardware limitations. Larger images will fail to import.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml
index 1578783b8b..d122d74e85 100644
--- a/doc/classes/ImageTexture.xml
+++ b/doc/classes/ImageTexture.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
A [Texture2D] based on an [Image]. Can be created from an [Image] with [method create_from_image].
+ [b]Note:[/b] The maximum image size is 16384×16384 pixels due to graphics hardware limitations. Larger images will fail to import.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/MonoGCHandle.xml b/doc/classes/JNISingleton.xml
index 1e33dd1359..84ab1a49c1 100644
--- a/doc/classes/MonoGCHandle.xml
+++ b/doc/classes/JNISingleton.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="MonoGCHandle" inherits="Reference" version="4.0">
+<class name="JNISingleton" inherits="Object" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml
index 4e48a24951..cb21db2d00 100644
--- a/doc/classes/Light3D.xml
+++ b/doc/classes/Light3D.xml
@@ -35,6 +35,9 @@
<member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only" default="false">
If [code]true[/code], the light only appears in the editor and will not be visible at runtime.
</member>
+ <member name="light_angular_distance" type="float" setter="set_param" getter="get_param" default="0.0">
+ Angular size of the light in degrees. Only available for [DirectionalLight3D]s. For reference, the sun from earth is approximately [code]0.5[/code].
+ </member>
<member name="light_bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="Light3D.BakeMode" default="1">
The light's bake mode. See [enum BakeMode].
</member>
@@ -53,24 +56,35 @@
<member name="light_negative" type="bool" setter="set_negative" getter="is_negative" default="false">
If [code]true[/code], the light's effect is reversed, darkening areas and casting bright shadows.
</member>
+ <member name="light_projector" type="Texture2D" setter="set_projector" getter="get_projector">
+ [Texture2D] projected by light. [member shadow_enabled] must be on for the projector to work. Light projectors make the light appear as if it is shining through a colored but transparent object, almost like light shining through stained glass.
+ </member>
+ <member name="light_size" type="float" setter="set_param" getter="get_param" default="0.0">
+ The size of the light in Godot units. Only available for [OmniLight3D]s and [SpotLight3D]s.
+ </member>
<member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5">
The intensity of the specular blob in objects affected by the light. At [code]0[/code] the light becomes a pure diffuse light.
</member>
- <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.15">
+ <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.02">
Used to adjust shadow appearance. Too small a value results in self-shadowing, while too large a value causes shadows to separate from casters. Adjust as needed.
</member>
+ <member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0">
+ Blurs the edges of the shadow. Can be used to hide pixel artifacts in low resolution shadow maps. A high value can make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible.
+ </member>
<member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color( 0, 0, 0, 1 )">
The color of shadows cast by this light.
</member>
- <member name="shadow_contact" type="float" setter="set_param" getter="get_param" default="0.0">
- Attempts to reduce [member shadow_bias] gap.
- </member>
<member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false">
If [code]true[/code], the light will cast shadows.
</member>
+ <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="1.0">
+ Offsets the lookup into the shadow map by the objects normal. This can be used reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible.
+ </member>
<member name="shadow_reverse_cull_face" type="bool" setter="set_shadow_reverse_cull_face" getter="get_shadow_reverse_cull_face" default="false">
If [code]true[/code], reverses the backface culling of the mesh. This can be useful when you have a flat mesh that has a light behind it. If you need to cast a shadow on both sides of the mesh, set the mesh to use double-sided shadows with [constant GeometryInstance3D.SHADOW_CASTING_SETTING_DOUBLE_SIDED].
</member>
+ <member name="shadow_transmittance_bias" type="float" setter="set_param" getter="get_param" default="0.05">
+ </member>
</members>
<constants>
<constant name="PARAM_ENERGY" value="0" enum="Param">
@@ -85,18 +99,18 @@
<constant name="PARAM_RANGE" value="3" enum="Param">
Constant for accessing [member OmniLight3D.omni_range] or [member SpotLight3D.spot_range].
</constant>
- <constant name="PARAM_ATTENUATION" value="4" enum="Param">
+ <constant name="PARAM_SIZE" value="4" enum="Param">
+ Constant for accessing [member light_size].
+ </constant>
+ <constant name="PARAM_ATTENUATION" value="5" enum="Param">
Constant for accessing [member OmniLight3D.omni_attenuation] or [member SpotLight3D.spot_attenuation].
</constant>
- <constant name="PARAM_SPOT_ANGLE" value="5" enum="Param">
+ <constant name="PARAM_SPOT_ANGLE" value="6" enum="Param">
Constant for accessing [member SpotLight3D.spot_angle].
</constant>
- <constant name="PARAM_SPOT_ATTENUATION" value="6" enum="Param">
+ <constant name="PARAM_SPOT_ATTENUATION" value="7" enum="Param">
Constant for accessing [member SpotLight3D.spot_angle_attenuation].
</constant>
- <constant name="PARAM_CONTACT_SHADOW_SIZE" value="7" enum="Param">
- Constant for accessing [member shadow_contact].
- </constant>
<constant name="PARAM_SHADOW_MAX_DISTANCE" value="8" enum="Param">
Constant for accessing [member DirectionalLight3D.directional_shadow_max_distance].
</constant>
@@ -110,17 +124,24 @@
Constant for accessing [member DirectionalLight3D.directional_shadow_split_3].
</constant>
<constant name="PARAM_SHADOW_FADE_START" value="12" enum="Param">
+ Constant for accessing [member DirectionalLight3D.directional_shadow_fade_start].
</constant>
<constant name="PARAM_SHADOW_NORMAL_BIAS" value="13" enum="Param">
- Constant for accessing [member DirectionalLight3D.directional_shadow_normal_bias].
+ Constant for accessing [member shadow_normal_bias].
</constant>
<constant name="PARAM_SHADOW_BIAS" value="14" enum="Param">
Constant for accessing [member shadow_bias].
</constant>
- <constant name="PARAM_SHADOW_BIAS_SPLIT_SCALE" value="15" enum="Param">
- Constant for accessing [member DirectionalLight3D.directional_shadow_bias_split_scale].
+ <constant name="PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="Param">
+ Constant for accessing [member DirectionalLight3D.directional_shadow_pancake_size].
+ </constant>
+ <constant name="PARAM_SHADOW_BLUR" value="16" enum="Param">
+ Constant for accessing [member shadow_blur].
+ </constant>
+ <constant name="PARAM_TRANSMITTANCE_BIAS" value="17" enum="Param">
+ Constant for accessing [member shadow_transmittance_bias].
</constant>
- <constant name="PARAM_MAX" value="16" enum="Param">
+ <constant name="PARAM_MAX" value="18" enum="Param">
Represents the size of the [enum Param] enum.
</constant>
<constant name="BAKE_DISABLED" value="0" enum="BakeMode">
diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml
index ef24f638fb..3e7d4d4c05 100644
--- a/doc/classes/Node3D.xml
+++ b/doc/classes/Node3D.xml
@@ -6,6 +6,7 @@
<description>
Most basic 3D game object, with a 3D [Transform] and visibility settings. All other 3D game objects inherit from Node3D. Use [Node3D] as a parent node to move, scale, rotate and show/hide children in a 3D project.
Affine operations (rotate, scale, translate) happen in parent's local coordinate system, unless the [Node3D] object is set as top-level. Affine operations in this coordinate system correspond to direct affine operations on the [Node3D]'s transform. The word local below refers to this coordinate system. The coordinate system that is attached to the [Node3D] object itself is referred to as object-local coordinate system.
+ [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad].
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/3d/introduction_to_3d.html</link>
diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml
index 5cb2aaf314..39d974ec47 100644
--- a/doc/classes/OptionButton.xml
+++ b/doc/classes/OptionButton.xml
@@ -214,14 +214,14 @@
</members>
<signals>
<signal name="item_focused">
- <argument index="0" name="id" type="int">
+ <argument index="0" name="index" type="int">
</argument>
<description>
Emitted the when user navigates to an item using the [code]ui_up[/code] or [code]ui_down[/code] actions. The index of the item selected is passed as argument.
</description>
</signal>
<signal name="item_selected">
- <argument index="0" name="id" type="int">
+ <argument index="0" name="index" type="int">
</argument>
<description>
Emitted when the current item has been changed by the user. The index of the item selected is passed as argument.
diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml
index e422545b7b..2d70dea012 100644
--- a/doc/classes/PackedScene.xml
+++ b/doc/classes/PackedScene.xml
@@ -9,23 +9,25 @@
[b]Note:[/b] The node doesn't need to own itself.
[b]Example of saving a node with different owners:[/b] The following example creates 3 objects: [code]Node2D[/code] ([code]node[/code]), [code]RigidBody2D[/code] ([code]rigid[/code]) and [code]CollisionObject2D[/code] ([code]collision[/code]). [code]collision[/code] is a child of [code]rigid[/code] which is a child of [code]node[/code]. Only [code]rigid[/code] is owned by [code]node[/code] and [code]pack[/code] will therefore only save those two nodes, but not [code]collision[/code].
[codeblock]
- # Create the objects
+ # Create the objects.
var node = Node2D.new()
var rigid = RigidBody2D.new()
var collision = CollisionShape2D.new()
- # Create the object hierarchy
+ # Create the object hierarchy.
rigid.add_child(collision)
node.add_child(rigid)
- # Change owner of rigid, but not of collision
+ # Change owner of `rigid`, but not of `collision`.
rigid.owner = node
var scene = PackedScene.new()
- # Only node and rigid are now packed
+ # Only `node` and `rigid` are now packed.
var result = scene.pack(node)
if result == OK:
- ResourceSaver.save("res://path/name.scn", scene) # Or "user://..."
+ var error = ResourceSaver.save("res://path/name.scn", scene) # Or "user://..."
+ if error != OK:
+ push_error("An error occurred while saving the scene to disk.")
[/codeblock]
</description>
<tutorials>
diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml
index d45c72ee87..58930aae37 100644
--- a/doc/classes/PhysicalBone3D.xml
+++ b/doc/classes/PhysicalBone3D.xml
@@ -25,6 +25,14 @@
<description>
</description>
</method>
+ <method name="get_axis_lock" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_bone_id" qualifiers="const">
<return type="int">
</return>
@@ -43,23 +51,74 @@
<description>
</description>
</method>
+ <method name="set_axis_lock">
+ <return type="void">
+ </return>
+ <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis">
+ </argument>
+ <argument index="1" name="lock" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
+ <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" default="-1.0">
+ Damps the body's rotation if greater than [code]0[/code].
+ </member>
+ <member name="axis_lock_angular_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ Lock the body's rotation in the X axis.
+ </member>
+ <member name="axis_lock_angular_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ Lock the body's rotation in the Y axis.
+ </member>
+ <member name="axis_lock_angular_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ Lock the body's rotation in the Z axis.
+ </member>
+ <member name="axis_lock_linear_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ Lock the body's movement in the X axis.
+ </member>
+ <member name="axis_lock_linear_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ Lock the body's movement in the Y axis.
+ </member>
+ <member name="axis_lock_linear_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ Lock the body's movement in the Z axis.
+ </member>
<member name="body_offset" type="Transform" setter="set_body_offset" getter="get_body_offset" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
+ Sets the body's transform.
</member>
<member name="bounce" type="float" setter="set_bounce" getter="get_bounce" default="0.0">
+ The body's bounciness. Values range from [code]0[/code] (no bounce) to [code]1[/code] (full bounciness).
+ </member>
+ <member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" default="true">
+ If [code]true[/code], the body is deactivated when there is no movement, so it will not take part in the simulation until it is awaken by an external force.
</member>
<member name="friction" type="float" setter="set_friction" getter="get_friction" default="1.0">
+ The body's friction, from [code]0[/code] (frictionless) to [code]1[/code] (max friction).
</member>
<member name="gravity_scale" type="float" setter="set_gravity_scale" getter="get_gravity_scale" default="1.0">
+ This is multiplied by the global 3D gravity setting found in [b]Project &gt; Project Settings &gt; Physics &gt; 3d[/b] to produce the body's gravity. For example, a value of 1 will be normal gravity, 2 will apply double gravity, and 0.5 will apply half gravity to this object.
</member>
<member name="joint_offset" type="Transform" setter="set_joint_offset" getter="get_joint_offset" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
+ Sets the joint's transform.
+ </member>
+ <member name="joint_rotation" type="Vector3" setter="set_joint_rotation" getter="get_joint_rotation">
+ Sets the joint's rotation in radians.
+ </member>
+ <member name="joint_rotation_degrees" type="Vector3" setter="set_joint_rotation_degrees" getter="get_joint_rotation_degrees" default="Vector3( 0, 0, 0 )">
+ Sets the joint's rotation in degrees.
</member>
<member name="joint_type" type="int" setter="set_joint_type" getter="get_joint_type" enum="PhysicalBone3D.JointType" default="0">
+ Sets the joint type. See [enum JointType] for possible values.
+ </member>
+ <member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" default="-1.0">
+ Damps the body's movement if greater than [code]0[/code].
</member>
<member name="mass" type="float" setter="set_mass" getter="get_mass" default="1.0">
+ The body's mass.
</member>
<member name="weight" type="float" setter="set_weight" getter="get_weight" default="9.8">
+ The body's weight based on its mass and the global 3D gravity. Global values are set in [b]Project &gt; Project Settings &gt; Physics &gt; 3d[/b].
</member>
</members>
<constants>
diff --git a/doc/classes/PhysicsDirectBodyState2DSW.xml b/doc/classes/PhysicsDirectBodyState2DSW.xml
deleted file mode 100644
index 94fc4213b7..0000000000
--- a/doc/classes/PhysicsDirectBodyState2DSW.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="PhysicsDirectBodyState2DSW" inherits="PhysicsDirectBodyState2D" version="4.0">
- <brief_description>
- Software implementation of [PhysicsDirectBodyState2D].
- </brief_description>
- <description>
- Software implementation of [PhysicsDirectBodyState2D]. This object exposes no new methods or properties and should not be used, as [PhysicsDirectBodyState2D] selects the best implementation available.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/PhysicsDirectSpaceState3D.xml b/doc/classes/PhysicsDirectSpaceState3D.xml
index 09ee93732d..ea094dcd90 100644
--- a/doc/classes/PhysicsDirectSpaceState3D.xml
+++ b/doc/classes/PhysicsDirectSpaceState3D.xml
@@ -19,7 +19,7 @@
</argument>
<description>
Checks whether the shape can travel to a point. The method will return an array with two floats between 0 and 1, both representing a fraction of [code]motion[/code]. The first is how far the shape can move without triggering a collision, and the second is the point at which a collision will occur. If no collision is detected, the returned array will be [code][1, 1][/code].
- If the shape can not move, the returned array will be [code][0, 0][/code] under Bullet, and empty under GodotPhysics.
+ If the shape can not move, the returned array will be [code][0, 0][/code] under Bullet, and empty under GodotPhysics3D.
</description>
</method>
<method name="collide_shape">
diff --git a/doc/classes/PhysicsServer2DSW.xml b/doc/classes/PhysicsServer2DSW.xml
deleted file mode 100644
index dac5e360f0..0000000000
--- a/doc/classes/PhysicsServer2DSW.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="PhysicsServer2DSW" inherits="PhysicsServer2D" version="4.0">
- <brief_description>
- Software implementation of [PhysicsServer2D].
- </brief_description>
- <description>
- This class exposes no new methods or properties and should not be used, as [PhysicsServer2D] automatically selects the best implementation available.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/ProceduralSkyMaterial.xml b/doc/classes/ProceduralSkyMaterial.xml
index 70e82d248c..d3e1dbca27 100644
--- a/doc/classes/ProceduralSkyMaterial.xml
+++ b/doc/classes/ProceduralSkyMaterial.xml
@@ -40,11 +40,8 @@
<member name="sun_angle_max" type="float" setter="set_sun_angle_max" getter="get_sun_angle_max" default="100.0">
Distance from center of sun where it fades out completely.
</member>
- <member name="sun_angle_min" type="float" setter="set_sun_angle_min" getter="get_sun_angle_min" default="1.0">
- Distance from sun where it goes from solid to starting to fade.
- </member>
<member name="sun_curve" type="float" setter="set_sun_curve" getter="get_sun_curve" default="0.05">
- How quickly the sun fades away between [member sun_angle_min] and [member sun_angle_max].
+ How quickly the sun fades away between the edge of the sun disk and [member sun_angle_max].
</member>
</members>
<constants>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 3a4e516d86..4eb089e511 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -806,18 +806,6 @@
<member name="memory/limits/multithreaded_server/rid_pool_prealloc" type="int" setter="" getter="" default="60">
This is used by servers when used in multi-threading mode (servers and visual). RIDs are preallocated to avoid stalling the server requesting them on threads. If servers get stalled too often when loading resources in a thread, increase this number.
</member>
- <member name="mono/debugger_agent/port" type="int" setter="" getter="" default="23685">
- </member>
- <member name="mono/debugger_agent/wait_for_debugger" type="bool" setter="" getter="" default="false">
- </member>
- <member name="mono/debugger_agent/wait_timeout" type="int" setter="" getter="" default="3000">
- </member>
- <member name="mono/profiler/args" type="String" setter="" getter="" default="&quot;log:calls,alloc,sample,output=output.mlpd&quot;">
- </member>
- <member name="mono/profiler/enabled" type="bool" setter="" getter="" default="false">
- </member>
- <member name="mono/unhandled_exception_policy" type="int" setter="" getter="" default="0">
- </member>
<member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="32768">
Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
</member>
@@ -911,7 +899,7 @@
</member>
<member name="physics/2d/physics_engine" type="String" setter="" getter="" default="&quot;DEFAULT&quot;">
Sets which physics engine to use for 2D physics.
- "DEFAULT" and "GodotPhysics" are the same, as there is currently no alternative 2D physics server implemented.
+ "DEFAULT" and "GodotPhysics2D" are the same, as there is currently no alternative 2D physics server implemented.
</member>
<member name="physics/2d/sleep_threshold_angular" type="float" setter="" getter="" default="0.139626">
Threshold angular velocity under which a 2D physics body will be considered inactive. See [constant PhysicsServer2D.SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD].
@@ -953,7 +941,7 @@
</member>
<member name="physics/3d/physics_engine" type="String" setter="" getter="" default="&quot;DEFAULT&quot;">
Sets which physics engine to use for 3D physics.
- "DEFAULT" is currently the [url=https://bulletphysics.org]Bullet[/url] physics engine. The "GodotPhysics" engine is still supported as an alternative.
+ "DEFAULT" is currently the [url=https://bulletphysics.org]Bullet[/url] physics engine. The "GodotPhysics3D" engine is still supported as an alternative.
</member>
<member name="physics/common/enable_object_picking" type="bool" setter="" getter="" default="true">
Enables [member Viewport.physics_object_picking] on the root viewport.
@@ -972,6 +960,8 @@
<member name="rendering/environment/default_environment" type="String" setter="" getter="" default="&quot;&quot;">
[Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here.
</member>
+ <member name="rendering/high_end/global_shader_variables_buffer_size" type="int" setter="" getter="" default="65536">
+ </member>
<member name="rendering/limits/rendering/max_renderable_elements" type="int" setter="" getter="" default="128000">
Max amount of elements renderable in a frame. If more than this are visible per frame, they will be dropped. Keep in mind elements refer to mesh surfaces and not meshes themselves.
</member>
@@ -982,6 +972,15 @@
<member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="" default="false">
If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. May help in some pixel art styles.
</member>
+ <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2">
+ Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother.
+ </member>
+ <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1">
+ Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the fastest. Circle is the most realistic, but also the most expensive to compute.
+ </member>
+ <member name="rendering/quality/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples.
+ </member>
<member name="rendering/quality/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default="&quot;PowerVR,Mali,Adreno,Apple&quot;">
Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this.
</member>
@@ -994,38 +993,29 @@
<member name="rendering/quality/directional_shadow/size.mobile" type="int" setter="" getter="" default="2048">
Lower-end override for [member rendering/quality/directional_shadow/size] on mobile devices, due to performance concerns or driver support.
</member>
+ <member name="rendering/quality/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="2">
+ Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
+ </member>
+ <member name="rendering/quality/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/quality/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
+ </member>
<member name="rendering/quality/driver/driver_name" type="String" setter="" getter="" default="&quot;Vulkan&quot;">
The video driver to use ("GLES2" or "Vulkan").
[b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument.
[b]FIXME:[/b] No longer valid after DisplayServer split:
In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time.
</member>
- <member name="rendering/quality/filters/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2">
- </member>
- <member name="rendering/quality/filters/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1">
- </member>
- <member name="rendering/quality/filters/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
- </member>
- <member name="rendering/quality/filters/max_anisotropy" type="int" setter="" getter="" default="4">
- </member>
- <member name="rendering/quality/filters/msaa" type="int" setter="" getter="" default="0">
- Sets the number of MSAA samples to use. 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.
- [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend.
- </member>
- <member name="rendering/quality/filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0">
- </member>
- <member name="rendering/quality/filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0">
- </member>
- <member name="rendering/quality/filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false">
- If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used.
- </member>
<member name="rendering/quality/gi_probes/anisotropic" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], take additional samples when rendering objects affected by a [GIProbe] to reduce artifacts from only sampling in one direction.
</member>
<member name="rendering/quality/gi_probes/quality" type="int" setter="" getter="" default="1">
+ Sets the number of cone samples taken when rendering objects affected by [GIProbe]s.
</member>
<member name="rendering/quality/glow/upscale_mode" type="int" setter="" getter="" default="1">
+ Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth.
</member>
<member name="rendering/quality/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/quality/glow/upscale_mode] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/quality/intended_usage/framebuffer_allocation" type="int" setter="" getter="" default="2">
Strategy used for framebuffer allocation. The simpler it is, the less resources it uses (but the less features it supports). If set to "2D Without Sampling" or "3D Without Effects", sample buffers will not be allocated. This means [code]SCREEN_TEXTURE[/code] and [code]DEPTH_TEXTURE[/code] will not be available in shaders and post-processing effects will not be available in the [Environment].
@@ -1060,7 +1050,22 @@
<member name="rendering/quality/reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false">
Lower-end override for [member rendering/quality/reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support.
</member>
+ <member name="rendering/quality/screen_filters/msaa" type="int" setter="" getter="" default="0">
+ Sets the number of MSAA samples to use. 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.
+ [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend.
+ </member>
+ <member name="rendering/quality/screen_filters/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.
+ Another way to combat specular aliasing is to enable [member rendering/quality/screen_filters/screen_space_roughness_limiter].
+ </member>
+ <member name="rendering/quality/screen_filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0">
+ Enables the screen-space roughness limiter which increases material roughness in areas with a high normal frequency (i.e. when normals change a lot from pixel to pixel). This helps to reduce the amount of specular aliasing in a scene. Specular aliasing looks like random bright pixels that occur in reflections.
+ </member>
+ <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0">
+ Curves the amount of the roughness limited effect. A higher value limits the effect to very sharply curved surfaces, while a lower threshold extends the effect to smoother surfaces.
+ </member>
<member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1">
+ Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better.
</member>
<member name="rendering/quality/shading/force_blinn_over_ggx" type="bool" setter="" getter="" default="false">
If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model.
@@ -1098,21 +1103,33 @@
<member name="rendering/quality/shadow_atlas/size.mobile" type="int" setter="" getter="" default="2048">
Lower-end override for [member rendering/quality/shadow_atlas/size] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/quality/shadows/filter_mode" type="int" setter="" getter="" default="1">
- Shadow filter mode. Higher-quality settings result in smoother shadows that flicker less when moving. "Disabled" is the fastest option, but also has the lowest quality. "PCF5" is smoother but is also slower. "PCF13" is the smoothest option, but is also the slowest.
+ <member name="rendering/quality/shadows/soft_shadow_quality" type="int" setter="" getter="" default="2">
+ Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
</member>
- <member name="rendering/quality/shadows/filter_mode.mobile" type="int" setter="" getter="" default="0">
- Lower-end override for [member rendering/quality/shadows/filter_mode] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/quality/shadows/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/quality/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/quality/ssao/half_size" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details.
</member>
<member name="rendering/quality/ssao/quality" type="int" setter="" getter="" default="1">
+ Sets the quality of the screen-space ambient occlusion effect. Higher values take more samples and so will result in better quality, at the cost of performance.
</member>
<member name="rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale" type="float" setter="" getter="" default="0.01">
+ Scales the depth over which the subsurface scattering effect is applied. A high value may allow light to scatter into a part of the mesh or another mesh that is close in screen space but far in depth.
</member>
<member name="rendering/quality/subsurface_scattering/subsurface_scattering_quality" type="int" setter="" getter="" default="1">
+ Sets the quality of the subsurface scattering effect. Higher values are slower but look nicer.
</member>
<member name="rendering/quality/subsurface_scattering/subsurface_scattering_scale" type="float" setter="" getter="" default="0.05">
+ Scales the distance over which samples are taken for subsurface scattering effect. Changing this does not impact performance, but higher values will result in significant artifacts as the samples will become obviously spread out. A lower value results in a smaller spread of scattered light.
+ </member>
+ <member name="rendering/quality/texture_filters/max_anisotropy" type="int" setter="" getter="" default="4">
+ Sets the maximum number of samples to take when using anisotropic filtering on textures. A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute.
+ Only power of two values are valid ([code]1[/code], [code]2[/code], [code]4[/code], [code]8[/code], [code]16[/code]). A value of [code]1[/code] forcibly disables anisotropic filtering, even on materials where it is enabled.
+ </member>
+ <member name="rendering/quality/texture_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used.
</member>
<member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1">
Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter.
diff --git a/doc/classes/RDAttachmentFormat.xml b/doc/classes/RDAttachmentFormat.xml
new file mode 100644
index 0000000000..4ee7b9b28e
--- /dev/null
+++ b/doc/classes/RDAttachmentFormat.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDAttachmentFormat" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="36">
+ </member>
+ <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0">
+ </member>
+ <member name="usage_flags" type="int" setter="set_usage_flags" getter="get_usage_flags" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineColorBlendState.xml b/doc/classes/RDPipelineColorBlendState.xml
new file mode 100644
index 0000000000..7cb31f6986
--- /dev/null
+++ b/doc/classes/RDPipelineColorBlendState.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineColorBlendState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_attachment">
+ <return type="void">
+ </return>
+ <argument index="0" name="atachment" type="RDPipelineColorBlendStateAttachment">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="add_blend_mix_attachment">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="add_no_blend_attachment">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="clear_attachments">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_attachments" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="blend_constant" type="Color" setter="set_blend_constant" getter="get_blend_constant" default="Color( 0, 0, 0, 1 )">
+ </member>
+ <member name="enable_logic_op" type="bool" setter="set_enable_logic_op" getter="get_enable_logic_op" default="false">
+ </member>
+ <member name="logic_op" type="int" setter="set_logic_op" getter="get_logic_op" enum="RenderingDevice.LogicOperation" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineColorBlendStateAttachment.xml b/doc/classes/RDPipelineColorBlendStateAttachment.xml
new file mode 100644
index 0000000000..a4caa622aa
--- /dev/null
+++ b/doc/classes/RDPipelineColorBlendStateAttachment.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineColorBlendStateAttachment" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="alpha_blend_op" type="int" setter="set_alpha_blend_op" getter="get_alpha_blend_op" enum="RenderingDevice.BlendOperation" default="0">
+ </member>
+ <member name="color_blend_op" type="int" setter="set_color_blend_op" getter="get_color_blend_op" enum="RenderingDevice.BlendOperation" default="0">
+ </member>
+ <member name="dst_alpha_blend_factor" type="int" setter="set_dst_alpha_blend_factor" getter="get_dst_alpha_blend_factor" enum="RenderingDevice.BlendFactor" default="0">
+ </member>
+ <member name="dst_color_blend_factor" type="int" setter="set_dst_color_blend_factor" getter="get_dst_color_blend_factor" enum="RenderingDevice.BlendFactor" default="0">
+ </member>
+ <member name="enable_blend" type="bool" setter="set_enable_blend" getter="get_enable_blend" default="false">
+ </member>
+ <member name="src_alpha_blend_factor" type="int" setter="set_src_alpha_blend_factor" getter="get_src_alpha_blend_factor" enum="RenderingDevice.BlendFactor" default="0">
+ </member>
+ <member name="src_color_blend_factor" type="int" setter="set_src_color_blend_factor" getter="get_src_color_blend_factor" enum="RenderingDevice.BlendFactor" default="0">
+ </member>
+ <member name="write_a" type="bool" setter="set_write_a" getter="get_write_a" default="true">
+ </member>
+ <member name="write_b" type="bool" setter="set_write_b" getter="get_write_b" default="true">
+ </member>
+ <member name="write_g" type="bool" setter="set_write_g" getter="get_write_g" default="true">
+ </member>
+ <member name="write_r" type="bool" setter="set_write_r" getter="get_write_r" default="true">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineDepthStencilState.xml b/doc/classes/RDPipelineDepthStencilState.xml
new file mode 100644
index 0000000000..562ff52819
--- /dev/null
+++ b/doc/classes/RDPipelineDepthStencilState.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineDepthStencilState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="back_op_compare" type="int" setter="set_back_op_compare" getter="get_back_op_compare" enum="RenderingDevice.CompareOperator" default="7">
+ </member>
+ <member name="back_op_compare_mask" type="int" setter="set_back_op_compare_mask" getter="get_back_op_compare_mask" default="0">
+ </member>
+ <member name="back_op_depth_fail" type="int" setter="set_back_op_depth_fail" getter="get_back_op_depth_fail" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="back_op_fail" type="int" setter="set_back_op_fail" getter="get_back_op_fail" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="back_op_pass" type="int" setter="set_back_op_pass" getter="get_back_op_pass" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="back_op_reference" type="int" setter="set_back_op_reference" getter="get_back_op_reference" default="0">
+ </member>
+ <member name="back_op_write_mask" type="int" setter="set_back_op_write_mask" getter="get_back_op_write_mask" default="0">
+ </member>
+ <member name="depth_compare_operator" type="int" setter="set_depth_compare_operator" getter="get_depth_compare_operator" enum="RenderingDevice.CompareOperator" default="7">
+ </member>
+ <member name="depth_range_max" type="float" setter="set_depth_range_max" getter="get_depth_range_max" default="0.0">
+ </member>
+ <member name="depth_range_min" type="float" setter="set_depth_range_min" getter="get_depth_range_min" default="0.0">
+ </member>
+ <member name="enable_depth_range" type="bool" setter="set_enable_depth_range" getter="get_enable_depth_range" default="false">
+ </member>
+ <member name="enable_depth_test" type="bool" setter="set_enable_depth_test" getter="get_enable_depth_test" default="false">
+ </member>
+ <member name="enable_depth_write" type="bool" setter="set_enable_depth_write" getter="get_enable_depth_write" default="false">
+ </member>
+ <member name="enable_stencil" type="bool" setter="set_enable_stencil" getter="get_enable_stencil" default="false">
+ </member>
+ <member name="front_op_compare" type="int" setter="set_front_op_compare" getter="get_front_op_compare" enum="RenderingDevice.CompareOperator" default="7">
+ </member>
+ <member name="front_op_compare_mask" type="int" setter="set_front_op_compare_mask" getter="get_front_op_compare_mask" default="0">
+ </member>
+ <member name="front_op_depth_fail" type="int" setter="set_front_op_depth_fail" getter="get_front_op_depth_fail" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="front_op_fail" type="int" setter="set_front_op_fail" getter="get_front_op_fail" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="front_op_pass" type="int" setter="set_front_op_pass" getter="get_front_op_pass" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="front_op_reference" type="int" setter="set_front_op_reference" getter="get_front_op_reference" default="0">
+ </member>
+ <member name="front_op_write_mask" type="int" setter="set_front_op_write_mask" getter="get_front_op_write_mask" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineMultisampleState.xml b/doc/classes/RDPipelineMultisampleState.xml
new file mode 100644
index 0000000000..b936ded4fe
--- /dev/null
+++ b/doc/classes/RDPipelineMultisampleState.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineMultisampleState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_sample_mask">
+ <return type="void">
+ </return>
+ <argument index="0" name="mask" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="clear_sample_masks">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sample_masks" qualifiers="const">
+ <return type="PackedInt64Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="enable_alpha_to_coverage" type="bool" setter="set_enable_alpha_to_coverage" getter="get_enable_alpha_to_coverage" default="false">
+ </member>
+ <member name="enable_alpha_to_one" type="bool" setter="set_enable_alpha_to_one" getter="get_enable_alpha_to_one" default="false">
+ </member>
+ <member name="enable_sample_shading" type="bool" setter="set_enable_sample_shading" getter="get_enable_sample_shading" default="false">
+ </member>
+ <member name="min_sample_shading" type="float" setter="set_min_sample_shading" getter="get_min_sample_shading" default="0.0">
+ </member>
+ <member name="sample_count" type="int" setter="set_sample_count" getter="get_sample_count" enum="RenderingDevice.TextureSamples" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineRasterizationState.xml b/doc/classes/RDPipelineRasterizationState.xml
new file mode 100644
index 0000000000..5064dd6deb
--- /dev/null
+++ b/doc/classes/RDPipelineRasterizationState.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineRasterizationState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" enum="RenderingDevice.PolygonCullMode" default="0">
+ </member>
+ <member name="depth_bias_clamp" type="float" setter="set_depth_bias_clamp" getter="get_depth_bias_clamp" default="0.0">
+ </member>
+ <member name="depth_bias_constant_factor" type="float" setter="set_depth_bias_constant_factor" getter="get_depth_bias_constant_factor" default="0.0">
+ </member>
+ <member name="depth_bias_enable" type="bool" setter="set_depth_bias_enable" getter="get_depth_bias_enable" default="false">
+ </member>
+ <member name="depth_bias_slope_factor" type="float" setter="set_depth_bias_slope_factor" getter="get_depth_bias_slope_factor" default="0.0">
+ </member>
+ <member name="discard_primitives" type="bool" setter="set_discard_primitives" getter="get_discard_primitives" default="false">
+ </member>
+ <member name="enable_depth_clamp" type="bool" setter="set_enable_depth_clamp" getter="get_enable_depth_clamp" default="false">
+ </member>
+ <member name="front_face" type="int" setter="set_front_face" getter="get_front_face" enum="RenderingDevice.PolygonFrontFace" default="0">
+ </member>
+ <member name="line_width" type="float" setter="set_line_width" getter="get_line_width" default="1.0">
+ </member>
+ <member name="patch_control_points" type="int" setter="set_patch_control_points" getter="get_patch_control_points" default="1">
+ </member>
+ <member name="wireframe" type="bool" setter="set_wireframe" getter="get_wireframe" default="false">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDSamplerState.xml b/doc/classes/RDSamplerState.xml
new file mode 100644
index 0000000000..ab31960b7c
--- /dev/null
+++ b/doc/classes/RDSamplerState.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDSamplerState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="anisotropy_max" type="float" setter="set_anisotropy_max" getter="get_anisotropy_max" default="1.0">
+ </member>
+ <member name="border_color" type="int" setter="set_border_color" getter="get_border_color" enum="RenderingDevice.SamplerBorderColor" default="2">
+ </member>
+ <member name="compare_op" type="int" setter="set_compare_op" getter="get_compare_op" enum="RenderingDevice.CompareOperator" default="7">
+ </member>
+ <member name="enable_compare" type="bool" setter="set_enable_compare" getter="get_enable_compare" default="false">
+ </member>
+ <member name="lod_bias" type="float" setter="set_lod_bias" getter="get_lod_bias" default="0.0">
+ </member>
+ <member name="mag_filter" type="int" setter="set_mag_filter" getter="get_mag_filter" enum="RenderingDevice.SamplerFilter" default="0">
+ </member>
+ <member name="max_lod" type="float" setter="set_max_lod" getter="get_max_lod" default="1e+20">
+ </member>
+ <member name="min_filter" type="int" setter="set_min_filter" getter="get_min_filter" enum="RenderingDevice.SamplerFilter" default="0">
+ </member>
+ <member name="min_lod" type="float" setter="set_min_lod" getter="get_min_lod" default="0.0">
+ </member>
+ <member name="mip_filter" type="int" setter="set_mip_filter" getter="get_mip_filter" enum="RenderingDevice.SamplerFilter" default="0">
+ </member>
+ <member name="repeat_u" type="int" setter="set_repeat_u" getter="get_repeat_u" enum="RenderingDevice.SamplerRepeatMode" default="2">
+ </member>
+ <member name="repeat_v" type="int" setter="set_repeat_v" getter="get_repeat_v" enum="RenderingDevice.SamplerRepeatMode" default="2">
+ </member>
+ <member name="repeat_w" type="int" setter="set_repeat_w" getter="get_repeat_w" enum="RenderingDevice.SamplerRepeatMode" default="2">
+ </member>
+ <member name="unnormalized_uvw" type="bool" setter="set_unnormalized_uvw" getter="get_unnormalized_uvw" default="false">
+ </member>
+ <member name="use_anisotropy" type="bool" setter="set_use_anisotropy" getter="get_use_anisotropy" default="false">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDShaderBytecode.xml b/doc/classes/RDShaderBytecode.xml
new file mode 100644
index 0000000000..7a3501004e
--- /dev/null
+++ b/doc/classes/RDShaderBytecode.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDShaderBytecode" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_stage_bytecode" qualifiers="const">
+ <return type="PackedByteArray">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_stage_compile_error" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stage_bytecode">
+ <return type="void">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <argument index="1" name="bytecode" type="PackedByteArray">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stage_compile_error">
+ <return type="void">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <argument index="1" name="compile_error" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="bytecode_compute" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="bytecode_fragment" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="bytecode_tesselation_control" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="bytecode_tesselation_evaluation" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="bytecode_vertex" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="compile_error_compute" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ <member name="compile_error_fragment" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ <member name="compile_error_tesselation_control" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ <member name="compile_error_tesselation_evaluation" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ <member name="compile_error_vertex" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDShaderFile.xml b/doc/classes/RDShaderFile.xml
new file mode 100644
index 0000000000..14e70d53ea
--- /dev/null
+++ b/doc/classes/RDShaderFile.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDShaderFile" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_bytecode" qualifiers="const">
+ <return type="RDShaderBytecode">
+ </return>
+ <argument index="0" name="version" type="StringName" default="@&quot;&quot;">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_version_list" qualifiers="const">
+ <return type="PackedStringArray">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_bytecode">
+ <return type="void">
+ </return>
+ <argument index="0" name="bytecode" type="RDShaderBytecode">
+ </argument>
+ <argument index="1" name="version" type="StringName" default="@&quot;&quot;">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="base_error" type="String" setter="set_base_error" getter="get_base_error" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDShaderSource.xml b/doc/classes/RDShaderSource.xml
new file mode 100644
index 0000000000..c1cfd34bb7
--- /dev/null
+++ b/doc/classes/RDShaderSource.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDShaderSource" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_stage_source" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stage_source">
+ <return type="void">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <argument index="1" name="source" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="language" type="int" setter="set_language" getter="get_language" enum="RenderingDevice.ShaderLanguage" default="0">
+ </member>
+ <member name="source_compute" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ <member name="source_fragment" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ <member name="source_tesselation_control" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ <member name="source_tesselation_evaluation" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ <member name="source_vertex" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDTextureFormat.xml b/doc/classes/RDTextureFormat.xml
new file mode 100644
index 0000000000..664d4cadff
--- /dev/null
+++ b/doc/classes/RDTextureFormat.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDTextureFormat" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_shareable_format">
+ <return type="void">
+ </return>
+ <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="remove_shareable_format">
+ <return type="void">
+ </return>
+ <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="array_layers" type="int" setter="set_array_layers" getter="get_array_layers" default="1">
+ </member>
+ <member name="depth" type="int" setter="set_depth" getter="get_depth" default="1">
+ </member>
+ <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="8">
+ </member>
+ <member name="height" type="int" setter="set_height" getter="get_height" default="1">
+ </member>
+ <member name="mipmaps" type="int" setter="set_mipmaps" getter="get_mipmaps" default="1">
+ </member>
+ <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0">
+ </member>
+ <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.TextureType" default="1">
+ </member>
+ <member name="usage_bits" type="int" setter="set_usage_bits" getter="get_usage_bits" default="0">
+ </member>
+ <member name="width" type="int" setter="set_width" getter="get_width" default="1">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDTextureView.xml b/doc/classes/RDTextureView.xml
new file mode 100644
index 0000000000..73b2a7ae4a
--- /dev/null
+++ b/doc/classes/RDTextureView.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDTextureView" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="format_override" type="int" setter="set_format_override" getter="get_format_override" enum="RenderingDevice.DataFormat" default="226">
+ </member>
+ <member name="swizzle_a" type="int" setter="set_swizzle_a" getter="get_swizzle_a" enum="RenderingDevice.TextureSwizzle" default="6">
+ </member>
+ <member name="swizzle_b" type="int" setter="set_swizzle_b" getter="get_swizzle_b" enum="RenderingDevice.TextureSwizzle" default="5">
+ </member>
+ <member name="swizzle_g" type="int" setter="set_swizzle_g" getter="get_swizzle_g" enum="RenderingDevice.TextureSwizzle" default="4">
+ </member>
+ <member name="swizzle_r" type="int" setter="set_swizzle_r" getter="get_swizzle_r" enum="RenderingDevice.TextureSwizzle" default="3">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDUniform.xml b/doc/classes/RDUniform.xml
new file mode 100644
index 0000000000..e5bace32af
--- /dev/null
+++ b/doc/classes/RDUniform.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDUniform" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_id">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="clear_ids">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_ids" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="binding" type="int" setter="set_binding" getter="get_binding" default="0">
+ </member>
+ <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.UniformType" default="3">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDVertexDescription.xml b/doc/classes/RDVertexDescription.xml
new file mode 100644
index 0000000000..90e37ee023
--- /dev/null
+++ b/doc/classes/RDVertexDescription.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDVertexDescription" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="226">
+ </member>
+ <member name="frequency" type="int" setter="set_frequency" getter="get_frequency" enum="RenderingDevice.VertexFrequency" default="0">
+ </member>
+ <member name="location" type="int" setter="set_location" getter="get_location" default="0">
+ </member>
+ <member name="offset" type="int" setter="set_offset" getter="get_offset" default="0">
+ </member>
+ <member name="stride" type="int" setter="set_stride" getter="get_stride" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index 2615f0a2e9..6d68eafc70 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -7,7 +7,1593 @@
<tutorials>
</tutorials>
<methods>
+ <method name="buffer_get_data">
+ <return type="PackedByteArray">
+ </return>
+ <argument index="0" name="buffer" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="buffer_update">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="buffer" type="RID">
+ </argument>
+ <argument index="1" name="offset" type="int">
+ </argument>
+ <argument index="2" name="size_bytes" type="int">
+ </argument>
+ <argument index="3" name="data" type="PackedByteArray">
+ </argument>
+ <argument index="4" name="sync_with_draw" type="bool" default="true">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="capture_timestamp">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="sync_to_draw" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_add_barrier">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_begin">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_bind_compute_pipeline">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <argument index="1" name="compute_pipeline" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_bind_uniform_set">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <argument index="1" name="uniform_set" type="RID">
+ </argument>
+ <argument index="2" name="set_index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_dispatch">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <argument index="1" name="x_groups" type="int">
+ </argument>
+ <argument index="2" name="y_groups" type="int">
+ </argument>
+ <argument index="3" name="z_groups" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_end">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_set_push_constant">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <argument index="1" name="buffer" type="PackedByteArray">
+ </argument>
+ <argument index="2" name="size_bytes" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_pipeline_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="shader" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_pipeline_is_valid">
+ <return type="bool">
+ </return>
+ <argument index="0" name="compute_pieline" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="create_local_device">
+ <return type="RenderingDevice">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_begin">
+ <return type="int">
+ </return>
+ <argument index="0" name="framebuffer" type="RID">
+ </argument>
+ <argument index="1" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction">
+ </argument>
+ <argument index="2" name="final_color_action" type="int" enum="RenderingDevice.FinalAction">
+ </argument>
+ <argument index="3" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction">
+ </argument>
+ <argument index="4" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction">
+ </argument>
+ <argument index="5" name="clear_color_values" type="PackedColorArray" default="PackedColorArray( )">
+ </argument>
+ <argument index="6" name="clear_depth" type="float" default="1.0">
+ </argument>
+ <argument index="7" name="clear_stencil" type="int" default="0">
+ </argument>
+ <argument index="8" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_begin_for_screen">
+ <return type="int">
+ </return>
+ <argument index="0" name="screen" type="int" default="0">
+ </argument>
+ <argument index="1" name="clear_color" type="Color" default="Color( 0, 0, 0, 1 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_begin_split">
+ <return type="PackedInt64Array">
+ </return>
+ <argument index="0" name="framebuffer" type="RID">
+ </argument>
+ <argument index="1" name="splits" type="int">
+ </argument>
+ <argument index="2" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction">
+ </argument>
+ <argument index="3" name="final_color_action" type="int" enum="RenderingDevice.FinalAction">
+ </argument>
+ <argument index="4" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction">
+ </argument>
+ <argument index="5" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction">
+ </argument>
+ <argument index="6" name="clear_color_values" type="PackedColorArray" default="PackedColorArray( )">
+ </argument>
+ <argument index="7" name="clear_depth" type="float" default="1.0">
+ </argument>
+ <argument index="8" name="clear_stencil" type="int" default="0">
+ </argument>
+ <argument index="9" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_bind_index_array">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="index_array" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_bind_render_pipeline">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="render_pipeline" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_bind_uniform_set">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="uniform_set" type="RID">
+ </argument>
+ <argument index="2" name="set_index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_bind_vertex_array">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="vertex_array" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_disable_scissor">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_draw">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="use_indices" type="bool">
+ </argument>
+ <argument index="2" name="instances" type="int">
+ </argument>
+ <argument index="3" name="procedural_vertex_count" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_enable_scissor">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="rect" type="Rect2" default="Rect2i( 0, 0, 0, 0 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_end">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_set_push_constant">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="buffer" type="PackedByteArray">
+ </argument>
+ <argument index="2" name="size_bytes" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="framebuffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="textures" type="Array">
+ </argument>
+ <argument index="1" name="validate_with_format" type="int" default="-1">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="framebuffer_format_create">
+ <return type="int">
+ </return>
+ <argument index="0" name="attachments" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="framebuffer_format_get_texture_samples">
+ <return type="int" enum="RenderingDevice.TextureSamples">
+ </return>
+ <argument index="0" name="format" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="framebuffer_get_format">
+ <return type="int">
+ </return>
+ <argument index="0" name="framebuffer" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="free">
+ <return type="void">
+ </return>
+ <argument index="0" name="rid" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamp_cpu_time" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamp_gpu_time" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamp_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamps_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamps_frame" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_frame_delay" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="index_array_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="index_buffer" type="RID">
+ </argument>
+ <argument index="1" name="index_offset" type="int">
+ </argument>
+ <argument index="2" name="index_count" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="index_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_indices" type="int">
+ </argument>
+ <argument index="1" name="format" type="int" enum="RenderingDevice.IndexBufferFormat">
+ </argument>
+ <argument index="2" name="data" type="PackedByteArray">
+ </argument>
+ <argument index="3" name="arg3" type="bool" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="limit_get">
+ <return type="int">
+ </return>
+ <argument index="0" name="limit" type="int" enum="RenderingDevice.Limit">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="render_pipeline_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="shader" type="RID">
+ </argument>
+ <argument index="1" name="framebuffer_format" type="int">
+ </argument>
+ <argument index="2" name="vertex_format" type="int">
+ </argument>
+ <argument index="3" name="primitive" type="int" enum="RenderingDevice.RenderPrimitive">
+ </argument>
+ <argument index="4" name="rasterization_state" type="RDPipelineRasterizationState">
+ </argument>
+ <argument index="5" name="multisample_state" type="RDPipelineMultisampleState">
+ </argument>
+ <argument index="6" name="stencil_state" type="RDPipelineDepthStencilState">
+ </argument>
+ <argument index="7" name="color_blend_state" type="RDPipelineColorBlendState">
+ </argument>
+ <argument index="8" name="dynamic_state_flags" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="render_pipeline_is_valid">
+ <return type="bool">
+ </return>
+ <argument index="0" name="render_pipeline" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="sampler_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="state" type="RDSamplerState">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="screen_get_framebuffer_format" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="screen_get_height" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="screen" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="screen_get_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="screen" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shader_compile_from_source">
+ <return type="RDShaderBytecode">
+ </return>
+ <argument index="0" name="shader_source" type="RDShaderSource">
+ </argument>
+ <argument index="1" name="allow_cache" type="bool" default="true">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shader_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="shader_data" type="RDShaderBytecode">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shader_get_vertex_input_attribute_mask">
+ <return type="int">
+ </return>
+ <argument index="0" name="shader" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="storage_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_bytes" type="int">
+ </argument>
+ <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="submit">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="sync">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="texture_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_bytes" type="int">
+ </argument>
+ <argument index="1" name="format" type="int" enum="RenderingDevice.DataFormat">
+ </argument>
+ <argument index="2" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_clear">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <argument index="1" name="color" type="Color">
+ </argument>
+ <argument index="2" name="base_mipmap" type="int">
+ </argument>
+ <argument index="3" name="mipmap_count" type="int">
+ </argument>
+ <argument index="4" name="base_layer" type="int">
+ </argument>
+ <argument index="5" name="layer_count" type="int">
+ </argument>
+ <argument index="6" name="sync_with_draw" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_copy">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="from_texture" type="RID">
+ </argument>
+ <argument index="1" name="to_texture" type="RID">
+ </argument>
+ <argument index="2" name="from_pos" type="Vector3">
+ </argument>
+ <argument index="3" name="to_pos" type="Vector3">
+ </argument>
+ <argument index="4" name="size" type="Vector3">
+ </argument>
+ <argument index="5" name="src_mipmap" type="int">
+ </argument>
+ <argument index="6" name="dst_mipmap" type="int">
+ </argument>
+ <argument index="7" name="src_layer" type="int">
+ </argument>
+ <argument index="8" name="dst_layer" type="int">
+ </argument>
+ <argument index="9" name="sync_with_draw" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="format" type="RDTextureFormat">
+ </argument>
+ <argument index="1" name="view" type="RDTextureView">
+ </argument>
+ <argument index="2" name="data" type="Array" default="[ ]">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_create_shared">
+ <return type="RID">
+ </return>
+ <argument index="0" name="view" type="RDTextureView">
+ </argument>
+ <argument index="1" name="with_texture" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_create_shared_from_slice">
+ <return type="RID">
+ </return>
+ <argument index="0" name="view" type="RDTextureView">
+ </argument>
+ <argument index="1" name="with_texture" type="RID">
+ </argument>
+ <argument index="2" name="layer" type="int">
+ </argument>
+ <argument index="3" name="mipmap" type="int">
+ </argument>
+ <argument index="4" name="slice_type" type="int" enum="RenderingDevice.TextureSliceType" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_get_data">
+ <return type="PackedByteArray">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <argument index="1" name="layer" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_is_format_supported_for_usage" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat">
+ </argument>
+ <argument index="1" name="usage_flags" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_is_shared">
+ <return type="bool">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_is_valid">
+ <return type="bool">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_resolve_multisample">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="from_texture" type="RID">
+ </argument>
+ <argument index="1" name="to_texture" type="RID">
+ </argument>
+ <argument index="2" name="sync_with_draw" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_update">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <argument index="1" name="layer" type="int">
+ </argument>
+ <argument index="2" name="data" type="PackedByteArray">
+ </argument>
+ <argument index="3" name="sync_with_draw" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="uniform_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_bytes" type="int">
+ </argument>
+ <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="uniform_set_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="uniforms" type="Array">
+ </argument>
+ <argument index="1" name="shader" type="RID">
+ </argument>
+ <argument index="2" name="shader_set" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="uniform_set_is_valid">
+ <return type="bool">
+ </return>
+ <argument index="0" name="uniform_set" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="vertex_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_bytes" type="int">
+ </argument>
+ <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="vertex_format_create">
+ <return type="int">
+ </return>
+ <argument index="0" name="vertex_descriptions" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<constants>
+ <constant name="DATA_FORMAT_R4G4_UNORM_PACK8" value="0" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R4G4B4A4_UNORM_PACK16" value="1" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B4G4R4A4_UNORM_PACK16" value="2" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R5G6B5_UNORM_PACK16" value="3" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B5G6R5_UNORM_PACK16" value="4" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R5G5B5A1_UNORM_PACK16" value="5" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B5G5R5A1_UNORM_PACK16" value="6" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A1R5G5B5_UNORM_PACK16" value="7" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_UNORM" value="8" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_SNORM" value="9" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_USCALED" value="10" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_SSCALED" value="11" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_UINT" value="12" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_SINT" value="13" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_SRGB" value="14" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_UNORM" value="15" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_SNORM" value="16" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_USCALED" value="17" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_SSCALED" value="18" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_UINT" value="19" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_SINT" value="20" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_SRGB" value="21" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_UNORM" value="22" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_SNORM" value="23" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_USCALED" value="24" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_SSCALED" value="25" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_UINT" value="26" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_SINT" value="27" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_SRGB" value="28" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_UNORM" value="29" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_SNORM" value="30" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_USCALED" value="31" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_SSCALED" value="32" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_UINT" value="33" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_SINT" value="34" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_SRGB" value="35" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_UNORM" value="36" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_SNORM" value="37" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_USCALED" value="38" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_SSCALED" value="39" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_UINT" value="40" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_SINT" value="41" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_SRGB" value="42" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_UNORM" value="43" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_SNORM" value="44" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_USCALED" value="45" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_SSCALED" value="46" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_UINT" value="47" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_SINT" value="48" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_SRGB" value="49" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_UNORM_PACK32" value="50" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_SNORM_PACK32" value="51" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_USCALED_PACK32" value="52" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_SSCALED_PACK32" value="53" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_UINT_PACK32" value="54" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_SINT_PACK32" value="55" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_SRGB_PACK32" value="56" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_UNORM_PACK32" value="57" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_SNORM_PACK32" value="58" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_USCALED_PACK32" value="59" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_SSCALED_PACK32" value="60" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_UINT_PACK32" value="61" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_SINT_PACK32" value="62" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_UNORM_PACK32" value="63" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_SNORM_PACK32" value="64" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_USCALED_PACK32" value="65" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_SSCALED_PACK32" value="66" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_UINT_PACK32" value="67" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_SINT_PACK32" value="68" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_UNORM" value="69" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_SNORM" value="70" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_USCALED" value="71" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_SSCALED" value="72" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_UINT" value="73" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_SINT" value="74" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_SFLOAT" value="75" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_UNORM" value="76" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_SNORM" value="77" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_USCALED" value="78" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_SSCALED" value="79" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_UINT" value="80" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_SINT" value="81" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_SFLOAT" value="82" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_UNORM" value="83" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_SNORM" value="84" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_USCALED" value="85" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_SSCALED" value="86" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_UINT" value="87" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_SINT" value="88" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_SFLOAT" value="89" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_UNORM" value="90" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_SNORM" value="91" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_USCALED" value="92" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_SSCALED" value="93" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_UINT" value="94" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_SINT" value="95" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_SFLOAT" value="96" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32_UINT" value="97" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32_SINT" value="98" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32_SFLOAT" value="99" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32_UINT" value="100" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32_SINT" value="101" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32_SFLOAT" value="102" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32_UINT" value="103" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32_SINT" value="104" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32_SFLOAT" value="105" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32A32_UINT" value="106" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32A32_SINT" value="107" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32A32_SFLOAT" value="108" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64_UINT" value="109" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64_SINT" value="110" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64_SFLOAT" value="111" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64_UINT" value="112" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64_SINT" value="113" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64_SFLOAT" value="114" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64_UINT" value="115" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64_SINT" value="116" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64_SFLOAT" value="117" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64A64_UINT" value="118" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64A64_SINT" value="119" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64A64_SFLOAT" value="120" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B10G11R11_UFLOAT_PACK32" value="121" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32" value="122" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D16_UNORM" value="123" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_X8_D24_UNORM_PACK32" value="124" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D32_SFLOAT" value="125" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_S8_UINT" value="126" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D16_UNORM_S8_UINT" value="127" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D24_UNORM_S8_UINT" value="128" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D32_SFLOAT_S8_UINT" value="129" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC1_RGB_UNORM_BLOCK" value="130" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC1_RGB_SRGB_BLOCK" value="131" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC1_RGBA_UNORM_BLOCK" value="132" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC1_RGBA_SRGB_BLOCK" value="133" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC2_UNORM_BLOCK" value="134" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC2_SRGB_BLOCK" value="135" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC3_UNORM_BLOCK" value="136" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC3_SRGB_BLOCK" value="137" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC4_UNORM_BLOCK" value="138" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC4_SNORM_BLOCK" value="139" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC5_UNORM_BLOCK" value="140" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC5_SNORM_BLOCK" value="141" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC6H_UFLOAT_BLOCK" value="142" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC6H_SFLOAT_BLOCK" value="143" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC7_UNORM_BLOCK" value="144" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC7_SRGB_BLOCK" value="145" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK" value="146" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK" value="147" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK" value="148" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK" value="149" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK" value="150" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK" value="151" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_EAC_R11_UNORM_BLOCK" value="152" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_EAC_R11_SNORM_BLOCK" value="153" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_EAC_R11G11_UNORM_BLOCK" value="154" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_EAC_R11G11_SNORM_BLOCK" value="155" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_4x4_UNORM_BLOCK" value="156" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_4x4_SRGB_BLOCK" value="157" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_5x4_UNORM_BLOCK" value="158" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_5x4_SRGB_BLOCK" value="159" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_5x5_UNORM_BLOCK" value="160" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_5x5_SRGB_BLOCK" value="161" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_6x5_UNORM_BLOCK" value="162" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_6x5_SRGB_BLOCK" value="163" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_6x6_UNORM_BLOCK" value="164" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_6x6_SRGB_BLOCK" value="165" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x5_UNORM_BLOCK" value="166" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x5_SRGB_BLOCK" value="167" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x6_UNORM_BLOCK" value="168" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x6_SRGB_BLOCK" value="169" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x8_UNORM_BLOCK" value="170" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x8_SRGB_BLOCK" value="171" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x5_UNORM_BLOCK" value="172" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x5_SRGB_BLOCK" value="173" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x6_UNORM_BLOCK" value="174" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x6_SRGB_BLOCK" value="175" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x8_UNORM_BLOCK" value="176" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x8_SRGB_BLOCK" value="177" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x10_UNORM_BLOCK" value="178" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x10_SRGB_BLOCK" value="179" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_12x10_UNORM_BLOCK" value="180" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_12x10_SRGB_BLOCK" value="181" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_12x12_UNORM_BLOCK" value="182" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_12x12_SRGB_BLOCK" value="183" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8B8G8R8_422_UNORM" value="184" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8G8_422_UNORM" value="185" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM" value="186" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM" value="187" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM" value="188" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM" value="189" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM" value="190" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R10X6_UNORM_PACK16" value="191" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R10X6G10X6_UNORM_2PACK16" value="192" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16" value="193" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16" value="194" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16" value="195" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16" value="196" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16" value="197" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16" value="198" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16" value="199" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16" value="200" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R12X4_UNORM_PACK16" value="201" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R12X4G12X4_UNORM_2PACK16" value="202" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16" value="203" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16" value="204" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16" value="205" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16" value="206" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16" value="207" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16" value="208" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16" value="209" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16" value="210" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16B16G16R16_422_UNORM" value="211" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B16G16R16G16_422_UNORM" value="212" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM" value="213" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM" value="214" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM" value="215" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM" value="216" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM" value="217" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG" value="218" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG" value="219" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG" value="220" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG" value="221" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG" value="222" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG" value="223" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG" value="224" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG" value="225" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_MAX" value="226" enum="DataFormat">
+ </constant>
+ <constant name="TEXTURE_TYPE_1D" value="0" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_2D" value="1" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_3D" value="2" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_CUBE" value="3" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_1D_ARRAY" value="4" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_2D_ARRAY" value="5" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_CUBE_ARRAY" value="6" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_MAX" value="7" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_1" value="0" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_2" value="1" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_4" value="2" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_8" value="3" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_16" value="4" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_32" value="5" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_64" value="6" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_MAX" value="7" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_USAGE_SAMPLING_BIT" value="1" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_COLOR_ATTACHMENT_BIT" value="2" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT" value="4" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_STORAGE_BIT" value="8" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_STORAGE_ATOMIC_BIT" value="16" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_CPU_READ_BIT" value="32" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_CAN_UPDATE_BIT" value="64" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_CAN_COPY_FROM_BIT" value="128" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_CAN_COPY_TO_BIT" value="256" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT" value="512" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_IDENTITY" value="0" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_ZERO" value="1" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_ONE" value="2" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_R" value="3" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_G" value="4" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_B" value="5" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_A" value="6" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_MAX" value="7" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SLICE_2D" value="0" enum="TextureSliceType">
+ </constant>
+ <constant name="TEXTURE_SLICE_CUBEMAP" value="1" enum="TextureSliceType">
+ </constant>
+ <constant name="TEXTURE_SLICE_3D" value="2" enum="TextureSliceType">
+ </constant>
+ <constant name="SAMPLER_FILTER_NEAREST" value="0" enum="SamplerFilter">
+ </constant>
+ <constant name="SAMPLER_FILTER_LINEAR" value="1" enum="SamplerFilter">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_REPEAT" value="0" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_MIRRORED_REPEAT" value="1" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE" value="2" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER" value="3" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE" value="4" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_MAX" value="5" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK" value="0" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK" value="1" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK" value="2" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK" value="3" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE" value="4" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE" value="5" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_MAX" value="6" enum="SamplerBorderColor">
+ </constant>
+ <constant name="VERTEX_FREQUENCY_VERTEX" value="0" enum="VertexFrequency">
+ </constant>
+ <constant name="VERTEX_FREQUENCY_INSTANCE" value="1" enum="VertexFrequency">
+ </constant>
+ <constant name="INDEX_BUFFER_FORMAT_UINT16" value="0" enum="IndexBufferFormat">
+ </constant>
+ <constant name="INDEX_BUFFER_FORMAT_UINT32" value="1" enum="IndexBufferFormat">
+ </constant>
+ <constant name="UNIFORM_TYPE_SAMPLER" value="0" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE" value="1" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_TEXTURE" value="2" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_IMAGE" value="3" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_TEXTURE_BUFFER" value="4" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER" value="5" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_IMAGE_BUFFER" value="6" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_UNIFORM_BUFFER" value="7" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_STORAGE_BUFFER" value="8" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_INPUT_ATTACHMENT" value="9" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_MAX" value="10" enum="UniformType">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_POINTS" value="0" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_LINES" value="1" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_LINES_WITH_ADJACENCY" value="2" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_LINESTRIPS" value="3" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY" value="4" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLES" value="5" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY" value="6" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS" value="7" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY" value="8" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX" value="9" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TESSELATION_PATCH" value="10" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_MAX" value="11" enum="RenderPrimitive">
+ </constant>
+ <constant name="POLYGON_CULL_DISABLED" value="0" enum="PolygonCullMode">
+ </constant>
+ <constant name="POLYGON_CULL_FRONT" value="1" enum="PolygonCullMode">
+ </constant>
+ <constant name="POLYGON_CULL_BACK" value="2" enum="PolygonCullMode">
+ </constant>
+ <constant name="POLYGON_FRONT_FACE_CLOCKWISE" value="0" enum="PolygonFrontFace">
+ </constant>
+ <constant name="POLYGON_FRONT_FACE_COUNTER_CLOCKWISE" value="1" enum="PolygonFrontFace">
+ </constant>
+ <constant name="STENCIL_OP_KEEP" value="0" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_ZERO" value="1" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_REPLACE" value="2" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_INCREMENT_AND_CLAMP" value="3" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_DECREMENT_AND_CLAMP" value="4" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_INVERT" value="5" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_INCREMENT_AND_WRAP" value="6" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_DECREMENT_AND_WRAP" value="7" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_MAX" value="8" enum="StencilOperation">
+ </constant>
+ <constant name="COMPARE_OP_NEVER" value="0" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_LESS" value="1" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_EQUAL" value="2" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_LESS_OR_EQUAL" value="3" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_GREATER" value="4" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_NOT_EQUAL" value="5" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_GREATER_OR_EQUAL" value="6" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_ALWAYS" value="7" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_MAX" value="8" enum="CompareOperator">
+ </constant>
+ <constant name="LOGIC_OP_CLEAR" value="0" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_AND" value="1" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_AND_REVERSE" value="2" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_COPY" value="3" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_AND_INVERTED" value="4" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_NO_OP" value="5" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_XOR" value="6" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_OR" value="7" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_NOR" value="8" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_EQUIVALENT" value="9" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_INVERT" value="10" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_OR_REVERSE" value="11" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_COPY_INVERTED" value="12" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_OR_INVERTED" value="13" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_NAND" value="14" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_SET" value="15" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_MAX" value="16" enum="LogicOperation">
+ </constant>
+ <constant name="BLEND_FACTOR_ZERO" value="0" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE" value="1" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC_COLOR" value="2" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_SRC_COLOR" value="3" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_DST_COLOR" value="4" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_DST_COLOR" value="5" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC_ALPHA" value="6" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_SRC_ALPHA" value="7" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_DST_ALPHA" value="8" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_DST_ALPHA" value="9" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_CONSTANT_COLOR" value="10" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR" value="11" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_CONSTANT_ALPHA" value="12" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA" value="13" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC_ALPHA_SATURATE" value="14" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC1_COLOR" value="15" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_SRC1_COLOR" value="16" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC1_ALPHA" value="17" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA" value="18" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_MAX" value="19" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_OP_ADD" value="0" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_SUBTRACT" value="1" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_REVERSE_SUBTRACT" value="2" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_MINIMUM" value="3" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_MAXIMUM" value="4" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_MAX" value="5" enum="BlendOperation">
+ </constant>
+ <constant name="DYNAMIC_STATE_LINE_WIDTH" value="1" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_DEPTH_BIAS" value="2" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_BLEND_CONSTANTS" value="4" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_DEPTH_BOUNDS" value="8" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_STENCIL_COMPARE_MASK" value="16" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_STENCIL_WRITE_MASK" value="32" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_STENCIL_REFERENCE" value="64" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="INITIAL_ACTION_CLEAR" value="0" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_KEEP" value="1" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_DROP" value="2" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_CONTINUE" value="3" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_MAX" value="4" enum="InitialAction">
+ </constant>
+ <constant name="FINAL_ACTION_READ" value="0" enum="FinalAction">
+ </constant>
+ <constant name="FINAL_ACTION_DISCARD" value="1" enum="FinalAction">
+ </constant>
+ <constant name="FINAL_ACTION_CONTINUE" value="2" enum="FinalAction">
+ </constant>
+ <constant name="FINAL_ACTION_MAX" value="3" enum="FinalAction">
+ </constant>
+ <constant name="SHADER_STAGE_VERTEX" value="0" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_FRAGMENT" value="1" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_TESSELATION_CONTROL" value="2" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_TESSELATION_EVALUATION" value="3" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_COMPUTE" value="4" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_MAX" value="5" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_VERTEX_BIT" value="1" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_FRAGMENT_BIT" value="2" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_TESSELATION_CONTROL_BIT" value="4" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_TESSELATION_EVALUATION_BIT" value="8" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_COMPUTE_BIT" value="16" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_LANGUAGE_GLSL" value="0" enum="ShaderLanguage">
+ </constant>
+ <constant name="SHADER_LANGUAGE_HLSL" value="1" enum="ShaderLanguage">
+ </constant>
+ <constant name="LIMIT_MAX_BOUND_UNIFORM_SETS" value="0" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS" value="1" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURES_PER_UNIFORM_SET" value="2" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET" value="3" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET" value="4" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET" value="5" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET" value="6" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_DRAW_INDEXED_INDEX" value="7" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_FRAMEBUFFER_HEIGHT" value="8" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_FRAMEBUFFER_WIDTH" value="9" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_ARRAY_LAYERS" value="10" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_SIZE_1D" value="11" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_SIZE_2D" value="12" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_SIZE_3D" value="13" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_SIZE_CUBE" value="14" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURES_PER_SHADER_STAGE" value="15" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE" value="16" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE" value="17" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE" value="18" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE" value="19" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_PUSH_CONSTANT_SIZE" value="20" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_UNIFORM_BUFFER_SIZE" value="21" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET" value="22" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES" value="23" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_VERTEX_INPUT_BINDINGS" value="24" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE" value="25" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT" value="26" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE" value="27" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X" value="28" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y" value="29" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z" value="30" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS" value="31" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X" value="32" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y" value="33" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z" value="34" enum="Limit">
+ </constant>
+ <constant name="INVALID_ID" value="-1">
+ </constant>
+ <constant name="INVALID_FORMAT_ID" value="-1">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index d2d13fe406..4e0762a68b 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -4,12 +4,12 @@
Server for anything visible.
</brief_description>
<description>
- Server for anything visible. The visual server is the API backend for everything visible. The whole scene system mounts on it to display.
- The visual server is completely opaque, the internals are entirely implementation specific and cannot be accessed.
- The visual server can be used to bypass the scene system entirely.
+ Server for anything visible. The rendering server is the API backend for everything visible. The whole scene system mounts on it to display.
+ The rendering server is completely opaque, the internals are entirely implementation specific and cannot be accessed.
+ The rendering server can be used to bypass the scene system entirely.
Resources are created using the [code]*_create[/code] functions.
All objects are drawn to a viewport. You can use the [Viewport] attached to the [SceneTree] or you can create one yourself with [method viewport_create]. When using a custom scenario or canvas, the scenario or canvas needs to be attached to the viewport using [method viewport_set_scenario] or [method viewport_attach_canvas].
- In 3D, all visual objects must be associated with a scenario. The scenario is a visual representation of the world. If accessing the visual server from a running game, the scenario can be accessed from the scene tree from any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be created with [method scenario_create].
+ In 3D, all visual objects must be associated with a scenario. The scenario is a visual representation of the world. If accessing the rendering server from a running game, the scenario can be accessed from the scene tree from any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be created with [method scenario_create].
Similarly in 2D, a canvas is needed to draw all canvas items.
In 3D, all visible objects are comprised of a resource and an instance. A resource can be a mesh, a particle system, a light, or any other 3D object. In order to be visible resources must be attached to an instance using [method instance_set_base]. The instance must also be attached to the scenario using [method instance_set_scenario] in order to be visible.
In 2D, all visible objects are some form of canvas item. In order to be visible, a canvas item needs to be the child of a canvas attached to a viewport, or it needs to be the child of another canvas item that is eventually attached to the canvas.
@@ -947,6 +947,58 @@
Returns the id of a white texture. Creates one if none exists.
</description>
</method>
+ <method name="global_variable_add">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <argument index="1" name="type" type="int" enum="RenderingServer.GlobalVariableType">
+ </argument>
+ <argument index="2" name="default_value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_get" qualifiers="const">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_get_list" qualifiers="const">
+ <return type="PackedStringArray">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_get_type" qualifiers="const">
+ <return type="int" enum="RenderingServer.GlobalVariableType">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_remove">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_set">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <argument index="1" name="value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="has_changed" qualifiers="const">
<return type="bool">
</return>
@@ -1113,7 +1165,7 @@
<return type="void">
</return>
<description>
- Initializes the visual server. This function is called internally by platform-dependent code during engine initialization. If called from a running game, it will not do anything.
+ Initializes the rendering server. This function is called internally by platform-dependent code during engine initialization. If called from a running game, it will not do anything.
</description>
</method>
<method name="instance_attach_object_instance_id">
@@ -3067,15 +3119,15 @@
Sets when the viewport should be updated. See [enum ViewportUpdateMode] constants for options.
</description>
</method>
- <method name="viewport_set_use_arvr">
+ <method name="viewport_set_use_xr">
<return type="void">
</return>
<argument index="0" name="viewport" type="RID">
</argument>
- <argument index="1" name="use_arvr" type="bool">
+ <argument index="1" name="use_xr" type="bool">
</argument>
<description>
- If [code]true[/code], the viewport uses augmented or virtual reality technologies. See [ARVRInterface].
+ If [code]true[/code], the viewport uses augmented or virtual reality technologies. See [XRInterface].
</description>
</method>
</methods>
@@ -3110,12 +3162,6 @@
<constant name="MAX_CURSORS" value="8">
Unused enum in Godot 3.x.
</constant>
- <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128">
- The minimum renderpriority of all materials.
- </constant>
- <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127">
- The maximum renderpriority of all materials.
- </constant>
<constant name="TEXTURE_LAYERED_2D_ARRAY" value="0" enum="TextureLayeredType">
</constant>
<constant name="TEXTURE_LAYERED_CUBEMAP" value="1" enum="TextureLayeredType">
@@ -3149,6 +3195,12 @@
<constant name="SHADER_MAX" value="4" enum="ShaderMode">
Represents the size of the [enum ShaderMode] enum.
</constant>
+ <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128">
+ The minimum renderpriority of all materials.
+ </constant>
+ <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127">
+ The maximum renderpriority of all materials.
+ </constant>
<constant name="ARRAY_VERTEX" value="0" enum="ArrayType">
Array is a vertex array.
</constant>
@@ -3224,14 +3276,14 @@
<constant name="ARRAY_COMPRESS_INDEX" value="131072" enum="ArrayFormat">
Flag used to mark a compressed index array.
</constant>
+ <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat">
+ Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly.
+ </constant>
<constant name="ARRAY_FLAG_USE_2D_VERTICES" value="262144" enum="ArrayFormat">
Flag used to mark that the array contains 2D vertices.
</constant>
<constant name="ARRAY_FLAG_USE_DYNAMIC_UPDATE" value="1048576" enum="ArrayFormat">
</constant>
- <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat">
- Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly.
- </constant>
<constant name="PRIMITIVE_POINTS" value="0" enum="PrimitiveType">
Primitive to draw consists of points.
</constant>
@@ -3282,18 +3334,18 @@
<constant name="LIGHT_PARAM_RANGE" value="3" enum="LightParam">
The light's range.
</constant>
- <constant name="LIGHT_PARAM_ATTENUATION" value="4" enum="LightParam">
+ <constant name="LIGHT_PARAM_SIZE" value="4" enum="LightParam">
+ The size of the light when using spot light or omni light. The angular size of the light when using directional light.
+ </constant>
+ <constant name="LIGHT_PARAM_ATTENUATION" value="5" enum="LightParam">
The light's attenuation.
</constant>
- <constant name="LIGHT_PARAM_SPOT_ANGLE" value="5" enum="LightParam">
+ <constant name="LIGHT_PARAM_SPOT_ANGLE" value="6" enum="LightParam">
The spotlight's angle.
</constant>
- <constant name="LIGHT_PARAM_SPOT_ATTENUATION" value="6" enum="LightParam">
+ <constant name="LIGHT_PARAM_SPOT_ATTENUATION" value="7" enum="LightParam">
The spotlight's attenuation.
</constant>
- <constant name="LIGHT_PARAM_CONTACT_SHADOW_SIZE" value="7" enum="LightParam">
- Scales the shadow color.
- </constant>
<constant name="LIGHT_PARAM_SHADOW_MAX_DISTANCE" value="8" enum="LightParam">
Max distance that shadows will be rendered.
</constant>
@@ -3307,6 +3359,7 @@
Proportion of shadow atlas occupied by the third split. The fourth split occupies the rest.
</constant>
<constant name="LIGHT_PARAM_SHADOW_FADE_START" value="12" enum="LightParam">
+ Proportion of shadow max distance where the shadow will start to fade out.
</constant>
<constant name="LIGHT_PARAM_SHADOW_NORMAL_BIAS" value="13" enum="LightParam">
Normal bias used to offset shadow lookup by object normal. Can be used to fix self-shadowing artifacts.
@@ -3314,10 +3367,15 @@
<constant name="LIGHT_PARAM_SHADOW_BIAS" value="14" enum="LightParam">
Bias the shadow lookup to fix self-shadowing artifacts.
</constant>
- <constant name="LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE" value="15" enum="LightParam">
- Increases bias on further splits to fix self-shadowing that only occurs far away from the camera.
+ <constant name="LIGHT_PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="LightParam">
+ Sets the size of the directional shadow pancake. The pancake offsets the start of the shadow's camera frustum to provide a higher effective depth resolution for the shadow. However, a high pancake size can cause artifacts in the shadows of large objects that are close to the edge of the frustum. Reducing the pancake size can help. Setting the size to [code]0[/code] turns off the pancaking effect.
+ </constant>
+ <constant name="LIGHT_PARAM_SHADOW_BLUR" value="16" enum="LightParam">
+ Blurs the edges of the shadow. Can be used to hide pixel artifacts in low resolution shadow maps. A high value can make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible.
</constant>
- <constant name="LIGHT_PARAM_MAX" value="16" enum="LightParam">
+ <constant name="LIGHT_PARAM_TRANSMITTANCE_BIAS" value="17" enum="LightParam">
+ </constant>
+ <constant name="LIGHT_PARAM_MAX" value="18" enum="LightParam">
Represents the size of the [enum LightParam] enum.
</constant>
<constant name="LIGHT_OMNI_SHADOW_DUAL_PARABOLOID" value="0" enum="LightOmniShadowMode">
@@ -3347,6 +3405,16 @@
<constant name="REFLECTION_PROBE_UPDATE_ALWAYS" value="1" enum="ReflectionProbeUpdateMode">
Reflection probe will update each frame. This mode is necessary to capture moving objects.
</constant>
+ <constant name="DECAL_TEXTURE_ALBEDO" value="0" enum="DecalTexture">
+ </constant>
+ <constant name="DECAL_TEXTURE_NORMAL" value="1" enum="DecalTexture">
+ </constant>
+ <constant name="DECAL_TEXTURE_ORM" value="2" enum="DecalTexture">
+ </constant>
+ <constant name="DECAL_TEXTURE_EMISSION" value="3" enum="DecalTexture">
+ </constant>
+ <constant name="DECAL_TEXTURE_MAX" value="4" enum="DecalTexture">
+ </constant>
<constant name="PARTICLES_DRAW_ORDER_INDEX" value="0" enum="ParticlesDrawOrder">
Draw particles in the order that they appear in the particles array.
</constant>
@@ -3383,22 +3451,24 @@
Multisample antialiasing is disabled.
</constant>
<constant name="VIEWPORT_MSAA_2X" value="1" enum="ViewportMSAA">
- Multisample antialiasing is set to 2×.
+ Multisample antialiasing uses 2 samples per pixel.
</constant>
<constant name="VIEWPORT_MSAA_4X" value="2" enum="ViewportMSAA">
- Multisample antialiasing is set to 4×.
+ Multisample antialiasing uses 4 samples per pixel.
</constant>
<constant name="VIEWPORT_MSAA_8X" value="3" enum="ViewportMSAA">
- Multisample antialiasing is set to 8×.
+ Multisample antialiasing uses 8 samples per pixel.
</constant>
<constant name="VIEWPORT_MSAA_16X" value="4" enum="ViewportMSAA">
- Multisample antialiasing is set to 16×.
+ Multisample antialiasing uses 16 samples per pixel.
+ </constant>
+ <constant name="VIEWPORT_MSAA_MAX" value="5" enum="ViewportMSAA">
</constant>
- <constant name="VIEWPORT_MSAA_EXT_2X" value="5" enum="ViewportMSAA">
- Multisample antialiasing is set to 2× on external texture. Special mode for GLES2 Android VR (Oculus Quest and Go).
+ <constant name="VIEWPORT_SCREEN_SPACE_AA_DISABLED" value="0" enum="ViewportScreenSpaceAA">
</constant>
- <constant name="VIEWPORT_MSAA_EXT_4X" value="6" enum="ViewportMSAA">
- Multisample antialiasing is set to 4× on external texture. Special mode for GLES2 Android VR (Oculus Quest and Go).
+ <constant name="VIEWPORT_SCREEN_SPACE_AA_FXAA" value="1" enum="ViewportScreenSpaceAA">
+ </constant>
+ <constant name="VIEWPORT_SCREEN_SPACE_AA_MAX" value="2" enum="ViewportScreenSpaceAA">
</constant>
<constant name="VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="ViewportRenderInfo">
Number of objects drawn in a single frame.
@@ -3425,37 +3495,54 @@
Debug draw is disabled. Default setting.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_UNSHADED" value="1" enum="ViewportDebugDraw">
- Debug draw sets objects to unshaded.
+ Objects are displayed without light information.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_LIGHTING" value="2" enum="ViewportDebugDraw">
+ Objects are displayed with only light information.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_OVERDRAW" value="3" enum="ViewportDebugDraw">
- Overwrites clear color to [code](0,0,0,0)[/code].
+ Objects are displayed semi-transparent with additive blending so you can see where they are drawing over top of one another. A higher overdraw means you are wasting performance on drawing pixels that are being hidden behind others.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_WIREFRAME" value="4" enum="ViewportDebugDraw">
Debug draw draws objects in wireframe.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER" value="5" enum="ViewportDebugDraw">
+ Normal buffer is drawn instead of regular scene so you can see the per-pixel normals that will be used by post-processing effects.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO" value="6" enum="ViewportDebugDraw">
+ Objects are displayed with only the albedo value from [GIProbe]s.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING" value="7" enum="ViewportDebugDraw">
+ Objects are displayed with only the lighting value from [GIProbe]s.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION" value="8" enum="ViewportDebugDraw">
+ Objects are displayed with only the emission color from [GIProbe]s.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS" value="9" enum="ViewportDebugDraw">
+ Draws the shadow atlas that stores shadows from [OmniLight3D]s and [SpotLight3D]s in the upper left quadrant of the [Viewport].
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS" value="10" enum="ViewportDebugDraw">
+ Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the upper left quadrant of the [Viewport].
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE" value="11" enum="ViewportDebugDraw">
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_SSAO" value="12" enum="ViewportDebugDraw">
+ Draws the screen space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment].
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="ViewportDebugDraw">
+ Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work.
+ </constant>
+ <constant name="VIEWPORT_DEBUG_DRAW_PSSM_SPLITS" value="14" enum="ViewportDebugDraw">
+ Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order they will be colored red, green, blue, yellow.
+ </constant>
+ <constant name="VIEWPORT_DEBUG_DRAW_DECAL_ATLAS" value="15" enum="ViewportDebugDraw">
</constant>
<constant name="SKY_MODE_QUALITY" value="0" enum="SkyMode">
+ Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples].
</constant>
<constant name="SKY_MODE_REALTIME" value="1" enum="SkyMode">
+ Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times.
+ [b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so [member Sky.radiance_size] must be set to [constant Sky.RADIANCE_SIZE_256].
</constant>
<constant name="ENV_BG_CLEAR_COLOR" value="0" enum="EnvironmentBG">
Use the clear color as background.
@@ -3479,28 +3566,40 @@
Represents the size of the [enum EnvironmentBG] enum.
</constant>
<constant name="ENV_AMBIENT_SOURCE_BG" value="0" enum="EnvironmentAmbientSource">
+ Gather ambient light from whichever source is specified as the background.
</constant>
<constant name="ENV_AMBIENT_SOURCE_DISABLED" value="1" enum="EnvironmentAmbientSource">
+ Disable ambient light.
</constant>
<constant name="ENV_AMBIENT_SOURCE_COLOR" value="2" enum="EnvironmentAmbientSource">
+ Specify a specific [Color] for ambient light.
</constant>
<constant name="ENV_AMBIENT_SOURCE_SKY" value="3" enum="EnvironmentAmbientSource">
+ Gather ambient light from the [Sky] regardless of what the background is.
</constant>
<constant name="ENV_REFLECTION_SOURCE_BG" value="0" enum="EnvironmentReflectionSource">
+ Use the background for reflections.
</constant>
<constant name="ENV_REFLECTION_SOURCE_DISABLED" value="1" enum="EnvironmentReflectionSource">
+ Disable reflections.
</constant>
<constant name="ENV_REFLECTION_SOURCE_SKY" value="2" enum="EnvironmentReflectionSource">
+ Use the [Sky] for reflections regardless of what the background is.
</constant>
<constant name="ENV_GLOW_BLEND_MODE_ADDITIVE" value="0" enum="EnvironmentGlowBlendMode">
+ Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources.
</constant>
<constant name="ENV_GLOW_BLEND_MODE_SCREEN" value="1" enum="EnvironmentGlowBlendMode">
+ Screen glow blending mode. Increases brightness, used frequently with bloom.
</constant>
<constant name="ENV_GLOW_BLEND_MODE_SOFTLIGHT" value="2" enum="EnvironmentGlowBlendMode">
+ Soft light glow blending mode. Modifies contrast, exposes shadows and highlights (vivid bloom).
</constant>
<constant name="ENV_GLOW_BLEND_MODE_REPLACE" value="3" enum="EnvironmentGlowBlendMode">
+ Replace glow blending mode. Replaces all pixels' color by the glow value. This can be used to simulate a full-screen blur effect by tweaking the glow parameters to match the original image's brightness.
</constant>
<constant name="ENV_GLOW_BLEND_MODE_MIX" value="4" enum="EnvironmentGlowBlendMode">
+ Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect.
</constant>
<constant name="ENV_TONE_MAPPER_LINEAR" value="0" enum="EnvironmentToneMapper">
Output color as they came in.
@@ -3514,6 +3613,14 @@
<constant name="ENV_TONE_MAPPER_ACES" value="3" enum="EnvironmentToneMapper">
Use the ACES tonemapper.
</constant>
+ <constant name="ENV_SSR_ROUGNESS_QUALITY_DISABLED" value="0" enum="EnvironmentSSRRoughnessQuality">
+ </constant>
+ <constant name="ENV_SSR_ROUGNESS_QUALITY_LOW" value="1" enum="EnvironmentSSRRoughnessQuality">
+ </constant>
+ <constant name="ENV_SSR_ROUGNESS_QUALITY_MEDIUM" value="2" enum="EnvironmentSSRRoughnessQuality">
+ </constant>
+ <constant name="ENV_SSR_ROUGNESS_QUALITY_HIGH" value="3" enum="EnvironmentSSRRoughnessQuality">
+ </constant>
<constant name="ENV_SSAO_BLUR_DISABLED" value="0" enum="EnvironmentSSAOBlur">
Disables the blur set for SSAO. Will make SSAO look noisier.
</constant>
@@ -3533,23 +3640,51 @@
Medium quality screen space ambient occlusion.
</constant>
<constant name="ENV_SSAO_QUALITY_HIGH" value="2" enum="EnvironmentSSAOQuality">
- Highest quality screen space ambient occlusion.
+ High quality screen space ambient occlusion.
</constant>
<constant name="ENV_SSAO_QUALITY_ULTRA" value="3" enum="EnvironmentSSAOQuality">
+ Highest quality screen space ambient occlusion.
+ </constant>
+ <constant name="SUB_SURFACE_SCATTERING_QUALITY_DISABLED" value="0" enum="SubSurfaceScatteringQuality">
+ </constant>
+ <constant name="SUB_SURFACE_SCATTERING_QUALITY_LOW" value="1" enum="SubSurfaceScatteringQuality">
+ </constant>
+ <constant name="SUB_SURFACE_SCATTERING_QUALITY_MEDIUM" value="2" enum="SubSurfaceScatteringQuality">
+ </constant>
+ <constant name="SUB_SURFACE_SCATTERING_QUALITY_HIGH" value="3" enum="SubSurfaceScatteringQuality">
</constant>
<constant name="DOF_BLUR_QUALITY_VERY_LOW" value="0" enum="DOFBlurQuality">
+ Lowest quality DOF blur. This is the fastest setting, but you may be able to see filtering artifacts.
</constant>
<constant name="DOF_BLUR_QUALITY_LOW" value="1" enum="DOFBlurQuality">
+ Low quality DOF blur.
</constant>
<constant name="DOF_BLUR_QUALITY_MEDIUM" value="2" enum="DOFBlurQuality">
+ Medium quality DOF blur.
</constant>
<constant name="DOF_BLUR_QUALITY_HIGH" value="3" enum="DOFBlurQuality">
+ Highest quality DOF blur. Results in the smoothest looking blur by taking the most samples, but is also significantly slower.
</constant>
<constant name="DOF_BOKEH_BOX" value="0" enum="DOFBokehShape">
+ Calculate the DOF blur using a box filter. The fastest option, but results in obvious lines in blur pattern.
</constant>
<constant name="DOF_BOKEH_HEXAGON" value="1" enum="DOFBokehShape">
+ Calculates DOF blur using a hexagon shaped filter.
</constant>
<constant name="DOF_BOKEH_CIRCLE" value="2" enum="DOFBokehShape">
+ Calculates DOF blur using a circle shaped filter. Best quality and most realistic, but slowest. Use only for areas where a lot of performance can be dedicated to post-processing (e.g. cutscenes).
+ </constant>
+ <constant name="SHADOW_QUALITY_HARD" value="0" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_SOFT_LOW" value="1" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_SOFT_MEDIUM" value="2" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_SOFT_HIGH" value="3" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_SOFT_ULTRA" value="4" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_MAX" value="5" enum="ShadowQuality">
</constant>
<constant name="SCENARIO_DEBUG_DISABLED" value="0" enum="ScenarioDebugMode">
Do not use a debug mode.
@@ -3584,13 +3719,16 @@
<constant name="INSTANCE_REFLECTION_PROBE" value="6" enum="InstanceType">
The instance is a reflection probe.
</constant>
- <constant name="INSTANCE_GI_PROBE" value="7" enum="InstanceType">
+ <constant name="INSTANCE_DECAL" value="7" enum="InstanceType">
+ The instance is a decal.
+ </constant>
+ <constant name="INSTANCE_GI_PROBE" value="8" enum="InstanceType">
The instance is a GI probe.
</constant>
- <constant name="INSTANCE_LIGHTMAP_CAPTURE" value="8" enum="InstanceType">
+ <constant name="INSTANCE_LIGHTMAP_CAPTURE" value="9" enum="InstanceType">
The instance is a lightmap capture.
</constant>
- <constant name="INSTANCE_MAX" value="9" enum="InstanceType">
+ <constant name="INSTANCE_MAX" value="10" enum="InstanceType">
Represents the size of the [enum InstanceType] enum.
</constant>
<constant name="INSTANCE_GEOMETRY_MASK" value="30" enum="InstanceType">
@@ -3600,6 +3738,7 @@
Allows the instance to be used in baked lighting.
</constant>
<constant name="INSTANCE_FLAG_USE_DYNAMIC_GI" value="1" enum="InstanceFlags">
+ Allows the instance to be used with dynamic global illumination.
</constant>
<constant name="INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE" value="2" enum="InstanceFlags">
When set, manually requests to draw geometry on next frame.
@@ -3629,30 +3768,43 @@
The nine patch gets filled with tiles where needed and stretches them a bit if needed.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_DEFAULT" value="0" enum="CanvasItemTextureFilter">
+ Uses the default filter mode for this [Viewport].
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="1" enum="CanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="2" enum="CanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="CanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="CanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="CanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="CanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_MAX" value="7" enum="CanvasItemTextureFilter">
+ Max value for [enum CanvasItemTextureFilter] enum.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT" value="0" enum="CanvasItemTextureRepeat">
+ Uses the default repeat mode for this [Viewport].
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_DISABLED" value="1" enum="CanvasItemTextureRepeat">
+ Disables textures repeating. Instead, when reading UVs outside the 0-1 range, the value will be clamped to the edge of the texture, resulting in a stretched out look at the borders of the texture.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_ENABLED" value="2" enum="CanvasItemTextureRepeat">
+ Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_MIRROR" value="3" enum="CanvasItemTextureRepeat">
+ Flip the texture when repeating so that the edge lines up instead of abruptly changing.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="4" enum="CanvasItemTextureRepeat">
+ Max value for [enum CanvasItemTextureRepeat] enum.
</constant>
<constant name="CANVAS_LIGHT_MODE_ADD" value="0" enum="CanvasLightMode">
Adds light color additive to the canvas.
@@ -3676,6 +3828,7 @@
Use PCF13 filtering to filter canvas light shadows.
</constant>
<constant name="CANVAS_LIGHT_FILTER_MAX" value="3" enum="CanvasLightShadowFilter">
+ Max value of the [enum CanvasLightShadowFilter] enum.
</constant>
<constant name="CANVAS_OCCLUDER_POLYGON_CULL_DISABLED" value="0" enum="CanvasOccluderPolygonCullMode">
Culling of the canvas occluder is disabled.
@@ -3686,6 +3839,64 @@
<constant name="CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE" value="2" enum="CanvasOccluderPolygonCullMode">
Culling of the canvas occluder is counterclockwise.
</constant>
+ <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalVariableType">
+ </constant>
<constant name="INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo">
The amount of objects in the frame.
</constant>
diff --git a/doc/classes/ResourceFormatLoaderCrypto.xml b/doc/classes/ResourceFormatLoaderCrypto.xml
deleted file mode 100644
index fda529fdbd..0000000000
--- a/doc/classes/ResourceFormatLoaderCrypto.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ResourceFormatLoaderCrypto" inherits="ResourceFormatLoader" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/ResourceFormatSaverCrypto.xml b/doc/classes/ResourceFormatSaverCrypto.xml
deleted file mode 100644
index 31db8ff4f5..0000000000
--- a/doc/classes/ResourceFormatSaverCrypto.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ResourceFormatSaverCrypto" inherits="ResourceFormatSaver" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml
index 829589f650..1db818d6af 100644
--- a/doc/classes/RigidBody3D.xml
+++ b/doc/classes/RigidBody3D.xml
@@ -28,7 +28,7 @@
<argument index="0" name="force" type="Vector3">
</argument>
<description>
- Adds a constant directional force without affecting rotation.
+ Adds a constant directional force (i.e. acceleration) without affecting rotation.
This is equivalent to [code]add_force(force, Vector3(0,0,0))[/code].
</description>
</method>
@@ -40,7 +40,8 @@
<argument index="1" name="position" type="Vector3">
</argument>
<description>
- Adds a constant force (i.e. acceleration).
+ Adds a constant directional force (i.e. acceleration).
+ The position uses the rotation of the global coordinate system, but is centered at the object's origin.
</description>
</method>
<method name="add_torque">
@@ -146,7 +147,7 @@
Lock the body's movement in the Z axis.
</member>
<member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" default="true">
- If [code]true[/code], the RigidBody3D will not calculate forces and will act as a static body while there is no movement. It will wake up when forces are applied through other collisions or when the [code]apply_impulse[/code] method is used.
+ If [code]true[/code], the body is deactivated when there is no movement, so it will not take part in the simulation until it is awaken by an external force.
</member>
<member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled" default="false">
If [code]true[/code], the RigidBody3D will emit signals when it collides with another RigidBody3D.
diff --git a/modules/bullet/doc_classes/BulletPhysicsServer3D.xml b/doc/classes/ShaderGlobalsOverride.xml
index b20595b4f6..2aa00aa5a9 100644
--- a/modules/bullet/doc_classes/BulletPhysicsServer3D.xml
+++ b/doc/classes/ShaderGlobalsOverride.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="BulletPhysicsServer3D" inherits="PhysicsServer3D" version="4.0">
+<class name="ShaderGlobalsOverride" inherits="Node" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/Sky.xml b/doc/classes/Sky.xml
index f574f42431..78c75d9c2b 100644
--- a/doc/classes/Sky.xml
+++ b/doc/classes/Sky.xml
@@ -49,7 +49,7 @@
Represents the size of the [enum RadianceSize] enum.
</constant>
<constant name="PROCESS_MODE_QUALITY" value="0" enum="ProcessMode">
- Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime.
+ Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples].
</constant>
<constant name="PROCESS_MODE_REALTIME" value="1" enum="ProcessMode">
Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times.
diff --git a/doc/classes/SubViewport.xml b/doc/classes/SubViewport.xml
index dc3d748496..6014762e3d 100644
--- a/doc/classes/SubViewport.xml
+++ b/doc/classes/SubViewport.xml
@@ -9,9 +9,6 @@
<methods>
</methods>
<members>
- <member name="arvr" type="bool" setter="set_use_arvr" getter="is_using_arvr" default="false">
- If [code]true[/code], the sub-viewport will be used in AR/VR process.
- </member>
<member name="render_target_clear_mode" type="int" setter="set_clear_mode" getter="get_clear_mode" enum="SubViewport.ClearMode" default="0">
The clear mode when the sub-viewport is used as a render target.
</member>
@@ -27,8 +24,20 @@
<member name="size_2d_override_stretch" type="bool" setter="set_size_2d_override_stretch" getter="is_size_2d_override_stretch_enabled" default="false">
If [code]true[/code], the 2D size override affects stretch as well.
</member>
+ <member name="xr" type="bool" setter="set_use_xr" getter="is_using_xr" default="false">
+ If [code]true[/code], the sub-viewport will be used in AR/VR process.
+ </member>
</members>
<constants>
+ <constant name="CLEAR_MODE_ALWAYS" value="0" enum="ClearMode">
+ Always clear the render target before drawing.
+ </constant>
+ <constant name="CLEAR_MODE_NEVER" value="1" enum="ClearMode">
+ Never clear the render target.
+ </constant>
+ <constant name="CLEAR_MODE_ONLY_NEXT_FRAME" value="2" enum="ClearMode">
+ Clear the render target next frame, then switch to [constant CLEAR_MODE_NEVER].
+ </constant>
<constant name="UPDATE_DISABLED" value="0" enum="UpdateMode">
Do not update the render target.
</constant>
@@ -44,14 +53,5 @@
<constant name="UPDATE_ALWAYS" value="4" enum="UpdateMode">
Always update the render target.
</constant>
- <constant name="CLEAR_MODE_ALWAYS" value="0" enum="ClearMode">
- Always clear the render target before drawing.
- </constant>
- <constant name="CLEAR_MODE_NEVER" value="1" enum="ClearMode">
- Never clear the render target.
- </constant>
- <constant name="CLEAR_MODE_ONLY_NEXT_FRAME" value="2" enum="ClearMode">
- Clear the render target next frame, then switch to [constant CLEAR_MODE_NEVER].
- </constant>
</constants>
</class>
diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml
index f7e94ad236..22e92ae5d9 100644
--- a/doc/classes/TabContainer.xml
+++ b/doc/classes/TabContainer.xml
@@ -36,10 +36,10 @@
<method name="get_tab_control" qualifiers="const">
<return type="Control">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="tab_idx" type="int">
</argument>
<description>
- Returns the currently visible tab's [Control] node.
+ Returns the [Control] node from the tab at index [code]tab_idx[/code].
</description>
</method>
<method name="get_tab_count" qualifiers="const">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index b515b27b31..b7cf93d672 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -433,6 +433,7 @@
</member>
<member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" />
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false">
+ If [code]true[/code], custom [code]font_color_selected[/code] will be used for selected text.
</member>
<member name="readonly" type="bool" setter="set_readonly" getter="is_readonly" default="false">
If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added.
@@ -611,6 +612,7 @@
<theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
</theme_item>
<theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )">
+ Sets the [Color] of the selected text. [member override_selected_font_color] has to be enabled.
</theme_item>
<theme_item name="function_color" type="Color" default="Color( 0.4, 0.64, 0.81, 1 )">
</theme_item>
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 1db1142aa0..5b7694b775 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -43,7 +43,7 @@
<argument index="1" name="y" type="int">
</argument>
<description>
- Returns the coordinate of the autotile variation in the tileset. Returns a zero vector if the cell doesn't have autotiling.
+ Returns the coordinate (subtile column and row) of the autotile variation in the tileset. Returns a zero vector if the cell doesn't have autotiling.
</description>
</method>
<method name="get_cellv" qualifiers="const">
@@ -161,7 +161,7 @@
<description>
Sets the tile index for the cell given by a Vector2.
An index of [code]-1[/code] clears the cell.
- Optionally, the tile can also be flipped, transposed, or given autotile coordinates.
+ Optionally, the tile can also be flipped, transposed, or given autotile coordinates. The autotile coordinate refers to the column and row of the subtile.
[b]Note:[/b] Data such as navigation polygons and collision shapes are not immediately updated for performance reasons.
If you need these to be immediately updated, you can call [method update_dirty_quadrants].
Overriding this method also overrides it internally, allowing custom logic to be implemented when tiles are placed/removed:
diff --git a/doc/classes/UndoRedo.xml b/doc/classes/UndoRedo.xml
index 766ebf7e32..2cc3e974e2 100644
--- a/doc/classes/UndoRedo.xml
+++ b/doc/classes/UndoRedo.xml
@@ -155,7 +155,7 @@
Returns [code]true[/code] if an "undo" action is available.
</description>
</method>
- <method name="is_commiting_action" qualifiers="const">
+ <method name="is_committing_action" qualifiers="const">
<return type="bool">
</return>
<description>
diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml
index 3faafdfe80..9394d6b430 100644
--- a/doc/classes/VSlider.xml
+++ b/doc/classes/VSlider.xml
@@ -23,6 +23,8 @@
<theme_item name="grabber_area" type="StyleBox">
The background of the area below the grabber.
</theme_item>
+ <theme_item name="grabber_area_highlight" type="StyleBox">
+ </theme_item>
<theme_item name="grabber_disabled" type="Texture2D">
The texture for the grabber when it's disabled.
</theme_item>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 5826822c6e..a2d53f8e0c 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -192,8 +192,10 @@
If [code]true[/code], the viewport will process 3D audio streams.
</member>
<member name="canvas_item_default_texture_filter" type="int" setter="set_default_canvas_item_texture_filter" getter="get_default_canvas_item_texture_filter" enum="Viewport.DefaultCanvasItemTextureFilter" default="1">
+ Sets the default filter mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureFilter] for options.
</member>
<member name="canvas_item_default_texture_repeat" type="int" setter="set_default_canvas_item_texture_repeat" getter="get_default_canvas_item_texture_repeat" enum="Viewport.DefaultCanvasItemTextureRepeat" default="0">
+ Sets the default repeat mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureRepeat] for options.
</member>
<member name="canvas_transform" type="Transform2D" setter="set_canvas_transform" getter="get_canvas_transform">
The canvas transform of the viewport, useful for changing the on-screen positions of all child [CanvasItem]s. This is relative to the global canvas transform of the viewport.
@@ -223,6 +225,9 @@
<member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" default="false">
If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process.
</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.
+ </member>
<member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2">
The subdivision amount of the first quadrant on the shadow atlas.
</member>
@@ -288,6 +293,33 @@
<constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_MAX" value="7" enum="ShadowAtlasQuadrantSubdiv">
Represents the size of the [enum ShadowAtlasQuadrantSubdiv] enum.
</constant>
+ <constant name="MSAA_DISABLED" value="0" enum="MSAA">
+ Multisample antialiasing mode disabled. This is the default value, and also the fastest setting.
+ </constant>
+ <constant name="MSAA_2X" value="1" enum="MSAA">
+ Use 2x Multisample Antialiasing.
+ </constant>
+ <constant name="MSAA_4X" value="2" enum="MSAA">
+ Use 4x Multisample Antialiasing.
+ </constant>
+ <constant name="MSAA_8X" value="3" enum="MSAA">
+ Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware.
+ </constant>
+ <constant name="MSAA_16X" value="4" enum="MSAA">
+ Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware.
+ </constant>
+ <constant name="MSAA_MAX" value="5" enum="MSAA">
+ Represents the size of the [enum MSAA] enum.
+ </constant>
+ <constant name="SCREEN_SPACE_AA_DISABLED" value="0" enum="ScreenSpaceAA">
+ Do not perform any antialiasing in the full screen post-process.
+ </constant>
+ <constant name="SCREEN_SPACE_AA_FXAA" value="1" enum="ScreenSpaceAA">
+ Use fast approximate antialiasing. FXAA is a popular screen-space antialising method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K.
+ </constant>
+ <constant name="SCREEN_SPACE_AA_MAX" value="2" enum="ScreenSpaceAA">
+ Represents the size of the [enum ScreenSpaceAA] enum.
+ </constant>
<constant name="RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo">
Amount of objects in frame.
</constant>
@@ -315,58 +347,71 @@
<constant name="DEBUG_DRAW_UNSHADED" value="1" enum="DebugDraw">
Objects are displayed without light information.
</constant>
+ <constant name="DEBUG_DRAW_LIGHTING" value="2" enum="DebugDraw">
+ </constant>
<constant name="DEBUG_DRAW_OVERDRAW" value="3" enum="DebugDraw">
- Objected are displayed semi-transparent with additive blending so you can see where they intersect.
+ Objects are displayed semi-transparent with additive blending so you can see where they are drawing over top of one another. A higher overdraw means you are wasting performance on drawing pixels that are being hidden behind others.
</constant>
<constant name="DEBUG_DRAW_WIREFRAME" value="4" enum="DebugDraw">
Objects are displayed in wireframe style.
</constant>
+ <constant name="DEBUG_DRAW_NORMAL_BUFFER" value="5" enum="DebugDraw">
+ </constant>
<constant name="DEBUG_DRAW_GI_PROBE_ALBEDO" value="6" enum="DebugDraw">
+ Objects are displayed with only the albedo value from [GIProbe]s.
</constant>
<constant name="DEBUG_DRAW_GI_PROBE_LIGHTING" value="7" enum="DebugDraw">
+ Objects are displayed with only the lighting value from [GIProbe]s.
</constant>
<constant name="DEBUG_DRAW_GI_PROBE_EMISSION" value="8" enum="DebugDraw">
+ Objects are displayed with only the emission color from [GIProbe]s.
</constant>
<constant name="DEBUG_DRAW_SHADOW_ATLAS" value="9" enum="DebugDraw">
+ Draws the shadow atlas that stores shadows from [OmniLight3D]s and [SpotLight3D]s in the upper left quadrant of the [Viewport].
</constant>
<constant name="DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS" value="10" enum="DebugDraw">
+ Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the upper left quadrant of the [Viewport].
</constant>
<constant name="DEBUG_DRAW_SCENE_LUMINANCE" value="11" enum="DebugDraw">
</constant>
<constant name="DEBUG_DRAW_SSAO" value="12" enum="DebugDraw">
+ Draws the screen-space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment].
</constant>
- <constant name="MSAA_DISABLED" value="0" enum="MSAA">
- Multisample anti-aliasing mode disabled. This is the default value.
- </constant>
- <constant name="MSAA_2X" value="1" enum="MSAA">
- Use 2x Multisample Antialiasing.
- </constant>
- <constant name="MSAA_4X" value="2" enum="MSAA">
- Use 4x Multisample Antialiasing.
+ <constant name="DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="DebugDraw">
+ Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work.
</constant>
- <constant name="MSAA_8X" value="3" enum="MSAA">
- Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware.
+ <constant name="DEBUG_DRAW_PSSM_SPLITS" value="14" enum="DebugDraw">
+ Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order, they will be colored red, green, blue, and yellow.
</constant>
- <constant name="MSAA_16X" value="4" enum="MSAA">
- Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware.
+ <constant name="DEBUG_DRAW_DECAL_ATLAS" value="15" enum="DebugDraw">
+ Draws the decal atlas used by [Decal]s and light projector textures in the upper left quadrant of the [Viewport].
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="0" enum="DefaultCanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="1" enum="DefaultCanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="2" enum="DefaultCanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="DefaultCanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX" value="4" enum="DefaultCanvasItemTextureFilter">
+ Max value for [enum DefaultCanvasItemTextureFilter] enum.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED" value="0" enum="DefaultCanvasItemTextureRepeat">
+ Disables textures repeating. Instead, when reading UVs outside the 0-1 range, the value will be clamped to the edge of the texture, resulting in a stretched out look at the borders of the texture.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED" value="1" enum="DefaultCanvasItemTextureRepeat">
+ Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR" value="2" enum="DefaultCanvasItemTextureRepeat">
+ Flip the texture when repeating so that the edge lines up instead of abruptly changing.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="3" enum="DefaultCanvasItemTextureRepeat">
+ Max value for [enum DefaultCanvasItemTextureRepeat] enum.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml
index 0bdecafbfa..f0e4c999ac 100644
--- a/doc/classes/VisibilityEnabler2D.xml
+++ b/doc/classes/VisibilityEnabler2D.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisibilityEnabler2D" inherits="VisibilityNotifier2D" version="4.0">
<brief_description>
- Enables certain nodes only when visible.
+ Enables certain nodes only when approximately visible.
</brief_description>
<description>
The VisibilityEnabler2D will disable [RigidBody2D], [AnimationPlayer], and other nodes when they are not visible. It will only affect nodes with the same root node as the VisibilityEnabler2D, and the root node itself.
- Note that VisibilityEnabler2D will not affect nodes added after scene initialization.
+ [b]Note:[/b] VisibilityEnabler2D uses an approximate heuristic for performance reasons. If you need exact visibility checking, use another method such as adding an [Area2D] node as a child of a [Camera2D] node.
+ [b]Note:[/b] VisibilityEnabler2D will not affect nodes added after scene initialization.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisibilityEnabler3D.xml b/doc/classes/VisibilityEnabler3D.xml
index 9c25c6c7c8..342a37e7a4 100644
--- a/doc/classes/VisibilityEnabler3D.xml
+++ b/doc/classes/VisibilityEnabler3D.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisibilityEnabler3D" inherits="VisibilityNotifier3D" version="4.0">
<brief_description>
- Enables certain nodes only when visible.
+ Enables certain nodes only when approximately visible.
</brief_description>
<description>
The VisibilityEnabler3D will disable [RigidBody3D] and [AnimationPlayer] nodes when they are not visible. It will only affect other nodes within the same scene as the VisibilityEnabler3D itself.
- Note that VisibilityEnabler3D will not affect nodes added after scene initialization.
+ [b]Note:[/b] VisibilityEnabler3D uses an approximate heuristic for performance reasons. It doesn't take walls and other occlusion into account. If you need exact visibility checking, use another method such as adding an [Area3D] node as a child of a [Camera3D] node.
+ [b]Note:[/b] VisibilityEnabler3D will not affect nodes added after scene initialization.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisibilityNotifier2D.xml b/doc/classes/VisibilityNotifier2D.xml
index f2a4a59d77..813f74f404 100644
--- a/doc/classes/VisibilityNotifier2D.xml
+++ b/doc/classes/VisibilityNotifier2D.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisibilityNotifier2D" inherits="Node2D" version="4.0">
<brief_description>
- Detects when the node is visible on screen.
+ Detects approximately when the node is visible on screen.
</brief_description>
<description>
The VisibilityNotifier2D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a viewport.
+ [b]Note:[/b] VisibilityNotifier2D uses an approximate heuristic for performance reasons. If you need exact visibility checking, use another method such as adding an [Area2D] node as a child of a [Camera2D] node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisibilityNotifier3D.xml b/doc/classes/VisibilityNotifier3D.xml
index d8a605c69c..eb7bb91f26 100644
--- a/doc/classes/VisibilityNotifier3D.xml
+++ b/doc/classes/VisibilityNotifier3D.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisibilityNotifier3D" inherits="Node3D" version="4.0">
<brief_description>
- Detects when the node is visible on screen.
+ Detects approximately when the node is visible on screen.
</brief_description>
<description>
The VisibilityNotifier3D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a [Camera3D]'s view.
+ [b]Note:[/b] VisibilityNotifier3D uses an approximate heuristic for performance reasons. It doesn't take walls and other occlusion into account. If you need exact visibility checking, use another method such as adding an [Area3D] node as a child of a [Camera3D] node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ARVRAnchor.xml b/doc/classes/XRAnchor3D.xml
index 82575ce7cb..a409c79230 100644
--- a/doc/classes/ARVRAnchor.xml
+++ b/doc/classes/XRAnchor3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRAnchor" inherits="Node3D" version="4.0">
+<class name="XRAnchor3D" inherits="Node3D" version="4.0">
<brief_description>
An anchor point in AR space.
</brief_description>
<description>
- The [ARVRAnchor] point is a spatial node that maps a real world location identified by the AR platform to a position within the game world. For example, as long as plane detection in ARKit is on, ARKit will identify and update the position of planes (tables, floors, etc) and create anchors for them.
+ The [XRAnchor3D] point is a spatial node that maps a real world location identified by the AR platform to a position within the game world. For example, as long as plane detection in ARKit is on, ARKit will identify and update the position of planes (tables, floors, etc) and create anchors for them.
This node is mapped to one of the anchors through its unique ID. When you receive a signal that a new anchor is available, you should add this node to your scene for that anchor. You can predefine nodes and set the ID; the nodes will simply remain on 0,0,0 until a plane is recognized.
Keep in mind that, as long as plane detection is enabled, the size, placing and orientation of an anchor will be updated as the detection logic learns more about the real world out there especially if only part of the surface is in view.
</description>
@@ -29,7 +29,7 @@
<return type="Mesh">
</return>
<description>
- If provided by the [ARVRInterface], this returns a mesh object for the anchor. For an anchor, this can be a shape related to the object being tracked or it can be a mesh that provides topology related to the anchor and can be used to create shadows/reflections on surfaces or for generating collision shapes.
+ If provided by the [XRInterface], this returns a mesh object for the anchor. For an anchor, this can be a shape related to the object being tracked or it can be a mesh that provides topology related to the anchor and can be used to create shadows/reflections on surfaces or for generating collision shapes.
</description>
</method>
<method name="get_plane" qualifiers="const">
diff --git a/doc/classes/ARVRCamera.xml b/doc/classes/XRCamera3D.xml
index c97d5cf1d8..4d86e24daa 100644
--- a/doc/classes/ARVRCamera.xml
+++ b/doc/classes/XRCamera3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRCamera" inherits="Camera3D" version="4.0">
+<class name="XRCamera3D" inherits="Camera3D" version="4.0">
<brief_description>
A camera node with a few overrules for AR/VR applied, such as location tracking.
</brief_description>
<description>
This is a helper spatial node for our camera; note that, if stereoscopic rendering is applicable (VR-HMD), most of the camera properties are ignored, as the HMD information overrides them. The only properties that can be trusted are the near and far planes.
- The position and orientation of this node is automatically updated by the ARVR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that, in contrast to the ARVR Controller, the render thread has access to the most up-to-date tracking data of the HMD and the location of the ARVRCamera can lag a few milliseconds behind what is used for rendering as a result.
+ The position and orientation of this node is automatically updated by the XR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that, in contrast to the XR Controller, the render thread has access to the most up-to-date tracking data of the HMD and the location of the XRCamera3D can lag a few milliseconds behind what is used for rendering as a result.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
diff --git a/doc/classes/ARVRController.xml b/doc/classes/XRController3D.xml
index 572b47ce6d..e4a06a80db 100644
--- a/doc/classes/ARVRController.xml
+++ b/doc/classes/XRController3D.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRController" inherits="Node3D" version="4.0">
+<class name="XRController3D" inherits="Node3D" version="4.0">
<brief_description>
A spatial node representing a spatially-tracked controller.
</brief_description>
<description>
This is a helper spatial node that is linked to the tracking of controllers. It also offers several handy passthroughs to the state of buttons and such on the controllers.
- Controllers are linked by their ID. You can create controller nodes before the controllers are available. If your game always uses two controllers (one for each hand), you can predefine the controllers with ID 1 and 2; they will become active as soon as the controllers are identified. If you expect additional controllers to be used, you should react to the signals and add ARVRController nodes to your scene.
- The position of the controller node is automatically updated by the [ARVRServer]. This makes this node ideal to add child nodes to visualize the controller.
+ Controllers are linked by their ID. You can create controller nodes before the controllers are available. If your game always uses two controllers (one for each hand), you can predefine the controllers with ID 1 and 2; they will become active as soon as the controllers are identified. If you expect additional controllers to be used, you should react to the signals and add XRController3D nodes to your scene.
+ The position of the controller node is automatically updated by the [XRServer]. This makes this node ideal to add child nodes to visualize the controller.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
@@ -20,17 +20,17 @@
</description>
</method>
<method name="get_hand" qualifiers="const">
- <return type="int" enum="ARVRPositionalTracker.TrackerHand">
+ <return type="int" enum="XRPositionalTracker.TrackerHand">
</return>
<description>
- Returns the hand holding this controller, if known. See [enum ARVRPositionalTracker.TrackerHand].
+ Returns the hand holding this controller, if known. See [enum XRPositionalTracker.TrackerHand].
</description>
</method>
<method name="get_is_active" qualifiers="const">
<return type="bool">
</return>
<description>
- Returns [code]true[/code] if the bound controller is active. ARVR systems attempt to track active controllers.
+ Returns [code]true[/code] if the bound controller is active. XR systems attempt to track active controllers.
</description>
</method>
<method name="get_joystick_axis" qualifiers="const">
@@ -46,14 +46,14 @@
<return type="int">
</return>
<description>
- Returns the ID of the joystick object bound to this. Every controller tracked by the [ARVRServer] that has buttons and axis will also be registered as a joystick within Godot. This means that all the normal joystick tracking and input mapping will work for buttons and axis found on the AR/VR controllers. This ID is purely offered as information so you can link up the controller with its joystick entry.
+ Returns the ID of the joystick object bound to this. Every controller tracked by the [XRServer] that has buttons and axis will also be registered as a joystick within Godot. This means that all the normal joystick tracking and input mapping will work for buttons and axis found on the AR/VR controllers. This ID is purely offered as information so you can link up the controller with its joystick entry.
</description>
</method>
<method name="get_mesh" qualifiers="const">
<return type="Mesh">
</return>
<description>
- If provided by the [ARVRInterface], this returns a mesh associated with the controller. This can be used to visualize the controller.
+ If provided by the [XRInterface], this returns a mesh associated with the controller. This can be used to visualize the controller.
</description>
</method>
<method name="is_button_pressed" qualifiers="const">
@@ -70,11 +70,11 @@
<member name="controller_id" type="int" setter="set_controller_id" getter="get_controller_id" default="1">
The controller's ID.
A controller ID of 0 is unbound and will always result in an inactive node. Controller ID 1 is reserved for the first controller that identifies itself as the left-hand controller and ID 2 is reserved for the first controller that identifies itself as the right-hand controller.
- For any other controller that the [ARVRServer] detects, we continue with controller ID 3.
+ For any other controller that the [XRServer] detects, we continue with controller ID 3.
When a controller is turned off, its slot is freed. This ensures controllers will keep the same ID even when controllers with lower IDs are turned off.
</member>
<member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0">
- The degree to which the controller vibrates. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member ARVRPositionalTracker.rumble] accordingly.
+ The degree to which the controller vibrates. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member XRPositionalTracker.rumble] accordingly.
This is a useful property to animate if you want the controller to vibrate for a limited duration.
</member>
</members>
diff --git a/doc/classes/ARVRInterface.xml b/doc/classes/XRInterface.xml
index 0727bda668..1985010223 100644
--- a/doc/classes/ARVRInterface.xml
+++ b/doc/classes/XRInterface.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRInterface" inherits="Reference" version="4.0">
+<class name="XRInterface" inherits="Reference" version="4.0">
<brief_description>
Base class for an AR/VR interface implementation.
</brief_description>
<description>
- This class needs to be implemented to make an AR or VR platform available to Godot and these should be implemented as C++ modules or GDNative modules (note that for GDNative the subclass ARVRScriptInterface should be used). Part of the interface is exposed to GDScript so you can detect, enable and configure an AR or VR platform.
- Interfaces should be written in such a way that simply enabling them will give us a working setup. You can query the available interfaces through [ARVRServer].
+ This class needs to be implemented to make an AR or VR platform available to Godot and these should be implemented as C++ modules or GDNative modules (note that for GDNative the subclass XRScriptInterface should be used). Part of the interface is exposed to GDScript so you can detect, enable and configure an AR or VR platform.
+ Interfaces should be written in such a way that simply enabling them will give us a working setup. You can query the available interfaces through [XRServer].
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
@@ -40,7 +40,7 @@
</description>
</method>
<method name="get_tracking_status" qualifiers="const">
- <return type="int" enum="ARVRInterface.Tracking_status">
+ <return type="int" enum="XRInterface.Tracking_status">
</return>
<description>
If supported, returns the status of our tracking. This will allow you to provide feedback to the user whether there are issues with positional tracking.
@@ -84,19 +84,19 @@
</member>
</members>
<constants>
- <constant name="ARVR_NONE" value="0" enum="Capabilities">
- No ARVR capabilities.
+ <constant name="XR_NONE" value="0" enum="Capabilities">
+ No XR capabilities.
</constant>
- <constant name="ARVR_MONO" value="1" enum="Capabilities">
+ <constant name="XR_MONO" value="1" enum="Capabilities">
This interface can work with normal rendering output (non-HMD based AR).
</constant>
- <constant name="ARVR_STEREO" value="2" enum="Capabilities">
+ <constant name="XR_STEREO" value="2" enum="Capabilities">
This interface supports stereoscopic rendering.
</constant>
- <constant name="ARVR_AR" value="4" enum="Capabilities">
+ <constant name="XR_AR" value="4" enum="Capabilities">
This interface supports AR (video background and real world tracking).
</constant>
- <constant name="ARVR_EXTERNAL" value="8" enum="Capabilities">
+ <constant name="XR_EXTERNAL" value="8" enum="Capabilities">
This interface outputs to an external device. If the main viewport is used, the on screen output is an unmodified buffer of either the left or right eye (stretched if the viewport size is not changed to the same aspect ratio of [method get_render_targetsize]). Using a separate viewport node frees up the main viewport for other purposes.
</constant>
<constant name="EYE_MONO" value="0" enum="Eyes">
@@ -108,19 +108,19 @@
<constant name="EYE_RIGHT" value="2" enum="Eyes">
Right eye output, this is mostly used internally when rendering the image for the right eye and obtaining positioning and projection information.
</constant>
- <constant name="ARVR_NORMAL_TRACKING" value="0" enum="Tracking_status">
+ <constant name="XR_NORMAL_TRACKING" value="0" enum="Tracking_status">
Tracking is behaving as expected.
</constant>
- <constant name="ARVR_EXCESSIVE_MOTION" value="1" enum="Tracking_status">
+ <constant name="XR_EXCESSIVE_MOTION" value="1" enum="Tracking_status">
Tracking is hindered by excessive motion (the player is moving faster than tracking can keep up).
</constant>
- <constant name="ARVR_INSUFFICIENT_FEATURES" value="2" enum="Tracking_status">
+ <constant name="XR_INSUFFICIENT_FEATURES" value="2" enum="Tracking_status">
Tracking is hindered by insufficient features, it's too dark (for camera-based tracking), player is blocked, etc.
</constant>
- <constant name="ARVR_UNKNOWN_TRACKING" value="3" enum="Tracking_status">
+ <constant name="XR_UNKNOWN_TRACKING" value="3" enum="Tracking_status">
We don't know the status of the tracking or this interface does not provide feedback.
</constant>
- <constant name="ARVR_NOT_TRACKING" value="4" enum="Tracking_status">
+ <constant name="XR_NOT_TRACKING" value="4" enum="Tracking_status">
Tracking is not functional (camera not plugged in or obscured, lighthouses turned off, etc.).
</constant>
</constants>
diff --git a/doc/classes/ARVROrigin.xml b/doc/classes/XROrigin3D.xml
index a88a89c927..57cf673d30 100644
--- a/doc/classes/ARVROrigin.xml
+++ b/doc/classes/XROrigin3D.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVROrigin" inherits="Node3D" version="4.0">
+<class name="XROrigin3D" inherits="Node3D" version="4.0">
<brief_description>
The origin point in AR/VR.
</brief_description>
<description>
This is a special node within the AR/VR system that maps the physical location of the center of our tracking space to the virtual location within our game world.
- There should be only one of these nodes in your scene and you must have one. All the ARVRCamera, ARVRController and ARVRAnchor nodes should be direct children of this node for spatial tracking to work correctly.
+ There should be only one of these nodes in your scene and you must have one. All the XRCamera3D, XRController3D and XRAnchor3D nodes should be direct children of this node for spatial tracking to work correctly.
It is the position of this node that you update when your character needs to move through your game world while we're not moving in the real world. Movement in the real world is always in relation to this origin point.
- For example, if your character is driving a car, the ARVROrigin node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node.
+ For example, if your character is driving a car, the XROrigin3D node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
@@ -17,7 +17,7 @@
<members>
<member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" default="1.0">
Allows you to adjust the scale to your game's units. Most AR/VR platforms assume a scale of 1 game world unit = 1 real world meter.
- [b]Note:[/b] This method is a passthrough to the [ARVRServer] itself.
+ [b]Note:[/b] This method is a passthrough to the [XRServer] itself.
</member>
</members>
<constants>
diff --git a/doc/classes/ARVRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml
index 640b721d37..2f7cc21703 100644
--- a/doc/classes/ARVRPositionalTracker.xml
+++ b/doc/classes/XRPositionalTracker.xml
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRPositionalTracker" inherits="Object" version="4.0">
+<class name="XRPositionalTracker" inherits="Object" version="4.0">
<brief_description>
A tracked object.
</brief_description>
<description>
An instance of this object represents a device that is tracked, such as a controller or anchor point. HMDs aren't represented here as they are handled internally.
- As controllers are turned on and the AR/VR interface detects them, instances of this object are automatically added to this list of active tracking objects accessible through the [ARVRServer].
- The [ARVRController] and [ARVRAnchor] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDNative-based interfaces can interact with them.
+ As controllers are turned on and the AR/VR interface detects them, instances of this object are automatically added to this list of active tracking objects accessible through the [XRServer].
+ The [XRController3D] and [XRAnchor3D] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDNative-based interfaces can interact with them.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
<method name="get_hand" qualifiers="const">
- <return type="int" enum="ARVRPositionalTracker.TrackerHand">
+ <return type="int" enum="XRPositionalTracker.TrackerHand">
</return>
<description>
Returns the hand holding this tracker, if known. See [enum TrackerHand] constants.
@@ -58,7 +58,7 @@
<return type="int">
</return>
<description>
- Returns the internal tracker ID. This uniquely identifies the tracker per tracker type and matches the ID you need to specify for nodes such as the [ARVRController] and [ARVRAnchor] nodes.
+ Returns the internal tracker ID. This uniquely identifies the tracker per tracker type and matches the ID you need to specify for nodes such as the [XRController3D] and [XRAnchor3D] nodes.
</description>
</method>
<method name="get_tracks_orientation" qualifiers="const">
@@ -85,7 +85,7 @@
</description>
</method>
<method name="get_type" qualifiers="const">
- <return type="int" enum="ARVRServer.TrackerType">
+ <return type="int" enum="XRServer.TrackerType">
</return>
<description>
Returns the tracker's type.
diff --git a/doc/classes/ARVRServer.xml b/doc/classes/XRServer.xml
index d8d069c048..5e6002aee3 100644
--- a/doc/classes/ARVRServer.xml
+++ b/doc/classes/XRServer.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRServer" inherits="Object" version="4.0">
+<class name="XRServer" inherits="Object" version="4.0">
<brief_description>
Server for AR and VR features.
</brief_description>
@@ -13,7 +13,7 @@
<method name="center_on_hmd">
<return type="void">
</return>
- <argument index="0" name="rotation_mode" type="int" enum="ARVRServer.RotationMode">
+ <argument index="0" name="rotation_mode" type="int" enum="XRServer.RotationMode">
</argument>
<argument index="1" name="keep_height" type="bool">
</argument>
@@ -27,7 +27,7 @@
</description>
</method>
<method name="find_interface" qualifiers="const">
- <return type="ARVRInterface">
+ <return type="XRInterface">
</return>
<argument index="0" name="name" type="String">
</argument>
@@ -43,7 +43,7 @@
</description>
</method>
<method name="get_interface" qualifiers="const">
- <return type="ARVRInterface">
+ <return type="XRInterface">
</return>
<argument index="0" name="idx" type="int">
</argument>
@@ -69,7 +69,7 @@
<return type="int">
</return>
<description>
- Returns the absolute timestamp (in μs) of the last [ARVRServer] commit of the AR/VR eyes to [RenderingServer]. The value comes from an internal call to [method OS.get_ticks_usec].
+ Returns the absolute timestamp (in μs) of the last [XRServer] commit of the AR/VR eyes to [RenderingServer]. The value comes from an internal call to [method OS.get_ticks_usec].
</description>
</method>
<method name="get_last_frame_usec">
@@ -83,7 +83,7 @@
<return type="int">
</return>
<description>
- Returns the absolute timestamp (in μs) of the last [ARVRServer] process callback. The value comes from an internal call to [method OS.get_ticks_usec].
+ Returns the absolute timestamp (in μs) of the last [XRServer] process callback. The value comes from an internal call to [method OS.get_ticks_usec].
</description>
</method>
<method name="get_reference_frame" qualifiers="const">
@@ -94,7 +94,7 @@
</description>
</method>
<method name="get_tracker" qualifiers="const">
- <return type="ARVRPositionalTracker">
+ <return type="XRPositionalTracker">
</return>
<argument index="0" name="idx" type="int">
</argument>
@@ -111,8 +111,8 @@
</method>
</methods>
<members>
- <member name="primary_interface" type="ARVRInterface" setter="set_primary_interface" getter="get_primary_interface">
- The primary [ARVRInterface] currently bound to the [ARVRServer].
+ <member name="primary_interface" type="XRInterface" setter="set_primary_interface" getter="get_primary_interface">
+ The primary [XRInterface] currently bound to the [XRServer].
</member>
<member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" default="1.0">
Allows you to adjust the scale to your game's units. Most AR/VR platforms assume a scale of 1 game world unit = 1 real world meter.
@@ -141,7 +141,7 @@
<argument index="2" name="id" type="int">
</argument>
<description>
- Emitted when a new tracker has been added. If you don't use a fixed number of controllers or if you're using [ARVRAnchor]s for an AR solution, it is important to react to this signal to add the appropriate [ARVRController] or [ARVRAnchor] nodes related to this new tracker.
+ Emitted when a new tracker has been added. If you don't use a fixed number of controllers or if you're using [XRAnchor3D]s for an AR solution, it is important to react to this signal to add the appropriate [XRController3D] or [XRAnchor3D] nodes related to this new tracker.
</description>
</signal>
<signal name="tracker_removed">
@@ -152,7 +152,7 @@
<argument index="2" name="id" type="int">
</argument>
<description>
- Emitted when a tracker is removed. You should remove any [ARVRController] or [ARVRAnchor] points if applicable. This is not mandatory, the nodes simply become inactive and will be made active again when a new tracker becomes available (i.e. a new controller is switched on that takes the place of the previous one).
+ Emitted when a tracker is removed. You should remove any [XRController3D] or [XRAnchor3D] points if applicable. This is not mandatory, the nodes simply become inactive and will be made active again when a new tracker becomes available (i.e. a new controller is switched on that takes the place of the previous one).
</description>
</signal>
</signals>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 9de5eac31d..c6c6cae6c0 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -424,7 +424,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
type_rst = property_def.type_name.to_rst(state)
default = property_def.default_value
if property_def.overridden:
- ml.append((type_rst, property_def.name, "**O:** " + default))
+ ml.append((type_rst, property_def.name, default + " *(parent override)*"))
else:
ref = ":ref:`{0}<class_{1}_property_{0}>`".format(property_def.name, class_name)
ml.append((type_rst, ref, default))
diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp
index 92919f25c8..ddd2943720 100644
--- a/drivers/dummy/texture_loader_dummy.cpp
+++ b/drivers/dummy/texture_loader_dummy.cpp
@@ -35,7 +35,7 @@
#include <string.h>
-RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
unsigned int width = 8;
unsigned int height = 8;
diff --git a/drivers/dummy/texture_loader_dummy.h b/drivers/dummy/texture_loader_dummy.h
index 2a7d01dd78..ef9f3b13b6 100644
--- a/drivers/dummy/texture_loader_dummy.h
+++ b/drivers/dummy/texture_loader_dummy.h
@@ -36,7 +36,7 @@
class ResourceFormatDummyTexture : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 2ba2147de9..bdf0559f58 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -4045,7 +4045,7 @@ void RasterizerSceneGLES2::initialize() {
//maximum compatibility, renderbuffer and RGBA shadow
glGenRenderbuffers(1, &directional_shadow.depth);
glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth);
- glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size);
+ glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_buffer_internalformat, directional_shadow.size, directional_shadow.size);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, directional_shadow.depth);
glGenTextures(1, &directional_shadow.color);
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 409722ff82..b8c7815f6a 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -6252,7 +6252,7 @@ void RasterizerStorageGLES2::initialize() {
#endif
config.force_vertex_shading = GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
- config.use_fast_texture_filter = GLOBAL_GET("rendering/quality/filters/use_nearest_mipmap_filter");
+ config.use_fast_texture_filter = GLOBAL_GET("rendering/quality/texture_filters/use_nearest_mipmap_filter");
}
void RasterizerStorageGLES2::finalize() {
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub
index 7ffdac27d5..91d0e42f80 100644
--- a/drivers/vulkan/SCsub
+++ b/drivers/vulkan/SCsub
@@ -4,7 +4,25 @@ Import("env")
env.add_source_files(env.drivers_sources, "*.cpp")
-if env["builtin_vulkan"]:
+if env["platform"] == "android":
+ # Use NDK Vulkan headers
+ thirdparty_dir = env["ANDROID_NDK_ROOT"] + "/sources/third_party/vulkan/src"
+ thirdparty_includes = [
+ thirdparty_dir,
+ thirdparty_dir + "/include",
+ thirdparty_dir + "/layers",
+ thirdparty_dir + "/layers/generated",
+ ]
+ env.Prepend(CPPPATH=thirdparty_includes)
+
+ # Build Vulkan memory allocator
+ env_thirdparty = env.Clone()
+ env_thirdparty.disable_warnings()
+
+ thirdparty_dir = "#thirdparty/vulkan"
+ vma_sources = [thirdparty_dir + "/android/vk_mem_alloc.cpp"]
+ env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
+elif env["builtin_vulkan"]:
# Use bundled Vulkan headers
thirdparty_dir = "#thirdparty/vulkan"
env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include", thirdparty_dir + "/loader"])
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 01da97cfd5..23e9227a39 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -1565,11 +1565,21 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.pNext = nullptr;
image_create_info.flags = 0;
- VkImageFormatListCreateInfoKHR format_list_create_info;
- Vector<VkFormat> allowed_formats;
+#ifndef _MSC_VER
+#warning TODO check for support via RenderingDevice to enable on mobile when possible
+#endif
+
+#ifndef ANDROID_ENABLED
+ // vkCreateImage fails with format list on Android (VK_ERROR_OUT_OF_HOST_MEMORY)
+ VkImageFormatListCreateInfoKHR format_list_create_info; //keep out of the if, needed for creation
+ Vector<VkFormat> allowed_formats; //keep out of the if, needed for creation
+#endif
if (p_format.shareable_formats.size()) {
image_create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+
+#ifndef ANDROID_ENABLED
+
for (int i = 0; i < p_format.shareable_formats.size(); i++) {
allowed_formats.push_back(vulkan_formats[p_format.shareable_formats[i]]);
}
@@ -1584,7 +1594,9 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
"If supplied a list of shareable formats, the current format must be present in the list");
ERR_FAIL_COND_V_MSG(p_view.format_override != DATA_FORMAT_MAX && p_format.shareable_formats.find(p_view.format_override) == -1, RID(),
"If supplied a list of shareable formats, the current view format override must be present in the list");
+#endif
}
+
if (p_format.type == TEXTURE_TYPE_CUBE || p_format.type == TEXTURE_TYPE_CUBE_ARRAY) {
image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
}
@@ -1760,6 +1772,8 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
texture.depth = image_create_info.extent.depth;
texture.layers = image_create_info.arrayLayers;
texture.mipmaps = image_create_info.mipLevels;
+ texture.base_mipmap = 0;
+ texture.base_layer = 0;
texture.usage_flags = p_format.usage_bits;
texture.samples = p_format.samples;
texture.allowed_shared_formats = p_format.shareable_formats;
@@ -2000,6 +2014,8 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
get_image_format_required_size(texture.format, texture.width, texture.height, texture.depth, p_mipmap + 1, &texture.width, &texture.height);
texture.mipmaps = 1;
texture.layers = p_slice_type == TEXTURE_SLICE_CUBEMAP ? 6 : 1;
+ texture.base_mipmap = p_mipmap;
+ texture.base_layer = p_layer;
VkImageViewCreateInfo image_view_create_info;
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
@@ -2660,6 +2676,159 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
return OK;
}
+Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw) {
+ _THREAD_SAFE_METHOD_
+
+ Texture *src_tex = texture_owner.getornull(p_from_texture);
+ ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER);
+
+ ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER,
+ "Source texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture.");
+ ERR_FAIL_COND_V_MSG(!(src_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT), ERR_INVALID_PARAMETER,
+ "Source texture requires the TEXTURE_USAGE_CAN_COPY_FROM_BIT in order to be retrieved.");
+
+ ERR_FAIL_COND_V_MSG(src_tex->type != TEXTURE_TYPE_2D, ERR_INVALID_PARAMETER, "Source texture must be 2D (or a slice of a 3D/Cube texture)");
+ ERR_FAIL_COND_V_MSG(src_tex->samples == TEXTURE_SAMPLES_1, ERR_INVALID_PARAMETER, "Source texture must be multisampled.");
+
+ Texture *dst_tex = texture_owner.getornull(p_to_texture);
+ ERR_FAIL_COND_V(!dst_tex, ERR_INVALID_PARAMETER);
+
+ ERR_FAIL_COND_V_MSG(p_sync_with_draw && dst_tex->bound, ERR_INVALID_PARAMETER,
+ "Destination texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture.");
+ ERR_FAIL_COND_V_MSG(!(dst_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT), ERR_INVALID_PARAMETER,
+ "Destination texture requires the TEXTURE_USAGE_CAN_COPY_TO_BIT in order to be retrieved.");
+
+ ERR_FAIL_COND_V_MSG(dst_tex->type != TEXTURE_TYPE_2D, ERR_INVALID_PARAMETER, "Destination texture must be 2D (or a slice of a 3D/Cube texture).");
+ ERR_FAIL_COND_V_MSG(dst_tex->samples != TEXTURE_SAMPLES_1, ERR_INVALID_PARAMETER, "Destination texture must not be multisampled.");
+
+ ERR_FAIL_COND_V_MSG(src_tex->format != dst_tex->format, ERR_INVALID_PARAMETER, "Source and Destionation textures must be the same format.");
+ ERR_FAIL_COND_V_MSG(src_tex->width != dst_tex->width && src_tex->height != dst_tex->height && src_tex->depth != dst_tex->depth, ERR_INVALID_PARAMETER, "Source and Destionation textures must have the same dimensions.");
+
+ ERR_FAIL_COND_V_MSG(src_tex->read_aspect_mask != dst_tex->read_aspect_mask, ERR_INVALID_PARAMETER,
+ "Source and destination texture must be of the same type (color or depth).");
+
+ VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
+
+ {
+
+ //PRE Copy the image
+
+ { //Source
+ VkImageMemoryBarrier image_memory_barrier;
+ image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ image_memory_barrier.pNext = nullptr;
+ image_memory_barrier.srcAccessMask = 0;
+ image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ image_memory_barrier.oldLayout = src_tex->layout;
+ image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+
+ image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.image = src_tex->image;
+ image_memory_barrier.subresourceRange.aspectMask = src_tex->barrier_aspect_mask;
+ image_memory_barrier.subresourceRange.baseMipLevel = src_tex->base_mipmap;
+ image_memory_barrier.subresourceRange.levelCount = 1;
+ image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer;
+ image_memory_barrier.subresourceRange.layerCount = 1;
+
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ }
+ { //Dest
+ VkImageMemoryBarrier image_memory_barrier;
+ image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ image_memory_barrier.pNext = nullptr;
+ image_memory_barrier.srcAccessMask = 0;
+ image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ image_memory_barrier.oldLayout = dst_tex->layout;
+ image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+
+ image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.image = dst_tex->image;
+ image_memory_barrier.subresourceRange.aspectMask = dst_tex->read_aspect_mask;
+ image_memory_barrier.subresourceRange.baseMipLevel = dst_tex->base_mipmap;
+ image_memory_barrier.subresourceRange.levelCount = 1;
+ image_memory_barrier.subresourceRange.baseArrayLayer = dst_tex->base_layer;
+ image_memory_barrier.subresourceRange.layerCount = 1;
+
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ }
+
+ //COPY
+
+ {
+
+ VkImageResolve image_copy_region;
+ image_copy_region.srcSubresource.aspectMask = src_tex->read_aspect_mask;
+ image_copy_region.srcSubresource.baseArrayLayer = src_tex->base_layer;
+ image_copy_region.srcSubresource.layerCount = 1;
+ image_copy_region.srcSubresource.mipLevel = src_tex->base_mipmap;
+ image_copy_region.srcOffset.x = 0;
+ image_copy_region.srcOffset.y = 0;
+ image_copy_region.srcOffset.z = 0;
+
+ image_copy_region.dstSubresource.aspectMask = dst_tex->read_aspect_mask;
+ image_copy_region.dstSubresource.baseArrayLayer = dst_tex->base_layer;
+ image_copy_region.dstSubresource.layerCount = 1;
+ image_copy_region.dstSubresource.mipLevel = dst_tex->base_mipmap;
+ image_copy_region.dstOffset.x = 0;
+ image_copy_region.dstOffset.y = 0;
+ image_copy_region.dstOffset.z = 0;
+
+ image_copy_region.extent.width = src_tex->width;
+ image_copy_region.extent.height = src_tex->height;
+ image_copy_region.extent.depth = src_tex->depth;
+
+ vkCmdResolveImage(command_buffer, src_tex->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_tex->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy_region);
+ }
+
+ // RESTORE LAYOUT for SRC and DST
+
+ { //restore src
+ VkImageMemoryBarrier image_memory_barrier;
+ image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ image_memory_barrier.pNext = nullptr;
+ image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ image_memory_barrier.newLayout = src_tex->layout;
+ image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.image = src_tex->image;
+ image_memory_barrier.subresourceRange.aspectMask = src_tex->barrier_aspect_mask;
+ image_memory_barrier.subresourceRange.baseMipLevel = src_tex->base_mipmap;
+ image_memory_barrier.subresourceRange.levelCount = 1;
+ image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer;
+ image_memory_barrier.subresourceRange.layerCount = 1;
+
+ vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ }
+
+ { //make dst readable
+
+ VkImageMemoryBarrier image_memory_barrier;
+ image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ image_memory_barrier.pNext = nullptr;
+ image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ image_memory_barrier.newLayout = dst_tex->layout;
+
+ image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.image = dst_tex->image;
+ image_memory_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ image_memory_barrier.subresourceRange.baseMipLevel = dst_tex->base_mipmap;
+ image_memory_barrier.subresourceRange.levelCount = 1;
+ image_memory_barrier.subresourceRange.baseArrayLayer = dst_tex->base_layer;
+ image_memory_barrier.subresourceRange.layerCount = 1;
+
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ }
+ }
+
+ return OK;
+}
Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw) {
@@ -2702,9 +2871,9 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = src_tex->image;
image_memory_barrier.subresourceRange.aspectMask = src_tex->read_aspect_mask;
- image_memory_barrier.subresourceRange.baseMipLevel = p_base_mipmap;
+ image_memory_barrier.subresourceRange.baseMipLevel = src_tex->base_mipmap + p_base_mipmap;
image_memory_barrier.subresourceRange.levelCount = p_mipmaps;
- image_memory_barrier.subresourceRange.baseArrayLayer = p_base_layer;
+ image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + p_base_layer;
image_memory_barrier.subresourceRange.layerCount = p_layers;
layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
@@ -2719,9 +2888,9 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
VkImageSubresourceRange range;
range.aspectMask = src_tex->read_aspect_mask;
- range.baseArrayLayer = p_base_layer;
+ range.baseArrayLayer = src_tex->base_layer + p_base_layer;
range.layerCount = p_layers;
- range.baseMipLevel = p_base_mipmap;
+ range.baseMipLevel = src_tex->base_mipmap + p_base_mipmap;
range.levelCount = p_mipmaps;
vkCmdClearColorImage(command_buffer, src_tex->image, layout, &clear_color, 1, &range);
@@ -2740,9 +2909,9 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = src_tex->image;
image_memory_barrier.subresourceRange.aspectMask = src_tex->read_aspect_mask;
- image_memory_barrier.subresourceRange.baseMipLevel = p_base_mipmap;
+ image_memory_barrier.subresourceRange.baseMipLevel = src_tex->base_mipmap + p_base_mipmap;
image_memory_barrier.subresourceRange.levelCount = p_mipmaps;
- image_memory_barrier.subresourceRange.baseArrayLayer = p_base_layer;
+ image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + p_base_layer;
image_memory_barrier.subresourceRange.layerCount = p_layers;
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
@@ -2840,6 +3009,21 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
}
} break;
+ case INITIAL_ACTION_DROP: {
+ if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ }
+ } break;
case INITIAL_ACTION_CONTINUE: {
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
@@ -3143,7 +3327,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec
}
// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
-RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) {
+RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) {
_THREAD_SAFE_METHOD_
@@ -3218,7 +3402,7 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo
//validate with buffer
{
- const VertexDescription &atf = vd.vertex_formats[i];
+ const VertexAttribute &atf = vd.vertex_formats[i];
uint32_t element_size = get_format_vertex_size(atf.format);
ERR_FAIL_COND_V(element_size == 0, RID()); //should never happens since this was prevalidated
@@ -4319,6 +4503,10 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
attachable_textures.push_back(texture->owner.is_valid() ? texture->owner : uniform.ids[j + 1]);
}
+ if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
+ //can also be used as storage, add to mutable sampled
+ mutable_sampled_textures.push_back(texture);
+ }
if (texture->owner.is_valid()) {
texture = texture_owner.getornull(texture->owner);
ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen
@@ -4327,11 +4515,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
image_info.push_back(img_info);
-
- if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
- //can also be used as storage, add to mutable sampled
- mutable_sampled_textures.push_back(texture);
- }
}
write.dstArrayElement = 0;
@@ -4371,6 +4554,11 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
attachable_textures.push_back(texture->owner.is_valid() ? texture->owner : uniform.ids[j]);
}
+ if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
+ //can also be used as storage, add to mutable sampled
+ mutable_sampled_textures.push_back(texture);
+ }
+
if (texture->owner.is_valid()) {
texture = texture_owner.getornull(texture->owner);
ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen
@@ -4379,11 +4567,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
image_info.push_back(img_info);
-
- if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
- //can also be used as storage, add to mutable sampled
- mutable_sampled_textures.push_back(texture);
- }
}
write.dstArrayElement = 0;
@@ -4420,6 +4603,11 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
img_info.sampler = VK_NULL_HANDLE;
img_info.imageView = texture->view;
+ if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
+ //can also be used as storage, add to mutable sampled
+ mutable_storage_textures.push_back(texture);
+ }
+
if (texture->owner.is_valid()) {
texture = texture_owner.getornull(texture->owner);
ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen
@@ -4428,11 +4616,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
image_info.push_back(img_info);
-
- if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
- //can also be used as storage, add to mutable sampled
- mutable_storage_textures.push_back(texture);
- }
}
write.dstArrayElement = 0;
@@ -4902,29 +5085,29 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
depth_stencil_state_create_info.depthBoundsTestEnable = p_depth_stencil_state.enable_depth_range;
depth_stencil_state_create_info.stencilTestEnable = p_depth_stencil_state.enable_stencil;
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.fail, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.front.failOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.fail];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.pass, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.front.passOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.pass];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.depth_fail, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.front.depthFailOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.depth_fail];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.compare, COMPARE_OP_MAX, RID());
- depth_stencil_state_create_info.front.compareOp = compare_operators[p_depth_stencil_state.stencil_operation_front.compare];
- depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.stencil_operation_front.compare_mask;
- depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.stencil_operation_front.write_mask;
- depth_stencil_state_create_info.front.reference = p_depth_stencil_state.stencil_operation_front.reference;
-
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.fail, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.back.failOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.fail];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.pass, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.back.passOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.pass];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.depth_fail, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.back.depthFailOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.depth_fail];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.compare, COMPARE_OP_MAX, RID());
- depth_stencil_state_create_info.back.compareOp = compare_operators[p_depth_stencil_state.stencil_operation_back.compare];
- depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.stencil_operation_back.compare_mask;
- depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.stencil_operation_back.write_mask;
- depth_stencil_state_create_info.back.reference = p_depth_stencil_state.stencil_operation_back.reference;
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.fail, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.front.failOp = stencil_operations[p_depth_stencil_state.front_op.fail];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.pass, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.front.passOp = stencil_operations[p_depth_stencil_state.front_op.pass];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.depth_fail, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.front.depthFailOp = stencil_operations[p_depth_stencil_state.front_op.depth_fail];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.compare, COMPARE_OP_MAX, RID());
+ depth_stencil_state_create_info.front.compareOp = compare_operators[p_depth_stencil_state.front_op.compare];
+ depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.front_op.compare_mask;
+ depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.front_op.write_mask;
+ depth_stencil_state_create_info.front.reference = p_depth_stencil_state.front_op.reference;
+
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.fail, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.back.failOp = stencil_operations[p_depth_stencil_state.back_op.fail];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.pass, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.back.passOp = stencil_operations[p_depth_stencil_state.back_op.pass];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.depth_fail, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.back.depthFailOp = stencil_operations[p_depth_stencil_state.back_op.depth_fail];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.compare, COMPARE_OP_MAX, RID());
+ depth_stencil_state_create_info.back.compareOp = compare_operators[p_depth_stencil_state.back_op.compare];
+ depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.back_op.compare_mask;
+ depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.back_op.write_mask;
+ depth_stencil_state_create_info.back.reference = p_depth_stencil_state.back_op.reference;
depth_stencil_state_create_info.minDepthBounds = p_depth_stencil_state.depth_range_min;
depth_stencil_state_create_info.maxDepthBounds = p_depth_stencil_state.depth_range_max;
@@ -5153,17 +5336,19 @@ bool RenderingDeviceVulkan::compute_pipeline_is_valid(RID p_pipeline) {
int RenderingDeviceVulkan::screen_get_width(DisplayServer::WindowID p_screen) const {
_THREAD_SAFE_METHOD_
-
+ ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen");
return context->window_get_width(p_screen);
}
int RenderingDeviceVulkan::screen_get_height(DisplayServer::WindowID p_screen) const {
_THREAD_SAFE_METHOD_
+ ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen");
return context->window_get_height(p_screen);
}
RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuffer_format() const {
_THREAD_SAFE_METHOD_
+ ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen");
//very hacky, but not used often per frame so I guess ok
VkFormat vkformat = context->get_screen_format();
@@ -5193,6 +5378,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuff
RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(DisplayServer::WindowID p_screen, const Color &p_clear_color) {
_THREAD_SAFE_METHOD_
+ ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen");
ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time.");
@@ -5857,7 +6043,7 @@ void RenderingDeviceVulkan::draw_list_set_line_width(DrawListID p_list, float p_
vkCmdSetLineWidth(dl->command_buffer, p_width);
}
-void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) {
+void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) {
DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl);
@@ -6200,9 +6386,9 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = textures_to_sampled[i]->image;
image_memory_barrier.subresourceRange.aspectMask = textures_to_sampled[i]->read_aspect_mask;
- image_memory_barrier.subresourceRange.baseMipLevel = 0;
+ image_memory_barrier.subresourceRange.baseMipLevel = textures_to_sampled[i]->base_mipmap;
image_memory_barrier.subresourceRange.levelCount = textures_to_sampled[i]->mipmaps;
- image_memory_barrier.subresourceRange.baseArrayLayer = 0;
+ image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_sampled[i]->base_layer;
image_memory_barrier.subresourceRange.layerCount = textures_to_sampled[i]->layers;
vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
@@ -6231,9 +6417,9 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = textures_to_storage[i]->image;
image_memory_barrier.subresourceRange.aspectMask = textures_to_storage[i]->read_aspect_mask;
- image_memory_barrier.subresourceRange.baseMipLevel = 0;
+ image_memory_barrier.subresourceRange.baseMipLevel = textures_to_storage[i]->base_mipmap;
image_memory_barrier.subresourceRange.levelCount = textures_to_storage[i]->mipmaps;
- image_memory_barrier.subresourceRange.baseArrayLayer = 0;
+ image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_storage[i]->base_layer;
image_memory_barrier.subresourceRange.layerCount = textures_to_storage[i]->layers;
vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
@@ -6260,7 +6446,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
#endif
}
-void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) {
+void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) {
ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST);
ERR_FAIL_COND(!compute_list);
@@ -6363,9 +6549,9 @@ void RenderingDeviceVulkan::compute_list_end() {
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = E->get()->image;
image_memory_barrier.subresourceRange.aspectMask = E->get()->read_aspect_mask;
- image_memory_barrier.subresourceRange.baseMipLevel = 0;
+ image_memory_barrier.subresourceRange.baseMipLevel = E->get()->base_mipmap;
image_memory_barrier.subresourceRange.levelCount = E->get()->mipmaps;
- image_memory_barrier.subresourceRange.baseArrayLayer = 0;
+ image_memory_barrier.subresourceRange.baseArrayLayer = E->get()->base_layer;
image_memory_barrier.subresourceRange.layerCount = E->get()->layers;
vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
@@ -6512,75 +6698,104 @@ void RenderingDeviceVulkan::free(RID p_id) {
_free_dependencies(p_id); //recursively erase dependencies first, to avoid potential API problems
_free_internal(p_id);
}
-void RenderingDeviceVulkan::swap_buffers() {
- _THREAD_SAFE_METHOD_
+void RenderingDeviceVulkan::_finalize_command_bufers() {
- { //finalize frame
+ if (draw_list) {
+ ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work).");
+ }
- if (draw_list) {
- ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work).");
- }
+ if (compute_list) {
+ ERR_PRINT("Found open compute list at the end of the frame, this should never happen (further compute will likely not work).");
+ }
- if (compute_list) {
- ERR_PRINT("Found open compute list at the end of the frame, this should never happen (further compute will likely not work).");
- }
+ { //complete the setup buffer (that needs to be processed before anything else)
+ vkEndCommandBuffer(frames[frame].setup_command_buffer);
+ vkEndCommandBuffer(frames[frame].draw_command_buffer);
+ }
+}
+
+void RenderingDeviceVulkan::_begin_frame() {
+
+ //erase pending resources
+ _free_pending_resources(frame);
+
+ //create setup command buffer and set as the setup buffer
+
+ {
+ VkCommandBufferBeginInfo cmdbuf_begin;
+ cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ cmdbuf_begin.pNext = nullptr;
+ cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ cmdbuf_begin.pInheritanceInfo = nullptr;
- { //complete the setup buffer (that needs to be processed before anything else)
- vkEndCommandBuffer(frames[frame].setup_command_buffer);
- vkEndCommandBuffer(frames[frame].draw_command_buffer);
+ VkResult err = vkResetCommandBuffer(frames[frame].setup_command_buffer, 0);
+ ERR_FAIL_COND_MSG(err, "vkResetCommandBuffer failed with error " + itos(err) + ".");
+
+ err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin);
+ ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
+ err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin);
+ ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
+
+ if (local_device.is_null()) {
+ context->append_command_buffer(frames[frame].draw_command_buffer);
+ context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else
}
- screen_prepared = false;
}
- //swap buffers
- context->swap_buffers();
+ //advance current frame
+ frames_drawn++;
+ //advance staging buffer if used
+ if (staging_buffer_used) {
+ staging_buffer_current = (staging_buffer_current + 1) % staging_buffer_blocks.size();
+ staging_buffer_used = false;
+ }
- { //advance frame
+ if (frames[frame].timestamp_count) {
+ vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
+ SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names);
+ SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values);
+ }
- frame = (frame + 1) % frame_count;
+ frames[frame].timestamp_result_count = frames[frame].timestamp_count;
+ frames[frame].timestamp_count = 0;
+ frames[frame].index = Engine::get_singleton()->get_frames_drawn();
+}
- //erase pending resources
- _free_pending_resources(frame);
+void RenderingDeviceVulkan::swap_buffers() {
- //create setup command buffer and set as the setup buffer
+ ERR_FAIL_COND_MSG(local_device.is_valid(), "Local devices can't swap buffers.");
+ _THREAD_SAFE_METHOD_
- {
- VkCommandBufferBeginInfo cmdbuf_begin;
- cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- cmdbuf_begin.pNext = nullptr;
- cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- cmdbuf_begin.pInheritanceInfo = nullptr;
+ _finalize_command_bufers();
- VkResult err = vkResetCommandBuffer(frames[frame].setup_command_buffer, 0);
- ERR_FAIL_COND_MSG(err, "vkResetCommandBuffer failed with error " + itos(err) + ".");
+ screen_prepared = false;
+ //swap buffers
+ context->swap_buffers();
- err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin);
- ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
- context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else
- err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin);
- ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
- context->append_command_buffer(frames[frame].draw_command_buffer);
- }
+ frame = (frame + 1) % frame_count;
- //advance current frame
- frames_drawn++;
- //advance staging buffer if used
- if (staging_buffer_used) {
- staging_buffer_current = (staging_buffer_current + 1) % staging_buffer_blocks.size();
- staging_buffer_used = false;
- }
+ _begin_frame();
+}
- if (frames[frame].timestamp_count) {
- vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
- SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names);
- SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values);
- }
+void RenderingDeviceVulkan::submit() {
+ ERR_FAIL_COND_MSG(local_device.is_null(), "Only local devices can submit and sync.");
+ ERR_FAIL_COND_MSG(local_device_processing, "device already submitted, call sync to wait until done.");
- frames[frame].timestamp_result_count = frames[frame].timestamp_count;
- frames[frame].timestamp_count = 0;
- frames[frame].index = Engine::get_singleton()->get_frames_drawn();
- }
+ _finalize_command_bufers();
+
+ VkCommandBuffer command_buffers[2] = { frames[frame].setup_command_buffer, frames[frame].draw_command_buffer };
+ context->local_device_push_command_buffers(local_device, command_buffers, 2);
+ local_device_processing = true;
+}
+
+void RenderingDeviceVulkan::sync() {
+
+ ERR_FAIL_COND_MSG(local_device.is_null(), "Only local devices can submit and sync.");
+ ERR_FAIL_COND_MSG(!local_device_processing, "sync can only be called after a submit");
+
+ context->local_device_sync(local_device);
+ _begin_frame();
}
void RenderingDeviceVulkan::_free_pending_resources(int p_frame) {
@@ -6699,14 +6914,21 @@ uint32_t RenderingDeviceVulkan::get_frame_delay() const {
void RenderingDeviceVulkan::_flush(bool p_current_frame) {
+ if (local_device.is_valid() && !p_current_frame) {
+ return; //flushign previous frames has no effect with local device
+ }
//not doing this crashes RADV (undefined behavior)
if (p_current_frame) {
vkEndCommandBuffer(frames[frame].setup_command_buffer);
vkEndCommandBuffer(frames[frame].draw_command_buffer);
}
- context->flush(p_current_frame, p_current_frame);
- //re-create the setup command
- if (p_current_frame) {
+
+ if (local_device.is_valid()) {
+
+ VkCommandBuffer command_buffers[2] = { frames[frame].setup_command_buffer, frames[frame].draw_command_buffer };
+ context->local_device_push_command_buffers(local_device, command_buffers, 2);
+ context->local_device_sync(local_device);
+
VkCommandBufferBeginInfo cmdbuf_begin;
cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdbuf_begin.pNext = nullptr;
@@ -6715,27 +6937,48 @@ void RenderingDeviceVulkan::_flush(bool p_current_frame) {
VkResult err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin);
ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
- context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else
- }
+ err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin);
+ ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
- if (p_current_frame) {
- VkCommandBufferBeginInfo cmdbuf_begin;
- cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- cmdbuf_begin.pNext = nullptr;
- cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- cmdbuf_begin.pInheritanceInfo = nullptr;
+ } else {
+ context->flush(p_current_frame, p_current_frame);
+ //re-create the setup command
+ if (p_current_frame) {
+ VkCommandBufferBeginInfo cmdbuf_begin;
+ cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ cmdbuf_begin.pNext = nullptr;
+ cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ cmdbuf_begin.pInheritanceInfo = nullptr;
- VkResult err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin);
- ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
- context->append_command_buffer(frames[frame].draw_command_buffer);
+ VkResult err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin);
+ ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
+ context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else
+ }
+
+ if (p_current_frame) {
+ VkCommandBufferBeginInfo cmdbuf_begin;
+ cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ cmdbuf_begin.pNext = nullptr;
+ cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ cmdbuf_begin.pInheritanceInfo = nullptr;
+
+ VkResult err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin);
+ ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
+ context->append_command_buffer(frames[frame].draw_command_buffer);
+ }
}
}
-void RenderingDeviceVulkan::initialize(VulkanContext *p_context) {
+void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_device) {
context = p_context;
device = p_context->get_device();
- frame_count = p_context->get_swapchain_image_count() + 1; //always need one extra to ensure it's unused at any time, without having to use a fence for this.
+ if (p_local_device) {
+ frame_count = 1;
+ local_device = p_context->local_device_create();
+ } else {
+ frame_count = p_context->get_swapchain_image_count() + 1; //always need one extra to ensure it's unused at any time, without having to use a fence for this.
+ }
limits = p_context->get_device_limits();
max_timestamp_query_elements = 256;
@@ -6816,11 +7059,13 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context) {
VkResult err = vkBeginCommandBuffer(frames[0].setup_command_buffer, &cmdbuf_begin);
ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
- context->set_setup_buffer(frames[0].setup_command_buffer); //append now so it's added before everything else
err = vkBeginCommandBuffer(frames[0].draw_command_buffer, &cmdbuf_begin);
ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
- context->append_command_buffer(frames[0].draw_command_buffer);
+ if (local_device.is_null()) {
+ context->set_setup_buffer(frames[0].setup_command_buffer); //append now so it's added before everything else
+ context->append_command_buffer(frames[0].draw_command_buffer);
+ }
}
staging_buffer_block_size = GLOBAL_DEF("rendering/vulkan/staging_buffer/block_size_kb", 256);
@@ -6929,9 +7174,42 @@ uint64_t RenderingDeviceVulkan::get_captured_timestamps_frame() const {
return frames[frame].index;
}
+static void mult64to128(uint64_t u, uint64_t v, uint64_t &h, uint64_t &l) {
+ uint64_t u1 = (u & 0xffffffff);
+ uint64_t v1 = (v & 0xffffffff);
+ uint64_t t = (u1 * v1);
+ uint64_t w3 = (t & 0xffffffff);
+ uint64_t k = (t >> 32);
+
+ u >>= 32;
+ t = (u * v1) + k;
+ k = (t & 0xffffffff);
+ uint64_t w1 = (t >> 32);
+
+ v >>= 32;
+ t = (u1 * v) + k;
+ k = (t >> 32);
+
+ h = (u * v) + w1 + k;
+ l = (t << 32) + w3;
+}
+
uint64_t RenderingDeviceVulkan::get_captured_timestamp_gpu_time(uint32_t p_index) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, 0);
- return frames[frame].timestamp_result_values[p_index] * limits.timestampPeriod;
+
+ // this sucks because timestampPeriod multiplier is a float, while the timestamp is 64 bits nanosecs.
+ // so, in cases like nvidia which give you enormous numbers and 1 as multiplier, multiplying is next to impossible
+ // need to do 128 bits fixed point multiplication to get the rigth value
+
+ uint64_t shift_bits = 16;
+
+ uint64_t h, l;
+
+ mult64to128(frames[frame].timestamp_result_values[p_index], uint64_t(double(limits.timestampPeriod) * double(1 << shift_bits)), h, l);
+ l >>= shift_bits;
+ l |= h << (64 - shift_bits);
+
+ return l;
}
uint64_t RenderingDeviceVulkan::get_captured_timestamp_cpu_time(uint32_t p_index) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, 0);
@@ -7058,12 +7336,30 @@ void RenderingDeviceVulkan::finalize() {
vertex_formats.erase(temp);
}
+ for (int i = 0; i < framebuffer_formats.size(); i++) {
+ vkDestroyRenderPass(device, framebuffer_formats[i].render_pass, nullptr);
+ }
+ framebuffer_formats.clear();
+
//all these should be clear at this point
ERR_FAIL_COND(descriptor_pools.size());
ERR_FAIL_COND(dependency_map.size());
ERR_FAIL_COND(reverse_dependency_map.size());
}
+RenderingDevice *RenderingDeviceVulkan::create_local_device() {
+ RenderingDeviceVulkan *rd = memnew(RenderingDeviceVulkan);
+ rd->initialize(context, true);
+ return rd;
+}
+
RenderingDeviceVulkan::RenderingDeviceVulkan() {
screen_prepared = false;
}
+
+RenderingDeviceVulkan::~RenderingDeviceVulkan() {
+ if (local_device.is_valid()) {
+ finalize();
+ context->local_device_free(local_device);
+ }
+}
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index a46b80e2f4..6432946fbe 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -37,8 +37,10 @@
#include "servers/rendering/rendering_device.h"
#ifdef DEBUG_ENABLED
+#ifndef _DEBUG
#define _DEBUG
#endif
+#endif
#include "vk_mem_alloc.h"
#include <vulkan/vulkan.h>
//todo:
@@ -136,6 +138,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t layers;
uint32_t mipmaps;
uint32_t usage_flags;
+ uint32_t base_mipmap;
+ uint32_t base_layer;
Vector<DataFormat> allowed_shared_formats;
@@ -328,7 +332,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
RID_Owner<Buffer, true> vertex_buffer_owner;
struct VertexDescriptionKey {
- Vector<VertexDescription> vertex_formats;
+ Vector<VertexAttribute> vertex_formats;
bool operator==(const VertexDescriptionKey &p_key) const {
int vdc = vertex_formats.size();
int vdck = p_key.vertex_formats.size();
@@ -336,11 +340,11 @@ class RenderingDeviceVulkan : public RenderingDevice {
if (vdc != vdck) {
return false;
} else {
- const VertexDescription *a_ptr = vertex_formats.ptr();
- const VertexDescription *b_ptr = p_key.vertex_formats.ptr();
+ const VertexAttribute *a_ptr = vertex_formats.ptr();
+ const VertexAttribute *b_ptr = p_key.vertex_formats.ptr();
for (int i = 0; i < vdc; i++) {
- const VertexDescription &a = a_ptr[i];
- const VertexDescription &b = b_ptr[i];
+ const VertexAttribute &a = a_ptr[i];
+ const VertexAttribute &b = b_ptr[i];
if (a.location != b.location) {
return false;
@@ -365,9 +369,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t hash() const {
int vdc = vertex_formats.size();
uint32_t h = hash_djb2_one_32(vdc);
- const VertexDescription *ptr = vertex_formats.ptr();
+ const VertexAttribute *ptr = vertex_formats.ptr();
for (int i = 0; i < vdc; i++) {
- const VertexDescription &vd = ptr[i];
+ const VertexAttribute &vd = ptr[i];
h = hash_djb2_one_32(vd.location, h);
h = hash_djb2_one_32(vd.offset, h);
h = hash_djb2_one_32(vd.format, h);
@@ -389,7 +393,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
HashMap<VertexDescriptionKey, VertexFormatID, VertexDescriptionHash> vertex_format_cache;
struct VertexDescriptionCache {
- Vector<VertexDescription> vertex_formats;
+ Vector<VertexAttribute> vertex_formats;
VkVertexInputBindingDescription *bindings;
VkVertexInputAttributeDescription *attributes;
VkPipelineVertexInputStateCreateInfo create_info;
@@ -948,10 +952,12 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t max_timestamp_query_elements;
- Frame *frames; //frames available, they are cycled (usually 3)
+ Frame *frames; //frames available, for main device they are cycled (usually 3), for local devices only 1
int frame; //current frame
int frame_count; //total amount of frames
uint64_t frames_drawn;
+ RID local_device;
+ bool local_device_processing = false;
void _free_pending_resources(int p_frame);
@@ -967,6 +973,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
template <class T>
void _free_rids(T &p_owner, const char *p_type);
+ void _finalize_command_bufers();
+ void _begin_frame();
+
public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>());
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture);
@@ -981,6 +990,7 @@ public:
virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false);
virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false);
+ virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw = false);
/*********************/
/**** FRAMEBUFFER ****/
@@ -1006,7 +1016,7 @@ public:
virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>());
// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
- virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats);
+ virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats);
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers);
virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_restart_indices = false);
@@ -1070,7 +1080,7 @@ public:
virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array);
virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array);
virtual void draw_list_set_line_width(DrawListID p_list, float p_width);
- virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size);
+ virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size);
virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0);
@@ -1086,7 +1096,7 @@ public:
virtual ComputeListID compute_list_begin();
virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline);
virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index);
- virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size);
+ virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size);
virtual void compute_list_add_barrier(ComputeListID p_list);
virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups);
@@ -1116,14 +1126,20 @@ public:
virtual int limit_get(Limit p_limit);
virtual void prepare_screen_for_drawing();
- void initialize(VulkanContext *p_context);
+ void initialize(VulkanContext *p_context, bool p_local_device = false);
void finalize();
- virtual void swap_buffers();
+ virtual void swap_buffers(); //for main device
+
+ virtual void submit(); //for local device
+ virtual void sync(); //for local device
virtual uint32_t get_frame_delay() const;
+ virtual RenderingDevice *create_local_device();
+
RenderingDeviceVulkan();
+ ~RenderingDeviceVulkan();
};
#endif // RENDERING_DEVICE_VULKAN_H
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 68b4cdf4a4..083b822676 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -1499,8 +1499,100 @@ VulkanContext::VulkanContext() {
swapchainImageCount = 0;
}
+RID VulkanContext::local_device_create() {
+ LocalDevice ld;
+
+ { //create device
+ VkResult err;
+ float queue_priorities[1] = { 0.0 };
+ VkDeviceQueueCreateInfo queues[2];
+ queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ queues[0].pNext = nullptr;
+ queues[0].queueFamilyIndex = graphics_queue_family_index;
+ queues[0].queueCount = 1;
+ queues[0].pQueuePriorities = queue_priorities;
+ queues[0].flags = 0;
+
+ VkDeviceCreateInfo sdevice = {
+ /*sType =*/VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+ /*pNext */ nullptr,
+ /*flags */ 0,
+ /*queueCreateInfoCount */ 1,
+ /*pQueueCreateInfos */ queues,
+ /*enabledLayerCount */ 0,
+ /*ppEnabledLayerNames */ nullptr,
+ /*enabledExtensionCount */ enabled_extension_count,
+ /*ppEnabledExtensionNames */ (const char *const *)extension_names,
+ /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here
+ };
+ err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device);
+ ERR_FAIL_COND_V(err, RID());
+ }
+
+ { //create graphics queue
+
+ vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue);
+ }
+
+ return local_device_owner.make_rid(ld);
+}
+
+VkDevice VulkanContext::local_device_get_vk_device(RID p_local_device) {
+ LocalDevice *ld = local_device_owner.getornull(p_local_device);
+ return ld->device;
+}
+
+void VulkanContext::local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count) {
+
+ LocalDevice *ld = local_device_owner.getornull(p_local_device);
+ ERR_FAIL_COND(ld->waiting);
+
+ VkSubmitInfo submit_info;
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.pNext = nullptr;
+ submit_info.pWaitDstStageMask = nullptr;
+ submit_info.waitSemaphoreCount = 0;
+ submit_info.pWaitSemaphores = nullptr;
+ submit_info.commandBufferCount = p_count;
+ submit_info.pCommandBuffers = p_buffers;
+ submit_info.signalSemaphoreCount = 0;
+ submit_info.pSignalSemaphores = nullptr;
+
+ VkResult err = vkQueueSubmit(ld->queue, 1, &submit_info, VK_NULL_HANDLE);
+ ERR_FAIL_COND(err);
+
+ ld->waiting = true;
+}
+
+void VulkanContext::local_device_sync(RID p_local_device) {
+
+ LocalDevice *ld = local_device_owner.getornull(p_local_device);
+ ERR_FAIL_COND(!ld->waiting);
+
+ vkDeviceWaitIdle(ld->device);
+ ld->waiting = false;
+}
+
+void VulkanContext::local_device_free(RID p_local_device) {
+
+ LocalDevice *ld = local_device_owner.getornull(p_local_device);
+ vkDestroyDevice(ld->device, nullptr);
+ local_device_owner.free(p_local_device);
+}
+
VulkanContext::~VulkanContext() {
if (queue_props) {
free(queue_props);
}
+ for (uint32_t i = 0; i < FRAME_LAG; i++) {
+ vkDestroyFence(device, fences[i], nullptr);
+ vkDestroySemaphore(device, image_acquired_semaphores[i], nullptr);
+ vkDestroySemaphore(device, draw_complete_semaphores[i], nullptr);
+ if (separate_present_queue) {
+ vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr);
+ }
+ }
+ DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr);
+ vkDestroyDevice(device, nullptr);
+ vkDestroyInstance(inst, nullptr);
}
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 2f10fbfdef..51c3febb47 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -33,6 +33,8 @@
#include "core/error_list.h"
#include "core/map.h"
+#include "core/os/mutex.h"
+#include "core/rid_owner.h"
#include "core/ustring.h"
#include "servers/display_server.h"
#include <vulkan/vulkan.h>
@@ -45,8 +47,6 @@ class VulkanContext {
FRAME_LAG = 2
};
- bool use_validation_layers;
-
VkInstance inst;
VkSurfaceKHR surface;
VkPhysicalDevice gpu;
@@ -107,6 +107,14 @@ class VulkanContext {
}
};
+ struct LocalDevice {
+ bool waiting = false;
+ VkDevice device;
+ VkQueue queue;
+ };
+
+ RID_Owner<LocalDevice, true> local_device_owner;
+
Map<DisplayServer::WindowID, Window> windows;
uint32_t swapchainImageCount;
@@ -181,6 +189,8 @@ protected:
bool buffers_prepared;
+ bool use_validation_layers;
+
public:
VkDevice get_device();
VkPhysicalDevice get_physical_device();
@@ -194,6 +204,12 @@ public:
VkFramebuffer window_get_framebuffer(DisplayServer::WindowID p_window = 0);
VkRenderPass window_get_render_pass(DisplayServer::WindowID p_window = 0);
+ RID local_device_create();
+ VkDevice local_device_get_vk_device(RID p_local_device);
+ void local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count);
+ void local_device_sync(RID p_local_device);
+ void local_device_free(RID p_local_device);
+
VkFormat get_screen_format() const;
VkPhysicalDeviceLimits get_device_limits() const;
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index b393ff5fd4..f10e439f10 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -1402,7 +1402,7 @@ void AnimationTimelineEdit::_zoom_changed(double) {
float AnimationTimelineEdit::get_zoom_scale() const {
- float zv = zoom->get_value();
+ float zv = zoom->get_max() - zoom->get_value();
if (zv < 1) {
zv = 1.0 - zv;
return Math::pow(1.0f + zv, 8.0f) * 100;
diff --git a/editor/doc_data.cpp b/editor/doc_data.cpp
index 096be1fe4b..310e78ee60 100644
--- a/editor/doc_data.cpp
+++ b/editor/doc_data.cpp
@@ -40,6 +40,9 @@
#include "core/version.h"
#include "scene/resources/theme.h"
+// Used for a hack preserving Mono properties on non-Mono builds.
+#include "modules/modules_enabled.gen.h"
+
void DocData::merge_from(const DocData &p_data) {
for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) {
@@ -154,6 +157,23 @@ void DocData::merge_from(const DocData &p_data) {
break;
}
}
+
+#ifndef MODULE_MONO_ENABLED
+ // The Mono module defines some properties that we want to keep when
+ // re-generating docs with a non-Mono build, to prevent pointless diffs
+ // (and loss of descriptions) depending on the config of the doc writer.
+ // We use a horrible hack to force keeping the relevant properties,
+ // hardcoded below. At least it's an ad hoc hack... ¯\_(ツ)_/¯
+ // Don't show this to your kids.
+ if (c.name == "@GlobalScope") {
+ // Retrieve GodotSharp singleton.
+ for (int j = 0; j < cf.properties.size(); j++) {
+ if (cf.properties[j].name == "GodotSharp") {
+ c.properties.push_back(cf.properties[j]);
+ }
+ }
+ }
+#endif
}
}
@@ -173,6 +193,8 @@ static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const Property
p_method.return_type = "int";
} else if (p_retinfo.class_name != StringName()) {
p_method.return_type = p_retinfo.class_name;
+ } else if (p_retinfo.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
+ p_method.return_type = p_retinfo.hint_string + "[]";
} else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
p_method.return_type = p_retinfo.hint_string;
} else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
@@ -195,6 +217,8 @@ static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const Pr
p_argument.type = "int";
} else if (p_arginfo.class_name != StringName()) {
p_argument.type = p_arginfo.class_name;
+ } else if (p_arginfo.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
+ p_argument.type = p_arginfo.hint_string + "[]";
} else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
p_argument.type = p_arginfo.hint_string;
} else if (p_arginfo.type == Variant::NIL) {
@@ -243,6 +267,12 @@ void DocData::generate(bool p_basic_types) {
Set<StringName> setters_getters;
String name = classes.front()->get();
+ if (!ClassDB::is_class_exposed(name)) {
+ print_verbose(vformat("Class '%s' is not exposed, skipping.", name));
+ classes.pop_front();
+ continue;
+ }
+
String cname = name;
if (cname.begins_with("_")) //proxy class
cname = cname.substr(1, name.length());
@@ -271,7 +301,7 @@ void DocData::generate(bool p_basic_types) {
EO = EO->next();
}
- if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL)
+ if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL)
continue;
PropertyDoc prop;
@@ -328,6 +358,8 @@ void DocData::generate(bool p_basic_types) {
prop.type = "int";
} else if (retinfo.class_name != StringName()) {
prop.type = retinfo.class_name;
+ } else if (retinfo.type == Variant::ARRAY && retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
+ prop.type = retinfo.hint_string + "[]";
} else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
prop.type = retinfo.hint_string;
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 942b4a8ee6..9c739474d1 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -1066,9 +1066,9 @@ Array EditorSelection::_get_transformable_selected_nodes() {
return ret;
}
-Array EditorSelection::get_selected_nodes() {
+TypedArray<Node> EditorSelection::get_selected_nodes() {
- Array ret;
+ TypedArray<Node> ret;
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
diff --git a/editor/editor_data.h b/editor/editor_data.h
index 4f5d68bfed..e4f4c67c8e 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -257,7 +257,7 @@ protected:
static void _bind_methods();
public:
- Array get_selected_nodes();
+ TypedArray<Node> get_selected_nodes();
void add_node(Node *p_node);
void remove_node(Node *p_node);
bool is_selected(Node *) const;
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index a36e2f360e..bad70d9714 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -198,7 +198,12 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
const Color text_color = get_theme_color("default_color", "RichTextLabel");
const Color type_color = get_theme_color("accent_color", "Editor").linear_interpolate(text_color, 0.5);
class_desc->push_color(type_color);
+ bool add_array = false;
if (can_ref) {
+ if (t.ends_with("[]")) {
+ add_array = true;
+ t = t.replace("[]", "");
+ }
if (p_enum.empty()) {
class_desc->push_meta("#" + t); //class
} else {
@@ -206,8 +211,15 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
}
}
class_desc->add_text(t);
- if (can_ref)
+ if (can_ref) {
class_desc->pop();
+ if (add_array) {
+ class_desc->add_text(" ");
+ class_desc->push_meta("#Array"); //class
+ class_desc->add_text("[]");
+ class_desc->pop();
+ }
+ }
class_desc->pop();
}
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index c92d1d009d..8fcd5bacb6 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -66,6 +66,11 @@ Size2 EditorProperty::get_minimum_size() const {
ms.width += key->get_width() + get_theme_constant("hseparator", "Tree");
}
+ if (deletable) {
+ Ref<Texture2D> key = get_theme_icon("Close", "EditorIcons");
+ ms.width += key->get_width() + get_theme_constant("hseparator", "Tree");
+ }
+
if (checkable) {
Ref<Texture2D> check = get_theme_icon("checked", "CheckBox");
ms.width += check->get_width() + get_theme_constant("hseparation", "CheckBox") + get_theme_constant("hseparator", "Tree");
@@ -154,6 +159,18 @@ void EditorProperty::_notification(int p_what) {
text_size -= key->get_width() + 4 * EDSCALE;
}
}
+
+ if (deletable) {
+ Ref<Texture2D> close;
+
+ close = get_theme_icon("Close", "EditorIcons");
+
+ rect.size.x -= close->get_width() + get_theme_constant("hseparator", "Tree");
+
+ if (no_children) {
+ text_size -= close->get_width() + 4 * EDSCALE;
+ }
+ }
}
//set children
@@ -278,6 +295,25 @@ void EditorProperty::_notification(int p_what) {
} else {
keying_rect = Rect2();
}
+
+ if (deletable) {
+ Ref<Texture2D> close;
+
+ close = get_theme_icon("Close", "EditorIcons");
+
+ ofs = size.width - close->get_width() - get_theme_constant("hseparator", "Tree");
+
+ Color color2(1, 1, 1);
+ if (delete_hover) {
+ color2.r *= 1.2;
+ color2.g *= 1.2;
+ color2.b *= 1.2;
+ }
+ delete_rect = Rect2(ofs, ((size.height - close->get_height()) / 2), close->get_width(), close->get_height());
+ draw_texture(close, delete_rect.position, color2);
+ } else {
+ delete_rect = Rect2();
+ }
}
}
@@ -547,6 +583,16 @@ void EditorProperty::set_keying(bool p_keying) {
queue_sort();
}
+void EditorProperty::set_deletable(bool p_deletable) {
+ deletable = p_deletable;
+ update();
+ queue_sort();
+}
+
+bool EditorProperty::is_deletable() const {
+ return deletable;
+}
+
bool EditorProperty::is_keying() const {
return keying;
}
@@ -619,6 +665,12 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
update();
}
+ bool new_delete_hover = delete_rect.has_point(me->get_position()) && !button_left;
+ if (new_delete_hover != delete_hover) {
+ delete_hover = new_delete_hover;
+ update();
+ }
+
bool new_revert_hover = revert_rect.has_point(me->get_position()) && !button_left;
if (new_revert_hover != revert_hover) {
revert_hover = new_revert_hover;
@@ -662,6 +714,9 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
call_deferred("update_property");
}
}
+ if (delete_rect.has_point(mb->get_position())) {
+ emit_signal("property_deleted", property);
+ }
if (revert_rect.has_point(mb->get_position())) {
@@ -821,6 +876,9 @@ void EditorProperty::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_keying", "keying"), &EditorProperty::set_keying);
ClassDB::bind_method(D_METHOD("is_keying"), &EditorProperty::is_keying);
+ ClassDB::bind_method(D_METHOD("set_deletable", "deletable"), &EditorProperty::set_deletable);
+ ClassDB::bind_method(D_METHOD("is_deletable"), &EditorProperty::is_deletable);
+
ClassDB::bind_method(D_METHOD("get_edited_property"), &EditorProperty::get_edited_property);
ClassDB::bind_method(D_METHOD("get_edited_object"), &EditorProperty::get_edited_object);
@@ -839,9 +897,11 @@ void EditorProperty::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "checked"), "set_checked", "is_checked");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_red"), "set_draw_red", "is_draw_red");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keying"), "set_keying", "is_keying");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deletable"), "set_deletable", "is_deletable");
ADD_SIGNAL(MethodInfo("property_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("multiple_properties_changed", PropertyInfo(Variant::PACKED_STRING_ARRAY, "properties"), PropertyInfo(Variant::ARRAY, "value")));
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING_NAME, "property")));
+ ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING_NAME, "property")));
ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::STRING, "bool")));
ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
@@ -865,6 +925,7 @@ EditorProperty::EditorProperty() {
checked = false;
draw_red = false;
keying = false;
+ deletable = false;
keying_hover = false;
revert_hover = false;
check_hover = false;
@@ -926,7 +987,7 @@ void EditorInspectorPlugin::parse_category(Object *p_object, const String &p_par
}
}
-bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) {
+bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
if (get_script_instance()) {
Variant arg[6] = {
@@ -1276,11 +1337,11 @@ EditorInspectorSection::~EditorInspectorSection() {
Ref<EditorInspectorPlugin> EditorInspector::inspector_plugins[MAX_PLUGINS];
int EditorInspector::inspector_plugin_count = 0;
-EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) {
+EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
for (int i = inspector_plugin_count - 1; i >= 0; i--) {
- inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage);
+ inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide);
if (inspector_plugins[i]->added_editors.size()) {
for (int j = 1; j < inspector_plugins[i]->added_editors.size(); j++) { //only keep first one
memdelete(inspector_plugins[i]->added_editors[j].property_editor);
@@ -1362,6 +1423,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->object = object;
ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed));
ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed));
+ ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED);
ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value));
ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked));
ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected));
@@ -1394,6 +1456,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->set_read_only(read_only);
ep->update_property();
ep->update_reload_status();
+ ep->set_deletable(deletable_properties);
}
}
ped->added_editors.clear();
@@ -1478,6 +1541,8 @@ void EditorInspector::update_tree() {
String filter = search_box ? search_box->get_text() : "";
String group;
String group_base;
+ String subgroup;
+ String subgroup_base;
VBoxContainer *category_vbox = nullptr;
List<PropertyInfo>
@@ -1503,10 +1568,19 @@ void EditorInspector::update_tree() {
//make sure the property can be edited
- if (p.usage & PROPERTY_USAGE_GROUP) {
+ if (p.usage & PROPERTY_USAGE_SUBGROUP) {
+
+ subgroup = p.name;
+ subgroup_base = p.hint_string;
+
+ continue;
+
+ } else if (p.usage & PROPERTY_USAGE_GROUP) {
group = p.name;
group_base = p.hint_string;
+ subgroup = "";
+ subgroup_base = "";
continue;
@@ -1514,6 +1588,8 @@ void EditorInspector::update_tree() {
group = "";
group_base = "";
+ subgroup = "";
+ subgroup_base = "";
if (!show_categories)
continue;
@@ -1577,18 +1653,33 @@ void EditorInspector::update_tree() {
}
String basename = p.name;
+
+ if (subgroup != "") {
+ if (subgroup_base != "") {
+ if (basename.begins_with(subgroup_base)) {
+ basename = basename.replace_first(subgroup_base, "");
+ } else if (subgroup_base.begins_with(basename)) {
+ //keep it, this is used pretty often
+ } else {
+ subgroup = ""; //no longer using subgroup base, clear
+ }
+ }
+ }
if (group != "") {
- if (group_base != "") {
+ if (group_base != "" && subgroup == "") {
if (basename.begins_with(group_base)) {
basename = basename.replace_first(group_base, "");
} else if (group_base.begins_with(basename)) {
//keep it, this is used pretty often
} else {
group = ""; //no longer using group base, clear
+ subgroup = "";
}
}
}
-
+ if (subgroup != "") {
+ basename = subgroup + "/" + basename;
+ }
if (group != "") {
basename = group + "/" + basename;
}
@@ -1734,7 +1825,7 @@ void EditorInspector::update_tree() {
for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) {
Ref<EditorInspectorPlugin> ped = E->get();
- bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage);
+ bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage, wide_editors);
List<EditorInspectorPlugin::AddedEditor> editors = ped->added_editors; //make a copy, since plugins may be used again in a sub-inspector
ped->added_editors.clear();
@@ -1778,6 +1869,7 @@ void EditorInspector::update_tree() {
ep->set_keying(keying);
ep->set_read_only(read_only);
+ ep->set_deletable(deletable_properties);
}
current_vbox->add_child(F->get().property_editor);
@@ -1789,6 +1881,7 @@ void EditorInspector::update_tree() {
ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed_update_all), varray(), CONNECT_DEFERRED);
}
ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed));
+ ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED);
ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value));
ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked));
ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected));
@@ -1972,6 +2065,10 @@ int EditorInspector::get_scroll_offset() const {
return get_v_scroll();
}
+void EditorInspector::set_use_wide_editors(bool p_enable) {
+ wide_editors = p_enable;
+}
+
void EditorInspector::set_sub_inspector(bool p_enable) {
sub_inspector = p_enable;
@@ -1985,6 +2082,10 @@ void EditorInspector::set_sub_inspector(bool p_enable) {
}
}
+void EditorInspector::set_use_deletable_properties(bool p_enabled) {
+ deletable_properties = p_enabled;
+}
+
void EditorInspector::_edit_request_change(Object *p_object, const String &p_property) {
if (object != p_object) //may be undoing/redoing for a non edited object, so ignore
@@ -2117,6 +2218,15 @@ void EditorInspector::_property_keyed(const String &p_path, bool p_advance) {
emit_signal("property_keyed", p_path, object->get(p_path), p_advance); //second param is deprecated
}
+void EditorInspector::_property_deleted(const String &p_path) {
+
+ print_line("deleted pressed?");
+ if (!object)
+ return;
+
+ emit_signal("property_deleted", p_path); //second param is deprecated
+}
+
void EditorInspector::_property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance) {
if (!object)
@@ -2320,6 +2430,7 @@ void EditorInspector::_bind_methods() {
ADD_SIGNAL(MethodInfo("property_selected", PropertyInfo(Variant::STRING, "property")));
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property")));
+ ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING, "property")));
ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "res"), PropertyInfo(Variant::STRING, "prop")));
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property")));
@@ -2337,6 +2448,7 @@ EditorInspector::EditorInspector() {
set_enable_h_scroll(false);
set_enable_v_scroll(true);
+ wide_editors = false;
show_categories = false;
hide_script = true;
use_doc_hints = false;
@@ -2355,6 +2467,7 @@ EditorInspector::EditorInspector() {
set_process(true);
property_focusable = -1;
sub_inspector = false;
+ deletable_properties = false;
get_v_scrollbar()->connect("value_changed", callable_mp(this, &EditorInspector::_vscroll_changed));
update_scroll_request = -1;
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index b49a4424f6..c8c1ecc49a 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -64,6 +64,7 @@ private:
bool checked;
bool draw_red;
bool keying;
+ bool deletable;
Rect2 right_child_rect;
Rect2 bottom_child_rect;
@@ -74,6 +75,8 @@ private:
bool revert_hover;
Rect2 check_rect;
bool check_hover;
+ Rect2 delete_rect;
+ bool delete_hover;
bool can_revert;
@@ -133,6 +136,8 @@ public:
void set_keying(bool p_keying);
bool is_keying() const;
+ void set_deletable(bool p_enable);
+ bool is_deletable() const;
void add_focusable(Control *p_control);
void select(int p_focusable = -1);
void deselect();
@@ -190,7 +195,7 @@ public:
virtual bool can_handle(Object *p_object);
virtual void parse_begin(Object *p_object);
virtual void parse_category(Object *p_object, const String &p_parse_category);
- virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage);
+ virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false);
virtual void parse_end();
};
@@ -283,6 +288,8 @@ class EditorInspector : public ScrollContainer {
bool read_only;
bool keying;
bool sub_inspector;
+ bool wide_editors;
+ bool deletable_properties;
float refresh_countdown;
bool update_tree_pending;
@@ -307,6 +314,7 @@ class EditorInspector : public ScrollContainer {
void _multiple_properties_changed(Vector<String> p_paths, Array p_values);
void _property_keyed(const String &p_path, bool p_advance);
void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance);
+ void _property_deleted(const String &p_path);
void _property_checked(const String &p_path, bool p_checked);
@@ -337,7 +345,7 @@ public:
static void remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin);
static void cleanup_plugins();
- static EditorProperty *instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage);
+ static EditorProperty *instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false);
void set_undo_redo(UndoRedo *p_undo_redo);
@@ -380,8 +388,11 @@ public:
void set_object_class(const String &p_class);
String get_object_class() const;
+ void set_use_wide_editors(bool p_enable);
void set_sub_inspector(bool p_enable);
+ void set_use_deletable_properties(bool p_enabled);
+
EditorInspector();
};
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index e7c1eaf777..3569cd411d 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -64,6 +64,7 @@
#include "servers/navigation_server_2d.h"
#include "servers/navigation_server_3d.h"
#include "servers/physics_server_2d.h"
+#include "servers/rendering/rendering_device.h"
#include "editor/audio_stream_preview.h"
#include "editor/debugger/editor_debugger_node.h"
@@ -97,6 +98,7 @@
#include "editor/import/resource_importer_layered_texture.h"
#include "editor/import/resource_importer_obj.h"
#include "editor/import/resource_importer_scene.h"
+#include "editor/import/resource_importer_shader_file.h"
#include "editor/import/resource_importer_texture.h"
#include "editor/import/resource_importer_texture_atlas.h"
#include "editor/import/resource_importer_wav.h"
@@ -147,6 +149,7 @@
#include "editor/plugins/script_editor_plugin.h"
#include "editor/plugins/script_text_editor.h"
#include "editor/plugins/shader_editor_plugin.h"
+#include "editor/plugins/shader_file_editor_plugin.h"
#include "editor/plugins/skeleton_2d_editor_plugin.h"
#include "editor/plugins/skeleton_3d_editor_plugin.h"
#include "editor/plugins/skeleton_ik_3d_editor_plugin.h"
@@ -358,13 +361,13 @@ void EditorNode::_notification(int p_what) {
scene_root->set_default_canvas_item_texture_repeat(tr);
}
- RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_shape")));
+ RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape")));
RS::get_singleton()->camera_effects_set_dof_blur_bokeh_shape(dof_shape);
- RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_quality")));
- bool dof_jitter = GLOBAL_GET("rendering/quality/filters/depth_of_field_use_jitter");
+ RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality")));
+ bool dof_jitter = GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter");
RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter);
RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"));
- RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter"), GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter_curve"));
+ RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_curve"));
bool glow_bicubic = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0;
RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic);
RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality")));
@@ -374,6 +377,10 @@ void EditorNode::_notification(int p_what) {
float sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale");
float sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale");
RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale);
+ RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality")));
+ RS::get_singleton()->shadows_quality_set(shadows_quality);
+ RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality")));
+ RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality);
}
ResourceImporterTexture::get_singleton()->update_imports();
@@ -704,6 +711,11 @@ void EditorNode::_sources_changed(bool p_exist) {
if (waiting_for_first_scan) {
waiting_for_first_scan = false;
+ // Reload the global shader variables, but this time
+ // loading texures, as they are now properly imported.
+ print_line("done scanning, reload textures");
+ RenderingServer::get_singleton()->global_variables_load_settings(true);
+
// Start preview thread now that it's safe.
if (!singleton->cmdline_export_mode) {
EditorResourcePreview::get_singleton()->start();
@@ -5706,6 +5718,10 @@ EditorNode::EditorNode() {
import_obj.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_obj);
+ Ref<ResourceImporterShaderFile> import_shader_file;
+ import_shader_file.instance();
+ ResourceFormatImporter::get_singleton()->add_importer(import_shader_file);
+
Ref<ResourceImporterScene> import_scene;
import_scene.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_scene);
@@ -6623,6 +6639,7 @@ EditorNode::EditorNode() {
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
add_editor_plugin(memnew(ShaderEditorPlugin(this)));
+ add_editor_plugin(memnew(ShaderFileEditorPlugin(this)));
add_editor_plugin(memnew(VisualShaderEditorPlugin(this)));
add_editor_plugin(memnew(Camera3DEditorPlugin(this)));
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index cf478f20e5..5213d7ec15 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -1150,12 +1150,15 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo
}
}
-EditorPropertyVector2::EditorPropertyVector2() {
+EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) {
bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing");
BoxContainer *bc;
- if (horizontal) {
+ if (p_force_wide) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ } else if (horizontal) {
bc = memnew(HBoxContainer);
add_child(bc);
set_bottom_editor(bc);
@@ -1231,13 +1234,16 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool
}
}
-EditorPropertyRect2::EditorPropertyRect2() {
+EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) {
- bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing");
+ bool horizontal = !p_force_wide && bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing"));
BoxContainer *bc;
- if (horizontal) {
+ if (p_force_wide) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ } else if (horizontal) {
bc = memnew(HBoxContainer);
add_child(bc);
set_bottom_editor(bc);
@@ -1311,12 +1317,15 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo
}
}
-EditorPropertyVector3::EditorPropertyVector3() {
+EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) {
bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing");
BoxContainer *bc;
- if (horizontal) {
+ if (p_force_wide) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ } else if (horizontal) {
bc = memnew(HBoxContainer);
add_child(bc);
set_bottom_editor(bc);
@@ -1343,6 +1352,255 @@ EditorPropertyVector3::EditorPropertyVector3() {
}
setting = false;
}
+
+///////////////////// VECTOR2i /////////////////////////
+
+void EditorPropertyVector2i::_value_changed(double val, const String &p_name) {
+ if (setting)
+ return;
+
+ Vector2i v2;
+ v2.x = spin[0]->get_value();
+ v2.y = spin[1]->get_value();
+ emit_changed(get_edited_property(), v2, p_name);
+}
+
+void EditorPropertyVector2i::update_property() {
+ Vector2i val = get_edited_object()->get(get_edited_property());
+ setting = true;
+ spin[0]->set_value(val.x);
+ spin[1]->set_value(val.y);
+ setting = false;
+}
+
+void EditorPropertyVector2i::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_theme_color("accent_color", "Editor");
+ for (int i = 0; i < 2; i++) {
+
+ Color c = base;
+ c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
+
+void EditorPropertyVector2i::_bind_methods() {
+}
+
+void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider) {
+ for (int i = 0; i < 2; i++) {
+ spin[i]->set_min(p_min);
+ spin[i]->set_max(p_max);
+ spin[i]->set_step(1);
+ spin[i]->set_hide_slider(p_no_slider);
+ spin[i]->set_allow_greater(true);
+ spin[i]->set_allow_lesser(true);
+ }
+}
+
+EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) {
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing");
+
+ BoxContainer *bc;
+
+ if (p_force_wide) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ } else if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
+ static const char *desc[2] = { "x", "y" };
+ for (int i = 0; i < 2; i++) {
+ spin[i] = memnew(EditorSpinSlider);
+ spin[i]->set_flat(true);
+ spin[i]->set_label(desc[i]);
+ bc->add_child(spin[i]);
+ add_focusable(spin[i]);
+ spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector2i::_value_changed), varray(desc[i]));
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
+ }
+ setting = false;
+}
+
+///////////////////// RECT2 /////////////////////////
+
+void EditorPropertyRect2i::_value_changed(double val, const String &p_name) {
+ if (setting)
+ return;
+
+ Rect2i r2;
+ r2.position.x = spin[0]->get_value();
+ r2.position.y = spin[1]->get_value();
+ r2.size.x = spin[2]->get_value();
+ r2.size.y = spin[3]->get_value();
+ emit_changed(get_edited_property(), r2, p_name);
+}
+
+void EditorPropertyRect2i::update_property() {
+ Rect2i val = get_edited_object()->get(get_edited_property());
+ setting = true;
+ spin[0]->set_value(val.position.x);
+ spin[1]->set_value(val.position.y);
+ spin[2]->set_value(val.size.x);
+ spin[3]->set_value(val.size.y);
+ setting = false;
+}
+void EditorPropertyRect2i::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_theme_color("accent_color", "Editor");
+ for (int i = 0; i < 4; i++) {
+
+ Color c = base;
+ c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
+void EditorPropertyRect2i::_bind_methods() {
+}
+
+void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider) {
+ for (int i = 0; i < 4; i++) {
+ spin[i]->set_min(p_min);
+ spin[i]->set_max(p_max);
+ spin[i]->set_step(1);
+ spin[i]->set_hide_slider(p_no_slider);
+ spin[i]->set_allow_greater(true);
+ spin[i]->set_allow_lesser(true);
+ }
+}
+
+EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) {
+
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing");
+
+ BoxContainer *bc;
+
+ if (p_force_wide) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ } else if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
+ static const char *desc[4] = { "x", "y", "w", "h" };
+ for (int i = 0; i < 4; i++) {
+ spin[i] = memnew(EditorSpinSlider);
+ spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
+ bc->add_child(spin[i]);
+ add_focusable(spin[i]);
+ spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2i::_value_changed), varray(desc[i]));
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
+ }
+ setting = false;
+}
+
+///////////////////// VECTOR3 /////////////////////////
+
+void EditorPropertyVector3i::_value_changed(double val, const String &p_name) {
+ if (setting)
+ return;
+
+ Vector3i v3;
+ v3.x = spin[0]->get_value();
+ v3.y = spin[1]->get_value();
+ v3.z = spin[2]->get_value();
+ emit_changed(get_edited_property(), v3, p_name);
+}
+
+void EditorPropertyVector3i::update_property() {
+ Vector3i val = get_edited_object()->get(get_edited_property());
+ setting = true;
+ spin[0]->set_value(val.x);
+ spin[1]->set_value(val.y);
+ spin[2]->set_value(val.z);
+ setting = false;
+}
+void EditorPropertyVector3i::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_theme_color("accent_color", "Editor");
+ for (int i = 0; i < 3; i++) {
+
+ Color c = base;
+ c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
+void EditorPropertyVector3i::_bind_methods() {
+}
+
+void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider) {
+ for (int i = 0; i < 3; i++) {
+ spin[i]->set_min(p_min);
+ spin[i]->set_max(p_max);
+ spin[i]->set_step(1);
+ spin[i]->set_hide_slider(p_no_slider);
+ spin[i]->set_allow_greater(true);
+ spin[i]->set_allow_lesser(true);
+ }
+}
+
+EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) {
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing");
+
+ BoxContainer *bc;
+ if (p_force_wide) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ } else if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
+ static const char *desc[3] = { "x", "y", "z" };
+ for (int i = 0; i < 3; i++) {
+ spin[i] = memnew(EditorSpinSlider);
+ spin[i]->set_flat(true);
+ spin[i]->set_label(desc[i]);
+ bc->add_child(spin[i]);
+ add_focusable(spin[i]);
+ spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector3i::_value_changed), varray(desc[i]));
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
+ }
+ setting = false;
+}
+
///////////////////// PLANE /////////////////////////
void EditorPropertyPlane::_value_changed(double val, const String &p_name) {
@@ -1391,13 +1649,16 @@ void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool
}
}
-EditorPropertyPlane::EditorPropertyPlane() {
+EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) {
bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing");
BoxContainer *bc;
- if (horizontal) {
+ if (p_force_wide) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ } else if (horizontal) {
bc = memnew(HBoxContainer);
add_child(bc);
set_bottom_editor(bc);
@@ -2877,7 +3138,7 @@ void EditorInspectorDefaultPlugin::parse_begin(Object *p_object) {
//do none
}
-bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) {
+bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
float default_float_step = EDITOR_GET("interface/inspector/default_float_step");
@@ -3083,7 +3344,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
// math types
case Variant::VECTOR2: {
- EditorPropertyVector2 *editor = memnew(EditorPropertyVector2);
+ EditorPropertyVector2 *editor = memnew(EditorPropertyVector2(p_wide));
double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
@@ -3100,8 +3361,23 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
add_property_editor(p_path, editor);
} break;
+ case Variant::VECTOR2I: {
+ EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i(p_wide));
+ int min = -65535, max = 65535;
+ bool hide_slider = true;
+
+ if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
+ min = p_hint_text.get_slice(",", 0).to_double();
+ max = p_hint_text.get_slice(",", 1).to_double();
+ hide_slider = false;
+ }
+
+ editor->setup(min, max, hide_slider);
+ add_property_editor(p_path, editor);
+
+ } break;
case Variant::RECT2: {
- EditorPropertyRect2 *editor = memnew(EditorPropertyRect2);
+ EditorPropertyRect2 *editor = memnew(EditorPropertyRect2(p_wide));
double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
@@ -3117,8 +3393,22 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
editor->setup(min, max, step, hide_slider);
add_property_editor(p_path, editor);
} break;
+ case Variant::RECT2I: {
+ EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i(p_wide));
+ int min = -65535, max = 65535;
+ bool hide_slider = true;
+
+ if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
+ min = p_hint_text.get_slice(",", 0).to_double();
+ max = p_hint_text.get_slice(",", 1).to_double();
+ hide_slider = false;
+ }
+
+ editor->setup(min, max, hide_slider);
+ add_property_editor(p_path, editor);
+ } break;
case Variant::VECTOR3: {
- EditorPropertyVector3 *editor = memnew(EditorPropertyVector3);
+ EditorPropertyVector3 *editor = memnew(EditorPropertyVector3(p_wide));
double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
@@ -3135,6 +3425,22 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
add_property_editor(p_path, editor);
} break;
+ case Variant::VECTOR3I: {
+ EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i(p_wide));
+ int min = -65535, max = 65535;
+ bool hide_slider = true;
+
+ if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
+ min = p_hint_text.get_slice(",", 0).to_double();
+ max = p_hint_text.get_slice(",", 1).to_double();
+
+ hide_slider = false;
+ }
+
+ editor->setup(min, max, hide_slider);
+ add_property_editor(p_path, editor);
+
+ } break;
case Variant::TRANSFORM2D: {
EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D);
double min = -65535, max = 65535, step = default_float_step;
@@ -3154,7 +3460,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break;
case Variant::PLANE: {
- EditorPropertyPlane *editor = memnew(EditorPropertyPlane);
+ EditorPropertyPlane *editor = memnew(EditorPropertyPlane(p_wide));
double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index c5fc8aaf77..61c11f4534 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -361,7 +361,7 @@ protected:
public:
virtual void update_property();
void setup(double p_min, double p_max, double p_step, bool p_no_slider);
- EditorPropertyVector2();
+ EditorPropertyVector2(bool p_force_wide = false);
};
class EditorPropertyRect2 : public EditorProperty {
@@ -377,7 +377,7 @@ protected:
public:
virtual void update_property();
void setup(double p_min, double p_max, double p_step, bool p_no_slider);
- EditorPropertyRect2();
+ EditorPropertyRect2(bool p_force_wide = false);
};
class EditorPropertyVector3 : public EditorProperty {
@@ -393,7 +393,55 @@ protected:
public:
virtual void update_property();
void setup(double p_min, double p_max, double p_step, bool p_no_slider);
- EditorPropertyVector3();
+ EditorPropertyVector3(bool p_force_wide = false);
+};
+
+class EditorPropertyVector2i : public EditorProperty {
+ GDCLASS(EditorPropertyVector2i, EditorProperty);
+ EditorSpinSlider *spin[2];
+ bool setting;
+ void _value_changed(double p_val, const String &p_name);
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ virtual void update_property();
+ void setup(int p_min, int p_max, bool p_no_slider);
+ EditorPropertyVector2i(bool p_force_wide = false);
+};
+
+class EditorPropertyRect2i : public EditorProperty {
+ GDCLASS(EditorPropertyRect2i, EditorProperty);
+ EditorSpinSlider *spin[4];
+ bool setting;
+ void _value_changed(double p_val, const String &p_name);
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ virtual void update_property();
+ void setup(int p_min, int p_max, bool p_no_slider);
+ EditorPropertyRect2i(bool p_force_wide = false);
+};
+
+class EditorPropertyVector3i : public EditorProperty {
+ GDCLASS(EditorPropertyVector3i, EditorProperty);
+ EditorSpinSlider *spin[3];
+ bool setting;
+ void _value_changed(double p_val, const String &p_name);
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ virtual void update_property();
+ void setup(int p_min, int p_max, bool p_no_slider);
+ EditorPropertyVector3i(bool p_force_wide = false);
};
class EditorPropertyPlane : public EditorProperty {
@@ -409,7 +457,7 @@ protected:
public:
virtual void update_property();
void setup(double p_min, double p_max, double p_step, bool p_no_slider);
- EditorPropertyPlane();
+ EditorPropertyPlane(bool p_force_wide = false);
};
class EditorPropertyQuat : public EditorProperty {
@@ -626,7 +674,7 @@ class EditorInspectorDefaultPlugin : public EditorInspectorPlugin {
public:
virtual bool can_handle(Object *p_object);
virtual void parse_begin(Object *p_object);
- virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage);
+ virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false);
virtual void parse_end();
};
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index b4ce60171b..fdd5bd8db6 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -742,6 +742,13 @@ void EditorPropertyDictionary::update_property() {
prop = editor;
} break;
+ case Variant::VECTOR2I: {
+
+ EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i);
+ editor->setup(-100000, 100000, true);
+ prop = editor;
+
+ } break;
case Variant::RECT2: {
EditorPropertyRect2 *editor = memnew(EditorPropertyRect2);
@@ -749,6 +756,13 @@ void EditorPropertyDictionary::update_property() {
prop = editor;
} break;
+ case Variant::RECT2I: {
+
+ EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i);
+ editor->setup(-100000, 100000, true);
+ prop = editor;
+
+ } break;
case Variant::VECTOR3: {
EditorPropertyVector3 *editor = memnew(EditorPropertyVector3);
@@ -756,6 +770,13 @@ void EditorPropertyDictionary::update_property() {
prop = editor;
} break;
+ case Variant::VECTOR3I: {
+
+ EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i);
+ editor->setup(-100000, 100000, true);
+ prop = editor;
+
+ } break;
case Variant::TRANSFORM2D: {
EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 5d5bb1242d..9b58c18f51 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -559,6 +559,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["editors/3d/navigation_feel/manipulation_translation_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/navigation_feel/manipulation_translation_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01");
// 3D: Freelook
+ _initial_set("editors/3d/freelook/freelook_navigation_scheme", false);
+ hints["editors/3d/freelook/freelook_navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_navigation_scheme", PROPERTY_HINT_ENUM, "Default,Partially Axis-Locked (id Tech),Fully Axis-Locked (Minecraft)");
_initial_set("editors/3d/freelook/freelook_inertia", 0.1);
hints["editors/3d/freelook/freelook_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/freelook/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01");
_initial_set("editors/3d/freelook/freelook_base_speed", 5.0);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 37bca661dd..576ee436de 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -961,12 +961,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("grabber", "HSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons"));
theme->set_stylebox("slider", "HSlider", make_flat_stylebox(dark_color_3, 0, default_margin_size / 2, 0, default_margin_size / 2));
theme->set_stylebox("grabber_area", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2));
+ theme->set_stylebox("grabber_area_highlight", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2));
// VSlider
theme->set_icon("grabber", "VSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons"));
theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons"));
theme->set_stylebox("slider", "VSlider", make_flat_stylebox(dark_color_3, default_margin_size / 2, 0, default_margin_size / 2, 0));
theme->set_stylebox("grabber_area", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0));
+ theme->set_stylebox("grabber_area_highlight", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0));
//RichTextLabel
theme->set_color("default_color", "RichTextLabel", font_color);
diff --git a/editor/icons/AcceptDialog.svg b/editor/icons/AcceptDialog.svg
index e0bf7b8336..07e54d722f 100644
--- a/editor/icons/AcceptDialog.svg
+++ b/editor/icons/AcceptDialog.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm9.4746 1.6367 1.4141 1.4141-4.9492 4.9492-2.8281-2.8281 1.4141-1.4141 1.4141 1.4141z" fill="#a5efac"/></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm9.4746 1.6367 1.4141 1.4141-4.9492 4.9492-2.8281-2.8281 1.4141-1.4141 1.4141 1.4141z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/ConfirmationDialog.svg b/editor/icons/ConfirmationDialog.svg
index d1f13fbb3b..2d6e45b51f 100644
--- a/editor/icons/ConfirmationDialog.svg
+++ b/editor/icons/ConfirmationDialog.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm6.9863 1.002c.34689-.0022844.6986.055762 1.0391.17969 1.3618.4956 2.1813 1.9126 1.9297 3.3398-.19105 1.0835-.96172 1.9461-1.9551 2.3008v.17773h-1-1v-.8418a1.0001 1.0001 0 0 1 1-1.1582c.49193 0 .89895-.34177.98438-.82617.085424-.4845-.18031-.94508-.64258-1.1133-.46227-.1683-.96106.013453-1.207.43945a1.0002 1.0002 0 0 1 -1.7324-1c.54346-.94148 1.5433-1.4912 2.584-1.498zm-.98633 6.998h2v1h-2z" fill="#a5efac"/></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm6.9863 1.002c.34689-.0022844.6986.055762 1.0391.17969 1.3618.4956 2.1813 1.9126 1.9297 3.3398-.19105 1.0835-.96172 1.9461-1.9551 2.3008v.17773h-1-1v-.8418a1.0001 1.0001 0 0 1 1-1.1582c.49193 0 .89895-.34177.98438-.82617.085424-.4845-.18031-.94508-.64258-1.1133-.46227-.1683-.96106.013453-1.207.43945a1.0002 1.0002 0 0 1 -1.7324-1c.54346-.94148 1.5433-1.4912 2.584-1.498zm-.98633 6.998h2v1h-2z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/PopupDialog.svg b/editor/icons/EditorFileDialog.svg
index d871e56a63..95906234ab 100644
--- a/editor/icons/PopupDialog.svg
+++ b/editor/icons/EditorFileDialog.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm6 1h2v5h-2zm0 6h2v2h-2z" fill="#a5efac"/></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/FileDialog.svg b/editor/icons/FileDialog.svg
index 7708659c21..95906234ab 100644
--- a/editor/icons/FileDialog.svg
+++ b/editor/icons/FileDialog.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#a5efac"/></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/Popup.svg b/editor/icons/Popup.svg
index 93f7e5000d..a497b7a7fc 100644
--- a/editor/icons/Popup.svg
+++ b/editor/icons/Popup.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm4 2h2v6h-2zm0 8h2v2h-2z" fill="#a5efac"/></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm4 2h2v6h-2zm0 8h2v2h-2z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/PopupMenu.svg b/editor/icons/PopupMenu.svg
index dd7b2bb0fd..ebf62208e0 100644
--- a/editor/icons/PopupMenu.svg
+++ b/editor/icons/PopupMenu.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h6v-4zm1 1h4l-2 2zm0 4a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-7a1 1 0 0 0 -1-1zm1 2h10v2h-10zm0 3h10v2h-10z" fill="#a5efac"/></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h6v-4zm1 1h4l-2 2zm0 4a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-7a1 1 0 0 0 -1-1zm1 2h10v2h-10zm0 3h10v2h-10z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/PopupPanel.svg b/editor/icons/PopupPanel.svg
index 47a5448f5b..b45a3c9c3c 100644
--- a/editor/icons/PopupPanel.svg
+++ b/editor/icons/PopupPanel.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h6v-4zm1 1h4l-2 2zm0 4c-.55228 0-1 .44772-1 1v7c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-7c0-.55228-.44772-1-1-1z" fill="#a5efac"/></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h6v-4zm1 1h4l-2 2zm0 4c-.55228 0-1 .44772-1 1v7c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-7c0-.55228-.44772-1-1-1z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/ScriptCreateDialog.svg b/editor/icons/ScriptCreateDialog.svg
index 751b799ba9..78a69c5e59 100644
--- a/editor/icons/ScriptCreateDialog.svg
+++ b/editor/icons/ScriptCreateDialog.svg
@@ -1 +1 @@
-<svg height="17.067" viewBox="0 0 16 16" width="17.067" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h6v-5l3-2v-3h3v-2c0-1.1046-.89543-2-2-2z" fill="#a5efac" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-3v3c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v3h5v-1h-4v-2c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#87e29f" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0" r="0"/><g fill="#87e29f"><ellipse cx="12" cy="1048.4" rx=".5" ry="3"/><ellipse cx="913.91" cy="513.79" rx=".5" ry="3" transform="matrix(.5 .8660254 -.8660254 .5 0 0)"/><ellipse cx="901.91" cy="-534.57" rx=".5" ry="3" transform="matrix(-.5 .8660254 -.8660254 -.5 0 0)"/></g></g></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm5.5722656 1h3.9980464a1.1426143 1.1426143 0 0 1 1.142579 1.1425781v1.1425781h-1.712891-2.2851562v-.5703124-.5722657c0-.6310659-.5115295-1.1425781-1.1425782-1.1425781zm0 .5722656c.3155215 0 .5703125.254791.5703125.5703125v.5722657.5703124.5722657h.5722657 2.2851562v3.9980471a1.1426143 1.1426143 0 0 1 -1.1425781 1.142578h-4c.6310487 0 1.1425781-.511529 1.1425781-1.142578v-5.7128909c0-.0785019.01823-.1545692.046875-.2226562v-.0019531c.02868-.0672829.0683226-.1266374.1191406-.1777344.00097-.00096.0029352-.0010048.0039063-.0019532.0513303-.0508898.1121075-.0944618.1796875-.1230468.0683505-.028909.1437752-.0429688.2226562-.0429688zm-2.2851562 5.1406254h1.1425781v1.142578c0 .315522-.2567441.572265-.5722656.572265-.0776611 0-.15125-.016852-.21875-.044922-.00206-.000799-.0038594-.003049-.0058594-.003906-.0656506-.028192-.1236101-.067817-.1738281-.117187a.57130715.57130715 0 0 1 -.0097656-.009766c-.0490902-.050487-.0893425-.107988-.1171876-.173828-.028908-.06835-.0449218-.143776-.0449218-.222656z"/><circle cx="-23.915255" cy="3.118624" r="0"/></g></svg> \ No newline at end of file
diff --git a/editor/icons/WindowDialog.svg b/editor/icons/Window.svg
index 3c7be2a58d..a02a86d56a 100644
--- a/editor/icons/WindowDialog.svg
+++ b/editor/icons/Window.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8z" fill="#a5efac"/></svg> \ No newline at end of file
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/ARVRAnchor.svg b/editor/icons/XRAnchor3D.svg
index f1571b3fcc..f1571b3fcc 100644
--- a/editor/icons/ARVRAnchor.svg
+++ b/editor/icons/XRAnchor3D.svg
diff --git a/editor/icons/ARVRCamera.svg b/editor/icons/XRCamera3D.svg
index f59a8c8b4a..f59a8c8b4a 100644
--- a/editor/icons/ARVRCamera.svg
+++ b/editor/icons/XRCamera3D.svg
diff --git a/editor/icons/ARVRController.svg b/editor/icons/XRController3D.svg
index 40e5b8dce1..40e5b8dce1 100644
--- a/editor/icons/ARVRController.svg
+++ b/editor/icons/XRController3D.svg
diff --git a/editor/icons/ARVROrigin.svg b/editor/icons/XROrigin3D.svg
index dbb93ba7a5..dbb93ba7a5 100644
--- a/editor/icons/ARVROrigin.svg
+++ b/editor/icons/XROrigin3D.svg
diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp
new file mode 100644
index 0000000000..a2f178de12
--- /dev/null
+++ b/editor/import/resource_importer_shader_file.cpp
@@ -0,0 +1,90 @@
+#include "resource_importer_shader_file.h"
+
+#include "core/io/marshalls.h"
+#include "core/io/resource_saver.h"
+#include "core/os/file_access.h"
+#include "editor/editor_node.h"
+#include "editor/plugins/shader_file_editor_plugin.h"
+#include "servers/rendering/rendering_device_binds.h"
+
+String ResourceImporterShaderFile::get_importer_name() const {
+
+ return "glsl";
+}
+
+String ResourceImporterShaderFile::get_visible_name() const {
+
+ return "GLSL Shader File";
+}
+void ResourceImporterShaderFile::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("glsl");
+}
+String ResourceImporterShaderFile::get_save_extension() const {
+ return "res";
+}
+
+String ResourceImporterShaderFile::get_resource_type() const {
+
+ return "RDShaderFile";
+}
+
+int ResourceImporterShaderFile::get_preset_count() const {
+ return 0;
+}
+String ResourceImporterShaderFile::get_preset_name(int p_idx) const {
+
+ return String();
+}
+
+void ResourceImporterShaderFile::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+}
+
+bool ResourceImporterShaderFile::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+ return true;
+}
+static String _include_function(const String &p_path, void *userpointer) {
+ Error err;
+
+ String *base_path = (String *)userpointer;
+
+ String include = p_path;
+ if (include.is_rel_path()) {
+ include = base_path->plus_file(include);
+ }
+
+ FileAccessRef file_inc = FileAccess::open(include, FileAccess::READ, &err);
+ if (err != OK) {
+ return String();
+ }
+ return file_inc->get_as_utf8_string();
+}
+
+Error ResourceImporterShaderFile::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
+
+ /* STEP 1, Read shader code */
+
+ Error err;
+ FileAccessRef file = FileAccess::open(p_source_file, FileAccess::READ, &err);
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_OPEN);
+ ERR_FAIL_COND_V(!file.operator->(), ERR_CANT_OPEN);
+
+ String file_txt = file->get_as_utf8_string();
+ Ref<RDShaderFile> shader_file;
+ shader_file.instance();
+ String base_path = p_source_file.get_base_dir();
+ err = shader_file->parse_versions_from_text(file_txt, _include_function, &base_path);
+
+ if (err != OK) {
+ if (!ShaderFileEditor::singleton->is_visible_in_tree()) {
+ EditorNode::get_singleton()->add_io_error(vformat(TTR("Error importing GLSL shader file: '%s'. Open the file in the filesystem dock in order to see the reason."), p_source_file));
+ }
+ }
+
+ ResourceSaver::save(p_save_path + ".res", shader_file);
+
+ return OK;
+}
+
+ResourceImporterShaderFile::ResourceImporterShaderFile() {
+}
diff --git a/editor/import/resource_importer_shader_file.h b/editor/import/resource_importer_shader_file.h
new file mode 100644
index 0000000000..f6b50bee9e
--- /dev/null
+++ b/editor/import/resource_importer_shader_file.h
@@ -0,0 +1,27 @@
+#ifndef RESOURCE_IMPORTER_SHADER_FILE_H
+#define RESOURCE_IMPORTER_SHADER_FILE_H
+
+#include "core/io/resource_importer.h"
+
+class ResourceImporterShaderFile : public ResourceImporter {
+ GDCLASS(ResourceImporterShaderFile, ResourceImporter);
+
+public:
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
+
+ ResourceImporterShaderFile();
+};
+
+#endif // RESOURCE_IMPORTER_SHADER_FILE_H
diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp
index c06e5f3741..31a8320209 100644
--- a/editor/node_3d_editor_gizmos.cpp
+++ b/editor/node_3d_editor_gizmos.cpp
@@ -37,6 +37,7 @@
#include "scene/3d/collision_polygon_3d.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/3d/cpu_particles_3d.h"
+#include "scene/3d/decal.h"
#include "scene/3d/gi_probe.h"
#include "scene/3d/gpu_particles_3d.h"
#include "scene/3d/light_3d.h"
@@ -2718,7 +2719,143 @@ void ReflectionProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_unscaled_billboard(icon, 0.05);
p_gizmo->add_handles(handles, get_material("handles"));
}
+///////////////////////////////
+////
+
+DecalGizmoPlugin::DecalGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/decal", Color(0.6, 0.5, 1.0));
+
+ create_material("decal_material", gizmo_color);
+
+ create_handle_material("handles");
+}
+
+bool DecalGizmoPlugin::has_gizmo(Node3D *p_spatial) {
+ return Object::cast_to<Decal>(p_spatial) != nullptr;
+}
+
+String DecalGizmoPlugin::get_name() const {
+ return "Decal";
+}
+
+int DecalGizmoPlugin::get_priority() const {
+ return -1;
+}
+
+String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
+
+ switch (p_idx) {
+ case 0: return "Extents X";
+ case 1: return "Extents Y";
+ case 2: return "Extents Z";
+ }
+
+ return "";
+}
+Variant DecalGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
+
+ Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
+ return decal->get_extents();
+}
+void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+
+ Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
+ Transform gt = decal->get_global_transform();
+
+ Transform gi = gt.affine_inverse();
+
+ Vector3 extents = decal->get_extents();
+
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
+
+ Vector3 axis;
+ axis[p_idx] = 1.0;
+
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
+ float d = ra[p_idx];
+ if (Node3DEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ }
+
+ if (d < 0.001)
+ d = 0.001;
+
+ extents[p_idx] = d;
+ decal->set_extents(extents);
+}
+
+void DecalGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
+
+ Vector3 restore = p_restore;
+
+ if (p_cancel) {
+ decal->set_extents(restore);
+ return;
+ }
+
+ UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Decal Extents"));
+ ur->add_do_method(decal, "set_extents", decal->get_extents());
+ ur->add_undo_method(decal, "set_extents", restore);
+ ur->commit_action();
+}
+
+void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
+
+ Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
+
+ Vector<Vector3> lines;
+ Vector3 extents = decal->get_extents();
+
+ AABB aabb;
+ aabb.position = -extents;
+ aabb.size = extents * 2;
+
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ if (a.y == b.y) {
+ lines.push_back(a);
+ lines.push_back(b);
+ } else {
+ Vector3 ah = a.linear_interpolate(b, 0.2);
+ lines.push_back(a);
+ lines.push_back(ah);
+ Vector3 bh = b.linear_interpolate(a, 0.2);
+ lines.push_back(b);
+ lines.push_back(bh);
+ }
+ }
+
+ lines.push_back(Vector3(0, extents.y, 0));
+ lines.push_back(Vector3(0, extents.y * 1.2, 0));
+
+ Vector<Vector3> handles;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ax;
+ ax[i] = aabb.position[i] + aabb.size[i];
+ handles.push_back(ax);
+ }
+
+ Ref<Material> material = get_material("decal_material", p_gizmo);
+
+ p_gizmo->add_lines(lines, material);
+
+ p_gizmo->add_handles(handles, get_material("handles"));
+}
+
+///////////////////////////////
GIProbeGizmoPlugin::GIProbeGizmoPlugin() {
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/gi_probe", Color(0.5, 1, 0.6));
@@ -4082,6 +4219,21 @@ Joint3DGizmoPlugin::Joint3DGizmoPlugin() {
create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1)));
create_material("joint_body_a_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1)));
create_material("joint_body_b_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1)));
+
+ update_timer = memnew(Timer);
+ update_timer->set_name("JointGizmoUpdateTimer");
+ update_timer->set_wait_time(1.0 / 120.0);
+ update_timer->connect("timeout", callable_mp(this, &Joint3DGizmoPlugin::incremental_update_gizmos));
+ update_timer->set_autostart(true);
+ EditorNode::get_singleton()->call_deferred("add_child", update_timer);
+}
+
+void Joint3DGizmoPlugin::incremental_update_gizmos() {
+ if (!current_gizmos.empty()) {
+ update_idx++;
+ update_idx = update_idx % current_gizmos.size();
+ redraw(current_gizmos[update_idx]);
+ }
}
bool Joint3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h
index 889b0e8315..6432feeecb 100644
--- a/editor/node_3d_editor_gizmos.h
+++ b/editor/node_3d_editor_gizmos.h
@@ -285,6 +285,24 @@ public:
ReflectionProbeGizmoPlugin();
};
+class DecalGizmoPlugin : public EditorNode3DGizmoPlugin {
+
+ GDCLASS(DecalGizmoPlugin, EditorNode3DGizmoPlugin);
+
+public:
+ bool has_gizmo(Node3D *p_spatial);
+ String get_name() const;
+ int get_priority() const;
+ void redraw(EditorNode3DGizmo *p_gizmo);
+
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point);
+ void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
+
+ DecalGizmoPlugin();
+};
+
class GIProbeGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(GIProbeGizmoPlugin, EditorNode3DGizmoPlugin);
@@ -391,6 +409,11 @@ class Joint3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(Joint3DGizmoPlugin, EditorNode3DGizmoPlugin);
+ Timer *update_timer;
+ uint64_t update_idx = 0;
+
+ void incremental_update_gizmos();
+
public:
bool has_gizmo(Node3D *p_spatial);
String get_name() const;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 2f7747d0ff..cd3df08276 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1919,6 +1919,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
Point2 offset = drag_to_local - drag_from_local;
Size2 scale = canvas_item->call("get_scale");
+ Size2 original_scale = scale;
float ratio = scale.y / scale.x;
if (drag_type == DRAG_SCALE_BOTH) {
Size2 scale_factor = drag_to_local / drag_from_local;
@@ -1931,6 +1932,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
Size2 scale_factor = Vector2(offset.x, -offset.y) / SCALE_HANDLE_DISTANCE;
Size2 parent_scale = parent_xform.get_scale();
scale_factor *= Vector2(1.0 / parent_scale.x, 1.0 / parent_scale.y);
+
if (drag_type == DRAG_SCALE_X) {
scale.x += scale_factor.x;
if (uniform) {
@@ -1945,8 +1947,13 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
}
if (snap_scale && !is_ctrl) {
- scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step;
- scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step;
+ if (snap_relative) {
+ scale.x = original_scale.x * (roundf((scale.x / original_scale.x) / snap_scale_step) * snap_scale_step);
+ scale.y = original_scale.y * (roundf((scale.y / original_scale.y) / snap_scale_step) * snap_scale_step);
+ } else {
+ scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step;
+ scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step;
+ }
}
canvas_item->call("set_scale", scale);
@@ -3193,13 +3200,15 @@ void CanvasItemEditor::_draw_selection() {
RID ci = viewport->get_canvas_item();
- List<CanvasItem *> selection = _get_edited_canvas_items(false, false);
+ List<CanvasItem *> selection = _get_edited_canvas_items(true, false);
bool single = selection.size() == 1;
for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
+ bool item_locked = canvas_item->has_meta("_edit_lock_");
+
// Draw the previous position if we are dragging the node
if (show_helpers &&
(drag_type == DRAG_MOVE || drag_type == DRAG_ROTATE ||
@@ -3239,6 +3248,10 @@ void CanvasItemEditor::_draw_selection() {
Color c = Color(1, 0.6, 0.4, 0.7);
+ if (item_locked) {
+ c = Color(0.7, 0.7, 0.7, 0.7);
+ }
+
for (int i = 0; i < 4; i++) {
viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, Math::round(2 * EDSCALE));
}
@@ -3251,7 +3264,7 @@ void CanvasItemEditor::_draw_selection() {
viewport->draw_set_transform_matrix(viewport->get_transform());
}
- if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks
+ if (single && !item_locked && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks
// Draw the pivot
if (canvas_item->_edit_use_pivot()) {
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index b005519a5e..ef4d7d7646 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -262,9 +262,8 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin(EditorNode *p_node) {
toolbar->add_child(memnew(VSeparator));
menu = memnew(MenuButton);
- menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK);
- menu->get_popup()->add_separator();
menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART);
+ menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK);
menu->set_text(TTR("CPUParticles2D"));
menu->set_switch_on_hover(true);
toolbar->add_child(menu);
diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
index 0c2fbaf62a..59a353a581 100644
--- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
@@ -104,9 +104,8 @@ CPUParticles3DEditor::CPUParticles3DEditor() {
particles_editor_hb->hide();
options->set_text(TTR("CPUParticles3D"));
- options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE);
- options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART);
+ options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE);
options->get_popup()->connect("id_pressed", callable_mp(this, &CPUParticles3DEditor::_menu_option));
}
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index 29c47a2b67..5c35285c22 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -371,14 +371,11 @@ GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin(EditorNode *p_node) {
toolbar->add_child(memnew(VSeparator));
menu = memnew(MenuButton);
+ menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART);
menu->get_popup()->add_item(TTR("Generate Visibility Rect"), MENU_GENERATE_VISIBILITY_RECT);
- menu->get_popup()->add_separator();
menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK);
// menu->get_popup()->add_item(TTR("Clear Emission Mask"), MENU_CLEAR_EMISSION_MASK);
- menu->get_popup()->add_separator();
menu->get_popup()->add_item(TTR("Convert to CPUParticles2D"), MENU_OPTION_CONVERT_TO_CPU_PARTICLES);
- menu->get_popup()->add_separator();
- menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART);
menu->set_text(TTR("GPUParticles2D"));
menu->set_switch_on_hover(true);
toolbar->add_child(menu);
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
index 534a228098..7f80acc176 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
@@ -433,13 +433,10 @@ GPUParticles3DEditor::GPUParticles3DEditor() {
particles_editor_hb->hide();
options->set_text(TTR("GPUParticles3D"));
+ options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART);
options->get_popup()->add_item(TTR("Generate AABB"), MENU_OPTION_GENERATE_AABB);
- options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE);
- options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Convert to CPUParticles3D"), MENU_OPTION_CONVERT_TO_CPU_PARTICLES);
- options->get_popup()->add_separator();
- options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART);
options->get_popup()->connect("id_pressed", callable_mp(this, &GPUParticles3DEditor::_menu_option));
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index 00e8a05e4e..eb14495b9c 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -95,6 +95,7 @@ void MaterialEditor::_button_pressed(Node *p_button) {
sphere_instance->hide();
box_switch->set_pressed(true);
sphere_switch->set_pressed(false);
+ EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", false);
}
if (p_button == sphere_switch) {
@@ -102,6 +103,7 @@ void MaterialEditor::_button_pressed(Node *p_button) {
sphere_instance->show();
box_switch->set_pressed(false);
sphere_switch->set_pressed(true);
+ EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", true);
}
}
@@ -155,7 +157,6 @@ MaterialEditor::MaterialEditor() {
sphere_instance->set_mesh(sphere_mesh);
box_mesh.instance();
box_instance->set_mesh(box_mesh);
- box_instance->hide();
set_custom_minimum_size(Size2(1, 150) * EDSCALE);
@@ -194,6 +195,15 @@ MaterialEditor::MaterialEditor() {
light_2_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed), varray(light_2_switch));
first_enter = true;
+
+ if (EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_on_sphere", true)) {
+ box_instance->hide();
+ } else {
+ box_instance->show();
+ sphere_instance->hide();
+ box_switch->set_pressed(true);
+ sphere_switch->set_pressed(false);
+ }
}
///////////////////////
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 1ebcd3abfd..f51b9b20e4 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -347,7 +347,7 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
if (orthogonal) {
float half_fov = Math::deg2rad(get_fov()) / 2.0;
float height = 2.0 * cursor.distance * Math::tan(half_fov);
- camera->set_orthogonal(height, 0.1, 8192);
+ camera->set_orthogonal(height, get_znear(), get_zfar());
} else {
camera->set_perspective(get_fov(), get_znear(), get_zfar());
}
@@ -364,7 +364,7 @@ Transform Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) cons
camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot);
if (orthogonal)
- camera_transform.translate(0, 0, 4096);
+ camera_transform.translate(0, 0, (get_zfar() - get_znear()) / 2.0);
else
camera_transform.translate(0, 0, p_cursor.distance);
@@ -2287,9 +2287,27 @@ void Node3DEditorViewport::_update_freelook(real_t delta) {
return;
}
- const Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
+ const FreelookNavigationScheme navigation_scheme = (FreelookNavigationScheme)EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_navigation_scheme").operator int();
+
+ Vector3 forward;
+ if (navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) {
+ // Forward/backward keys will always go straight forward/backward, never moving on the Y axis.
+ forward = Vector3(0, 0, -1).rotated(Vector3(0, 1, 0), camera->get_rotation().y);
+ } else {
+ // Forward/backward keys will be relative to the camera pitch.
+ forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
+ }
+
const Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0));
- const Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0));
+
+ Vector3 up;
+ if (navigation_scheme == FREELOOK_PARTIALLY_AXIS_LOCKED || navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) {
+ // Up/down keys will always go up/down regardless of camera pitch.
+ up = Vector3(0, 1, 0);
+ } else {
+ // Up/down keys will be relative to the camera pitch.
+ up = camera->get_transform().basis.xform(Vector3(0, 1, 0));
+ }
Vector3 direction;
@@ -2478,11 +2496,15 @@ void Node3DEditorViewport::_notification(int p_what) {
//update msaa if changed
- int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/filters/msaa");
+ int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa");
viewport->set_msaa(Viewport::MSAA(msaa_mode));
+ int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa");
+ viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));
bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
- info_label->set_visible(show_info);
+ if (show_info != info_label->is_visible()) {
+ info_label->set_visible(show_info);
+ }
Camera3D *current_camera;
@@ -2509,17 +2531,46 @@ void Node3DEditorViewport::_notification(int p_what) {
text += TTR("Surface Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SURFACE_CHANGES_IN_FRAME)) + "\n";
text += TTR("Draw Calls") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME)) + "\n";
text += TTR("Vertices") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_VERTICES_IN_FRAME));
+
info_label->set_text(text);
}
// FPS Counter.
- bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS));
- fps_label->set_visible(show_fps);
-
+ bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
+
+ if (show_fps != fps_label->is_visible()) {
+ fps_label->set_visible(show_fps);
+ RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps);
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
+ cpu_time_history[i] = 0;
+ gpu_time_history[i] = 0;
+ }
+ cpu_time_history_index = 0;
+ cpu_time_history_index = 0;
+ }
if (show_fps) {
+
+ cpu_time_history[cpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_cpu(viewport->get_viewport_rid());
+ cpu_time_history_index = (cpu_time_history_index + 1) % FRAME_TIME_HISTORY;
+ float cpu_time = 0.0;
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
+ cpu_time += cpu_time_history[i];
+ }
+ cpu_time /= FRAME_TIME_HISTORY;
+
+ gpu_time_history[gpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_gpu(viewport->get_viewport_rid());
+ gpu_time_history_index = (gpu_time_history_index + 1) % FRAME_TIME_HISTORY;
+ float gpu_time = 0.0;
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
+ gpu_time += gpu_time_history[i];
+ }
+ gpu_time /= FRAME_TIME_HISTORY;
+
String text;
- const float temp_fps = Engine::get_singleton()->get_frames_per_second();
- text += TTR(vformat("FPS: %d (%s ms)", temp_fps, String::num(1000.0f / temp_fps, 2)));
+ text += TTR("CPU Time") + ": " + String::num(cpu_time, 1) + " ms\n";
+ text += TTR("GPU Time") + ": " + String::num(gpu_time, 1) + " ms\n";
+ text += TTR("FPS") + ": " + itos(1000.0 / gpu_time);
+
fps_label->set_text(text);
}
@@ -2980,9 +3031,9 @@ void Node3DEditorViewport::_menu_option(int p_option) {
view_menu->get_popup()->set_item_checked(idx, !current);
} break;
- case VIEW_FPS: {
+ case VIEW_FRAME_TIME: {
- int idx = view_menu->get_popup()->get_item_index(VIEW_FPS);
+ int idx = view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME);
bool current = view_menu->get_popup()->is_item_checked(idx);
view_menu->get_popup()->set_item_checked(idx, !current);
@@ -3000,6 +3051,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
case VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION:
case VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE:
case VIEW_DISPLAY_DEBUG_SSAO:
+ case VIEW_DISPLAY_DEBUG_PSSM_SPLITS:
+ case VIEW_DISPLAY_DEBUG_DECAL_ATLAS:
case VIEW_DISPLAY_DEBUG_ROUGHNESS_LIMITER: {
static const int display_options[] = {
@@ -3018,6 +3071,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE,
VIEW_DISPLAY_DEBUG_SSAO,
VIEW_DISPLAY_DEBUG_ROUGHNESS_LIMITER,
+ VIEW_DISPLAY_DEBUG_PSSM_SPLITS,
+ VIEW_DISPLAY_DEBUG_DECAL_ATLAS,
VIEW_MAX
};
static const Viewport::DebugDraw debug_draw_modes[] = {
@@ -3036,6 +3091,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
Viewport::DEBUG_DRAW_SCENE_LUMINANCE,
Viewport::DEBUG_DRAW_SSAO,
Viewport::DEBUG_DRAW_ROUGHNESS_LIMITER,
+ Viewport::DEBUG_DRAW_PSSM_SPLITS,
+ Viewport::DEBUG_DRAW_DECAL_ATLAS,
};
int idx = 0;
@@ -3335,12 +3392,12 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) {
if (view_menu->get_popup()->is_item_checked(idx) != information)
_menu_option(VIEW_INFORMATION);
}
- if (p_state.has("fps")) {
- bool fps = p_state["fps"];
+ if (p_state.has("frame_time")) {
+ bool fps = p_state["frame_time"];
- int idx = view_menu->get_popup()->get_item_index(VIEW_FPS);
+ int idx = view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME);
if (view_menu->get_popup()->is_item_checked(idx) != fps)
- _menu_option(VIEW_FPS);
+ _menu_option(VIEW_FRAME_TIME);
}
if (p_state.has("half_res")) {
bool half_res = p_state["half_res"];
@@ -3397,7 +3454,7 @@ Dictionary Node3DEditorViewport::get_state() const {
d["doppler"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER));
d["gizmos"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS));
d["information"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
- d["fps"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS));
+ d["frame_time"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
d["half_res"] = subviewport_container->get_stretch_shrink() > 1;
d["cinematic_preview"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
if (previewing)
@@ -3809,6 +3866,9 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index) {
+ cpu_time_history_index = 0;
+ gpu_time_history_index = 0;
+
_edit.mode = TRANSFORM_NONE;
_edit.plane = TRANSFORM_VIEW;
_edit.edited_gizmo = 0;
@@ -3887,11 +3947,15 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_lighting", TTR("Display Lighting")), VIEW_DISPLAY_LIGHTING);
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_unshaded", TTR("Display Unshaded")), VIEW_DISPLAY_SHADELESS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), true);
+ display_submenu->add_radio_check_item(TTR("Directional Shadow Splits"), VIEW_DISPLAY_DEBUG_PSSM_SPLITS);
+ display_submenu->add_separator();
display_submenu->add_radio_check_item(TTR("Normal Buffer"), VIEW_DISPLAY_NORMAL_BUFFER);
display_submenu->add_separator();
display_submenu->add_radio_check_item(TTR("Shadow Atlas"), VIEW_DISPLAY_DEBUG_SHADOW_ATLAS);
display_submenu->add_radio_check_item(TTR("Directional Shadow"), VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS);
display_submenu->add_separator();
+ display_submenu->add_radio_check_item(TTR("Decal Atlas"), VIEW_DISPLAY_DEBUG_DECAL_ATLAS);
+ display_submenu->add_separator();
display_submenu->add_radio_check_item(TTR("GIProbe Lighting"), VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING);
display_submenu->add_radio_check_item(TTR("GIProbe Albedo"), VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO);
display_submenu->add_radio_check_item(TTR("GIProbe Emission"), VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION);
@@ -3907,7 +3971,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("View Environment")), VIEW_ENVIRONMENT);
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("View Gizmos")), VIEW_GIZMOS);
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_information", TTR("View Information")), VIEW_INFORMATION);
- view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_fps", TTR("View FPS")), VIEW_FPS);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_fps", TTR("View Frame Time")), VIEW_FRAME_TIME);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT), true);
view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_half_resolution", TTR("Half Resolution")), VIEW_HALF_RESOLUTION);
@@ -3984,7 +4048,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
fps_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
fps_label->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -10 * EDSCALE);
fps_label->set_h_grow_direction(GROW_DIRECTION_BEGIN);
- fps_label->set_tooltip(TTR("Note: The FPS value displayed is the editor's framerate.\nIt cannot be used as a reliable indication of in-game performance."));
+ fps_label->set_tooltip(TTR("Note: The FPS is estimated on a 60hz refresh rate."));
fps_label->set_mouse_filter(MOUSE_FILTER_PASS); // Otherwise tooltip doesn't show.
surface->add_child(fps_label);
fps_label->hide();
@@ -5922,6 +5986,7 @@ void Node3DEditor::_register_all_gizmos() {
add_gizmo_plugin(Ref<GPUParticles3DGizmoPlugin>(memnew(GPUParticles3DGizmoPlugin)));
add_gizmo_plugin(Ref<CPUParticles3DGizmoPlugin>(memnew(CPUParticles3DGizmoPlugin)));
add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
+ add_gizmo_plugin(Ref<DecalGizmoPlugin>(memnew(DecalGizmoPlugin)));
add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
// add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin)));
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 552afb99e0..71da14ae1a 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -202,7 +202,7 @@ class Node3DEditorViewport : public Control {
VIEW_AUDIO_DOPPLER,
VIEW_GIZMOS,
VIEW_INFORMATION,
- VIEW_FPS,
+ VIEW_FRAME_TIME,
VIEW_DISPLAY_NORMAL,
VIEW_DISPLAY_WIREFRAME,
VIEW_DISPLAY_OVERDRAW,
@@ -218,6 +218,8 @@ class Node3DEditorViewport : public Control {
VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE,
VIEW_DISPLAY_DEBUG_SSAO,
VIEW_DISPLAY_DEBUG_ROUGHNESS_LIMITER,
+ VIEW_DISPLAY_DEBUG_PSSM_SPLITS,
+ VIEW_DISPLAY_DEBUG_DECAL_ATLAS,
VIEW_LOCK_ROTATION,
VIEW_CINEMATIC_PREVIEW,
VIEW_AUTO_ORTHOGONAL,
@@ -228,7 +230,9 @@ public:
enum {
GIZMO_BASE_LAYER = 27,
GIZMO_EDIT_LAYER = 26,
- GIZMO_GRID_LAYER = 25
+ GIZMO_GRID_LAYER = 25,
+
+ FRAME_TIME_HISTORY = 20,
};
enum NavigationScheme {
@@ -237,7 +241,18 @@ public:
NAVIGATION_MODO,
};
+ enum FreelookNavigationScheme {
+ FREELOOK_DEFAULT,
+ FREELOOK_PARTIALLY_AXIS_LOCKED,
+ FREELOOK_FULLY_AXIS_LOCKED,
+ };
+
private:
+ float cpu_time_history[FRAME_TIME_HISTORY];
+ int cpu_time_history_index;
+ float gpu_time_history[FRAME_TIME_HISTORY];
+ int gpu_time_history_index;
+
int index;
String name;
void _menu_option(int p_option);
@@ -841,12 +856,11 @@ public:
static const int HIDDEN = 1;
static const int ON_TOP = 2;
-private:
+protected:
int current_state;
List<EditorNode3DGizmo *> current_gizmos;
HashMap<String, Vector<Ref<StandardMaterial3D>>> materials;
-protected:
static void _bind_methods();
virtual bool has_gizmo(Node3D *p_spatial);
virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial);
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index 67e836082d..a7120c5d68 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -288,7 +288,7 @@ void EditorInspectorRootMotionPlugin::parse_begin(Object *p_object) {
//do none
}
-bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) {
+bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
if (p_path == "root_motion_track" && p_object->is_class("AnimationTree") && p_type == Variant::NODE_PATH) {
EditorPropertyRootMotion *editor = memnew(EditorPropertyRootMotion);
diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h
index 8a7691de5d..f72ad1ec05 100644
--- a/editor/plugins/root_motion_editor_plugin.h
+++ b/editor/plugins/root_motion_editor_plugin.h
@@ -65,7 +65,7 @@ class EditorInspectorRootMotionPlugin : public EditorInspectorPlugin {
public:
virtual bool can_handle(Object *p_object);
virtual void parse_begin(Object *p_object);
- virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage);
+ virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false);
virtual void parse_end();
};
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 0b97ade278..2c831979de 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1778,9 +1778,11 @@ void ScriptEditor::_update_script_names() {
if (built_in) {
name = path.get_file();
- String resource_name = se->get_edited_resource()->get_name();
+ const String &resource_name = se->get_edited_resource()->get_name();
if (resource_name != "") {
- name = name.substr(0, name.find("::", 0) + 2) + resource_name;
+ // If the built-in script has a custom resource name defined,
+ // display the built-in script name as follows: `ResourceName (scene_file.tscn)`
+ name = vformat("%s (%s)", resource_name, name.substr(0, name.find("::", 0)));
}
} else {
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 4b8383e1e5..1a77eeb9de 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -172,7 +172,7 @@ void ScriptTextEditor::_update_member_keywords() {
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
String name = E->get().name;
- if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP)
+ if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP)
continue;
if (name.find("/") != -1)
continue;
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 2a36700105..9ef8148241 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -193,6 +193,12 @@ void ShaderTextEditor::_check_shader_mode() {
}
}
+static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) {
+
+ RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable);
+ return RS::global_variable_type_get_shader_datatype(gvt);
+}
+
void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) {
_check_shader_mode();
@@ -200,7 +206,7 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCo
ShaderLanguage sl;
String calltip;
- sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip);
+ sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip);
get_text_edit()->set_code_hint(calltip);
}
@@ -215,7 +221,7 @@ void ShaderTextEditor::_validate_script() {
ShaderLanguage sl;
- Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types());
+ Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
if (err != OK) {
String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp
new file mode 100644
index 0000000000..296c7a01b6
--- /dev/null
+++ b/editor/plugins/shader_file_editor_plugin.cpp
@@ -0,0 +1,303 @@
+#include "shader_file_editor_plugin.h"
+
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/os/keyboard.h"
+#include "core/os/os.h"
+#include "editor/editor_node.h"
+#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
+#include "editor/property_editor.h"
+#include "servers/display_server.h"
+#include "servers/rendering/shader_types.h"
+
+/*** SHADER SCRIPT EDITOR ****/
+
+/*** SCRIPT EDITOR ******/
+
+void ShaderFileEditor::_update_version(const StringName &p_version_txt, const RD::ShaderStage p_stage) {
+}
+
+void ShaderFileEditor::_version_selected(int p_option) {
+
+ int c = versions->get_current();
+ StringName version_txt = versions->get_item_metadata(c);
+
+ RD::ShaderStage stage = RD::SHADER_STAGE_MAX;
+ int first_found = -1;
+
+ Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(version_txt);
+ ERR_FAIL_COND(bytecode.is_null());
+
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) {
+ stages[i]->set_icon(Ref<Texture2D>());
+ continue;
+ }
+
+ Ref<Texture2D> icon;
+ if (bytecode->get_stage_compile_error(RD::ShaderStage(i)) != String()) {
+ icon = get_theme_icon("ImportFail", "EditorIcons");
+ } else {
+ icon = get_theme_icon("ImportCheck", "EditorIcons");
+ }
+ stages[i]->set_icon(icon);
+
+ if (first_found == -1) {
+ first_found = i;
+ }
+
+ if (stages[i]->is_pressed()) {
+ stage = RD::ShaderStage(i);
+ break;
+ }
+ }
+
+ error_text->clear();
+
+ if (stage == RD::SHADER_STAGE_MAX) { //need to change stage, does not have it
+ if (first_found == -1) {
+ error_text->add_text(TTR("No valid shader stages found."));
+ return; //well you did not put any stage I guess?
+ }
+ stages[first_found]->set_pressed(true);
+ stage = RD::ShaderStage(first_found);
+ }
+
+ String error = bytecode->get_stage_compile_error(stage);
+
+ error_text->push_font(get_theme_font("source", "EditorFonts"));
+
+ if (error == String()) {
+ error_text->add_text(TTR("Shader stage compiled without errors."));
+ } else {
+ error_text->add_text(error);
+ }
+}
+
+void ShaderFileEditor::_update_options() {
+
+ ERR_FAIL_COND(shader_file.is_null());
+
+ if (shader_file->get_base_error() != String()) {
+ stage_hb->hide();
+ versions->hide();
+ error_text->clear();
+ error_text->push_font(get_theme_font("source", "EditorFonts"));
+ error_text->add_text(vformat(TTR("File structure for '%s' contains unrecoverable errors:\n\n"), shader_file->get_path().get_file()));
+ error_text->add_text(shader_file->get_base_error());
+ return;
+ }
+
+ stage_hb->show();
+ versions->show();
+
+ int c = versions->get_current();
+ //remember current
+ versions->clear();
+ Vector<StringName> version_list = shader_file->get_version_list();
+
+ if (c >= version_list.size()) {
+ c = version_list.size() - 1;
+ }
+ if (c < 0) {
+ c = 0;
+ }
+
+ StringName current_version;
+
+ for (int i = 0; i < version_list.size(); i++) {
+ String title = version_list[i];
+ if (title == "") {
+ title = "default";
+ }
+
+ Ref<Texture2D> icon;
+
+ Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(version_list[i]);
+ ERR_FAIL_COND(bytecode.is_null());
+
+ bool failed = false;
+ for (int j = 0; j < RD::SHADER_STAGE_MAX; j++) {
+ String error = bytecode->get_stage_compile_error(RD::ShaderStage(j));
+ if (error != String()) {
+ failed = true;
+ }
+ }
+
+ if (failed) {
+ icon = get_theme_icon("ImportFail", "EditorIcons");
+ } else {
+ icon = get_theme_icon("ImportCheck", "EditorIcons");
+ }
+
+ versions->add_item(title, icon);
+ versions->set_item_metadata(i, version_list[i]);
+
+ if (i == c) {
+ versions->select(i);
+ current_version = version_list[i];
+ }
+ }
+
+ if (version_list.size() == 0) {
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ stages[i]->set_disabled(true);
+ }
+ return;
+ }
+
+ Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(current_version);
+ ERR_FAIL_COND(bytecode.is_null());
+ int first_valid = -1;
+ int current = -1;
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ Vector<uint8_t> bc = bytecode->get_stage_bytecode(RD::ShaderStage(i));
+ String error = bytecode->get_stage_compile_error(RD::ShaderStage(i));
+ bool disable = error == String() && bc.empty();
+ stages[i]->set_disabled(disable);
+ if (!disable) {
+ if (stages[i]->is_pressed()) {
+ current = i;
+ }
+ first_valid = i;
+ }
+ }
+
+ if (current == -1 && first_valid != -1) {
+ stages[first_valid]->set_pressed(true);
+ }
+
+ _version_selected(0);
+}
+
+void ShaderFileEditor::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_WM_FOCUS_IN) {
+ if (is_visible_in_tree() && shader_file.is_valid()) {
+ _update_options();
+ }
+ }
+}
+
+void ShaderFileEditor::_editor_settings_changed() {
+
+ if (is_visible_in_tree() && shader_file.is_valid()) {
+ _update_options();
+ }
+}
+
+void ShaderFileEditor::_bind_methods() {
+}
+
+void ShaderFileEditor::edit(const Ref<RDShaderFile> &p_shader) {
+
+ if (p_shader.is_null()) {
+ if (shader_file.is_valid()) {
+ shader_file->disconnect("changed", callable_mp(this, &ShaderFileEditor::_shader_changed));
+ }
+ return;
+ }
+
+ if (shader_file == p_shader)
+ return;
+
+ shader_file = p_shader;
+
+ if (shader_file.is_valid()) {
+ shader_file->connect("changed", callable_mp(this, &ShaderFileEditor::_shader_changed));
+ }
+
+ _update_options();
+}
+
+void ShaderFileEditor::_shader_changed() {
+
+ if (is_visible_in_tree()) {
+ _update_options();
+ }
+}
+
+ShaderFileEditor *ShaderFileEditor::singleton = nullptr;
+
+ShaderFileEditor::ShaderFileEditor(EditorNode *p_node) {
+ singleton = this;
+ HSplitContainer *main_hs = memnew(HSplitContainer);
+
+ add_child(main_hs);
+
+ versions = memnew(ItemList);
+ versions->connect("item_selected", callable_mp(this, &ShaderFileEditor::_version_selected));
+ versions->set_custom_minimum_size(Size2i(200 * EDSCALE, 0));
+ main_hs->add_child(versions);
+
+ VBoxContainer *main_vb = memnew(VBoxContainer);
+ main_vb->set_h_size_flags(SIZE_EXPAND_FILL);
+ main_hs->add_child(main_vb);
+
+ static const char *stage_str[RD::SHADER_STAGE_MAX] = {
+ "Vertex",
+ "Fragment",
+ "TessControl",
+ "TessEval",
+ "Compute"
+ };
+
+ stage_hb = memnew(HBoxContainer);
+ main_vb->add_child(stage_hb);
+
+ Ref<ButtonGroup> bg;
+ bg.instance();
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ Button *button = memnew(Button(stage_str[i]));
+ button->set_toggle_mode(true);
+ button->set_focus_mode(FOCUS_NONE);
+ stage_hb->add_child(button);
+ stages[i] = button;
+ button->set_button_group(bg);
+ button->connect("pressed", callable_mp(this, &ShaderFileEditor::_version_selected), varray(i));
+ }
+
+ error_text = memnew(RichTextLabel);
+ error_text->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_vb->add_child(error_text);
+}
+
+void ShaderFileEditorPlugin::edit(Object *p_object) {
+
+ RDShaderFile *s = Object::cast_to<RDShaderFile>(p_object);
+ shader_editor->edit(s);
+}
+
+bool ShaderFileEditorPlugin::handles(Object *p_object) const {
+
+ RDShaderFile *shader = Object::cast_to<RDShaderFile>(p_object);
+ return shader != nullptr;
+}
+
+void ShaderFileEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ button->show();
+ editor->make_bottom_panel_item_visible(shader_editor);
+
+ } else {
+
+ button->hide();
+ if (shader_editor->is_visible_in_tree())
+ editor->hide_bottom_panel();
+ }
+}
+
+ShaderFileEditorPlugin::ShaderFileEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ shader_editor = memnew(ShaderFileEditor(p_node));
+
+ shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
+ button = editor->add_bottom_panel_item(TTR("ShaderFile"), shader_editor);
+ button->hide();
+}
+
+ShaderFileEditorPlugin::~ShaderFileEditorPlugin() {
+}
diff --git a/editor/plugins/shader_file_editor_plugin.h b/editor/plugins/shader_file_editor_plugin.h
new file mode 100644
index 0000000000..44d32de2f1
--- /dev/null
+++ b/editor/plugins/shader_file_editor_plugin.h
@@ -0,0 +1,64 @@
+#ifndef SHADER_FILE_EDITOR_PLUGIN_H
+#define SHADER_FILE_EDITOR_PLUGIN_H
+
+#include "editor/code_editor.h"
+#include "editor/editor_plugin.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/panel_container.h"
+#include "scene/gui/rich_text_label.h"
+#include "scene/gui/tab_container.h"
+#include "scene/gui/text_edit.h"
+#include "scene/main/timer.h"
+#include "servers/rendering/rendering_device_binds.h"
+
+class ShaderFileEditor : public PanelContainer {
+
+ GDCLASS(ShaderFileEditor, PanelContainer);
+
+ Ref<RDShaderFile> shader_file;
+
+ HBoxContainer *stage_hb;
+ ItemList *versions;
+ Button *stages[RD::SHADER_STAGE_MAX];
+ RichTextLabel *error_text;
+
+ void _update_version(const StringName &p_version_txt, const RenderingDevice::ShaderStage p_stage);
+ void _version_selected(int p_stage);
+ void _editor_settings_changed();
+
+ void _update_options();
+ void _shader_changed();
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ static ShaderFileEditor *singleton;
+ void edit(const Ref<RDShaderFile> &p_shader);
+
+ ShaderFileEditor(EditorNode *p_node);
+};
+
+class ShaderFileEditorPlugin : public EditorPlugin {
+
+ GDCLASS(ShaderFileEditorPlugin, EditorPlugin);
+
+ ShaderFileEditor *shader_editor;
+ EditorNode *editor;
+ Button *button;
+
+public:
+ virtual String get_name() const { return "ShaderFile"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_object);
+ virtual bool handles(Object *p_object) const;
+ virtual void make_visible(bool p_visible);
+
+ ShaderFileEditor *get_shader_editor() const { return shader_editor; }
+
+ ShaderFileEditorPlugin(EditorNode *p_node);
+ ~ShaderFileEditorPlugin();
+};
+
+#endif // SHADER_FILE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp
index fbb6616dea..eb6e261305 100644
--- a/editor/plugins/style_box_editor_plugin.cpp
+++ b/editor/plugins/style_box_editor_plugin.cpp
@@ -45,7 +45,7 @@ void EditorInspectorPluginStyleBox::parse_begin(Object *p_object) {
preview->edit(sb);
add_custom_control(preview);
}
-bool EditorInspectorPluginStyleBox::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) {
+bool EditorInspectorPluginStyleBox::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
return false; //do not want
}
void EditorInspectorPluginStyleBox::parse_end() {
diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h
index f4a72d9d1c..1eea9260b2 100644
--- a/editor/plugins/style_box_editor_plugin.h
+++ b/editor/plugins/style_box_editor_plugin.h
@@ -62,7 +62,7 @@ class EditorInspectorPluginStyleBox : public EditorInspectorPlugin {
public:
virtual bool can_handle(Object *p_object);
virtual void parse_begin(Object *p_object);
- virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage);
+ virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false);
virtual void parse_end();
};
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index ce421ac0a5..9e88cd8889 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -57,17 +57,18 @@ void TileMapEditor::_notification(int p_what) {
} break;
+ case NOTIFICATION_ENTER_TREE: {
+
+ get_tree()->connect("node_removed", callable_mp(this, &TileMapEditor::_node_removed));
+ [[fallthrough]];
+ }
+
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
if (is_visible_in_tree()) {
_update_palette();
}
- [[fallthrough]];
- }
- case NOTIFICATION_ENTER_TREE: {
-
- get_tree()->connect("node_removed", callable_mp(this, &TileMapEditor::_node_removed));
paint_button->set_icon(get_theme_icon("Edit", "EditorIcons"));
bucket_fill_button->set_icon(get_theme_icon("Bucket", "EditorIcons"));
picker_button->set_icon(get_theme_icon("ColorPick", "EditorIcons"));
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 294ce2c4cd..d5128db0d5 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -2261,6 +2261,12 @@ void VisualShaderEditor::_show_preview_text() {
}
}
+static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) {
+
+ RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable);
+ return RS::global_variable_type_get_shader_datatype(gvt);
+}
+
void VisualShaderEditor::_update_preview() {
if (!preview_showed) {
@@ -2274,7 +2280,7 @@ void VisualShaderEditor::_update_preview() {
ShaderLanguage sl;
- Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types());
+ Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
for (int i = 0; i < preview_text->get_line_count(); i++) {
preview_text->set_line_as_marked(i, false);
@@ -3291,7 +3297,7 @@ void EditorInspectorShaderModePlugin::parse_begin(Object *p_object) {
//do none
}
-bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) {
+bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
if (p_path == "mode" && p_object->is_class("VisualShader") && p_type == Variant::INT) {
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 473c1bb070..a495b09b5c 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -338,7 +338,7 @@ class EditorInspectorShaderModePlugin : public EditorInspectorPlugin {
public:
virtual bool can_handle(Object *p_object);
virtual void parse_begin(Object *p_object);
- virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage);
+ virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false);
virtual void parse_end();
};
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 42493191a8..49c02dc895 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -2135,6 +2135,11 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
tab_container->add_child(autoload_settings);
autoload_settings->connect("autoload_changed", callable_mp(this, &ProjectSettingsEditor::_settings_changed));
+ shaders_global_variables_editor = memnew(ShaderGlobalsEditor);
+ shaders_global_variables_editor->set_name(TTR("Shader Globals"));
+ tab_container->add_child(shaders_global_variables_editor);
+ shaders_global_variables_editor->connect("globals_changed", callable_mp(this, &ProjectSettingsEditor::_settings_changed));
+
plugin_settings = memnew(EditorPluginSettings);
plugin_settings->set_name(TTR("Plugins"));
tab_container->add_child(plugin_settings);
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index 2cecb13198..5475bb5508 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -36,6 +36,7 @@
#include "editor/editor_data.h"
#include "editor/editor_plugin_settings.h"
#include "editor/editor_sectioned_inspector.h"
+#include "editor/shader_globals_editor.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/tab_container.h"
@@ -85,6 +86,7 @@ class ProjectSettingsEditor : public AcceptDialog {
OptionButton *device_index;
Label *device_index_label;
MenuButton *popup_copy_to_feature;
+ ShaderGlobalsEditor *shaders_global_variables_editor;
LineEdit *action_name;
Button *action_add;
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index a729f62123..4041256dd5 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -2867,6 +2867,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
edit_local->set_h_size_flags(SIZE_EXPAND_FILL);
edit_local->set_text(TTR("Local"));
edit_local->set_toggle_mode(true);
+ edit_local->set_pressed(true);
edit_local->connect("pressed", callable_mp(this, &SceneTreeDock::_local_tree_selected));
remote_tree = nullptr;
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 82199fc1f1..12b21d871b 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -689,6 +689,8 @@ void ScriptCreateDialog::_update_dialog() {
// Is Script created or loaded from existing file?
+ builtin_warning_label->set_visible(is_built_in);
+
if (is_built_in) {
get_ok()->set_text(TTR("Create"));
parent_name->set_editable(true);
@@ -756,6 +758,13 @@ ScriptCreateDialog::ScriptCreateDialog() {
path_error_label = memnew(Label);
vb->add_child(path_error_label);
+ builtin_warning_label = memnew(Label);
+ builtin_warning_label->set_text(
+ TTR("Note: Built-in scripts have some limitations and can't be edited using an external editor."));
+ vb->add_child(builtin_warning_label);
+ builtin_warning_label->set_autowrap(true);
+ builtin_warning_label->hide();
+
status_panel = memnew(PanelContainer);
status_panel->set_h_size_flags(Control::SIZE_FILL);
status_panel->add_child(vb);
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index f164cd2a15..63a30eba88 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -49,6 +49,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
LineEdit *class_name;
Label *error_label;
Label *path_error_label;
+ Label *builtin_warning_label;
PanelContainer *status_panel;
LineEdit *parent_name;
Button *parent_browse_button;
diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp
new file mode 100644
index 0000000000..566ac54612
--- /dev/null
+++ b/editor/shader_globals_editor.cpp
@@ -0,0 +1,452 @@
+#include "shader_globals_editor.h"
+#include "editor_node.h"
+
+static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = {
+ "bool",
+ "bvec2",
+ "bvec3",
+ "bvec4",
+ "int",
+ "ivec2",
+ "ivec3",
+ "ivec4",
+ "rect2i",
+ "uint",
+ "uvec2",
+ "uvec3",
+ "uvec4",
+ "float",
+ "vec2",
+ "vec3",
+ "vec4",
+ "color",
+ "rect2",
+ "mat2",
+ "mat3",
+ "mat4",
+ "transform_2d",
+ "transform",
+ "sampler2D",
+ "sampler2DArray",
+ "sampler3D",
+ "samplerCube",
+};
+
+class ShaderGlobalsEditorInterface : public Object {
+ GDCLASS(ShaderGlobalsEditorInterface, Object)
+
+ void _var_changed() {
+ emit_signal("var_changed");
+ }
+
+protected:
+ static void _bind_methods() {
+ ClassDB::bind_method("_var_changed", &ShaderGlobalsEditorInterface::_var_changed);
+ ADD_SIGNAL(MethodInfo("var_changed"));
+ }
+
+ bool _set(const StringName &p_name, const Variant &p_value) {
+ Variant existing = RS::get_singleton()->global_variable_get(p_name);
+
+ if (existing.get_type() == Variant::NIL) {
+ return false;
+ }
+
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
+
+ undo_redo->create_action("Set Shader Global Variable");
+ undo_redo->add_do_method(RS::get_singleton(), "global_variable_set", p_name, p_value);
+ undo_redo->add_undo_method(RS::get_singleton(), "global_variable_set", p_name, existing);
+ RS::GlobalVariableType type = RS::get_singleton()->global_variable_get_type(p_name);
+ Dictionary gv;
+ gv["type"] = global_var_type_names[type];
+ if (type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) {
+ RES res = p_value;
+ if (res.is_valid()) {
+ gv["value"] = res->get_path();
+ } else {
+ gv["value"] = "";
+ }
+ } else {
+ gv["value"] = p_value;
+ }
+
+ String path = "shader_globals/" + String(p_name);
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), path, gv);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), path, ProjectSettings::get_singleton()->get(path));
+ undo_redo->add_do_method(this, "_var_changed");
+ undo_redo->add_undo_method(this, "_var_changed");
+ block_update = true;
+ undo_redo->commit_action();
+ block_update = false;
+
+ print_line("all good?");
+ return true;
+ }
+
+ bool _get(const StringName &p_name, Variant &r_ret) const {
+ r_ret = RS::get_singleton()->global_variable_get(p_name);
+ return r_ret.get_type() != Variant::NIL;
+ }
+ void _get_property_list(List<PropertyInfo> *p_list) const {
+ Vector<StringName> variables;
+ variables = RS::get_singleton()->global_variable_get_list();
+ for (int i = 0; i < variables.size(); i++) {
+ PropertyInfo pinfo;
+ pinfo.name = variables[i];
+
+ switch (RS::get_singleton()->global_variable_get_type(variables[i])) {
+ case RS::GLOBAL_VAR_TYPE_BOOL: {
+ pinfo.type = Variant::BOOL;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC2: {
+ pinfo.type = Variant::INT;
+ pinfo.hint = PROPERTY_HINT_FLAGS;
+ pinfo.hint_string = "x,y";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC3: {
+ pinfo.type = Variant::INT;
+ pinfo.hint = PROPERTY_HINT_FLAGS;
+ pinfo.hint_string = "x,y,z";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC4: {
+ pinfo.type = Variant::INT;
+ pinfo.hint = PROPERTY_HINT_FLAGS;
+ pinfo.hint_string = "x,y,z,w";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_INT: {
+ pinfo.type = Variant::INT;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC2: {
+ pinfo.type = Variant::VECTOR2I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC3: {
+ pinfo.type = Variant::VECTOR3I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC4: {
+ pinfo.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_RECT2I: {
+ pinfo.type = Variant::RECT2I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UINT: {
+ pinfo.type = Variant::INT;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC2: {
+ pinfo.type = Variant::VECTOR2I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC3: {
+ pinfo.type = Variant::VECTOR3I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC4: {
+ pinfo.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_FLOAT: {
+ pinfo.type = Variant::FLOAT;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC2: {
+ pinfo.type = Variant::VECTOR2;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC3: {
+ pinfo.type = Variant::VECTOR3;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC4: {
+ pinfo.type = Variant::PLANE;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_RECT2: {
+ pinfo.type = Variant::RECT2;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_COLOR: {
+ pinfo.type = Variant::COLOR;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT2: {
+ pinfo.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT3: {
+ pinfo.type = Variant::BASIS;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {
+ pinfo.type = Variant::TRANSFORM2D;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
+ pinfo.type = Variant::TRANSFORM;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT4: {
+ pinfo.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2D: {
+ pinfo.type = Variant::OBJECT;
+ pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pinfo.hint_string = "Texture2D";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: {
+ pinfo.type = Variant::OBJECT;
+ pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pinfo.hint_string = "Texture2DArray";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER3D: {
+ pinfo.type = Variant::OBJECT;
+ pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pinfo.hint_string = "Texture3D";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: {
+ pinfo.type = Variant::OBJECT;
+ pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pinfo.hint_string = "Cubemap";
+ } break;
+ default: {
+
+ } break;
+ }
+
+ p_list->push_back(pinfo);
+ }
+ }
+
+public:
+ bool block_update = false;
+
+ ShaderGlobalsEditorInterface() {
+ }
+};
+
+static Variant create_var(RS::GlobalVariableType p_type) {
+ switch (p_type) {
+ case RS::GLOBAL_VAR_TYPE_BOOL: {
+ return false;
+ }
+ case RS::GLOBAL_VAR_TYPE_BVEC2: {
+ return 0; //bits
+ }
+ case RS::GLOBAL_VAR_TYPE_BVEC3: {
+ return 0; //bits
+ }
+ case RS::GLOBAL_VAR_TYPE_BVEC4: {
+ return 0; //bits
+ }
+ case RS::GLOBAL_VAR_TYPE_INT: {
+ return 0; //bits
+ }
+ case RS::GLOBAL_VAR_TYPE_IVEC2: {
+ return Vector2i();
+ }
+ case RS::GLOBAL_VAR_TYPE_IVEC3: {
+ return Vector3i();
+ }
+ case RS::GLOBAL_VAR_TYPE_IVEC4: {
+ Vector<int> v4;
+ v4.resize(4);
+ v4.write[0] = 0;
+ v4.write[1] = 0;
+ v4.write[2] = 0;
+ v4.write[3] = 0;
+ return v4;
+ }
+ case RS::GLOBAL_VAR_TYPE_RECT2I: {
+ return Rect2i();
+ }
+ case RS::GLOBAL_VAR_TYPE_UINT: {
+ return 0;
+ }
+ case RS::GLOBAL_VAR_TYPE_UVEC2: {
+ return Vector2i();
+ }
+ case RS::GLOBAL_VAR_TYPE_UVEC3: {
+ return Vector3i();
+ }
+ case RS::GLOBAL_VAR_TYPE_UVEC4: {
+ return Rect2i();
+ }
+ case RS::GLOBAL_VAR_TYPE_FLOAT: {
+ return 0.0;
+ }
+ case RS::GLOBAL_VAR_TYPE_VEC2: {
+ return Vector2();
+ }
+ case RS::GLOBAL_VAR_TYPE_VEC3: {
+ return Vector3();
+ }
+ case RS::GLOBAL_VAR_TYPE_VEC4: {
+ return Plane();
+ }
+ case RS::GLOBAL_VAR_TYPE_RECT2: {
+ return Rect2();
+ }
+ case RS::GLOBAL_VAR_TYPE_COLOR: {
+ return Color();
+ }
+ case RS::GLOBAL_VAR_TYPE_MAT2: {
+ Vector<real_t> xform;
+ xform.resize(4);
+ xform.write[0] = 1;
+ xform.write[1] = 0;
+ xform.write[2] = 0;
+ xform.write[3] = 1;
+ return xform;
+ }
+ case RS::GLOBAL_VAR_TYPE_MAT3: {
+ return Basis();
+ }
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {
+ return Transform2D();
+ }
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
+ return Transform();
+ }
+ case RS::GLOBAL_VAR_TYPE_MAT4: {
+ Vector<real_t> xform;
+ xform.resize(4);
+ xform.write[0] = 1;
+ xform.write[1] = 0;
+ xform.write[2] = 0;
+ xform.write[3] = 0;
+
+ xform.write[4] = 0;
+ xform.write[5] = 1;
+ xform.write[6] = 0;
+ xform.write[7] = 0;
+
+ xform.write[8] = 0;
+ xform.write[9] = 0;
+ xform.write[10] = 1;
+ xform.write[11] = 0;
+
+ xform.write[12] = 0;
+ xform.write[13] = 0;
+ xform.write[14] = 0;
+ xform.write[15] = 1;
+
+ return xform;
+ }
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2D: {
+ return "";
+ }
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: {
+ return "";
+ }
+ case RS::GLOBAL_VAR_TYPE_SAMPLER3D: {
+ return "";
+ }
+ case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: {
+ return "";
+ }
+ default: {
+ return Variant();
+ }
+ }
+}
+
+void ShaderGlobalsEditor::_variable_added() {
+
+ String var = variable_name->get_text().strip_edges();
+ if (var == "" || !var.is_valid_identifier()) {
+ EditorNode::get_singleton()->show_warning(TTR("Please specify a valid variable identifier name."));
+ return;
+ }
+
+ if (RenderingServer::get_singleton()->global_variable_get(var).get_type() != Variant::NIL) {
+ EditorNode::get_singleton()->show_warning(vformat(TTR("Global variable '%s' already exists'"), var));
+ return;
+ }
+
+ List<String> keywords;
+ ShaderLanguage::get_keyword_list(&keywords);
+
+ if (keywords.find(var) != nullptr || var == "script") {
+ EditorNode::get_singleton()->show_warning(vformat(TTR("Name '%s' is a reserved shader language keyword."), var));
+ return;
+ }
+
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
+
+ Variant value = create_var(RS::GlobalVariableType(variable_type->get_selected()));
+
+ undo_redo->create_action("Add Shader Global Variable");
+ undo_redo->add_do_method(RS::get_singleton(), "global_variable_add", var, RS::GlobalVariableType(variable_type->get_selected()), value);
+ undo_redo->add_undo_method(RS::get_singleton(), "global_variable_remove", var);
+ Dictionary gv;
+ gv["type"] = global_var_type_names[variable_type->get_selected()];
+ gv["value"] = value;
+
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + var, gv);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + var, Variant());
+ undo_redo->add_do_method(this, "_changed");
+ undo_redo->add_undo_method(this, "_changed");
+ undo_redo->commit_action();
+}
+
+void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) {
+
+ print_line("deleted " + p_variable);
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
+
+ undo_redo->create_action("Add Shader Global Variable");
+ undo_redo->add_do_method(RS::get_singleton(), "global_variable_remove", p_variable);
+ undo_redo->add_undo_method(RS::get_singleton(), "global_variable_add", p_variable, RS::get_singleton()->global_variable_get_type(p_variable), RS::get_singleton()->global_variable_get(p_variable));
+
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, Variant());
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, ProjectSettings::get_singleton()->get("shader_globals/" + p_variable));
+ undo_redo->add_do_method(this, "_changed");
+ undo_redo->add_undo_method(this, "_changed");
+ undo_redo->commit_action();
+}
+
+void ShaderGlobalsEditor::_changed() {
+ emit_signal("globals_changed");
+ if (!interface->block_update) {
+ interface->_change_notify();
+ }
+}
+
+void ShaderGlobalsEditor::_bind_methods() {
+ ClassDB::bind_method("_changed", &ShaderGlobalsEditor::_changed);
+ ADD_SIGNAL(MethodInfo("globals_changed"));
+}
+
+void ShaderGlobalsEditor::_notification(int p_what) {
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ if (is_visible_in_tree()) {
+ print_line("OK load settings in globalseditor");
+ inspector->edit(interface);
+ }
+ }
+}
+
+ShaderGlobalsEditor::ShaderGlobalsEditor() {
+
+ HBoxContainer *add_menu_hb = memnew(HBoxContainer);
+ add_child(add_menu_hb);
+
+ add_menu_hb->add_child(memnew(Label(TTR("Name:"))));
+ variable_name = memnew(LineEdit);
+ variable_name->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_menu_hb->add_child(variable_name);
+
+ add_menu_hb->add_child(memnew(Label(TTR("Type:"))));
+ variable_type = memnew(OptionButton);
+ variable_type->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_menu_hb->add_child(variable_type);
+
+ for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) {
+ variable_type->add_item(global_var_type_names[i]);
+ }
+
+ variable_add = memnew(Button(TTR("Add")));
+ add_menu_hb->add_child(variable_add);
+ variable_add->connect("pressed", callable_mp(this, &ShaderGlobalsEditor::_variable_added));
+
+ inspector = memnew(EditorInspector);
+ inspector->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(inspector);
+ inspector->set_use_wide_editors(true);
+ inspector->set_enable_capitalize_paths(false);
+ inspector->set_use_deletable_properties(true);
+ inspector->connect("property_deleted", callable_mp(this, &ShaderGlobalsEditor::_variable_deleted), varray(), CONNECT_DEFERRED);
+
+ interface = memnew(ShaderGlobalsEditorInterface);
+ interface->connect("var_changed", Callable(this, "_changed"));
+}
+ShaderGlobalsEditor::~ShaderGlobalsEditor() {
+ inspector->edit(NULL);
+ memdelete(interface);
+}
diff --git a/editor/shader_globals_editor.h b/editor/shader_globals_editor.h
new file mode 100644
index 0000000000..59cdeddd8d
--- /dev/null
+++ b/editor/shader_globals_editor.h
@@ -0,0 +1,38 @@
+#ifndef SHADER_GLOBALS_EDITOR_H
+#define SHADER_GLOBALS_EDITOR_H
+
+#include "core/undo_redo.h"
+#include "editor/editor_autoload_settings.h"
+#include "editor/editor_data.h"
+#include "editor/editor_plugin_settings.h"
+#include "editor/editor_sectioned_inspector.h"
+#include "scene/gui/dialogs.h"
+#include "scene/gui/tab_container.h"
+
+class ShaderGlobalsEditorInterface;
+
+class ShaderGlobalsEditor : public VBoxContainer {
+
+ GDCLASS(ShaderGlobalsEditor, VBoxContainer)
+
+ ShaderGlobalsEditorInterface *interface;
+ EditorInspector *inspector;
+
+ LineEdit *variable_name;
+ OptionButton *variable_type;
+ Button *variable_add;
+
+ void _variable_added();
+ void _variable_deleted(const String &p_variable);
+ void _changed();
+
+protected:
+ static void _bind_methods();
+ void _notification(int p_what);
+
+public:
+ ShaderGlobalsEditor();
+ ~ShaderGlobalsEditor();
+};
+
+#endif // SHADER_GLOBALS_EDITOR_H
diff --git a/editor/translations/af.po b/editor/translations/af.po
index 23afeb2e55..d9e1753c65 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -1505,7 +1505,7 @@ msgstr "Skuif AutoLaai"
msgid "Remove Autoload"
msgstr "Hernoem AutoLaai"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Aktiveer"
@@ -2974,7 +2974,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -4040,7 +4044,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6936,14 +6940,6 @@ msgid "Open Godot online documentation."
msgstr "Opnoemings"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7393,6 +7389,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7482,13 +7482,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10928,6 +10928,12 @@ msgid "Script file already exists."
msgstr "AutoLaai '%s' bestaan reeds!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Klas:"
@@ -12592,6 +12598,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 2cd523ec69..2ea1bd1dd5 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -33,12 +33,14 @@
# traveller010 <manar.bushnaq.001@gmail.com>, 2019.
# Ahmed Shahwan <dev.ahmed.shahwan@gmail.com>, 2019.
# hshw <shw@tutanota.com>, 2020.
+# Youssef Harmal <the.coder.crab@gmail.com>, 2020.
+# Nabeel20 <nabeelandnizam@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-01-16 22:23+0000\n"
-"Last-Translator: hshw <shw@tutanota.com>\n"
+"PO-Revision-Date: 2020-04-15 14:29+0000\n"
+"Last-Translator: Nabeel20 <nabeelandnizam@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
"Language: ar\n"
@@ -47,7 +49,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 3.10.2-dev\n"
+"X-Generator: Weblate 4.0-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -710,7 +712,7 @@ msgstr "رقم الخط:"
#: editor/code_editor.cpp
#, fuzzy
msgid "%d replaced."
-msgstr "إستبدال"
+msgstr "تم إستبدال %d"
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
@@ -747,7 +749,7 @@ msgstr "معياري"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
-msgstr ""
+msgstr "تحديد التبويب البرمجي"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
@@ -915,7 +917,7 @@ msgstr "هل أنت(ÙŠ) متأكد(Ø©) أنك تود إزالة كل الإتصØ
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
-msgstr "إشارات"
+msgstr "الإشارات"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
@@ -1225,9 +1227,8 @@ msgid "The following files failed extraction from package:"
msgstr "ÙØ´Ù„ استخراج Ø§Ù„Ù…Ù„ÙØ§Øª التالية من الحزمة:"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "And %s more files."
-msgstr "%d مزيد من Ø§Ù„Ù…Ù„ÙØ§Øª"
+msgstr "%s مزيد من Ø§Ù„Ù…Ù„ÙØ§Øª"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
@@ -1381,9 +1382,8 @@ msgid "Invalid file, not an audio bus layout."
msgstr "مل٠خطأ، ليس مل٠نسق بيوس الصوت."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Error saving file: %s"
-msgstr "خطأ ÙÙŠ Ø­ÙØ¸ مجموعة البلاط!"
+msgstr "خطأ !خطأ ÙÙŠ تسجيل الملÙ: s%"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
@@ -1469,7 +1469,7 @@ msgstr "نقل التحميل التلقائي"
msgid "Remove Autoload"
msgstr "ازالة التحميل التلقائي"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "تمكين"
@@ -1609,9 +1609,8 @@ msgstr ""
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Custom debug template not found."
-msgstr "مل٠النموذج غير موجود:"
+msgstr "نمودج تصحيح الأخطاء غير موجود."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -1628,9 +1627,8 @@ msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "3D Editor"
-msgstr "Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
+msgstr "معدل تلاثي الأبعاد"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1643,22 +1641,19 @@ msgstr "مكتبة الأصول"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
-msgstr ""
+msgstr "تعديل شجرة المشهد"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Import Dock"
-msgstr "إستيراد"
+msgstr "رصي٠الاستيراد"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
-msgstr "وضع التحريك"
+msgstr "رصي٠العقد"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem and Import Docks"
-msgstr "نظام Ø§Ù„Ù…Ù„ÙØ§Øª"
+msgstr "رصي٠نظام Ø§Ù„Ù…Ù„ÙØ§Øª Ùˆ الاستيراد"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -3010,8 +3005,13 @@ msgid "Q&A"
msgstr "الأسئلة و الأجوبة"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "متتبع الأخطاء"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "إعادة إستيراد"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4100,7 +4100,7 @@ msgid "Reimport"
msgstr "إعادة إستيراد"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7090,14 +7090,6 @@ msgid "Open Godot online documentation."
msgstr "ÙÙØªØ­ مؤخراً"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7552,6 +7544,10 @@ msgid "This operation requires a single selected node."
msgstr "هذه العملية تتطلب عقدة واحدة محددة."
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7642,13 +7638,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -9157,38 +9153,39 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
msgstr ""
+"ثابت E ويعادل القيمة (2.718282)ØŒ وهو يمثل الأساس ÙÙŠ اللوغاريتم الطبيعي."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Epsilon constant (0.00001). Smallest possible scalar number."
-msgstr ""
+msgstr "ثابت إيبسلون (0.00001)، أصغر الأعداد على الإطلاق."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Phi constant (1.618034). Golden ratio."
-msgstr ""
+msgstr "ثابت ÙØ§ÙŠ (1.618034)ØŒ ويمثل النسبة الذهبية ذاتها."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/4 constant (0.785398) or 45 degrees."
-msgstr ""
+msgstr "ثابت باي/4 (0.785398) أو 45 درجة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/2 constant (1.570796) or 90 degrees."
-msgstr ""
+msgstr "ثابت باي/2 (1.570796) أو 90 درجة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi constant (3.141593) or 180 degrees."
-msgstr ""
+msgstr "ثابت باي (3.141593) أو 180 درجة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Tau constant (6.283185) or 360 degrees."
-msgstr ""
+msgstr "ثابت تاو Tau وقيمته (6.283185) أو 360 درجة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Sqrt2 constant (1.414214). Square root of 2."
-msgstr ""
+msgstr "ثابت جذر-العدد2 (1.414214)، أي قيمة جذر العدد 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
-msgstr ""
+msgstr "يحسب القيمة المطلقة لقيمة المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
@@ -11166,6 +11163,12 @@ msgid "Script file already exists."
msgstr "التحميل التلقائي '%s' موجود اصلا!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "إسم صنÙ"
@@ -12859,6 +12862,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "مصدر غير صالح للمعاينة."
@@ -12887,6 +12894,9 @@ msgstr "يمكن تعيين المتغيرات Ùقط ÙÙŠ الذروة ."
msgid "Constants cannot be modified."
msgstr "لا يمكن تعديل الثوابت."
+#~ msgid "Issue Tracker"
+#~ msgstr "متتبع الأخطاء"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Ø¥Ø³ØªØ¨ÙØ¯Ù„ %d حادثة(حوادث)."
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 651776b6ab..1dcaf7fa32 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -6,14 +6,15 @@
# Иван Пенев (Ðдмирал ÐнимЕ) <aeternus.arcis@gmail.com>, 2016-2017.
# Любомир ВаÑилев <lyubomirv@abv.bg>, 2018, 2020.
# MaresPW <marespw206@gmail.com>, 2018.
-# PakoSt <kokotekilata@gmail.com>, 2018.
+# PakoSt <kokotekilata@gmail.com>, 2018, 2020.
# Damyan Dichev <mwshock2@gmail.com>, 2019.
+# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-02-28 13:33+0000\n"
-"Last-Translator: Любомир ВаÑилев <lyubomirv@abv.bg>\n"
+"PO-Revision-Date: 2020-03-27 15:42+0000\n"
+"Last-Translator: PakoSt <kokotekilata@gmail.com>\n"
"Language-Team: Bulgarian <https://hosted.weblate.org/projects/godot-engine/"
"godot/bg/>\n"
"Language: bg\n"
@@ -42,11 +43,12 @@ msgstr "ÐедоÑтатъчно байтове за разкодиране ил
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr ""
+msgstr "Ðеправилно въведени дани %i (не подаден) в израза"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
msgstr ""
+"self не може да Ñе ползва, тъй като инÑтанциÑта е null (не е била подадена)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -58,7 +60,7 @@ msgstr "Ðевалиден Ð¸Ð½Ð´ÐµÐºÑ Ð¾Ñ‚ тип %s за базов тип %s
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
-msgstr ""
+msgstr "Ðевалидно наименован Ð¸Ð½Ð´ÐµÐºÑ '%s' за базов тип %s"
#: core/math/expression.cpp
msgid "Invalid arguments to construct '%s'"
@@ -66,7 +68,7 @@ msgstr "Ðеправилни аргументи за Ñъздаване на „
#: core/math/expression.cpp
msgid "On call to '%s':"
-msgstr ""
+msgstr "При обаждане към '%s':"
#: core/ustring.cpp
msgid "B"
@@ -118,15 +120,15 @@ msgstr "СтойноÑÑ‚:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
-msgstr ""
+msgstr "Вмъкване на ключ тук"
#: editor/animation_bezier_editor.cpp
msgid "Duplicate Selected Key(s)"
-msgstr ""
+msgstr "Копиране на избран(и) ключ(ове)"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
-msgstr ""
+msgstr "Изтриване на избран(и) ключ(ове)"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
@@ -138,31 +140,31 @@ msgstr "ПремеÑтване на точки на Безие"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
-msgstr ""
+msgstr "Копиране на ключ(ове) (ÐнимациÑ)"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Delete Keys"
-msgstr ""
+msgstr "Изтриване на ключ(ове) (ÐнимациÑ)"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Time"
-msgstr ""
+msgstr "ПромÑна на момент на ключов кадър (ÐнимациÑ)"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transition"
-msgstr ""
+msgstr "ПромÑна на вид преход (ÐнимациÑ)"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transform"
-msgstr ""
+msgstr "ПромÑна на транÑÑ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ (ÐнимациÑ)"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Value"
-msgstr ""
+msgstr "ПромÑна на ÑтойноÑÑ‚ на ключов кадър (ÐнимациÑ)"
#: editor/animation_track_editor.cpp
msgid "Anim Change Call"
-msgstr ""
+msgstr "ПромÑна на повикана Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ (ÐнимациÑ)"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Time"
@@ -1417,7 +1419,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2821,7 +2823,12 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Повторно внаÑÑне"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3844,7 +3851,7 @@ msgid "Reimport"
msgstr "Повторно внаÑÑне"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6694,14 +6701,6 @@ msgid "Open Godot online documentation."
msgstr "ОтварÑне на документациÑта на Godot в Интернет."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7139,6 +7138,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7230,13 +7233,13 @@ msgid "Freelook Slow Modifier"
msgstr "Свободен Изглед Отпред"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10656,6 +10659,12 @@ msgid "Script file already exists."
msgstr "Група Ñ Ñ‚Ð¾Ð²Ð° име вече ÑъщеÑтвува."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "КлаÑ:"
@@ -12375,6 +12384,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 77ff28a113..b37267652e 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -1537,7 +1537,7 @@ msgstr "Autoload সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করà§à¦¨"
msgid "Remove Autoload"
msgstr "Autoload অপসারণ করà§à¦¨"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨"
@@ -3130,8 +3130,13 @@ msgid "Q&A"
msgstr "Q&A"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "ইসà§à¦¯à§ টà§à¦°à§à¦¯à¦¾à¦•ার"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "পà§à¦¨-ইমà§à¦ªà§‹à¦°à§à¦Ÿ"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4291,7 +4296,7 @@ msgid "Reimport"
msgstr "পà§à¦¨-ইমà§à¦ªà§‹à¦°à§à¦Ÿ"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7354,14 +7359,6 @@ msgid "Open Godot online documentation."
msgstr "রেফারেনà§à¦¸à§‡à¦° ডকà§à¦®à§‡à¦¨à§à¦Ÿà§‡à¦¶à¦¨à§‡ খà§à¦à¦œà§à¦¨à¥¤"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "রেফারেনà§à¦¸à§‡à¦° ডকà§à¦®à§‡à¦¨à§à¦Ÿà§‡à¦¶à¦¨à§‡ খà§à¦à¦œà§à¦¨à¥¤"
@@ -7836,6 +7833,11 @@ msgstr "à¦à¦‡ কাজটি করার জনà§à¦¯ à¦à¦•টি à¦à¦•ক
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "সমকোণীয় (Orthogonal)"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Lock View Rotation"
msgstr "তথà§à¦¯ দেখà§à¦¨"
@@ -7935,17 +7937,17 @@ msgid "Freelook Slow Modifier"
msgstr "ফà§à¦°à¦¿ লà§à¦• সà§à¦ªà¦¿à¦¡ মডিফায়ার"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "তথà§à¦¯ দেখà§à¦¨"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "তথà§à¦¯ দেখà§à¦¨"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XForm à¦à¦° সংলাপ"
@@ -11620,6 +11622,12 @@ msgid "Script file already exists."
msgstr "'%s' অà§à¦¯à¦¾à¦•শন ইতিমধà§à¦¯à§‡à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "কà§à¦²à¦¾à¦¸ নাম:"
@@ -13433,6 +13441,10 @@ msgstr ""
"আকার ধারণ করতে পারে। অনà§à¦¯à¦¥à¦¾à§Ÿ, à¦à¦Ÿà¦¿à¦•ে à¦à¦•টি RenderTarget করà§à¦¨ à¦à¦¬à¦‚ à¦à¦° অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ "
"দৃশà§à¦¯à¦¾à¦¬à¦²à¦¿à¦•ে (texture) দৃশà§à¦¯à¦®à¦¾à¦¨ করতে কোনো নোডে হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨à¥¤"
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -13464,6 +13476,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Issue Tracker"
+#~ msgstr "ইসà§à¦¯à§ টà§à¦°à§à¦¯à¦¾à¦•ার"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d সংখà§à¦¯à¦• সংঘটন পà§à¦°à¦¤à¦¿à¦¸à§à¦¥à¦¾à¦ªà¦¿à¦¤ হয়েছে ।"
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 304fa8905b..21886cea24 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -1452,7 +1452,7 @@ msgstr "Mou l'AutoCàrrega"
msgid "Remove Autoload"
msgstr "Treu Autocàrrega"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Activa"
@@ -2953,8 +2953,13 @@ msgid "Q&A"
msgstr "Preguntes i Respostes"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Seguiment d'Incidències"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "ReImportar"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4027,7 +4032,8 @@ msgid "Reimport"
msgstr "ReImportar"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Guardar escenes, reimportar i reiniciar"
#: editor/import_dock.cpp
@@ -6956,15 +6962,6 @@ msgid "Open Godot online documentation."
msgstr "Obrir la documentació en línia de Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Sol·licitar Documentació"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Ajudeu a millorar la documentació de Godot donant comentaris"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Cerca dins la documentació de referència."
@@ -7416,6 +7413,11 @@ msgid "This operation requires a single selected node."
msgstr "Aquesta operació requereix un únic node seleccionat."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Bloquejar Rotació de la Vista"
@@ -7507,6 +7509,10 @@ msgid "Freelook Slow Modifier"
msgstr "Modificador de la Velocitat de la Vista Lliure"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Rotació de la Vista Bloquejada"
+
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
@@ -7516,10 +7522,6 @@ msgstr ""
"No es pot utilitzar com una indicació fiable del rendiment en el joc."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Rotació de la Vista Bloquejada"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Diàleg XForm"
@@ -11209,6 +11211,12 @@ msgid "Script file already exists."
msgstr "L'Acció '%s' ja existeix!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Nom de Classe"
@@ -13063,6 +13071,10 @@ msgstr ""
"forma per tal d'obtenir-ne la mida. Altrament, establiu-la com a Destinació "
"de Renderització i assigneu-ne la textura interna a algun node."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -13093,6 +13105,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Les constants no es poden modificar."
+#~ msgid "Issue Tracker"
+#~ msgstr "Seguiment d'Incidències"
+
+#~ msgid "Request Docs"
+#~ msgstr "Sol·licitar Documentació"
+
+#, fuzzy
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Ajudeu a millorar la documentació de Godot donant comentaris"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d ocurrència/es reemplaçades."
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 595db1837f..887bbeb8f4 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -1455,7 +1455,7 @@ msgstr "Přemístit Autoload"
msgid "Remove Autoload"
msgstr "Odstranit Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Povolit"
@@ -2933,8 +2933,13 @@ msgid "Q&A"
msgstr "Otázky a odpovědi"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Sledování chyb"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Znovu importovat"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3972,7 +3977,7 @@ msgid "Reimport"
msgstr "Znovu importovat"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6828,14 +6833,6 @@ msgid "Open Godot online documentation."
msgstr "Otevřít online dokumentaci Godotu."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Požádat o dokumentaci"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Hledat v referenÄní dokumentaci."
@@ -7282,6 +7279,11 @@ msgstr "Tato operace vyžaduje jeden vybraný uzel."
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonální"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Lock View Rotation"
msgstr "Zobrazit informace"
@@ -7372,17 +7374,17 @@ msgid "Freelook Slow Modifier"
msgstr "Rychlost volného pohledu"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "Zobrazit informace"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "Zobrazit informace"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XForm Dialog"
@@ -10904,6 +10906,12 @@ msgid "Script file already exists."
msgstr "Soubor skriptu již existuje."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Jméno třídy:"
@@ -12648,6 +12656,10 @@ msgstr ""
"mohl získat velikost. Jinak ho nastavte jako render target a pÅ™iÅ™aÄte jeho "
"vnitřní texturu nějakému uzlu k zobrazení."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -12678,6 +12690,12 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanty není možné upravovat."
+#~ msgid "Issue Tracker"
+#~ msgstr "Sledování chyb"
+
+#~ msgid "Request Docs"
+#~ msgstr "Požádat o dokumentaci"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Nahrazeno %d výskytů."
diff --git a/editor/translations/da.po b/editor/translations/da.po
index 3d2c4cb48b..e582e4f3f9 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -1508,7 +1508,7 @@ msgstr "Flyt Autoload"
msgid "Remove Autoload"
msgstr "Fjern Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Aktivér"
@@ -3041,8 +3041,13 @@ msgid "Q&A"
msgstr "Spørgsmål og Svar"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Problem Tracker"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Genimporter"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4132,7 +4137,7 @@ msgid "Reimport"
msgstr "Genimporter"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7083,14 +7088,6 @@ msgid "Open Godot online documentation."
msgstr "Ã…ben Seneste"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7546,6 +7543,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7636,13 +7637,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -11161,6 +11162,12 @@ msgid "Script file already exists."
msgstr "Autoload '%s' eksisterer allerede!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Klasse:"
@@ -12917,6 +12924,10 @@ msgstr ""
"den kan opnå en størrelse. Ellers gør den til en RenderTarget og tildel dens "
"indre textur til en node så den kan vises."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -12948,6 +12959,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanter kan ikke ændres."
+#~ msgid "Issue Tracker"
+#~ msgstr "Problem Tracker"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Erstattede %d forekomst(er)."
diff --git a/editor/translations/de.po b/editor/translations/de.po
index 1520c3aa2a..dc12e814b0 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -1494,7 +1494,7 @@ msgstr "Autoload verschieben"
msgid "Remove Autoload"
msgstr "Autoload entfernen"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Aktivieren"
@@ -2992,8 +2992,13 @@ msgid "Q&A"
msgstr "Fragen & Antworten"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Problem-Melder"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Neuimport"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4051,7 +4056,8 @@ msgid "Reimport"
msgstr "Neuimport"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Szenen speichern, reimportieren und neu starten"
#: editor/import_dock.cpp
@@ -6920,15 +6926,6 @@ msgid "Open Godot online documentation."
msgstr "Godot-Onlinedokumentation öffnen."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Dokumentation anfragen"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-"Mithelfen die Godot-Dokumentation durch Meinungsäußerungen zu verbessern."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Durchsuche die Referenzdokumentation."
@@ -7368,6 +7365,11 @@ msgid "This operation requires a single selected node."
msgstr "Diese Aktion benötigt einen einzelnen ausgewählten Node."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Orthogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Sichtrotation sperren"
@@ -7456,6 +7458,10 @@ msgid "Freelook Slow Modifier"
msgstr "Freisicht Trägheitsregler"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Sichtrotation gesperrt"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7464,10 +7470,6 @@ msgstr ""
"Sie ist kein zuverlässiger Vergleichswert für die In-Spiel-Leistung."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Sichtrotation gesperrt"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Transformationsdialog"
@@ -10989,6 +10991,12 @@ msgid "Script file already exists."
msgstr "Skriptdatei existiert bereits."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Klassenname:"
@@ -12797,6 +12805,10 @@ msgstr ""
"Eigenschaft ‚Render Target‘ des Viewports aktiviert und seine Textur "
"irgendeinem Node zum Anzeigen zugewiesen werden."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Ungültige Quelle für Vorschau."
@@ -12825,6 +12837,16 @@ msgstr "Varyings können nur in Vertex-Funktion zugewiesen werden."
msgid "Constants cannot be modified."
msgstr "Konstanten können nicht verändert werden."
+#~ msgid "Issue Tracker"
+#~ msgstr "Problem-Melder"
+
+#~ msgid "Request Docs"
+#~ msgstr "Dokumentation anfragen"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr ""
+#~ "Mithelfen die Godot-Dokumentation durch Meinungsäußerungen zu verbessern."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Suchbegriff wurde %d mal ersetzt."
diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po
index 84e1dd1599..e17231a0dd 100644
--- a/editor/translations/de_CH.po
+++ b/editor/translations/de_CH.po
@@ -1458,7 +1458,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2918,7 +2918,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3992,7 +3996,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6925,14 +6929,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7378,6 +7374,10 @@ msgid "This operation requires a single selected node."
msgstr "Bitte nur ein Node selektieren."
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7468,13 +7468,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10962,6 +10962,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12667,6 +12673,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 232f6eb087..466aa8fa7f 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -1401,7 +1401,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2804,7 +2804,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3825,7 +3829,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6607,14 +6611,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7044,6 +7040,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7132,13 +7132,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10456,6 +10456,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12069,6 +12075,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index fb9029a861..2c8335393b 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-08 22:32+0000\n"
+"PO-Revision-Date: 2020-03-23 03:47+0000\n"
"Last-Translator: George Tsiamasiotis <gtsiam@windowslive.com>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/"
"el/>\n"
@@ -1451,7 +1451,7 @@ msgstr "Μετακίνηση AutoLoad"
msgid "Remove Autoload"
msgstr "ΑφαίÏεση AutoLoad"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "ΕνεÏγοποίηση"
@@ -2951,8 +2951,13 @@ msgid "Q&A"
msgstr "ΕÏωτήσεις & Απαντήσεις"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "ΔιαχείÏιση Ï€Ïοβλημάτων"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Επανεισαγωγή"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4013,7 +4018,8 @@ msgid "Reimport"
msgstr "Επανεισαγωγή"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Αποθήκευση σκηνών, επανεισαγωγή και επανεκκίνηση"
#: editor/import_dock.cpp
@@ -5992,9 +5998,8 @@ msgstr ""
"Είναι η πιο ακÏιβής (αλλά αÏγότεÏη) επιλογή για εντοπισμό σÏγκÏουσης."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
-msgstr "ΔημιουÏγία Μοναδικών ΚυÏτών Αδελφών ΣÏγκÏουσης"
+msgstr "ΔημιουÏγία ÎœÎ¿Î½Î±Î´Î¹ÎºÎ¿Ï ÎšÏ…ÏÏ„Î¿Ï Î‘Î´ÎµÎ»Ï†Î¿Ï Î£ÏγκÏουσης"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6889,14 +6894,6 @@ msgid "Open Godot online documentation."
msgstr "Άνοιγμα ηλεκτÏονικής τεκμηÏίωσης της Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Αίτηση ΤεκμηÏίωσης"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Βοηθήστε στην βελτίωση της τεκμηÏίωσης σχολιάζοντας."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Αναζήτηση στην τεκμηÏίωση αναφοÏάς."
@@ -7337,6 +7334,11 @@ msgid "This operation requires a single selected node."
msgstr "Αυτή η λειτουÏγία απαιτεί έναν μόνο επιλεγμένο κόμβο."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "ΑξονομετÏική"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Κλείδωμα ΠεÏιστÏοφής ΠÏοβολής"
@@ -7425,6 +7427,10 @@ msgid "Freelook Slow Modifier"
msgstr "ΑÏγός ΤÏοποποιητής ΕλεÏθεÏου Κοιτάγματος"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Κλείδωμα ΠεÏιστÏοφής"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7434,10 +7440,6 @@ msgstr ""
"παιχνιδιοÏ."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Κλείδωμα ΠεÏιστÏοφής"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Διάλογος XForm"
@@ -10949,6 +10951,12 @@ msgid "Script file already exists."
msgstr "ΥπαÏκτό αÏχείο δέσμης ενεÏγειών."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Όνομα Κλάσης:"
@@ -12446,6 +12454,8 @@ msgstr ""
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
msgstr ""
+"Το ConcavePolygonShape δεν υποστηÏίζει το RigidBody εκτός της static "
+"λειτουÏγίας."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
@@ -12749,6 +12759,10 @@ msgstr ""
"μέγεθος. Αλλιώς, κάντε το ένα RenderTarget και οÏίστε το internal texture σε "
"έναν κόμβο για απεικόνιση."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "ΆκυÏη πηγή για Ï€Ïοεπισκόπηση."
@@ -12777,6 +12791,15 @@ msgstr "Τα «varying» μποÏοÏν να ανατεθοÏν μόνο στηÎ
msgid "Constants cannot be modified."
msgstr "Οι σταθεÏές δεν μποÏοÏν να Ï„ÏοποποιηθοÏν."
+#~ msgid "Issue Tracker"
+#~ msgstr "ΔιαχείÏιση Ï€Ïοβλημάτων"
+
+#~ msgid "Request Docs"
+#~ msgstr "Αίτηση ΤεκμηÏίωσης"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Βοηθήστε στην βελτίωση της τεκμηÏίωσης σχολιάζοντας."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Αντικαταστάθηκαν %d εμφανίσεις."
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index cd84f54a40..7dc152659f 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -1439,7 +1439,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2895,7 +2895,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3929,7 +3933,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6727,15 +6731,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Helpi plibonigi la Godotan dokumentadon per doni reagon."
-
-#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "Search the reference documentation."
msgstr "Serĉi la referencan dokumentadon."
@@ -7167,6 +7162,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7255,13 +7254,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10606,6 +10605,12 @@ msgid "Script file already exists."
msgstr "Grupa nomo jam ekzistas."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Nomo:"
@@ -12237,6 +12242,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -12267,6 +12276,10 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#, fuzzy
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Helpi plibonigi la Godotan dokumentadon per doni reagon."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "AnstataÅ­igis %d apero(j)n."
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 3bbe96bcb3..c9ca261498 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -43,12 +43,15 @@
# Dario <darlex259@gmail.com>, 2019.
# Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2019.
# Julián Luini <jluini@gmail.com>, 2020.
+# anonymous <noreply@weblate.org>, 2020.
+# Victor S. <victorstancioiu@gmail.com>, 2020.
+# henry rujano herrera <rujhen@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-11 12:20+0000\n"
-"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
+"PO-Revision-Date: 2020-04-16 11:03+0000\n"
+"Last-Translator: anonymous <noreply@weblate.org>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -56,12 +59,13 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "Argumento de tipo inválido para convert(), utiliza constantes TYPE_*."
+msgstr ""
+"Tipo de argumento inválido para 'convert()', utiliza constantes TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -76,7 +80,7 @@ msgstr ""
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr "Entrada inválida %i (no pasó) en la expresión"
+msgstr "Entrada inválida %i (no se pasó) en la expresión"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
@@ -638,7 +642,7 @@ msgstr "Usar Curvas Bezier"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
-msgstr "Optimizar Animación"
+msgstr "Optimizador de Animación"
#: editor/animation_track_editor.cpp
msgid "Max. Linear Error:"
@@ -841,7 +845,7 @@ msgstr "Eliminar"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr "Añadir Argumento de Llamada Extra:"
+msgstr "Añadir un Argumento de Llamada Extra:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
@@ -1488,7 +1492,7 @@ msgstr "Mover Autoload"
msgid "Remove Autoload"
msgstr "Eliminar Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Activar"
@@ -2990,8 +2994,13 @@ msgid "Q&A"
msgstr "Preguntas y respuestas"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Registro de problemas"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Reimportar"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3003,7 +3012,7 @@ msgstr "Acerca de"
#: editor/editor_node.cpp
msgid "Play the project."
-msgstr "Reproducir el proyecto."
+msgstr "Ejecutar el proyecto."
#: editor/editor_node.cpp
msgid "Play"
@@ -4051,7 +4060,8 @@ msgid "Reimport"
msgstr "Reimportar"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Guardar escenas, reimportar y reiniciar"
#: editor/import_dock.cpp
@@ -5264,7 +5274,7 @@ msgid ""
"When active, moving Control nodes changes their anchors instead of their "
"margins."
msgstr ""
-"Cuando esté activo, los nodos de Control en movimiento cambian sus anclas en "
+"Cuando esté activo, moviendo los nodos de Control cambiará sus anclas en "
"lugar de sus márgenes."
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -6921,14 +6931,6 @@ msgid "Open Godot online documentation."
msgstr "Abrir la documentación en línea de Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Solicitar Documentos"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Ayuda a mejorar la documentación de Godot aportando retroalimentación."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Buscar en la documentación de referencia."
@@ -7365,6 +7367,11 @@ msgid "This operation requires a single selected node."
msgstr "Esta operación requiere un solo nodo seleccionado."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Bloquear Rotación de Vista"
@@ -7453,6 +7460,10 @@ msgid "Freelook Slow Modifier"
msgstr "Modificador de Velocidad de Vista Libre"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Bloquear Rotación de Vista"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7461,10 +7472,6 @@ msgstr ""
"No se puede utilizar como un indicador fiable del rendimiento en el juego."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Bloquear Rotación de Vista"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Diálogo XForm"
@@ -7823,7 +7830,7 @@ msgstr "Añadir Textura desde Archivo"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
-msgstr "Añadir Frames de un Sprite Sheet"
+msgstr "Añadir Frames desde un Sprite Sheet"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
@@ -8457,11 +8464,11 @@ msgstr "Editar Ãndice Z de Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Make Convex"
-msgstr "Crear Convexo"
+msgstr "Hacerlo Convexo"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Make Concave"
-msgstr "Crear Cóncavo"
+msgstr "Hacerlo Cóncavo"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create Collision Polygon"
@@ -9447,7 +9454,7 @@ msgstr "Editar Propiedad Visual"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Visual Shader Mode Changed"
-msgstr "Cambiar Modo de Visual Shader"
+msgstr "El Modo de Visual Shader ha cambiado"
#: editor/project_export.cpp
msgid "Runnable"
@@ -9518,7 +9525,7 @@ msgid ""
"Only one preset per platform may be marked as runnable."
msgstr ""
"Si se selecciona, la plantilla estará disponible para su uso en un "
-"despliegue con “un clickâ€.\n"
+"despliegue con un clic.\n"
"Sólo se puede marcar como ejecutable una plantilla por plataforma."
#: editor/project_export.cpp
@@ -10977,6 +10984,12 @@ msgid "Script file already exists."
msgstr "El archivo de script ya existe."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Nombre de Clase:"
@@ -11430,7 +11443,7 @@ msgstr "Eliminar Rotación del Cursor"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Paste Selects"
-msgstr "Pegar Seleccionados"
+msgstr "Pegar Selecciona"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Clear Selection"
@@ -12020,7 +12033,7 @@ msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
-"Intentando construir a partir de una plantilla personalizada, pero no existe "
+"Se intentó construir a partir de una plantilla personalizada, pero no existe "
"información de la versión para ello. Por favor, reinstala desde el menú "
"'Proyecto'."
@@ -12785,6 +12798,10 @@ msgstr ""
"bien, conviértalo en un RenderTarget y asigne su textura interna a algún "
"nodo para que se muestre."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fuente inválida para la vista previa."
@@ -12813,6 +12830,16 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
+#~ msgid "Issue Tracker"
+#~ msgstr "Registro de problemas"
+
+#~ msgid "Request Docs"
+#~ msgstr "Solicitar Documentos"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr ""
+#~ "Ayuda a mejorar la documentación de Godot aportando retroalimentación."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d ocurrencia(s) reemplazada(s)."
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 7781d59f34..7e7ed33aca 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -1457,7 +1457,7 @@ msgstr "Mover Autoload"
msgid "Remove Autoload"
msgstr "Quitar Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Activar"
@@ -2954,8 +2954,13 @@ msgid "Q&A"
msgstr "Q&A"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Registro de problemas"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Reimportar"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4015,7 +4020,8 @@ msgid "Reimport"
msgstr "Reimportar"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Guardar escenas, reimportar y reiniciar"
#: editor/import_dock.cpp
@@ -6881,14 +6887,6 @@ msgid "Open Godot online documentation."
msgstr "Abrir la documentación en línea de Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Solicitar Docum."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Ayudá a mejorar la documentación de Godot dando feedback."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Buscar en la documentación de referencia."
@@ -7325,6 +7323,11 @@ msgid "This operation requires a single selected node."
msgstr "Esta operación requiere un solo nodo seleccionado."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Trabar Rotación de Vista"
@@ -7413,6 +7416,10 @@ msgid "Freelook Slow Modifier"
msgstr "Modificador de Velocidad de Vista Libre"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Rotación de Vista Trabada"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7421,10 +7428,6 @@ msgstr ""
"No se puede utilizar como un indicador fiable del rendimiento en el juego."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Rotación de Vista Trabada"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Dialogo XForm"
@@ -10937,6 +10940,12 @@ msgid "Script file already exists."
msgstr "El archivo de script ya existe."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Nombre de Clase:"
@@ -12736,6 +12745,10 @@ msgstr ""
"pueda obtener un tamaño. Alternativamente, haz un RenderTarget y asigna su "
"textura interna a algún otro nodo para mostrar."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fuente inválida para la vista previa."
@@ -12764,6 +12777,15 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
+#~ msgid "Issue Tracker"
+#~ msgstr "Registro de problemas"
+
+#~ msgid "Request Docs"
+#~ msgstr "Solicitar Docum."
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Ayudá a mejorar la documentación de Godot dando feedback."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d ocurrencia(s) Reemplazadas."
diff --git a/editor/translations/et.po b/editor/translations/et.po
index 9b9d9b9137..6c052803e0 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -1409,7 +1409,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2816,7 +2816,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3838,7 +3842,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6626,14 +6630,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7064,6 +7060,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7152,13 +7152,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10481,6 +10481,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12100,6 +12106,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index 1075a4a046..49fb37e599 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -1406,7 +1406,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2809,7 +2809,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3830,7 +3834,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6612,14 +6616,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7049,6 +7045,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7137,13 +7137,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10461,6 +10461,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12074,6 +12080,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index caee80995e..f45393c505 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -10,7 +10,7 @@
# sayyed hamed nasib <cghamed752@chmail.ir>, 2017.
# Behrooz Kashani <bkashani@gmail.com>, 2018.
# Mahdi <sadisticwarlock@gmail.com>, 2018.
-# hpn33 <hamed.hpn332@gmail.com>, 2019.
+# hpn33 <hamed.hpn332@gmail.com>, 2019, 2020.
# Focus <saeeddashticlash@gmail.com>, 2019.
# anonymous <noreply@weblate.org>, 2020.
# mohamad por <mohamad24xx@gmail.com>, 2020.
@@ -18,8 +18,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-08 22:33+0000\n"
-"Last-Translator: mohamad por <mohamad24xx@gmail.com>\n"
+"PO-Revision-Date: 2020-04-09 07:52+0000\n"
+"Last-Translator: hpn33 <hamed.hpn332@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
@@ -31,10 +31,9 @@ msgstr ""
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
-#, fuzzy
msgid "Invalid type argument to convert(), use TYPE_* constants."
msgstr ""
-"نوع آرگومان برای متد ()convert ‌ نامعتبر است ،‌ از ثابت های *_TYPE‌ Ø§Ø³ØªÙØ§Ø¯Ù‡ "
+"نوع ورودی برای متد ()convert ‌ نامعتبر است ،‌ از ثابت های *_TYPE‌ Ø§Ø³ØªÙØ§Ø¯Ù‡ "
"کنید ."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
@@ -1497,7 +1496,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2984,7 +2983,12 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "وارد کردن دوباره"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -4071,7 +4075,7 @@ msgid "Reimport"
msgstr "وارد کردن دوباره"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7017,14 +7021,6 @@ msgid "Open Godot online documentation."
msgstr "شمارش ها"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7483,6 +7479,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Lock View Rotation"
msgstr "بومی‌سازی"
@@ -7578,17 +7578,17 @@ msgid "Freelook Slow Modifier"
msgstr "غلطاندن به پایین."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "بومی‌سازی"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "بومی‌سازی"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr ""
@@ -11119,6 +11119,12 @@ msgid "Script file already exists."
msgstr "پیش از این وجود داشته است"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "کلاس:"
@@ -12899,6 +12905,10 @@ msgstr ""
"تا بتواند یک اندازه بگیرد. در غیر اینصورت، آن را یک RenderTarget قرار دهید و "
"Ø¨Ø§ÙØª داخلی آن را برای نمایش به تعدادی گره تخصیص دهید."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index 2798d56d28..74bc461021 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -1444,7 +1444,7 @@ msgstr "Siirrä automaattisesti ladattavaa"
msgid "Remove Autoload"
msgstr "Poista automaattinen lataus"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Ota käyttöön"
@@ -2921,8 +2921,13 @@ msgid "Q&A"
msgstr "Kysymykset ja vastaukset"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Ilmoita viasta"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Tuo uudelleen"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3976,7 +3981,8 @@ msgid "Reimport"
msgstr "Tuo uudelleen"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Tallenna skenet, tuo uudelleen ja käynnistä uudelleen"
#: editor/import_dock.cpp
@@ -6836,14 +6842,6 @@ msgid "Open Godot online documentation."
msgstr "Avaa Godotin online-dokumentaatio."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Pyydä dokumentaatiota"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Auta parantamaan Godotin dokumentaatiota antamalla palautetta."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Etsi dokumentaatiosta."
@@ -7279,6 +7277,11 @@ msgid "This operation requires a single selected node."
msgstr "Tämä toiminto vaatii yhden valitun solmun."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonaalinen"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Lukitse näkymän kierto"
@@ -7367,6 +7370,10 @@ msgid "Freelook Slow Modifier"
msgstr "Liikkumisen hitauskerroin"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Näkymän kierto lukittu"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7375,10 +7382,6 @@ msgstr ""
"Sitä ei voi käyttää luotettavana pelin sisäisenä tehokkuuden ilmaisimena."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Näkymän kierto lukittu"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XForm-ikkuna"
@@ -10882,6 +10885,12 @@ msgid "Script file already exists."
msgstr "Skriptitiedosto on jo olemassa."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Luokan nimi:"
@@ -12661,6 +12670,10 @@ msgstr ""
"saada koon. Muutoin tee siitä RenderTarget ja aseta sen sisäinen tekstuuri "
"johonkin solmuun näkyväksi."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Virheellinen lähde esikatselulle."
@@ -12689,6 +12702,15 @@ msgstr "Varying tyypin voi sijoittaa vain vertex-funktiossa."
msgid "Constants cannot be modified."
msgstr "Vakioita ei voi muokata."
+#~ msgid "Issue Tracker"
+#~ msgstr "Ilmoita viasta"
+
+#~ msgid "Request Docs"
+#~ msgstr "Pyydä dokumentaatiota"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Auta parantamaan Godotin dokumentaatiota antamalla palautetta."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Korvattu %d osuvuutta."
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index 60445be723..5a1942fee5 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -1414,7 +1414,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2818,7 +2818,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3841,7 +3845,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6628,14 +6632,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7065,6 +7061,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7153,13 +7153,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10480,6 +10480,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12098,6 +12104,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 2c53fcb8e2..0844df8dc7 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -70,12 +70,14 @@
# Camille Mohr-Daurat <pouleyketchoup@gmail.com>, 2019.
# Pierre Stempin <pierre.stempin@gmail.com>, 2019.
# Pierre Caye <pierrecaye@laposte.net>, 2020.
+# Kevin Bouancheau <kevin.bouancheau@gmail.com>, 2020.
+# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-02-27 07:01+0000\n"
-"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n"
+"PO-Revision-Date: 2020-04-03 09:09+0000\n"
+"Last-Translator: anonymous <noreply@weblate.org>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -93,7 +95,7 @@ msgstr ""
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "Attendu chaîne de longueur 1 (un caractère)."
+msgstr "Une chaîne de caractères de longueur 1 est attendue (un caractère)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -1518,7 +1520,7 @@ msgstr "Déplacer l'AutoLoad"
msgid "Remove Autoload"
msgstr "Supprimer l'AutoLoad"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Activer"
@@ -3022,8 +3024,13 @@ msgid "Q&A"
msgstr "Questions et réponses"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Traqueur de problèmes"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Réimporter"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4085,7 +4092,8 @@ msgid "Reimport"
msgstr "Réimporter"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Sauvegarde des scènes, réimportation et redémarrage"
#: editor/import_dock.cpp
@@ -6966,14 +6974,6 @@ msgid "Open Godot online documentation."
msgstr "Ouvrir la documentation de Godot en ligne."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Demande de documentation"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Aider à améliorer la documentation de Godot en donnant vos réactions."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Rechercher dans la documentation de référence."
@@ -7413,6 +7413,11 @@ msgstr ""
"sélectionné."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Orthogonale"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Verrouiller la rotation de la vue"
@@ -7501,6 +7506,10 @@ msgid "Freelook Slow Modifier"
msgstr "Modificateur de vitesse de la vue libre"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Verrouiller la rotation de la vue"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7510,10 +7519,6 @@ msgstr ""
"jeu."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Verrouiller la rotation de la vue"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Dialogue XForm"
@@ -10496,7 +10501,7 @@ msgstr "Valeur par laquelle le compteur est incrémenté pour chaque nœud"
#: editor/rename_dialog.cpp
msgid "Padding"
-msgstr "Remplissage"
+msgstr "Remplissage(Padding)"
#: editor/rename_dialog.cpp
msgid ""
@@ -11034,6 +11039,12 @@ msgid "Script file already exists."
msgstr "Le fichier de script existe déjà."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Nom de la classe :"
@@ -12543,6 +12554,8 @@ msgstr ""
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
msgstr ""
+"ConcavePolygonShape ne supporte pas RigidBody dans un autre mode que le mode "
+"statique."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
@@ -12851,6 +12864,10 @@ msgstr ""
"nœud de type Control afin qu'il en obtienne une taille. Sinon, faites-en une "
"RenderTarget et assignez sa texture à un nœud pouvant l'afficher."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Source invalide pour la prévisualisation."
@@ -12879,6 +12896,16 @@ msgstr "Les variations ne peuvent être affectées que dans la fonction vertex."
msgid "Constants cannot be modified."
msgstr "Les constantes ne peuvent être modifiées."
+#~ msgid "Issue Tracker"
+#~ msgstr "Traqueur de problèmes"
+
+#~ msgid "Request Docs"
+#~ msgstr "Demande de documentation"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr ""
+#~ "Aider à améliorer la documentation de Godot en donnant vos réactions."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d occurrence(s) remplacée(s)."
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index e4e77fffc1..d40b50cd90 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -1408,7 +1408,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2812,7 +2812,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3836,7 +3840,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6621,14 +6625,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7058,6 +7054,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7146,13 +7146,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10476,6 +10476,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12095,6 +12101,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/he.po b/editor/translations/he.po
index 17e04827a0..1a82804b31 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -1489,7 +1489,7 @@ msgstr "הזזת טעינה ×וטומטית"
msgid "Remove Autoload"
msgstr "הסרת טעינה ×וטומטית"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "הפעלה"
@@ -2984,8 +2984,13 @@ msgid "Q&A"
msgstr "ש×לות ותשובות נפוצות"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "עוקב תקלות"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "×™×™×‘×•× ×ž×—×“×©"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4065,7 +4070,7 @@ msgid "Reimport"
msgstr "×™×™×‘×•× ×ž×—×“×©"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7009,14 +7014,6 @@ msgid "Open Godot online documentation."
msgstr "פתיחת התיעוד המקוון של Godot"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7477,6 +7474,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Lock View Rotation"
msgstr "הצגת מידע"
@@ -7567,17 +7568,17 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "הצגת מידע"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "הצגת מידע"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr ""
@@ -11086,6 +11087,12 @@ msgid "Script file already exists."
msgstr "הפעולה ‚%s’ כבר קיימת!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "מחלקה:"
@@ -12757,6 +12764,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -12788,6 +12799,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Issue Tracker"
+#~ msgstr "עוקב תקלות"
+
#~ msgid "enum "
#~ msgstr "מונה "
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index d043407257..75f29b8e0b 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -9,11 +9,14 @@
# Abhay Patel <abhay111patel@gmail.com>, 2019.
# Lakshmi-Jayakumar <lakshmi.jayakumar.tkm@gmail.com>, 2019.
# Devashishsingh98 <devashishsingh98@gmail.com>, 2019.
+# Shirious <sad3119823@gmail.com>, 2020.
+# anonymous <noreply@weblate.org>, 2020.
+# Abhay Patel <Traumaticbean@protonmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-01-30 03:56+0000\n"
+"PO-Revision-Date: 2020-04-03 09:50+0000\n"
"Last-Translator: Suryansh5545 <suryanshpathak5545@gmail.com>\n"
"Language-Team: Hindi <https://hosted.weblate.org/projects/godot-engine/godot/"
"hi/>\n"
@@ -22,7 +25,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.11-dev\n"
+"X-Generator: Weblate 4.0-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -31,17 +34,17 @@ msgstr "कनà¥à¤µà¤°à¥à¤Ÿ करने के लिठअमानà¥à¤¯ à
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "लंबाई 1 (à¤à¤• चरितà¥à¤°) की à¤à¤• सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग की उमà¥à¤®à¥€à¤¦ है।"
+msgstr "सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग की लंबाई 1 (1 अकà¥à¤·à¤°) अपेकà¥à¤·à¤¿à¤¤ है."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr "डिकोडिंग बाइट, या अमानà¥à¤¯ पà¥à¤°à¤¾à¤°à¥‚प के लिठपरà¥à¤¯à¤¾à¤ªà¥à¤¤ बाइट नहीं।"
+msgstr "अमानà¥à¤¯ फ़ोरà¥à¤®à¥ˆà¤Ÿ, या बाइटà¥à¤¸ डिकोडिंग के लिठपरà¥à¤¯à¤¾à¤ªà¥à¤¤ बाइटà¥à¤¸ नहीं।"
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr "अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ में अमानà¥à¤¯ इनपà¥à¤Ÿ%i (पारित नहीं)"
+msgstr "à¤à¤•à¥à¤¸à¤ªà¥à¤°à¥‡à¤¶à¤¨ मे अमानà¥à¤¯ इनपà¥à¤Ÿ %i (पास नहीं हो पाया)"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
@@ -105,7 +108,7 @@ msgstr "संतà¥à¤²à¤¿à¤¤"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
-msgstr "दरà¥à¤ªà¤£"
+msgstr "आइना"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
@@ -666,7 +669,7 @@ msgstr "ऑडियो टà¥à¤°à¥ˆà¤• कà¥à¤²à¤¿à¤ª à¤à¤‚ड ऑफसेà¤
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr "रीसाइज रीवà¥à¤¯à¥‚"
+msgstr "Array को बड़ा या छोटा करना"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
@@ -682,24 +685,23 @@ msgstr "लाइन पर जाà¤à¤‚"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr "लाइन नंबर:"
+msgstr "लाइन कà¥à¤°.:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "बदलने के"
+msgstr "%d बदले."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr "% d मैच।"
+msgstr "% d मिल गया।"
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d matches."
-msgstr "% डी मैच।"
+msgstr "%d मिल गया।"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
-msgstr "मैच मामला"
+msgstr "पूंजीकरण मेल करे"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Whole Words"
@@ -707,7 +709,7 @@ msgstr "पूरे शबà¥à¤¦"
#: editor/code_editor.cpp editor/rename_dialog.cpp
msgid "Replace"
-msgstr "बदलने के"
+msgstr "बदले"
#: editor/code_editor.cpp
msgid "Replace All"
@@ -715,7 +717,7 @@ msgstr "सबको बदली करें"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr "केवल चयन"
+msgstr "सिरà¥à¤« चयन किये हà¥à¤"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
@@ -748,40 +750,39 @@ msgstr "चेतावनियाà¤"
#: editor/code_editor.cpp
msgid "Line and column numbers."
-msgstr "लाइन और कॉलम नंबर।"
+msgstr "पंकà¥à¤¤à¤¿ और क़तार कà¥à¤°.।"
#: editor/connections_dialog.cpp
msgid "Method in target node must be specified."
-msgstr "लकà¥à¤·à¥à¤¯ नोड में विधि निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ की जानी चाहिà¤à¥¤"
+msgstr "Method को target node में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कीजिà¤."
#: editor/connections_dialog.cpp
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
-msgstr ""
-"लकà¥à¤·à¥à¤¯ विधि नहीं मिली। à¤à¤• मानà¥à¤¯ विधि निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ करें या सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ को लकà¥à¤·à¥à¤¯ नोड में संलगà¥à¤¨ करें।"
+msgstr "target node नहीं मिला। method उलà¥à¤²à¤¿à¤–ित करें या script जोड़िये।"
#: editor/connections_dialog.cpp
msgid "Connect to Node:"
-msgstr "नोड से कनेकà¥à¤Ÿ करें:"
+msgstr "Node से कनेकà¥à¤Ÿ करें:"
#: editor/connections_dialog.cpp
msgid "Connect to Script:"
-msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ से कनेकà¥à¤Ÿ:"
+msgstr "Script से कनेकà¥à¤Ÿ:"
#: editor/connections_dialog.cpp
msgid "From Signal:"
-msgstr "सिगà¥à¤¨à¤² से:"
+msgstr "Signal से:"
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
-msgstr "सीन में कोई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं होती।"
+msgstr "Scene में कोई script नहीं पाई गयी।"
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
msgid "Add"
-msgstr "जोड़ें"
+msgstr "जोड़िये"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
@@ -792,23 +793,23 @@ msgstr "जोड़ें"
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
-msgstr "मिटाना"
+msgstr "मिटाइये"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr "अतिरिकà¥à¤¤ कॉल तरà¥à¤• जोड़ें:"
+msgstr "अतिरिकà¥à¤¤ Call Argument अपेकà¥à¤·à¤¿à¤¤ है:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr "अतिरिकà¥à¤¤ कॉल तरà¥à¤•:"
+msgstr "अतिरिकà¥à¤¤ Call Arguments:"
#: editor/connections_dialog.cpp
msgid "Receiver Method:"
-msgstr "रिसीवर विधि:"
+msgstr "पानेवाली Method:"
#: editor/connections_dialog.cpp
msgid "Advanced"
-msgstr "उनà¥à¤¨à¤¤"
+msgstr "अगà¥à¤°à¤µà¤°à¥à¤¤à¥€"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -818,20 +819,20 @@ msgstr "सà¥à¤¥à¤—ित"
msgid ""
"Defers the signal, storing it in a queue and only firing it at idle time."
msgstr ""
-"संकेत को सà¥à¤¥à¤—ित कर देता है, इसे à¤à¤• कतार में संगà¥à¤°à¤¹à¤¿à¤¤ करता है और केवल निषà¥à¤•à¥à¤°à¤¿à¤¯ समय पर इसे "
+"इशारा को सà¥à¤¥à¤—ित कर देता है, इसे à¤à¤• कतार में संगà¥à¤°à¤¹à¤¿à¤¤ करता है और केवल निषà¥à¤•à¥à¤°à¤¿à¤¯ समय पर इसे "
"फायरिंग करता है।"
#: editor/connections_dialog.cpp
msgid "Oneshot"
-msgstr "वनशॉट"
+msgstr "à¤à¤• बार"
#: editor/connections_dialog.cpp
msgid "Disconnects the signal after its first emission."
-msgstr "अपने पहले उतà¥à¤¸à¤°à¥à¤œà¤¨ के बाद संकेत डिसà¥à¤•नेकà¥à¤Ÿ करता है।"
+msgstr "इसके पहले उतà¥à¤¸à¤°à¥à¤œà¤¨ के बाद सिगà¥à¤¨à¤² को डिसà¥à¤•नेकà¥à¤Ÿ करें"
#: editor/connections_dialog.cpp
msgid "Cannot connect signal"
-msgstr "सिगà¥à¤¨à¤² कनेकà¥à¤Ÿ नहीं कर सकते"
+msgstr "इशारा कनेकà¥à¤Ÿ नहीं कर सकते"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/export_template_manager.cpp editor/groups_editor.cpp
@@ -850,11 +851,11 @@ msgstr "बंद करे"
#: editor/connections_dialog.cpp
msgid "Connect"
-msgstr "जोड़ना"
+msgstr "जोड़िये"
#: editor/connections_dialog.cpp
msgid "Signal:"
-msgstr "संकेत:"
+msgstr "इशारा:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -862,11 +863,11 @@ msgstr "'%' को '%' से कनेकà¥à¤Ÿ करें"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
-msgstr "'%' से डिसà¥à¤•नेकà¥à¤Ÿ करें '%'"
+msgstr "'%' से '%' को डिसà¥à¤•नेकà¥à¤Ÿ करें"
#: editor/connections_dialog.cpp
msgid "Disconnect all from signal: '%s'"
-msgstr "सभी को सिगà¥à¤¨à¤² से डिसà¥à¤•नेकà¥à¤Ÿ करें: '%s'"
+msgstr "सभी इशारो से डिसà¥à¤•नेकà¥à¤Ÿ करें: '%s'"
#: editor/connections_dialog.cpp
msgid "Connect..."
@@ -875,15 +876,15 @@ msgstr "जोड़ना..."
#: editor/connections_dialog.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Disconnect"
-msgstr "डिसà¥à¤•नेकà¥à¤Ÿ"
+msgstr "विलगन"
#: editor/connections_dialog.cpp
msgid "Connect a Signal to a Method"
-msgstr "à¤à¤• विधि के लिठà¤à¤• संकेत कनेकà¥à¤Ÿ"
+msgstr "method इशारे से जोड़िà¤"
#: editor/connections_dialog.cpp
msgid "Edit Connection:"
-msgstr "संपादित करें कनेकà¥à¤¶à¤¨:"
+msgstr "कनेकà¥à¤¶à¤¨ संपादित करें:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
@@ -903,19 +904,19 @@ msgstr "सभी को डिसà¥à¤•नेकà¥à¤Ÿ करें"
#: editor/connections_dialog.cpp
msgid "Edit..."
-msgstr "संपादित..."
+msgstr "संपादित करें..."
#: editor/connections_dialog.cpp
msgid "Go To Method"
-msgstr ""
+msgstr "मेथड पे जाये"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr ""
+msgstr "%s का टाइप बदले"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
msgid "Change"
-msgstr "परिवरà¥à¤¤à¤¨"
+msgstr "बदली"
#: editor/create_dialog.cpp
msgid "Create New %s"
@@ -1196,11 +1197,11 @@ msgstr "असंपीड़ित संपतà¥à¤¤à¤¿à¤¯à¤¾à¤‚"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "The following files failed extraction from package:"
-msgstr ""
+msgstr "निमà¥à¤¨ फ़ाइलों का निसà¥à¤¸à¤¾à¤°à¤£ नहीं हो पाया:"
#: editor/editor_asset_installer.cpp
msgid "And %s more files."
-msgstr ""
+msgstr "और %s फ़ाइलें."
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
@@ -1213,7 +1214,7 @@ msgstr "सफलता!"
#: editor/editor_asset_installer.cpp
msgid "Package Contents:"
-msgstr "पैकेज सामगà¥à¤°à¥€:"
+msgstr "पैकेज में है:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1273,7 +1274,7 @@ msgstr "पà¥à¤¨à¤°à¥à¤µà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ करने के लिà¤
#: editor/editor_audio_buses.cpp
msgid "Solo"
-msgstr "à¤à¤•ल"
+msgstr "सोलो"
#: editor/editor_audio_buses.cpp
msgid "Mute"
@@ -1298,7 +1299,7 @@ msgstr "वॉलà¥à¤¯à¥‚म रीसेट करें"
#: editor/editor_audio_buses.cpp
msgid "Delete Effect"
-msgstr "डिलीट इफेकà¥à¤Ÿ"
+msgstr "इफेकà¥à¤Ÿ मिटाइये"
#: editor/editor_audio_buses.cpp
msgid "Audio"
@@ -1306,31 +1307,31 @@ msgstr "ऑडियो"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
-msgstr ""
+msgstr "ऑडियो बस à¤à¤¡ कीजिà¤"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr ""
+msgstr "मासà¥à¤Ÿà¤° बस नहीं मिटा सकते!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr ""
+msgstr "ऑडियो बस मिटाइये"
#: editor/editor_audio_buses.cpp
msgid "Duplicate Audio Bus"
-msgstr ""
+msgstr "ऑडियो बस दà¥à¤—à¥à¤¨à¤¾ करे"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
-msgstr ""
+msgstr "बस की धà¥à¤µà¤¨à¤¿ मातà¥à¤°à¤¾ पूरà¥à¤µà¤°à¥‚प करे"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
-msgstr ""
+msgstr "ऑडियो बस हटाइये"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr ""
+msgstr "ऑडियो बस लेआउट इस तरह बचा के रखिये..."
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
@@ -1338,113 +1339,113 @@ msgstr "नठलेआउट के लिठसà¥à¤¥à¤¾à¤¨..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr ""
+msgstr "ऑडियो बस लेआउट खोलिये"
#: editor/editor_audio_buses.cpp
msgid "There is no '%s' file."
-msgstr ""
+msgstr "कोई '%s' फ़ाइल नहीं."
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
msgid "Layout"
-msgstr ""
+msgstr "लेआउट"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
-msgstr ""
+msgstr "अमानà¥à¤¯ फ़ाइल, ऑडियो बस लेआउट."
#: editor/editor_audio_buses.cpp
msgid "Error saving file: %s"
-msgstr "तà¥à¤°à¥à¤Ÿà¤¿ बचत फ़ाइल: %s"
+msgstr "फ़ाइल बचाने में चूक: %s"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
-msgstr ""
+msgstr "बस à¤à¤¡ कीजिà¤"
#: editor/editor_audio_buses.cpp
msgid "Add a new Audio Bus to this layout."
-msgstr ""
+msgstr "लेआउट में नई ऑडियो बस à¤à¤¡ कीजिà¤."
#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
#: editor/script_create_dialog.cpp
msgid "Load"
-msgstr ""
+msgstr "लोड कीजिये"
#: editor/editor_audio_buses.cpp
msgid "Load an existing Bus Layout."
-msgstr ""
+msgstr "मौजूदा बस लेआउट लोड कीजिये."
#: editor/editor_audio_buses.cpp
msgid "Save As"
-msgstr ""
+msgstr "इस तरह बचा के रखिये"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr ""
+msgstr "बस लेआउट को फ़ाइल में बचा के रखिये."
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
-msgstr ""
+msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤• लोड कीजिये"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr ""
+msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤• बस लेआउट लोड कीजिये."
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
-msgstr ""
+msgstr "नई बस लेआउट बनाइये."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
-msgstr ""
+msgstr "अमानà¥à¤¯ नाम."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
-msgstr ""
+msgstr "मानà¥à¤¯ अकà¥à¤·à¤°:"
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing engine class name."
-msgstr ""
+msgstr "मौजूदा कà¥à¤²à¤¾à¤¸ इंजन नाम से मेल नहीं खाना चाहिà¤."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing built-in type name."
-msgstr ""
+msgstr "मौजूदा बिलà¥à¤Ÿ-इन टाइप के नाम से मेल नहीं खाना चाहिà¤."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing global constant name."
-msgstr ""
+msgstr "मौजूदा गà¥à¤²à¥‹à¤¬à¤² कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ के नाम से मेल नहीं खाना चाहिà¤."
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
-msgstr ""
+msgstr "कीवरà¥à¤¡ को औटोलोड नाम के तरह नहीं इसà¥à¤¤à¥‡à¤®à¤¾à¤² कर सकते."
#: editor/editor_autoload_settings.cpp
msgid "Autoload '%s' already exists!"
-msgstr ""
+msgstr "औटोलोड '%s' पहले से मौजूद!"
#: editor/editor_autoload_settings.cpp
msgid "Rename Autoload"
-msgstr ""
+msgstr "औटोलोड का नाम बदली कीजिये"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
-msgstr ""
+msgstr "औटोलोड गà¥à¤²à¥‹à¤¬à¤² टॉगल कीजिये"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
-msgstr ""
+msgstr "औटोलोड हिलाइये"
#: editor/editor_autoload_settings.cpp
msgid "Remove Autoload"
-msgstr ""
+msgstr "औटोलोड हटा दीजिये"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
-msgstr ""
+msgstr "सकà¥à¤°à¤¿à¤¯ करे"
#: editor/editor_autoload_settings.cpp
msgid "Rearrange Autoloads"
-msgstr ""
+msgstr "औटोलोड पà¥à¤¨à¤°à¥à¤µà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ करें"
#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
msgid "Invalid path."
@@ -1452,114 +1453,118 @@ msgstr "अमानà¥à¤¯ रासà¥à¤¤à¤¾à¥¤"
#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
msgid "File does not exist."
-msgstr ""
+msgstr "फ़ाइल नहीं मौजूद."
#: editor/editor_autoload_settings.cpp
msgid "Not in resource path."
-msgstr ""
+msgstr "रेसोरà¥à¤¸ पाथ में नहीं."
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
-msgstr ""
+msgstr "औटोलोड à¤à¤¡ कीजिà¤"
#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp
msgid "Path:"
-msgstr ""
+msgstr "पाथ:"
#: editor/editor_autoload_settings.cpp
msgid "Node Name:"
-msgstr ""
+msgstr "नोड का नाम:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
#: editor/editor_profiler.cpp editor/project_manager.cpp
#: editor/settings_config_dialog.cpp
msgid "Name"
-msgstr ""
+msgstr "नाम"
#: editor/editor_autoload_settings.cpp
msgid "Singleton"
-msgstr ""
+msgstr "सिनà¥à¤—लटन"
#: editor/editor_data.cpp editor/inspector_dock.cpp
msgid "Paste Params"
-msgstr ""
+msgstr "पैरैमिटरà¥à¤¸ पेसà¥à¤Ÿ कीजिये"
#: editor/editor_data.cpp
msgid "Updating Scene"
-msgstr ""
+msgstr "सीन अपडेट कर रहा है"
#: editor/editor_data.cpp
msgid "Storing local changes..."
-msgstr ""
+msgstr "लोकल बदलीया सà¥à¤Ÿà¥‹à¤° कर रहा है..."
#: editor/editor_data.cpp
msgid "Updating scene..."
-msgstr ""
+msgstr "सीन अपडेट कर रहा है..."
#: editor/editor_data.cpp editor/editor_properties.cpp
msgid "[empty]"
-msgstr ""
+msgstr "[खाली]"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr ""
+msgstr "[अनसेवà¥à¤¡]"
#: editor/editor_dir_dialog.cpp
msgid "Please select a base directory first."
-msgstr ""
+msgstr "कृपया पहले बेस डायरेकà¥à¤Ÿà¤°à¥€ सिलेकà¥à¤Ÿ कीजिये."
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
-msgstr ""
+msgstr "डायरेकà¥à¤Ÿà¤°à¥€ चà¥à¤¨à¥‡à¤‚"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
#: scene/gui/file_dialog.cpp
msgid "Create Folder"
-msgstr ""
+msgstr "फ़ोलà¥à¤¡à¤° बनाइये"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp
msgid "Name:"
-msgstr ""
+msgstr "नाम:"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
msgid "Could not create folder."
-msgstr ""
+msgstr "फ़ोलà¥à¤¡à¤° नही बना सकते."
#: editor/editor_dir_dialog.cpp
msgid "Choose"
-msgstr ""
+msgstr "चà¥à¤¨à¥‡à¤‚"
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr ""
+msgstr "फ़ाइल सà¥à¤Ÿà¥‹à¤° कर रहा है:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
-msgstr ""
+msgstr "निशà¥à¤šà¤¿à¤¤ पाथ पर â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ नहीं मिला:"
#: editor/editor_export.cpp
msgid "Packing"
-msgstr ""
+msgstr "पैक कर रहा है"
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
"Etc' in Project Settings."
msgstr ""
+"GLES2 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. 'Import Etc' "
+"को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' texture compression for GLES3. Enable "
"'Import Etc 2' in Project Settings."
msgstr ""
+"GLES3 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC2' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. 'Import Etc "
+"2' को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे."
#: editor/editor_export.cpp
msgid ""
@@ -1568,364 +1573,361 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"GLES2 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. \n"
+"'Import Etc' को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे, या 'Driver Fallback Enabled' को "
+"निषà¥à¤•à¥à¤°à¤¿à¤¯ करे."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
msgid "Custom debug template not found."
-msgstr ""
+msgstr "कसà¥à¤Ÿà¤® डिबग टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ नहीं मिला."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
msgid "Custom release template not found."
-msgstr ""
+msgstr "कसà¥à¤Ÿà¤® रिलिज टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ नहीं मिला."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
-msgstr ""
+msgstr "टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ फ़ाइल नहीं मिला:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "32-बिट â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ पर à¤à¤®à¤¬à¥‡à¤¡à¥à¤¡à¥‡à¤¡ PCK 4 GiB से बड़ी नहीं इसà¥à¤¤à¥‡à¤®à¤¾à¤² कर सकते."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
msgstr "3D संपादक"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Script Editor"
-msgstr "निरà¥à¤­à¤°à¤¤à¤¾ संपादक"
+msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ à¤à¤¡à¥€à¤Ÿà¤°"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr ""
+msgstr "असà¥à¤¸à¥‡à¤Ÿ संगà¥à¤°à¤¹"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
-msgstr ""
+msgstr "सीन टà¥à¤°à¥€ à¤à¤¡à¤¿à¤Ÿà¤¿à¤‚ग"
#: editor/editor_feature_profile.cpp
msgid "Import Dock"
-msgstr ""
+msgstr "इंपोरà¥à¤Ÿ डॉक"
#: editor/editor_feature_profile.cpp
msgid "Node Dock"
-msgstr ""
+msgstr "नोड डॉक"
#: editor/editor_feature_profile.cpp
msgid "FileSystem and Import Docks"
-msgstr ""
+msgstr "फाइलसिसà¥à¤Ÿà¥‡à¤® और इंपोरà¥à¤Ÿ डोकà¥à¤¸"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
-msgstr ""
+msgstr "पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² '%s' को मिटाà¤à¤‚? (इसे अंडू नहीं किया जा सकता है)"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
-msgstr ""
+msgstr "पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² का à¤à¤• वैध फ़ाइलनेम होना चाहिठऔर उसमे '.' नहीं होना चाहिà¤"
#: editor/editor_feature_profile.cpp
msgid "Profile with this name already exists."
-msgstr ""
+msgstr "इस नाम का पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² पहले से मौजूद है।"
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled, Properties Disabled)"
-msgstr ""
+msgstr "(à¤à¤¡à¥€à¤Ÿà¤° निषà¥à¤•à¥à¤°à¤¿à¤¯,पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ निषà¥à¤•à¥à¤°à¤¿à¤¯)"
#: editor/editor_feature_profile.cpp
msgid "(Properties Disabled)"
-msgstr ""
+msgstr "(पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ निषà¥à¤•à¥à¤°à¤¿à¤¯)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Editor Disabled)"
-msgstr "बंद कर दिया गया है"
+msgstr "(à¤à¤¡à¥€à¤Ÿà¤° निषà¥à¤•à¥à¤°à¤¿à¤¯)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options:"
-msgstr "विवरण:"
+msgstr "कà¥à¤²à¤¾à¤¸ विकलà¥à¤ª:"
#: editor/editor_feature_profile.cpp
msgid "Enable Contextual Editor"
-msgstr ""
+msgstr "कोनà¥à¤Ÿà¥‡à¤•à¥à¤¸à¤šà¥à¤…ल à¤à¤¡à¥€à¤Ÿà¤° सकà¥à¤°à¤¿à¤¯ करे"
#: editor/editor_feature_profile.cpp
msgid "Enabled Properties:"
-msgstr ""
+msgstr "सकà¥à¤°à¤¿à¤¯ पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Features:"
-msgstr ""
+msgstr "सकà¥à¤°à¤¿à¤¯ फ़िचरà¥à¤¸:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Classes:"
-msgstr ""
+msgstr "सकà¥à¤°à¤¿à¤¯ कà¥à¤²à¤¾à¤¸:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
-msgstr ""
+msgstr "'%s' फ़ोरà¥à¤®à¥ˆà¤Ÿ की फ़ाइल अमानà¥à¤¯, इंपोरà¥à¤Ÿ रोका गया."
#: editor/editor_feature_profile.cpp
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
-msgstr ""
+msgstr "'%s' पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² पहले से मौजूद. इंपोरà¥à¤Ÿ से पहले हटा दीजिये, इंपोरà¥à¤Ÿ रोका गया."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Error saving profile to path: '%s'."
-msgstr "लोड हो रहा है तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤!"
+msgstr "पाथ मे पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² सेव करनेमे à¤à¤°à¤°: '%s'."
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "अनà¥à¤¸à¥‡à¤Ÿ"
#: editor/editor_feature_profile.cpp
msgid "Current Profile:"
-msgstr ""
+msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
-msgstr ""
+msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ बनाय"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/version_control_editor_plugin.cpp
msgid "New"
-msgstr ""
+msgstr "नई"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
msgid "Import"
-msgstr ""
+msgstr "इंपोरà¥à¤Ÿ"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
-msgstr ""
+msgstr "â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ"
#: editor/editor_feature_profile.cpp
msgid "Available Profiles:"
-msgstr ""
+msgstr "उपलबà¥à¤§ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options"
-msgstr "विवरण:"
+msgstr "कà¥à¤²à¤¾à¤¸ विकलà¥à¤ª"
#: editor/editor_feature_profile.cpp
msgid "New profile name:"
-msgstr ""
+msgstr "नया पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² नाम:"
#: editor/editor_feature_profile.cpp
msgid "Erase Profile"
-msgstr ""
+msgstr "पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² मिटाय"
#: editor/editor_feature_profile.cpp
msgid "Godot Feature Profile"
-msgstr ""
+msgstr "Godot फ़िचर पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²"
#: editor/editor_feature_profile.cpp
msgid "Import Profile(s)"
-msgstr ""
+msgstr "इंपोरà¥à¤Ÿ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²"
#: editor/editor_feature_profile.cpp
msgid "Export Profile"
-msgstr ""
+msgstr "â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²"
#: editor/editor_feature_profile.cpp
msgid "Manage Editor Feature Profiles"
-msgstr ""
+msgstr "à¤à¤¡à¥€à¤Ÿà¤° फ़िचर पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾ कीजिये"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
-msgstr ""
+msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ फ़ोलà¥à¤¡à¤° सिलेकà¥à¤Ÿ कीजिये"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File Exists, Overwrite?"
-msgstr ""
+msgstr "फ़ाइल पहले से मौजूद, मौजूदा के ऊपर लिखे?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select This Folder"
-msgstr ""
+msgstr "यह फ़ोलà¥à¤¡à¤° सिलेकà¥à¤Ÿ कीजिये"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr ""
+msgstr "पाथ कौपी कीजिये"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open in File Manager"
-msgstr "खोलो इसे"
+msgstr "फ़ाइल मैनेजर में खोलिये"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
msgid "Show in File Manager"
-msgstr ""
+msgstr "फ़ाइल मैनेजर मे दिखाइà¤"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "New Folder..."
-msgstr ""
+msgstr "नया फ़ोलà¥à¤¡à¤°..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
-msgstr ""
+msgstr "रिफ़à¥à¤°à¥‡à¤¶"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
-msgstr ""
+msgstr "सभी सà¥à¤µà¥€à¤•ृत"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
-msgstr ""
+msgstr "सभी फ़ाइल (*)"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File"
-msgstr ""
+msgstr "फ़ाइल खोलिये"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open File(s)"
-msgstr ""
+msgstr "फ़ाइल(s) खोलिये"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a Directory"
-msgstr ""
+msgstr "डायरेकà¥à¤Ÿà¤°à¥€ खोलिये"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File or Directory"
-msgstr ""
+msgstr "फ़ाइल या डायरेकà¥à¤Ÿà¤°à¥€ खोलिये"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/editor_properties.cpp editor/inspector_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
-msgstr ""
+msgstr "सेव कीजिये"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Save a File"
-msgstr ""
+msgstr "फ़ाइल सेव कीजिये"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
-msgstr ""
+msgstr "पीछे जाय"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
-msgstr ""
+msgstr "आगे जाय"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
-msgstr ""
+msgstr "ऊपर जाय"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr ""
+msgstr "छिपी फ़ाइले टॉगल कीजिये"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr ""
+msgstr "फ़ेवरेट टॉगल कीजिये"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr ""
+msgstr "मोड टॉगल कीजिये"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr ""
+msgstr "फ़ोकस पाथ"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr ""
+msgstr "फ़ेवरेट उपर लीजिये"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
-msgstr ""
+msgstr "फ़ेवरेट नीचे लीजिये"
#: editor/editor_file_dialog.cpp
msgid "Go to previous folder."
-msgstr ""
+msgstr "पिछले फ़ोलà¥à¤¡à¤° पे जाय."
#: editor/editor_file_dialog.cpp
msgid "Go to next folder."
-msgstr ""
+msgstr "अगले फ़ोलà¥à¤¡à¤° पे जाय."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
-msgstr ""
+msgstr "मूल फ़ोलà¥à¤¡à¤° पे जाय."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Refresh files."
-msgstr "खोज कर:"
+msgstr "रिफ़à¥à¤°à¥‡à¤¶ फ़ाइल."
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
-msgstr ""
+msgstr "फ़ेवरेट मे से वरà¥à¤¤à¤®à¤¾à¤¨ फ़ोलà¥à¤¡à¤° निकाले."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Toggle the visibility of hidden files."
-msgstr ""
+msgstr "छिपी फ़ाइलों की दृशà¥à¤¯ टॉगल कीजिये."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
-msgstr ""
+msgstr "आइटम थमà¥à¤¬à¤¨à¥‡à¤²à¥à¤¸ के ढाà¤à¤šà¥‡ के तरह देखे."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a list."
-msgstr ""
+msgstr "आइटम लिसà¥à¤Ÿ के तरह देखे."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Directories & Files:"
-msgstr ""
+msgstr "डायरेकà¥à¤Ÿà¤°à¤¿à¤œ & फ़ाइले:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Preview:"
-msgstr ""
+msgstr "पूरà¥à¤µ दरà¥à¤¶à¤¨:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File:"
-msgstr ""
+msgstr "फ़ाइल:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Must use a valid extension."
-msgstr ""
+msgstr "मानà¥à¤¯ à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤¨à¤¶à¤¨ इसà¥à¤¤à¥‡à¤®à¤¾à¤² कीजिये."
#: editor/editor_file_system.cpp
msgid "ScanSources"
-msgstr ""
+msgstr "सà¥à¤°à¥‹à¤¤à¤¸à¥à¤•ैन कीजिये"
#: editor/editor_file_system.cpp
msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
msgstr ""
+"विभिनà¥à¤¨ पà¥à¤°à¤•ार के लिठकई आयातक हैं जो % फाइल करने की ओर इशारा करते हैं, आयात निरसà¥à¤¤"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
-msgstr ""
+msgstr "असà¥à¤¸à¥‡à¤Ÿ (पà¥à¤¨:) इंपोरà¥à¤Ÿ"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Top"
-msgstr ""
+msgstr "सरà¥à¤µà¥‹à¤šà¥à¤š"
#: editor/editor_help.cpp
msgid "Class:"
-msgstr ""
+msgstr "कà¥à¤²à¤¾à¤¸:"
#: editor/editor_help.cpp editor/scene_tree_editor.cpp
#: editor/script_create_dialog.cpp
msgid "Inherits:"
-msgstr ""
+msgstr "निमà¥à¤¨ का उतà¥à¤¤à¤°à¤¾à¤§à¤¿à¤•ारी:"
#: editor/editor_help.cpp
msgid "Inherited by:"
-msgstr ""
+msgstr "निमà¥à¤¨ से उतà¥à¤¤à¤°à¤¾à¤§à¤¿à¤•ार पà¥à¤°à¤¾à¤ªà¥à¤¤:"
#: editor/editor_help.cpp
msgid "Description"
@@ -1933,155 +1935,152 @@ msgstr "विवरण"
#: editor/editor_help.cpp
msgid "Online Tutorials"
-msgstr ""
+msgstr "ऑनलाइन टà¥à¤¯à¥‚टोरियल"
#: editor/editor_help.cpp
msgid "Properties"
-msgstr ""
+msgstr "पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ"
#: editor/editor_help.cpp
msgid "override:"
-msgstr ""
+msgstr "अधिभावी करता है:"
#: editor/editor_help.cpp
msgid "default:"
-msgstr ""
+msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤•:"
#: editor/editor_help.cpp
msgid "Methods"
-msgstr ""
+msgstr "मेथड"
#: editor/editor_help.cpp
msgid "Theme Properties"
-msgstr ""
+msgstr "थिम पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ"
#: editor/editor_help.cpp
msgid "Enumerations"
-msgstr ""
+msgstr "à¤à¤¨à¥à¤¯à¥à¤®à¤°à¥‡à¤¶à¤¨"
#: editor/editor_help.cpp
msgid "Constants"
-msgstr ""
+msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Property Descriptions"
-msgstr "विवरण:"
+msgstr "पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€ का विवरण"
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "मूलà¥à¤¯ :"
+msgstr "(मूलà¥à¤¯)"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this property. Please help us by "
"[color=$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"वरà¥à¤¤à¤®à¤¾à¤¨ में पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€ का विवरण नहीं. आप हमें [color=$color][url=$url]योगदान करके[/url]"
+"[/color] मदत कर सकते है!"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Method Descriptions"
-msgstr "विवरण:"
+msgstr "मेथड विवरण"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this method. Please help us by [color="
"$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"वरà¥à¤¤à¤®à¤¾à¤¨ में मेथड का विवरण नहीं. आप हमें [color=$color][url=$url]योगदान करके[/url][/"
+"color] मदत कर सकते है!"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr ""
+msgstr "मदत खोजे"
#: editor/editor_help_search.cpp
msgid "Case Sensitive"
-msgstr ""
+msgstr "अकà¥à¤·à¤° संवेदनशील"
#: editor/editor_help_search.cpp
msgid "Show Hierarchy"
-msgstr ""
+msgstr "उतà¥à¤•à¥à¤°à¤® दिखाइà¤"
#: editor/editor_help_search.cpp
msgid "Display All"
-msgstr ""
+msgstr "सब दिखाइà¤"
#: editor/editor_help_search.cpp
msgid "Classes Only"
-msgstr ""
+msgstr "सिरà¥à¤« कà¥à¤²à¤¾à¤¸"
#: editor/editor_help_search.cpp
msgid "Methods Only"
-msgstr ""
+msgstr "सिरà¥à¤« मेथड"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Signals Only"
-msgstr "संकेत"
+msgstr "सिरà¥à¤« सिगà¥à¤¨à¤²"
#: editor/editor_help_search.cpp
msgid "Constants Only"
-msgstr ""
+msgstr "सिरà¥à¤« कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
#: editor/editor_help_search.cpp
msgid "Properties Only"
-msgstr ""
+msgstr "सिरà¥à¤« पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ"
#: editor/editor_help_search.cpp
msgid "Theme Properties Only"
-msgstr ""
+msgstr "सिरà¥à¤« थिम पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ"
#: editor/editor_help_search.cpp
msgid "Member Type"
-msgstr ""
+msgstr "मेंबर टाइप"
#: editor/editor_help_search.cpp
msgid "Class"
-msgstr ""
+msgstr "कà¥à¤²à¤¾à¤¸"
#: editor/editor_help_search.cpp
msgid "Method"
-msgstr ""
+msgstr "मेथड"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
-msgstr "संकेत"
+msgstr "सिगà¥à¤¨à¤²"
#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
-msgstr ""
+msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Property"
-msgstr "गà¥à¤£(Property) टà¥à¤°à¥ˆà¤•"
+msgstr "पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€"
#: editor/editor_help_search.cpp
msgid "Theme Property"
-msgstr ""
+msgstr "थिम पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
-msgstr ""
+msgstr "पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€:"
#: editor/editor_inspector.cpp
msgid "Set"
-msgstr ""
+msgstr "सेट करे"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
-msgstr ""
+msgstr "अनेक सेट करे:"
#: editor/editor_log.cpp
msgid "Output:"
-msgstr ""
+msgstr "परिणाम:"
#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Copy Selection"
-msgstr "सभी खंड"
+msgstr "खंड कौपी कीजिये"
#: editor/editor_log.cpp editor/editor_network_profiler.cpp
#: editor/editor_profiler.cpp editor/editor_properties.cpp
@@ -2091,176 +2090,178 @@ msgstr "सभी खंड"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr ""
+msgstr "साफ़"
#: editor/editor_log.cpp
msgid "Clear Output"
-msgstr ""
+msgstr "परिणाम साफ़ करे"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
msgid "Stop"
-msgstr ""
+msgstr "रोकिये"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
msgid "Start"
-msgstr ""
+msgstr "शà¥à¤°à¥‚ कीजिये"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s/s"
#: editor/editor_network_profiler.cpp
msgid "Down"
-msgstr ""
+msgstr "नीचे"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr ""
+msgstr "ऊपर"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
-msgstr ""
+msgstr "नोड"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "आगामी RPC"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "आगामी RSET"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RPC"
-msgstr ""
+msgstr "बाहर जाने वाला RPC"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RSET"
-msgstr ""
+msgstr "बाहर जाने वाला RSET"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
-msgstr ""
+msgstr "नया विंडो"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr ""
+msgstr "इंपोरà¥à¤Ÿà¥‡à¤¡ रेसोरà¥à¤¸à¥‡à¤¸ सेव नहीं कर सकते."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
msgid "OK"
-msgstr ""
+msgstr "ठीक है"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr ""
+msgstr "रेसोरà¥à¤¸ सेव करनेमे à¤à¤°à¤°!"
#: editor/editor_node.cpp
msgid ""
"This resource can't be saved because it does not belong to the edited scene. "
"Make it unique first."
-msgstr ""
+msgstr "रेसोरà¥à¤¸ सेव नहीं कर सकते कà¥à¤¯à¥‹à¤‚कि यह संपादित सीन से संबंधित नहीं. इसे पहले यà¥à¤¨à¤¿à¤• बनाय."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
-msgstr ""
+msgstr "रेसोरà¥à¤¸ इसपà¥à¤°à¤•ार सेव कीजिये..."
#: editor/editor_node.cpp
msgid "Can't open file for writing:"
-msgstr ""
+msgstr "फ़ाइल रायटिंग के लिठनहीं खोल सकते:"
#: editor/editor_node.cpp
msgid "Requested file format unknown:"
-msgstr ""
+msgstr "निवेदित फ़ाइल फ़ोरà¥à¤®à¥ˆà¤Ÿ अजà¥à¤žà¤¾à¤¤:"
#: editor/editor_node.cpp
msgid "Error while saving."
-msgstr ""
+msgstr "सेव करनेमे à¤à¤°à¤°."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Can't open '%s'. The file could have been moved or deleted."
-msgstr ""
+msgstr "'%s' नहीं खोल सकते. फ़ाइल हिलाइ गयी या हटाई गयी."
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
-msgstr ""
+msgstr "'%s' पारà¥à¤¸ करनेमे à¤à¤°à¤°."
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
-msgstr ""
+msgstr "अनपेकà¥à¤·à¤¿à¤¤ फ़ाइल समापà¥à¤¤à¤¿ '%s'."
#: editor/editor_node.cpp
msgid "Missing '%s' or its dependencies."
-msgstr ""
+msgstr "'%s' या उसकी निरà¥à¤­à¤°à¤¿à¤¤ फ़ाइलें नहीं मिली."
#: editor/editor_node.cpp
msgid "Error while loading '%s'."
-msgstr ""
+msgstr "लोड करनेमे à¤à¤°à¤° '%s'."
#: editor/editor_node.cpp
msgid "Saving Scene"
-msgstr ""
+msgstr "सीन सेव कर रहा है"
#: editor/editor_node.cpp
msgid "Analyzing"
-msgstr ""
+msgstr "विशà¥à¤²à¥‡à¤·à¤£"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
-msgstr ""
+msgstr "थंबनेल बनाना"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
-msgstr ""
+msgstr "यह ऑपरेशन पेड़ की जड़ के बिना नहीं किया जा सकता है।"
#: editor/editor_node.cpp
msgid ""
"This scene can't be saved because there is a cyclic instancing inclusion.\n"
"Please resolve it and then attempt to save again."
msgstr ""
+"इस दृशà¥à¤¯ को बचाया नहीं जा सकता कà¥à¤¯à¥‹à¤‚कि à¤à¤• चकà¥à¤°à¥€à¤¯ instancing समावेश है ।\n"
+"कृपया इसे हल करें और फिर फिर से बचाने का पà¥à¤°à¤¯à¤¾à¤¸ करें।"
#: editor/editor_node.cpp
msgid ""
"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
"be satisfied."
-msgstr ""
+msgstr "दृशà¥à¤¯ नहीं बचा सका । संभावित निरà¥à¤­à¤°à¤¤à¤¾ (उदाहरण या विरासत) संतà¥à¤·à¥à¤Ÿ नहीं हो सकीं।"
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
-msgstr ""
+msgstr "दृशà¥à¤¯ है कि अभी भी खà¥à¤²à¤¾ है ओवरराइट नहीं कर सकते!"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
-msgstr ""
+msgstr "विलय के लिठMeshLibrary लोड नहीं कर सकते!"
#: editor/editor_node.cpp
msgid "Error saving MeshLibrary!"
-msgstr ""
+msgstr "तà¥à¤°à¥à¤Ÿà¤¿ बचत मेष लाइबà¥à¤°à¥‡à¤°à¥€!"
#: editor/editor_node.cpp
msgid "Can't load TileSet for merging!"
-msgstr ""
+msgstr "विलय के लिठTileSet लोड नहीं कर सकते!"
#: editor/editor_node.cpp
msgid "Error saving TileSet!"
-msgstr ""
+msgstr "तà¥à¤°à¥à¤Ÿà¤¿ बचत टाइलसेट!"
#: editor/editor_node.cpp
msgid "Error trying to save layout!"
-msgstr ""
+msgstr "लेआउट को बचाने की कोशिश कर रहा तà¥à¤°à¥à¤Ÿà¤¿!"
#: editor/editor_node.cpp
msgid "Default editor layout overridden."
-msgstr ""
+msgstr "डिफ़ॉलà¥à¤Ÿ संपादक लेआउट अभिभूत।"
#: editor/editor_node.cpp
msgid "Layout name not found!"
-msgstr ""
+msgstr "लेआउट नाम नहीं मिला!"
#: editor/editor_node.cpp
msgid "Restored default layout to base settings."
-msgstr ""
+msgstr "आधार सेटिंगà¥à¤¸ के लिठडिफ़ॉलà¥à¤Ÿ लेआउट बहाल।"
#: editor/editor_node.cpp
msgid ""
@@ -2268,18 +2269,26 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
+"यह संसाधन à¤à¤• दृशà¥à¤¯ है कि आयात किया गया था के अंतरà¥à¤—त आता है, तो यह संपादन योगà¥à¤¯ नहीं है "
+"।\n"
+"कृपया इस कारà¥à¤¯à¤ªà¥à¤°à¤µà¤¾à¤¹ को बेहतर ढंग से समà¤à¤¨à¥‡ के लिठदृशà¥à¤¯à¥‹à¤‚ का आयात करने के लिठपà¥à¤°à¤¾à¤¸à¤‚गिक "
+"दसà¥à¤¤à¤¾à¤µà¥‡à¤œ पढ़ें।"
#: editor/editor_node.cpp
msgid ""
"This resource belongs to a scene that was instanced or inherited.\n"
"Changes to it won't be kept when saving the current scene."
msgstr ""
+"यह संसाधन à¤à¤• दृशà¥à¤¯ है कि उदाहरण या विरासत में मिला था के अंतरà¥à¤—त आता है ।\n"
+"वरà¥à¤¤à¤®à¤¾à¤¨ दृशà¥à¤¯ को सहेजते समय इसमें परिवरà¥à¤¤à¤¨ नहीं रखे जाà¤à¤‚गे।"
#: editor/editor_node.cpp
msgid ""
"This resource was imported, so it's not editable. Change its settings in the "
"import panel and then re-import."
msgstr ""
+"इस संसाधन का आयात किया गया था, तो यह संपादन योगà¥à¤¯ नहीं है । आयात पैनल में अपनी सेटिंग "
+"बदलें और फिर फिर से आयात करें।"
#: editor/editor_node.cpp
msgid ""
@@ -2288,6 +2297,10 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
+"यह दृशà¥à¤¯ आयात किया गया था, इसलिठइसमें परिवरà¥à¤¤à¤¨ नहीं रखे जाà¤à¤‚गे।\n"
+"यह instancing या विरासत में यह परिवरà¥à¤¤à¤¨ करने की अनà¥à¤®à¤¤à¤¿ होगी ।\n"
+"कृपया इस कारà¥à¤¯à¤ªà¥à¤°à¤µà¤¾à¤¹ को बेहतर ढंग से समà¤à¤¨à¥‡ के लिठदृशà¥à¤¯à¥‹à¤‚ का आयात करने के लिठपà¥à¤°à¤¾à¤¸à¤‚गिक "
+"दसà¥à¤¤à¤¾à¤µà¥‡à¤œ पढ़ें।"
#: editor/editor_node.cpp
msgid ""
@@ -2295,26 +2308,28 @@ msgid ""
"Please read the documentation relevant to debugging to better understand "
"this workflow."
msgstr ""
+"यह à¤à¤• दूरसà¥à¤¥ वसà¥à¤¤à¥ है, इसलिठइसमें परिवरà¥à¤¤à¤¨ नहीं रखे जाà¤à¤‚गे।\n"
+"कृपया इस कारà¥à¤¯à¤ªà¥à¤°à¤µà¤¾à¤¹ को बेहतर ढंग से समà¤à¤¨à¥‡ के लिठडिबगिंग के लिठपà¥à¤°à¤¾à¤¸à¤‚गिक दसà¥à¤¤à¤¾à¤µà¥‡à¤œ पढ़ें।"
#: editor/editor_node.cpp
msgid "There is no defined scene to run."
-msgstr ""
+msgstr "चलाने के लिठकोई परिभाषित दृशà¥à¤¯ नहीं है ।"
#: editor/editor_node.cpp
msgid "Current scene was never saved, please save it prior to running."
-msgstr ""
+msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ दृशà¥à¤¯ कभी नहीं बचाया गया था, कृपया इसे चलाने से पहले बचाने के लिठ।"
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
-msgstr ""
+msgstr "उपपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ शà¥à¤°à¥‚ नहीं कर सका!"
#: editor/editor_node.cpp editor/filesystem_dock.cpp
msgid "Open Scene"
-msgstr ""
+msgstr "खà¥à¤²à¤¾ दृशà¥à¤¯"
#: editor/editor_node.cpp
msgid "Open Base Scene"
-msgstr ""
+msgstr "ओपन बेस सीन"
#: editor/editor_node.cpp
#, fuzzy
@@ -2323,121 +2338,123 @@ msgstr "खोलो इसे"
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
-msgstr ""
+msgstr "कà¥à¤µà¤¿à¤• ओपन सीन..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr ""
+msgstr "कà¥à¤µà¤¿à¤• ओपन सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ..."
#: editor/editor_node.cpp
msgid "Save & Close"
-msgstr ""
+msgstr "सहेजें और बंद"
#: editor/editor_node.cpp
msgid "Save changes to '%s' before closing?"
-msgstr ""
+msgstr "बंद करने से पहले '%' में परिवरà¥à¤¤à¤¨ सहेजें?"
#: editor/editor_node.cpp
msgid "Saved %s modified resource(s)."
-msgstr ""
+msgstr "सहेजा गया% संशोधित संसाधन (à¤à¤¸)"
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
-msgstr ""
+msgstr "दृशà¥à¤¯ को बचाने के लिठà¤à¤• रूट नोड की आवशà¥à¤¯à¤•ता होती है।"
#: editor/editor_node.cpp
msgid "Save Scene As..."
-msgstr ""
+msgstr "दृशà¥à¤¯ के रूप में सहेजें ..."
#: editor/editor_node.cpp
msgid "No"
-msgstr ""
+msgstr "नहीं"
#: editor/editor_node.cpp
msgid "Yes"
-msgstr ""
+msgstr "हाà¤"
#: editor/editor_node.cpp
msgid "This scene has never been saved. Save before running?"
-msgstr ""
+msgstr "इस सीन को कभी नहीं बचाया गया। दौड़ने से पहले सहेजें?"
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
-msgstr ""
+msgstr "यह ऑपरेशन बिना किसी दृशà¥à¤¯ के नहीं किया जा सकता है।"
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr ""
+msgstr "निरà¥à¤¯à¤¾à¤¤ मेष पà¥à¤¸à¥à¤¤à¤•ालय"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
-msgstr ""
+msgstr "यह ऑपरेशन रूट नोड के बिना नहीं किया जा सकता है।"
#: editor/editor_node.cpp
msgid "Export Tile Set"
-msgstr ""
+msgstr "निरà¥à¤¯à¤¾à¤¤ टाइल सेट"
#: editor/editor_node.cpp
msgid "This operation can't be done without a selected node."
-msgstr ""
+msgstr "यह ऑपरेशन चयनित नोड के बिना नहीं किया जा सकता है।"
#: editor/editor_node.cpp
msgid "Current scene not saved. Open anyway?"
-msgstr ""
+msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ दृशà¥à¤¯ को बचाया नहीं गया । वैसे भी खà¥à¤²à¤¾?"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
-msgstr ""
+msgstr "à¤à¤• दृशà¥à¤¯ है कि कभी नहीं बचाया गया था फिर से लोड नहीं कर सकते ।"
#: editor/editor_node.cpp
msgid "Revert"
-msgstr ""
+msgstr "वापस लौटना"
#: editor/editor_node.cpp
msgid "This action cannot be undone. Revert anyway?"
-msgstr ""
+msgstr "इस कारà¥à¤°à¤µà¤¾à¤ˆ को पूरà¥à¤µà¤µà¤¤ नहीं किया जा सकता । वैसे भी वापस?"
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
-msgstr ""
+msgstr "कà¥à¤µà¤¿à¤• रन सीन..."
#: editor/editor_node.cpp
msgid "Quit"
-msgstr ""
+msgstr "छोड़ना"
#: editor/editor_node.cpp
msgid "Exit the editor?"
-msgstr ""
+msgstr "संपादक से बाहर निकलें?"
#: editor/editor_node.cpp
msgid "Open Project Manager?"
-msgstr ""
+msgstr "ओपन पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ मैनेजर?"
#: editor/editor_node.cpp
msgid "Save & Quit"
-msgstr ""
+msgstr "सहेजें और छोड़ो"
#: editor/editor_node.cpp
msgid "Save changes to the following scene(s) before quitting?"
-msgstr ""
+msgstr "छोड़ने से पहले निमà¥à¤¨à¤²à¤¿à¤–ित दृशà¥à¤¯ (ओं) में परिवरà¥à¤¤à¤¨ सहेजें?"
#: editor/editor_node.cpp
msgid "Save changes the following scene(s) before opening Project Manager?"
-msgstr ""
+msgstr "परियोजना पà¥à¤°à¤¬à¤‚धक खोलने से पहले निमà¥à¤¨à¤²à¤¿à¤–ित दृशà¥à¤¯ (ओं) में परिवरà¥à¤¤à¤¨ सहेजें?"
#: editor/editor_node.cpp
msgid ""
"This option is deprecated. Situations where refresh must be forced are now "
"considered a bug. Please report."
msgstr ""
+"यह विकलà¥à¤ª बहिषà¥à¤•ृत है। सà¥à¤¥à¤¿à¤¤à¤¿à¤¯à¥‹à¤‚ जहां ताज़ा मजबूर किया जाना चाहिठअब à¤à¤• बग माना जाता "
+"है । कृपया रिपोरà¥à¤Ÿ करें।"
#: editor/editor_node.cpp
msgid "Pick a Main Scene"
-msgstr ""
+msgstr "à¤à¤• मà¥à¤–à¥à¤¯ दृशà¥à¤¯ चà¥à¤¨à¥‡à¤‚"
#: editor/editor_node.cpp
msgid "Close Scene"
-msgstr ""
+msgstr "कà¥à¤²à¥‹à¤œ सीन"
#: editor/editor_node.cpp
#, fuzzy
@@ -2446,50 +2463,56 @@ msgstr "खोलो इसे"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
-msgstr ""
+msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन को सकà¥à¤·à¤® करने में असमरà¥à¤¥: '%' कॉनà¥à¤«à¤¿à¤— का पारà¥à¤¸à¤¿à¤‚ग विफल रहा।"
#: editor/editor_node.cpp
msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
+msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन के लिठसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ फ़ीलà¥à¤¡ खोजने में असमरà¥à¤¥: 'res://addons/% s'।"
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr ""
+msgstr "पथ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '%' ।"
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
+"रासà¥à¤¤à¥‡ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '% à¤à¤¸' कोड में गड़बड़ी लगती है, कृपया सिंटेकà¥à¤¸ की "
+"जांच करें।"
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
-msgstr ""
+msgstr "पथ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '%' आधार पà¥à¤°à¤•ार संपादकपà¥à¤²à¤—इन नहीं है।"
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
-msgstr ""
+msgstr "पथ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '%' सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ टूल मोड में नहीं है।"
#: editor/editor_node.cpp
msgid ""
"Scene '%s' was automatically imported, so it can't be modified.\n"
"To make changes to it, a new inherited scene can be created."
msgstr ""
+"दृशà¥à¤¯ '%' सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ रूप से आयात किया गया था, इसलिठइसे संशोधित नहीं किया जा सकता है।\n"
+"इसमें बदलाव करने के लिठविरासत में मिला à¤à¤• नया सीन बनाया जा सकता है।"
#: editor/editor_node.cpp
msgid ""
"Error loading scene, it must be inside the project path. Use 'Import' to "
"open the scene, then save it inside the project path."
msgstr ""
+"तà¥à¤°à¥à¤Ÿà¤¿ लोडिंग दृशà¥à¤¯, यह परियोजना पथ के अंदर होना चाहिà¤à¥¤ दृशà¥à¤¯ खोलने के लिठ'आयात' का "
+"उपयोग करें, फिर इसे परियोजना पथ के अंदर बचाà¤à¤‚।"
#: editor/editor_node.cpp
msgid "Scene '%s' has broken dependencies:"
-msgstr ""
+msgstr "दृशà¥à¤¯ '%' निरà¥à¤­à¤°à¤¤à¤¾ टूट गया है:"
#: editor/editor_node.cpp
msgid "Clear Recent Scenes"
-msgstr ""
+msgstr "हाल के दृशà¥à¤¯à¥‹à¤‚ को साफ करें"
#: editor/editor_node.cpp
msgid ""
@@ -2497,6 +2520,8 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"कोई मà¥à¤–à¥à¤¯ दृशà¥à¤¯ कभी परिभाषित किया गया है, à¤à¤• का चयन करें?\n"
+"आप इसे बाद में 'à¤à¤ªà¥à¤²à¤¿à¤•ेशन' शà¥à¤°à¥‡à¤£à¥€ के तहत \"पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸\" में बदल सकते हैं।"
#: editor/editor_node.cpp
msgid ""
@@ -2504,6 +2529,8 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"चयनित दृशà¥à¤¯ '%' मौजूद नहीं है, à¤à¤• वैध का चयन करें?\n"
+"आप इसे बाद में 'à¤à¤ªà¥à¤²à¤¿à¤•ेशन' शà¥à¤°à¥‡à¤£à¥€ के तहत \"पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸\" में बदल सकते हैं।"
#: editor/editor_node.cpp
msgid ""
@@ -2511,28 +2538,30 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"चयनित दृशà¥à¤¯ '%' à¤à¤• दृशà¥à¤¯ फ़ाइल नहीं है, à¤à¤• वैध का चयन करें?\n"
+"आप इसे बाद में 'à¤à¤ªà¥à¤²à¤¿à¤•ेशन' शà¥à¤°à¥‡à¤£à¥€ के तहत \"पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸\" में बदल सकते हैं।"
#: editor/editor_node.cpp
msgid "Save Layout"
-msgstr ""
+msgstr "लेआउट सहेजें"
#: editor/editor_node.cpp
msgid "Delete Layout"
-msgstr ""
+msgstr "लेआउट हटाà¤à¤‚"
#: editor/editor_node.cpp editor/import_dock.cpp
#: editor/script_create_dialog.cpp
msgid "Default"
-msgstr ""
+msgstr "चूक"
#: editor/editor_node.cpp editor/editor_properties.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
msgid "Show in FileSystem"
-msgstr ""
+msgstr "शो में फाइल सिसà¥à¤Ÿà¤®"
#: editor/editor_node.cpp
msgid "Play This Scene"
-msgstr ""
+msgstr "इस दृशà¥à¤¯ को खेलो"
#: editor/editor_node.cpp
#, fuzzy
@@ -2546,11 +2575,11 @@ msgstr "बंद करे"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
-msgstr ""
+msgstr "बंद करें अनà¥à¤¯ टैब"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "टैब को दाईं ओर बंद करें"
#: editor/editor_node.cpp
#, fuzzy
@@ -2559,43 +2588,43 @@ msgstr "बंद करे"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
-msgstr ""
+msgstr "सà¥à¤µà¤¿à¤š सीन टैब"
#: editor/editor_node.cpp
msgid "%d more files or folders"
-msgstr ""
+msgstr "% डी अधिक फाइलें या फ़ोलà¥à¤¡à¤°"
#: editor/editor_node.cpp
msgid "%d more folders"
-msgstr ""
+msgstr "% डी अधिक फ़ोलà¥à¤¡à¤°à¥à¤¸"
#: editor/editor_node.cpp
msgid "%d more files"
-msgstr ""
+msgstr "% डी अधिक फाइलें"
#: editor/editor_node.cpp
msgid "Dock Position"
-msgstr ""
+msgstr "डॉक पोजीशन"
#: editor/editor_node.cpp
msgid "Distraction Free Mode"
-msgstr ""
+msgstr "वà¥à¤¯à¤¾à¤•à¥à¤²à¤¤à¤¾ मà¥à¤•à¥à¤¤ मोड"
#: editor/editor_node.cpp
msgid "Toggle distraction-free mode."
-msgstr ""
+msgstr "वà¥à¤¯à¤¾à¤•à¥à¤²à¤¤à¤¾ मà¥à¤•à¥à¤¤ मोड टॉगल।"
#: editor/editor_node.cpp
msgid "Add a new scene."
-msgstr ""
+msgstr "à¤à¤• नया दृशà¥à¤¯ जोड़ें।"
#: editor/editor_node.cpp
msgid "Scene"
-msgstr ""
+msgstr "दृशà¥à¤¯"
#: editor/editor_node.cpp
msgid "Go to previously opened scene."
-msgstr ""
+msgstr "पहले खोले गठदृशà¥à¤¯ में जाà¤à¤‚।"
#: editor/editor_node.cpp
#, fuzzy
@@ -2604,102 +2633,102 @@ msgstr "सभी खंड"
#: editor/editor_node.cpp
msgid "Next tab"
-msgstr ""
+msgstr "अगला टैब"
#: editor/editor_node.cpp
msgid "Previous tab"
-msgstr ""
+msgstr "पिछला टैब"
#: editor/editor_node.cpp
msgid "Filter Files..."
-msgstr ""
+msgstr "फ़िलà¥à¤Ÿà¤° फ़ाइलें..."
#: editor/editor_node.cpp
msgid "Operations with scene files."
-msgstr ""
+msgstr "दृशà¥à¤¯ फ़ाइलों के साथ संचालन।"
#: editor/editor_node.cpp
msgid "New Scene"
-msgstr ""
+msgstr "नया दृशà¥à¤¯"
#: editor/editor_node.cpp
msgid "New Inherited Scene..."
-msgstr ""
+msgstr "नया विरासत में मिला दृशà¥à¤¯..."
#: editor/editor_node.cpp
msgid "Open Scene..."
-msgstr ""
+msgstr "खà¥à¤²à¤¾ दृशà¥à¤¯..."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Open Recent"
-msgstr ""
+msgstr "खà¥à¤²à¤¾ हाल"
#: editor/editor_node.cpp
msgid "Save Scene"
-msgstr ""
+msgstr "दृशà¥à¤¯ बचाओ"
#: editor/editor_node.cpp
msgid "Save All Scenes"
-msgstr ""
+msgstr "सभी दृशà¥à¤¯à¥‹à¤‚ को सहेजें"
#: editor/editor_node.cpp
msgid "Convert To..."
-msgstr ""
+msgstr "बदलने के लिà¤..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr ""
+msgstr "मेष लाइबà¥à¤°à¥‡à¤°à¥€..."
#: editor/editor_node.cpp
msgid "TileSet..."
-msgstr ""
+msgstr "Tileset ..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Undo"
-msgstr ""
+msgstr "पूरà¥à¤µà¤µà¤¤à¥"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Redo"
-msgstr ""
+msgstr "दोहराà¤à¤"
#: editor/editor_node.cpp
msgid "Revert Scene"
-msgstr ""
+msgstr "वापस दृशà¥à¤¯"
#: editor/editor_node.cpp
msgid "Miscellaneous project or scene-wide tools."
-msgstr ""
+msgstr "विविध परियोजना या दृशà¥à¤¯-वà¥à¤¯à¤¾à¤ªà¥€ उपकरण।"
#: editor/editor_node.cpp editor/project_manager.cpp
#: editor/script_create_dialog.cpp
msgid "Project"
-msgstr ""
+msgstr "परियोजना"
#: editor/editor_node.cpp
msgid "Project Settings..."
-msgstr ""
+msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंग ..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
-msgstr ""
+msgstr "वरà¥à¤œà¤¨ कंटà¥à¤°à¥‹à¤²"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "वरà¥à¤œà¤¨ नियंतà¥à¤°à¤£ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "वरà¥à¤œà¤¨ नियंतà¥à¤°à¤£ बंद करें"
#: editor/editor_node.cpp
msgid "Export..."
-msgstr ""
+msgstr "निरà¥à¤¯à¤¾à¤¤..."
#: editor/editor_node.cpp
msgid "Install Android Build Template..."
-msgstr ""
+msgstr "à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें..."
#: editor/editor_node.cpp
#, fuzzy
@@ -2708,7 +2737,7 @@ msgstr "परियोजना के संसà¥à¤¥à¤¾à¤ªà¤•"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
-msgstr ""
+msgstr "उपकरण"
#: editor/editor_node.cpp
#, fuzzy
@@ -2717,26 +2746,28 @@ msgstr "Orphan Resource Explorer"
#: editor/editor_node.cpp
msgid "Quit to Project List"
-msgstr ""
+msgstr "परियोजना सूची में छोड़ो"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
msgid "Debug"
-msgstr ""
+msgstr "डीबग करें"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
-msgstr ""
+msgstr "रिमोट डिबग के साथ तैनात"
#: editor/editor_node.cpp
msgid ""
"When exporting or deploying, the resulting executable will attempt to "
"connect to the IP of this computer in order to be debugged."
msgstr ""
+"निरà¥à¤¯à¤¾à¤¤ या तैनाती करते समय, परिणामी निषà¥à¤ªà¤¾à¤¦à¤• इस कंपà¥à¤¯à¥‚टर के आईपी से जà¥à¤¡à¤¼à¤¨à¥‡ का पà¥à¤°à¤¯à¤¾à¤¸ करेगा "
+"ताकि डिबग किया जा सके।"
#: editor/editor_node.cpp
msgid "Small Deploy with Network FS"
-msgstr ""
+msgstr "नेटवरà¥à¤• à¤à¤«à¤à¤¸ के साथ छोटे तैनात"
#: editor/editor_node.cpp
msgid ""
@@ -2747,30 +2778,36 @@ msgid ""
"On Android, deploy will use the USB cable for faster performance. This "
"option speeds up testing for games with a large footprint."
msgstr ""
+"जब यह विकलà¥à¤ª सकà¥à¤·à¤® हो जाता है, तो निरà¥à¤¯à¤¾à¤¤ या तैनाती नà¥à¤¯à¥‚नतम निषà¥à¤ªà¤¾à¤¦à¤¿à¤¤ उतà¥à¤ªà¤¾à¤¦à¤¨ करेगी।\n"
+"नेटवरà¥à¤• के ऊपर संपादक दà¥à¤µà¤¾à¤°à¤¾ परियोजना से फाइलसिसà¥à¤Ÿà¤® उपलबà¥à¤§ कराया जाà¤à¤—ा।\n"
+"à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ पर, तैनात तेजी से पà¥à¤°à¤¦à¤°à¥à¤¶à¤¨ के लिठयूà¤à¤¸à¤¬à¥€ केबल का उपयोग करेंगे । यह विकलà¥à¤ª à¤à¤• बड़े "
+"पदचिहà¥à¤¨ के साथ खेल के लिठपरीकà¥à¤·à¤£ को गति देता है।"
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
-msgstr ""
+msgstr "दृशà¥à¤¯à¤®à¤¾à¤¨ टकराव आकार"
#: editor/editor_node.cpp
msgid ""
"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
"running game if this option is turned on."
msgstr ""
+"यदि यह विकलà¥à¤ª चालू हो जाता है तो टकराव के आकार और रेकासà¥à¤Ÿ नोडà¥à¤¸ (2डी और 3 डी के लिà¤) "
+"चल रहे खेल पर दिखाई देंगे।"
#: editor/editor_node.cpp
msgid "Visible Navigation"
-msgstr ""
+msgstr "दरà¥à¤¶à¤¨à¥€à¤¯ नेविगेशन"
#: editor/editor_node.cpp
msgid ""
"Navigation meshes and polygons will be visible on the running game if this "
"option is turned on."
-msgstr ""
+msgstr "यदि यह विकलà¥à¤ª चालू हो जाता है तो नेविगेशन मेशेस और बहà¥à¤­à¥à¤œ चल रहे खेल पर दिखाई देंगे।"
#: editor/editor_node.cpp
msgid "Sync Scene Changes"
-msgstr ""
+msgstr "सिंक सीन बदलता है"
#: editor/editor_node.cpp
msgid ""
@@ -2779,10 +2816,14 @@ msgid ""
"When used remotely on a device, this is more efficient with network "
"filesystem."
msgstr ""
+"जब इस विकलà¥à¤ª को चालू किया जाता है, तो संपादक में दृशà¥à¤¯ में किठगठकिसी भी परिवरà¥à¤¤à¤¨ को "
+"चल रहे खेल में दोहराया जाà¤à¤—ा।\n"
+"जब किसी डिवाइस पर दूर से उपयोग किया जाता है, तो यह नेटवरà¥à¤• फाइलसिसà¥à¤Ÿà¤® के साथ अधिक "
+"कà¥à¤¶à¤² होता है।"
#: editor/editor_node.cpp
msgid "Sync Script Changes"
-msgstr ""
+msgstr "सिंक सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ परिवरà¥à¤¤à¤¨"
#: editor/editor_node.cpp
msgid ""
@@ -2791,10 +2832,14 @@ msgid ""
"When used remotely on a device, this is more efficient with network "
"filesystem."
msgstr ""
+"जब यह विकलà¥à¤ª चालू हो जाà¤à¤—ा, तो सहेजी गई किसी भी सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ को चल रहे गेम पर फिर से लोड "
+"किया जाà¤à¤—ा।\n"
+"जब किसी डिवाइस पर दूर से उपयोग किया जाता है, तो यह नेटवरà¥à¤• फाइलसिसà¥à¤Ÿà¤® के साथ अधिक "
+"कà¥à¤¶à¤² होता है।"
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
-msgstr ""
+msgstr "संपादक"
#: editor/editor_node.cpp
#, fuzzy
@@ -2803,47 +2848,47 @@ msgstr "अनà¥à¤µà¤¾à¤¦ में बदलाव करें:"
#: editor/editor_node.cpp
msgid "Editor Layout"
-msgstr ""
+msgstr "संपादक लेआउट"
#: editor/editor_node.cpp
msgid "Take Screenshot"
-msgstr ""
+msgstr "सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ लें"
#: editor/editor_node.cpp
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr ""
+msgstr "सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ à¤à¤¡à¤¿à¤Ÿà¤° डेटा/सेटिंगà¥à¤¸ फोलà¥à¤¡à¤° में सà¥à¤Ÿà¥‹à¤° किठजाते हैं ।"
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr ""
+msgstr "पूरà¥à¤£à¤¸à¥à¤•à¥à¤°à¥€à¤¨ चालू करें"
#: editor/editor_node.cpp
msgid "Toggle System Console"
-msgstr ""
+msgstr "टॉगल सिसà¥à¤Ÿà¤® कंसोल"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
-msgstr ""
+msgstr "संपादक डेटा / सेटिंगà¥à¤¸ फ़ोलà¥à¤¡à¤° खोलें"
#: editor/editor_node.cpp
msgid "Open Editor Data Folder"
-msgstr ""
+msgstr "संपादक डेटा फ़ोलà¥à¤¡à¤° खोलें"
#: editor/editor_node.cpp
msgid "Open Editor Settings Folder"
-msgstr ""
+msgstr "ओपन à¤à¤¡à¤¿à¤Ÿà¤° सेटिंगफ़र"
#: editor/editor_node.cpp
msgid "Manage Editor Features..."
-msgstr ""
+msgstr "संपादक सà¥à¤µà¤¿à¤§à¤¾à¤à¤ पà¥à¤°à¤¬à¤‚धित करें ..."
#: editor/editor_node.cpp
msgid "Manage Export Templates..."
-msgstr ""
+msgstr "निरà¥à¤¯à¤¾à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ का पà¥à¤°à¤¬à¤‚धन करें ..."
#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
-msgstr ""
+msgstr "मदद"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -2852,19 +2897,23 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
-msgstr ""
+msgstr "ढूंढें"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
-msgstr ""
+msgstr "ऑनलाइन डॉकà¥à¤¸"
#: editor/editor_node.cpp
msgid "Q&A"
+msgstr "Q&A"
+
+#: editor/editor_node.cpp
+msgid "Report a Bug"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -2877,92 +2926,92 @@ msgstr "के बारे में"
#: editor/editor_node.cpp
msgid "Play the project."
-msgstr ""
+msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ चलाà¤à¤‚।"
#: editor/editor_node.cpp
msgid "Play"
-msgstr ""
+msgstr "खेल"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr ""
+msgstr "डिबगिंग के लिठदृशà¥à¤¯ निषà¥à¤ªà¤¾à¤¦à¤¨ को रोकें।"
#: editor/editor_node.cpp
msgid "Pause Scene"
-msgstr ""
+msgstr "दृशà¥à¤¯ रोकें"
#: editor/editor_node.cpp
msgid "Stop the scene."
-msgstr ""
+msgstr "सीन बंद करो।"
#: editor/editor_node.cpp
msgid "Play the edited scene."
-msgstr ""
+msgstr "संपादित दृशà¥à¤¯ खेलते हैं।"
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr ""
+msgstr "पà¥à¤²à¥‡ सीन"
#: editor/editor_node.cpp
msgid "Play custom scene"
-msgstr ""
+msgstr "कसà¥à¤Ÿà¤® दृशà¥à¤¯ बजाना"
#: editor/editor_node.cpp
msgid "Play Custom Scene"
-msgstr ""
+msgstr "कसà¥à¤Ÿà¤® दृशà¥à¤¯ बजाना"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
-msgstr ""
+msgstr "वीडियो डà¥à¤°à¤¾à¤‡à¤µà¤° को बदलने के लिठसंपादक को फिर से शà¥à¤°à¥‚ करने की आवशà¥à¤¯à¤•ता होती है।"
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
msgid "Save & Restart"
-msgstr ""
+msgstr "सहेजें और पà¥à¤¨à¤ƒ आरंभ करें"
#: editor/editor_node.cpp
msgid "Spins when the editor window redraws."
-msgstr ""
+msgstr "जब संपादक खिड़की फिर से खींचता है तो सà¥à¤ªà¤¿à¤¨ करता है।"
#: editor/editor_node.cpp
msgid "Update Continuously"
-msgstr ""
+msgstr "लगातार अपडेट करें"
#: editor/editor_node.cpp
msgid "Update When Changed"
-msgstr ""
+msgstr "जब बदला अदà¥à¤¯à¤¤à¤¨"
#: editor/editor_node.cpp
msgid "Hide Update Spinner"
-msgstr ""
+msgstr "अपडेट सà¥à¤ªà¤¿à¤¨à¤° को छिपाà¤à¤‚"
#: editor/editor_node.cpp
msgid "FileSystem"
-msgstr ""
+msgstr "फ़ाइल"
#: editor/editor_node.cpp
msgid "Inspector"
-msgstr ""
+msgstr "निरीकà¥à¤·à¤•"
#: editor/editor_node.cpp
msgid "Expand Bottom Panel"
-msgstr ""
+msgstr "बॉटम पैनल का विसà¥à¤¤à¤¾à¤° करें"
#: editor/editor_node.cpp
msgid "Output"
-msgstr ""
+msgstr "आउटपà¥à¤Ÿ"
#: editor/editor_node.cpp
msgid "Don't Save"
-msgstr ""
+msgstr "सहेजें मत करो"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
-msgstr ""
+msgstr "à¤à¤‚डà¥à¤°à¥‰à¤‡à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ गायब है, कृपया पà¥à¤°à¤¾à¤¸à¤‚गिक टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें।"
#: editor/editor_node.cpp
msgid "Manage Templates"
-msgstr ""
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ का पà¥à¤°à¤¬à¤‚धन करें"
#: editor/editor_node.cpp
msgid ""
@@ -2974,6 +3023,12 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
+"यह \"res://android/build\" के लिठसà¥à¤°à¥‹à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करके कसà¥à¤Ÿà¤® à¤à¤‚डà¥à¤°à¥‰à¤‡à¤¡ बिलà¥à¤¡ के "
+"लिठआपकी परियोजना सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करेगा।\n"
+"फिर आप संशोधनों को लागू कर सकते हैं और निरà¥à¤¯à¤¾à¤¤ पर अपना खà¥à¤¦ का कसà¥à¤Ÿà¤® à¤à¤ªà¥€à¤•े बना सकते हैं "
+"(मॉडà¥à¤¯à¥‚ल जोड़ना, AndroidManifest.xml, आदि बदलना)।\n"
+"धà¥à¤¯à¤¾à¤¨ दें कि पूरà¥à¤µ-निरà¥à¤®à¤¿à¤¤ à¤à¤ªà¥€à¤•े का उपयोग करने के बजाय कसà¥à¤Ÿà¤® बिलà¥à¤¡ बनाने के लिà¤, à¤à¤‚डà¥à¤°à¥‰à¤‡à¤¡ "
+"निरà¥à¤¯à¤¾à¤¤ पूरà¥à¤µ निरà¥à¤§à¤¾à¤°à¤¿à¤¤ में \"उपयोग कसà¥à¤Ÿà¤® बिलà¥à¤¡\" विकलà¥à¤ª सकà¥à¤·à¤® किया जाना चाहिà¤à¥¤"
#: editor/editor_node.cpp
msgid ""
@@ -2982,66 +3037,70 @@ msgid ""
"Remove the \"res://android/build\" directory manually before attempting this "
"operation again."
msgstr ""
+"à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ पहले से ही इस परियोजना में सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ है और यह अधिक नहीं लिखा जाà¤à¤—ा "
+"।\n"
+"इस ऑपरेशन को फिर से पà¥à¤°à¤¯à¤¾à¤¸ करने से पहले मैनà¥à¤¯à¥à¤…ल रूप से \"res://android/build\" "
+"निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा निकालें।"
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
-msgstr ""
+msgstr "जिप फाइल से आयात टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸"
#: editor/editor_node.cpp
msgid "Template Package"
-msgstr ""
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ पैकेज"
#: editor/editor_node.cpp
msgid "Export Library"
-msgstr ""
+msgstr "à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ लाइबà¥à¤°à¥‡à¤°à¥€"
#: editor/editor_node.cpp
msgid "Merge With Existing"
-msgstr ""
+msgstr "मौजूदा के साथ विलय"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
-msgstr ""
+msgstr "ओपन à¤à¤‚ड रन à¤à¤• सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ"
#: editor/editor_node.cpp
msgid "New Inherited"
-msgstr ""
+msgstr "नई विरासत में मिली"
#: editor/editor_node.cpp
msgid "Load Errors"
-msgstr ""
+msgstr "लोड तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
msgid "Select"
-msgstr ""
+msgstr "चà¥à¤¨à¥‡à¤‚"
#: editor/editor_node.cpp
msgid "Open 2D Editor"
-msgstr ""
+msgstr "ओपन 2D संपादक"
#: editor/editor_node.cpp
msgid "Open 3D Editor"
-msgstr ""
+msgstr "ओपन 3डी à¤à¤¡à¤¿à¤Ÿà¤°"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr ""
+msgstr "ओपन सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ à¤à¤¡à¤¿à¤Ÿà¤°"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
-msgstr ""
+msgstr "ओपन à¤à¤¸à¥‡à¤Ÿ लाइबà¥à¤°à¥‡à¤°à¥€"
#: editor/editor_node.cpp
msgid "Open the next Editor"
-msgstr ""
+msgstr "अगले संपादक खोलें"
#: editor/editor_node.cpp
msgid "Open the previous Editor"
-msgstr ""
+msgstr "पिछले संपादक खोलें"
#: editor/editor_node.h
msgid "Warning!"
-msgstr ""
+msgstr "चेतावनी!"
#: editor/editor_path.cpp
#, fuzzy
@@ -3050,11 +3109,11 @@ msgstr "संसाधन"
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
-msgstr ""
+msgstr "मेष पूरà¥à¤µà¤¾à¤µà¤²à¥‹à¤•न बनाना"
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
-msgstr ""
+msgstr "थंबनेल..."
#: editor/editor_plugin_settings.cpp
#, fuzzy
@@ -3063,72 +3122,72 @@ msgstr "निरà¥à¤­à¤°à¤¤à¤¾ संपादक"
#: editor/editor_plugin_settings.cpp
msgid "Edit Plugin"
-msgstr ""
+msgstr "पà¥à¤²à¤—इन को संपादित करें"
#: editor/editor_plugin_settings.cpp
msgid "Installed Plugins:"
-msgstr ""
+msgstr "सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ पà¥à¤²à¤—इनà¥à¤¸:"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
msgid "Update"
-msgstr ""
+msgstr "अदà¥à¤¯à¤¤à¤¨"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Version:"
-msgstr ""
+msgstr "संसà¥à¤•रण:"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
msgid "Author:"
-msgstr ""
+msgstr "लेखक:"
#: editor/editor_plugin_settings.cpp
msgid "Status:"
-msgstr ""
+msgstr "सà¥à¤¥à¤¿à¤¤à¤¿:"
#: editor/editor_plugin_settings.cpp
msgid "Edit:"
-msgstr ""
+msgstr "संपादित:"
#: editor/editor_profiler.cpp
msgid "Measure:"
-msgstr ""
+msgstr "рдорд╛рдк:"
#: editor/editor_profiler.cpp
msgid "Frame Time (sec)"
-msgstr ""
+msgstr "फà¥à¤°à¥‡à¤® समय (सेकंड)"
#: editor/editor_profiler.cpp
msgid "Average Time (sec)"
-msgstr ""
+msgstr "औसत समय (सेकंड)"
#: editor/editor_profiler.cpp
msgid "Frame %"
-msgstr ""
+msgstr "फ़à¥à¤°à¥‡à¤®%"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
-msgstr ""
+msgstr "फिजिकà¥à¤¸ फà¥à¤°à¥‡à¤® %"
#: editor/editor_profiler.cpp
msgid "Inclusive"
-msgstr ""
+msgstr "समावेशी"
#: editor/editor_profiler.cpp
msgid "Self"
-msgstr ""
+msgstr "सà¥à¤µà¤¯à¤‚"
#: editor/editor_profiler.cpp
msgid "Frame #:"
-msgstr ""
+msgstr "फà¥à¤°à¥‡à¤® #:"
#: editor/editor_profiler.cpp
msgid "Time"
-msgstr ""
+msgstr "समय"
#: editor/editor_profiler.cpp
msgid "Calls"
-msgstr ""
+msgstr "कॉल"
#: editor/editor_properties.cpp
#, fuzzy
@@ -3137,23 +3196,23 @@ msgstr "परिवरà¥à¤¤à¤¨ वकà¥à¤° चयन"
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
-msgstr ""
+msgstr "पर"
#: editor/editor_properties.cpp
msgid "Layer"
-msgstr ""
+msgstr "परत"
#: editor/editor_properties.cpp
msgid "Bit %d, value %d"
-msgstr ""
+msgstr "बिट%d, मूलà¥à¤¯ % डी"
#: editor/editor_properties.cpp
msgid "[Empty]"
-msgstr ""
+msgstr "[खाली]"
#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
msgid "Assign..."
-msgstr ""
+msgstr "सौंपना..."
#: editor/editor_properties.cpp
#, fuzzy
@@ -3165,12 +3224,15 @@ msgid ""
"The selected resource (%s) does not match any type expected for this "
"property (%s)."
msgstr ""
+"चयनित संसाधन (%s) इस संपतà¥à¤¤à¤¿ (% à¤à¤¸) के लिठअपेकà¥à¤·à¤¿à¤¤ किसी भी पà¥à¤°à¤•ार से मेल नहीं खाता है।"
#: editor/editor_properties.cpp
msgid ""
"Can't create a ViewportTexture on resources saved as a file.\n"
"Resource needs to belong to a scene."
msgstr ""
+"फ़ाइल के रूप में सहेजे गठसंसाधनों पर वà¥à¤¯à¥‚पोरà¥à¤Ÿà¤Ÿà¥‡à¤•à¥à¤¸à¤šà¤° नहीं बना सकते.\n"
+"संसाधन के लिठà¤à¤• दृशà¥à¤¯ से संबंधित की जरूरत है ।"
#: editor/editor_properties.cpp
msgid ""
@@ -3179,26 +3241,28 @@ msgid ""
"Please switch on the 'local to scene' property on it (and all resources "
"containing it up to a node)."
msgstr ""
+"इस संसाधन पर वà¥à¤¯à¥‚पोरà¥à¤Ÿà¤Ÿà¥‡à¤•à¥à¤¸à¤šà¤° नहीं बना सकते कà¥à¤¯à¥‹à¤‚कि यह सà¥à¤¥à¤¾à¤¨à¥€à¤¯ से दृशà¥à¤¯ के रूप में सेट नहीं है।\n"
+"कृपया उस पर 'सà¥à¤¥à¤¾à¤¨à¥€à¤¯ से दृशà¥à¤¯' संपतà¥à¤¤à¤¿ पर सà¥à¤µà¤¿à¤š करें (और इसे यà¥à¤•à¥à¤¤ सभी संसाधन à¤à¤• नोड तक)।"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Pick a Viewport"
-msgstr ""
+msgstr "वà¥à¤¯à¥‚पोरà¥à¤Ÿ चà¥à¤¨à¥‡à¤‚"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New Script"
-msgstr ""
+msgstr "नई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ"
#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
msgid "Extend Script"
-msgstr ""
+msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ बढ़ाà¤à¤"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New %s"
-msgstr ""
+msgstr "नया%s"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Make Unique"
-msgstr ""
+msgstr "अदà¥à¤µà¤¿à¤¤à¥€à¤¯ बनाओ"
#: editor/editor_properties.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
@@ -3212,193 +3276,197 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
-msgstr ""
+msgstr "चिपकाà¤à¤"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Convert To %s"
-msgstr ""
+msgstr "% à¤à¤¸ में परिवरà¥à¤¤à¤¿à¤¤ करें"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Selected node is not a Viewport!"
-msgstr ""
+msgstr "चयनित नोड वà¥à¤¯à¥‚पोरà¥à¤Ÿ नहीं है!"
#: editor/editor_properties_array_dict.cpp
msgid "Size: "
-msgstr ""
+msgstr "आकार: "
#: editor/editor_properties_array_dict.cpp
msgid "Page: "
-msgstr ""
+msgstr "पृषà¥à¤ : "
#: editor/editor_properties_array_dict.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove Item"
-msgstr ""
+msgstr "आइटम निकालें"
#: editor/editor_properties_array_dict.cpp
msgid "New Key:"
-msgstr ""
+msgstr "नई कà¥à¤‚जी:"
#: editor/editor_properties_array_dict.cpp
msgid "New Value:"
-msgstr ""
+msgstr "नया मूलà¥à¤¯:"
#: editor/editor_properties_array_dict.cpp
msgid "Add Key/Value Pair"
-msgstr ""
+msgstr "कà¥à¤‚जी/मूलà¥à¤¯ जोड़ी जोड़ें"
#: editor/editor_run_native.cpp
msgid ""
"No runnable export preset found for this platform.\n"
"Please add a runnable preset in the export menu."
msgstr ""
+"इस मंच के लिठकोई रननयोगà¥à¤¯ निरà¥à¤¯à¤¾à¤¤ पूरà¥à¤µ निरà¥à¤§à¤¾à¤°à¤¿à¤¤ नहीं मिला।\n"
+"कृपया निरà¥à¤¯à¤¾à¤¤ मेनू में à¤à¤• रननेबल पà¥à¤°à¥€à¤¸à¥‡à¤Ÿ जोड़ें।"
#: editor/editor_run_script.cpp
msgid "Write your logic in the _run() method."
-msgstr ""
+msgstr "अपने तरà¥à¤• को _run () विधि में लिखें।"
#: editor/editor_run_script.cpp
msgid "There is an edited scene already."
-msgstr ""
+msgstr "वहां à¤à¤• संपादित दृशà¥à¤¯ पहले से ही है ।"
#: editor/editor_run_script.cpp
msgid "Couldn't instance script:"
-msgstr ""
+msgstr "उदाहरण सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं कर सका:"
#: editor/editor_run_script.cpp
msgid "Did you forget the 'tool' keyword?"
-msgstr ""
+msgstr "कà¥à¤¯à¤¾ आप 'टूल' कीवरà¥à¤¡ भूल गà¤?"
#: editor/editor_run_script.cpp
msgid "Couldn't run script:"
-msgstr ""
+msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं चला सका:"
#: editor/editor_run_script.cpp
msgid "Did you forget the '_run' method?"
-msgstr ""
+msgstr "कà¥à¤¯à¤¾ आप '_run' विधि को भूल गà¤?"
#: editor/editor_sub_scene.cpp
msgid "Select Node(s) to Import"
-msgstr ""
+msgstr "आयात करने के लिठनोड (à¤à¤¸) का चयन करें"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
msgid "Browse"
-msgstr ""
+msgstr "बà¥à¤°à¤¾à¤‰à¤œà¤¼"
#: editor/editor_sub_scene.cpp
msgid "Scene Path:"
-msgstr ""
+msgstr "दृशà¥à¤¯ पथ:"
#: editor/editor_sub_scene.cpp
msgid "Import From Node:"
-msgstr ""
+msgstr "नोड से आयात:"
#: editor/export_template_manager.cpp
msgid "Redownload"
-msgstr ""
+msgstr "रीडाउनलोड करें"
#: editor/export_template_manager.cpp
msgid "Uninstall"
-msgstr ""
+msgstr "अनइंसà¥à¤Ÿà¤¾à¤² करें"
#: editor/export_template_manager.cpp
msgid "(Installed)"
-msgstr ""
+msgstr "(सà¥à¤¥à¤¾à¤ªà¤¿à¤¤)"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download"
-msgstr ""
+msgstr "डाउनलोड"
#: editor/export_template_manager.cpp
msgid "Official export templates aren't available for development builds."
-msgstr ""
+msgstr "विकास के निरà¥à¤®à¤¾à¤£ के लिठआधिकारिक निरà¥à¤¯à¤¾à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¤‰à¤ªà¤²à¤¬à¥à¤§ नहीं हैं।"
#: editor/export_template_manager.cpp
msgid "(Missing)"
-msgstr ""
+msgstr "(लापता)"
#: editor/export_template_manager.cpp
msgid "(Current)"
-msgstr ""
+msgstr "(वरà¥à¤¤à¤®à¤¾à¤¨)"
#: editor/export_template_manager.cpp
msgid "Retrieving mirrors, please wait..."
-msgstr ""
+msgstr "दरà¥à¤ªà¤£ को पà¥à¤¨à¤ƒ पà¥à¤°à¤¾à¤ªà¥à¤¤ करना, कृपया पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करें ..."
#: editor/export_template_manager.cpp
msgid "Remove template version '%s'?"
-msgstr ""
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ संसà¥à¤•रण '%s'?"
#: editor/export_template_manager.cpp
msgid "Can't open export templates zip."
-msgstr ""
+msgstr "निरà¥à¤¯à¤¾à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ ज़िप नहीं खोल सकते।"
#: editor/export_template_manager.cpp
msgid "Invalid version.txt format inside templates: %s."
-msgstr ""
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ के अंदर अमानà¥à¤¯ संसà¥à¤•रण.txt पà¥à¤°à¤¾à¤°à¥‚प: % à¤à¤¸à¥¤"
#: editor/export_template_manager.cpp
msgid "No version.txt found inside templates."
-msgstr ""
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ के अंदर कोई संसà¥à¤•रण.txt नहीं मिला।"
#: editor/export_template_manager.cpp
msgid "Error creating path for templates:"
-msgstr ""
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ के लिठपथ बनाने में तà¥à¤°à¥à¤Ÿà¤¿:"
#: editor/export_template_manager.cpp
msgid "Extracting Export Templates"
-msgstr ""
+msgstr "à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ निकालना"
#: editor/export_template_manager.cpp
msgid "Importing:"
-msgstr ""
+msgstr "आयात:"
#: editor/export_template_manager.cpp
msgid "Error getting the list of mirrors."
-msgstr ""
+msgstr "तà¥à¤°à¥à¤Ÿà¤¿ दरà¥à¤ªà¤£ की सूची हो रही है।"
#: editor/export_template_manager.cpp
msgid "Error parsing JSON of mirror list. Please report this issue!"
-msgstr ""
+msgstr "मिरर लिसà¥à¤Ÿ की तà¥à¤°à¥à¤Ÿà¤¿ पारà¥à¤¸à¤¿à¤‚ग जेसन । कृपया इस मà¥à¤¦à¥à¤¦à¥‡ की रिपोरà¥à¤Ÿ करें!"
#: editor/export_template_manager.cpp
msgid ""
"No download links found for this version. Direct download is only available "
"for official releases."
msgstr ""
+"इस संसà¥à¤•रण के लिठकोई डाउनलोड लिंक नहीं मिला। पà¥à¤°à¤¤à¥à¤¯à¤•à¥à¤· डाउनलोड केवल आधिकारिक रिलीज के "
+"लिठउपलबà¥à¤§ है।"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Can't resolve."
-msgstr ""
+msgstr "हल नहीं कर सकते।"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Can't connect."
-msgstr ""
+msgstr "कनेकà¥à¤Ÿ नहीं कर सकते।"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No response."
-msgstr ""
+msgstr "कोई जवाब नहीं।"
#: editor/export_template_manager.cpp
msgid "Request Failed."
-msgstr ""
+msgstr "अनà¥à¤°à¥‹à¤§ विफल रहा।"
#: editor/export_template_manager.cpp
msgid "Redirect Loop."
-msgstr ""
+msgstr "लूप को रीडायरेकà¥à¤Ÿ करते हैं।"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed:"
-msgstr ""
+msgstr "विफल:"
#: editor/export_template_manager.cpp
msgid "Download Complete."
-msgstr ""
+msgstr "पूरा डाउनलोड करें।"
#: editor/export_template_manager.cpp
#, fuzzy
@@ -3410,6 +3478,8 @@ msgid ""
"Templates installation failed.\n"
"The problematic templates archives can be found at '%s'."
msgstr ""
+"टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ विफल रही।\n"
+"समसà¥à¤¯à¤¾à¤—à¥à¤°à¤¸à¥à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ अभिलेखागार '%' पर पाया जा सकता है।"
#: editor/export_template_manager.cpp
msgid "Error requesting URL:"
@@ -3417,24 +3487,24 @@ msgstr "लोड होने मे तà¥à¤°à¥à¤Ÿà¤¿:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
-msgstr ""
+msgstr "मिरर से कनेकà¥à¤Ÿ..."
#: editor/export_template_manager.cpp
msgid "Disconnected"
-msgstr ""
+msgstr "डिसà¥à¤•नेकà¥à¤Ÿ"
#: editor/export_template_manager.cpp
msgid "Resolving"
-msgstr ""
+msgstr "समाधान"
#: editor/export_template_manager.cpp
msgid "Can't Resolve"
-msgstr ""
+msgstr "हल नहीं कर सकते"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connecting..."
-msgstr ""
+msgstr "जोड़ने..."
#: editor/export_template_manager.cpp
msgid "Can't Connect"
@@ -3442,24 +3512,24 @@ msgstr "कनेकà¥à¤Ÿ नहीं कर सकते"
#: editor/export_template_manager.cpp
msgid "Connected"
-msgstr ""
+msgstr "जà¥à¤¡à¤¼à¤¾"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Requesting..."
-msgstr ""
+msgstr "अनà¥à¤°à¥‹à¤§..."
#: editor/export_template_manager.cpp
msgid "Downloading"
-msgstr ""
+msgstr "डाउनलोड"
#: editor/export_template_manager.cpp
msgid "Connection Error"
-msgstr ""
+msgstr "कनेकà¥à¤¶à¤¨ तà¥à¤°à¥à¤Ÿà¤¿"
#: editor/export_template_manager.cpp
msgid "SSL Handshake Error"
-msgstr ""
+msgstr "à¤à¤¸à¤à¤¸à¤à¤² हैंडशेक à¤à¤°à¤°"
#: editor/export_template_manager.cpp
msgid "Uncompressing Android Build Sources"
@@ -3467,19 +3537,19 @@ msgstr "अनकॉमिंग à¤à¤‚डà¥à¤°à¥‰à¤‡à¤¡ बिलà¥à¤¡ सà¥
#: editor/export_template_manager.cpp
msgid "Current Version:"
-msgstr ""
+msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ संसà¥à¤•रण:"
#: editor/export_template_manager.cpp
msgid "Installed Versions:"
-msgstr ""
+msgstr "सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ संसà¥à¤•रण:"
#: editor/export_template_manager.cpp
msgid "Install From File"
-msgstr ""
+msgstr "फ़ाइल से इंसà¥à¤Ÿà¥‰à¤² करें"
#: editor/export_template_manager.cpp
msgid "Remove Template"
-msgstr ""
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ निकालें"
#: editor/export_template_manager.cpp
msgid "Select Template File"
@@ -3487,19 +3557,19 @@ msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ फ़ाइल का चयन करें"
#: editor/export_template_manager.cpp
msgid "Godot Export Templates"
-msgstr ""
+msgstr "गोडॉट à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸"
#: editor/export_template_manager.cpp
msgid "Export Template Manager"
-msgstr ""
+msgstr "à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ टेमà¥à¤ªà¤²à¥‡à¤Ÿ मैनेजर"
#: editor/export_template_manager.cpp
msgid "Download Templates"
-msgstr ""
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ डाउनलोड करें"
#: editor/export_template_manager.cpp
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
-msgstr ""
+msgstr "सूची से दरà¥à¤ªà¤£ चà¥à¤¨à¥‡à¤‚: (शिफà¥à¤Ÿ +कà¥à¤²à¤¿à¤•: बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° में खà¥à¤²à¤¾)"
#: editor/filesystem_dock.cpp
msgid "Favorites"
@@ -3508,14 +3578,15 @@ msgstr "पसंद"
#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
+"सà¥à¤¥à¤¿à¤¤à¤¿: फाइल का आयात विफल रहा। कृपया फाइल को ठीक करें और मैनà¥à¤¯à¥à¤…ल रूप से पà¥à¤¨à¤°à¥à¤†à¤¯à¤¾à¤¤ करें।"
#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
-msgstr ""
+msgstr "संसाधनों की जड़ को सà¥à¤¥à¤¾à¤¨à¤¾à¤‚तरित/नाम नहीं दे सकते ।"
#: editor/filesystem_dock.cpp
msgid "Cannot move a folder into itself."
-msgstr ""
+msgstr "फ़ोलà¥à¤¡à¤° को अपने आप में नहीं ले जा सकते।"
#: editor/filesystem_dock.cpp
msgid "Error moving:"
@@ -3531,11 +3602,11 @@ msgstr "निरà¥à¤­à¤°à¤¤à¤¾ को अपडेट करने में à
#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
msgid "No name provided."
-msgstr ""
+msgstr "कोई नाम पà¥à¤°à¤¦à¤¾à¤¨ नहीं किया गया।"
#: editor/filesystem_dock.cpp
msgid "Provided name contains invalid characters."
-msgstr ""
+msgstr "बशरà¥à¤¤à¥‡ नाम में अमानà¥à¤¯ पातà¥à¤° होते हैं।"
#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
@@ -3890,7 +3961,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6691,14 +6762,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7136,6 +7199,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7224,13 +7291,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10633,6 +10700,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12280,6 +12353,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -12311,6 +12388,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Issue Tracker"
+#~ msgstr "मà¥à¤¦à¥à¤¦à¤¾ पर नज़र रखने वाला"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "बदल दिया % डी घटना (à¤à¤¸) ।"
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index ce8191c638..5087044b13 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -1423,7 +1423,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2829,7 +2829,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3855,7 +3859,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6654,14 +6658,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7091,6 +7087,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7179,13 +7179,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10526,6 +10526,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12154,6 +12160,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index cbe475b022..54206db36f 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -1507,7 +1507,7 @@ msgstr "AutoLoad Ãthelyezése"
msgid "Remove Autoload"
msgstr "AutoLoad Eltávolítása"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Engedélyezés"
@@ -3075,8 +3075,13 @@ msgid "Q&A"
msgstr "Kérdések és Válaszok"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Problémakövető"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Újraimportálás"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4167,7 +4172,7 @@ msgid "Reimport"
msgstr "Újraimportálás"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7177,14 +7182,6 @@ msgid "Open Godot online documentation."
msgstr "Godot online dokumentáció megnyitása"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Keresés a referencia dokumentációban."
@@ -7645,6 +7642,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7735,13 +7736,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -11270,6 +11271,12 @@ msgid "Script file already exists."
msgstr "Már létezik '%s' AutoLoad!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Osztály:"
@@ -12954,6 +12961,10 @@ msgstr ""
"gyermekévé, hogy így kapjon méretet. Ellenkező esetben tegye RenderTarget-"
"té, és állítsa hozzá a belső textúráját valamilyen node-hoz kirajzolásra."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -12985,6 +12996,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Issue Tracker"
+#~ msgstr "Problémakövető"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Lecserélve %d előfordulás."
diff --git a/editor/translations/id.po b/editor/translations/id.po
index c4ead514c6..087a274249 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -25,12 +25,13 @@
# Akhmad Zulfikar <azuldegratz@gmail.com>, 2020.
# Ade Fikri Malihuddin <ade.fm97@gmail.com>, 2020.
# zephyroths <ridho.hikaru@gmail.com>, 2020.
+# Richard Urban <redasuio1@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-08 22:33+0000\n"
-"Last-Translator: Sofyan Sugianto <sofyanartem@gmail.com>\n"
+"PO-Revision-Date: 2020-04-16 11:03+0000\n"
+"Last-Translator: Richard Urban <redasuio1@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -38,7 +39,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -1462,7 +1463,7 @@ msgstr "Pindahkan Autoload"
msgid "Remove Autoload"
msgstr "Hapus Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Aktifkan"
@@ -2947,8 +2948,13 @@ msgid "Q&A"
msgstr "Tanya Jawab"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Pelacak Isu"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Impor ulang"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4000,7 +4006,8 @@ msgid "Reimport"
msgstr "Impor ulang"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Simpan skena, impor ulang, dan mulai ulang"
#: editor/import_dock.cpp
@@ -5874,7 +5881,6 @@ msgid "Couldn't create a single convex collision shape."
msgstr "Tidak dapat membuat convex collision shape tunggal."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Shape"
msgstr "Buat Bentuk Cembung"
@@ -5887,7 +5893,6 @@ msgid "Couldn't create any collision shapes."
msgstr "Tidak dapat membuat bentuk collision."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Shapes"
msgstr "Buat Beberapa Bentuk Cembung"
@@ -5964,7 +5969,6 @@ msgstr ""
"collision."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
msgstr "Buat Saudara Tunggal Convex Collision"
@@ -6855,14 +6859,6 @@ msgid "Open Godot online documentation."
msgstr "Buka dokumentasi daring Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Minta Dokumentasi"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Bantu tingkatkan dokumentasi Godot dengan memberikan tanggapan."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Cari dokumentasi referensi."
@@ -7301,6 +7297,11 @@ msgid "This operation requires a single selected node."
msgstr "Operasi ini membutuhkan satu node yang dipilih."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Kunci Rotasi Tampilan"
@@ -7389,6 +7390,10 @@ msgid "Freelook Slow Modifier"
msgstr "Pengubah Lambat Tampilan Bebas"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Rotasi Tampilan Terkunci"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7397,10 +7402,6 @@ msgstr ""
"Tidak bisa digunakan sebagai indikasi kinerja gim yang dapat dihandalkan."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Rotasi Tampilan Terkunci"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Dialog XForm"
@@ -10914,6 +10915,12 @@ msgid "Script file already exists."
msgstr "Berkas skrip sudah ada."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Nama Kelas:"
@@ -11298,7 +11305,6 @@ msgid "GridMap Paste Selection"
msgstr "Rekat(Paste) Seleksi GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Paint"
msgstr "Cat GridMap"
@@ -11716,7 +11722,7 @@ msgstr "Tidak dapat membuat fungsi dengan node fungsi."
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't create function of nodes from nodes of multiple functions."
-msgstr ""
+msgstr "Tidak dapat membuat fungsi node dari node beberapa fungsi."
#: modules/visual_script/visual_script_editor.cpp
msgid "Select at least one node with sequence port."
@@ -11881,19 +11887,19 @@ msgstr "Nama paket tidak ada."
#: platform/android/export/export.cpp
msgid "Package segments must be of non-zero length."
-msgstr ""
+msgstr "Segmen paket panjangnya harus tidak boleh nol."
#: platform/android/export/export.cpp
msgid "The character '%s' is not allowed in Android application package names."
-msgstr ""
+msgstr "Karakter '%s' tidak diizinkan dalam penamaan paket aplikasi Android."
#: platform/android/export/export.cpp
msgid "A digit cannot be the first character in a package segment."
-msgstr ""
+msgstr "Digit tidak boleh diletakkan sebagai karakter awal di segmen paket."
#: platform/android/export/export.cpp
msgid "The character '%s' cannot be the first character in a package segment."
-msgstr ""
+msgstr "Karakter '%s' tidak bisa dijadikan karakter awal dalam segmen paket."
#: platform/android/export/export.cpp
msgid "The package must have at least one '.' separator."
@@ -11939,7 +11945,7 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
-msgstr ""
+msgstr "Kunci Publik untuk ekspansi APK tidak valid."
#: platform/android/export/export.cpp
msgid "Invalid package name:"
@@ -11950,6 +11956,8 @@ msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
+"Mencoba untuk membangun dari templat build khusus, tapi tidak ada informasi "
+"versinya. Silakan pasang ulang dari menu 'Proyek'."
#: platform/android/export/export.cpp
msgid ""
@@ -11958,24 +11966,30 @@ msgid ""
" Godot Version: %s\n"
"Please reinstall Android build template from 'Project' menu."
msgstr ""
+"Versi build Android tidak cocok:\n"
+" Templat terpasang: %s\n"
+" Versi Godot: %s\n"
+"Silakan pasang ulang templat build Android dari menu 'Project'."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr ""
+msgstr "Membangun Proyek Android (gradle)"
#: platform/android/export/export.cpp
msgid ""
"Building of Android project failed, check output for the error.\n"
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
+"Pembangunan proyek Android gagal, periksa output untuk galatnya.\n"
+"Atau kunjungi docs.godotengine.org untuk dokumentasi build Android."
#: platform/android/export/export.cpp
msgid "No build apk generated at: "
-msgstr ""
+msgstr "Tak ada build apk yang dihasilkan di: "
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
-msgstr ""
+msgstr "Kurang identifier."
#: platform/iphone/export/export.cpp
msgid "The character '%s' is not allowed in Identifier."
@@ -11984,6 +11998,7 @@ msgstr "Karakter '%s' tidak diizinkan dalam Identifier."
#: platform/iphone/export/export.cpp
msgid "App Store Team ID not specified - cannot configure the project."
msgstr ""
+"App Store Team ID tidak ditetapkan - tidak dapat mengonfigurasi proyek."
#: platform/iphone/export/export.cpp
msgid "Invalid Identifier:"
@@ -11991,19 +12006,19 @@ msgstr "Identifier tidak valid:"
#: platform/iphone/export/export.cpp
msgid "Required icon is not specified in the preset."
-msgstr ""
+msgstr "Ikon yang dibutuhkan tidak ditentukan dalam preset."
#: platform/javascript/export/export.cpp
msgid "Stop HTTP Server"
-msgstr ""
+msgstr "Hentikan Server HTTP"
#: platform/javascript/export/export.cpp
msgid "Run in Browser"
-msgstr ""
+msgstr "Jalankan di Peramban"
#: platform/javascript/export/export.cpp
msgid "Run exported HTML in the system's default browser."
-msgstr ""
+msgstr "Jalankan HTML yang diekspor dalam peramban baku sistem."
#: platform/javascript/export/export.cpp
msgid "Could not write file:"
@@ -12055,31 +12070,31 @@ msgstr "Warna latar belakang tidak valid."
#: platform/uwp/export/export.cpp
msgid "Invalid Store Logo image dimensions (should be 50x50)."
-msgstr ""
+msgstr "Dimensi gambar Logo Store tidak valid (harus 50x50)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
-msgstr ""
+msgstr "Dimensi gambar logo persegi 44x44 tidak valid (harus 44x44)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
-msgstr ""
+msgstr "Dimensi gambar logo persegi 71x71 tidak valid (harus 71x71)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
-msgstr ""
+msgstr "Dimensi gambar logo persegi 150x150 tidak valid (harus 150x150)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
-msgstr ""
+msgstr "Dimensi gambar logo persegi 310x310 tidak valid (harus 310x310)."
#: platform/uwp/export/export.cpp
msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
-msgstr ""
+msgstr "Dimensi gambar logo 310x150 lebarnya tidak valid (harus 310x150)."
#: platform/uwp/export/export.cpp
msgid "Invalid splash screen image dimensions (should be 620x300)."
-msgstr ""
+msgstr "Dimensi gambar splash screen tidak valid (harus 620x300)."
#: scene/2d/animated_sprite.cpp
msgid ""
@@ -12104,6 +12119,10 @@ msgid ""
"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
"define its shape."
msgstr ""
+"Node ini tidak punya shape, jadi dia tidak bisa bertabrakan atau "
+"berinteraksi dengan objek lain.\n"
+"Pertimbangkan untuk menambahkan CollisionShape2D atau CollisionPolygon2D "
+"sebagai anak untuk mendefinisikan bentuknya."
#: scene/2d/collision_polygon_2d.cpp
msgid ""
@@ -12145,6 +12164,8 @@ msgid ""
"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
"\"Particles Animation\" enabled."
msgstr ""
+"Animasi CPUParticles2D membutuhkan penggunaan CanvasItemMaterial dengan "
+"\"Animasi Partikel\" diaktifkan."
#: scene/2d/light_2d.cpp
msgid ""
@@ -12194,18 +12215,25 @@ msgid ""
"Use the CPUParticles2D node instead. You can use the \"Convert to "
"CPUParticles\" option for this purpose."
msgstr ""
+"Partikel berbasis GPU tidak didukung oleh video driver GLES2.\n"
+"Gunakan node CPUParticles2D sebagai gantinya. Anda dapat menggunakan opsi "
+"\"Konversikan jadi CPUParticles\" untuk tujuan ini."
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
"imprinted."
msgstr ""
+"Material untuk memproses partikel belum ditetapkan, jadi tidak ada perilaku "
+"yang dimunculkan."
#: scene/2d/particles_2d.cpp
msgid ""
"Particles2D animation requires the usage of a CanvasItemMaterial with "
"\"Particles Animation\" enabled."
msgstr ""
+"Animasi Particles2D membutuhkan penggunaan CanvasItemMaterial dengan "
+"\"Animasi Partikel\" diaktifkan."
#: scene/2d/path_2d.cpp
msgid "PathFollow2D only works when set as a child of a Path2D node."
@@ -12219,6 +12247,9 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"Perubahan ukuran RigidBody2D (dalam mode karakter atau rigid/pejal) akan "
+"ditimpa oleh mesin fisika saat menjalankan.\n"
+"Sebagai gantinya, ubahlah ukuran di anakan collision shape-nya saja."
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
@@ -12227,16 +12258,19 @@ msgstr ""
#: scene/2d/skeleton_2d.cpp
msgid "This Bone2D chain should end at a Skeleton2D node."
-msgstr ""
+msgstr "Ikatan Bone2D ini harus diakhiri dengan node Skeleton2D."
#: scene/2d/skeleton_2d.cpp
msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
msgstr ""
+"Bone2D hanya bekerja dengan Skeleton2D atau Bone2D lain sebagai node induk."
#: scene/2d/skeleton_2d.cpp
msgid ""
"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
msgstr ""
+"Tulang ini tidak memiliki pose REST yang sesuai. Pergi ke node Skeleton2D "
+"dan tetapkan."
#: scene/2d/tile_map.cpp
msgid ""
@@ -12258,47 +12292,51 @@ msgstr ""
#: scene/3d/arvr_nodes.cpp
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr ""
+msgstr "ARVRCamera wajib memiliki node ARVROrigin sebagai induknya."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
-msgstr ""
+msgstr "ARVRController wajib memiliki node ARVROrigin sebagai induknya."
#: scene/3d/arvr_nodes.cpp
msgid ""
"The controller ID must not be 0 or this controller won't be bound to an "
"actual controller."
msgstr ""
+"ID pengontrol tidak boleh 0 atau pengontrol ini tidak terikat ke pengontrol "
+"yang sebenarnya."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr ""
+msgstr "ARVRAnchor wajib memiliki node ARVROrigin sebagai induknya."
#: scene/3d/arvr_nodes.cpp
msgid ""
"The anchor ID must not be 0 or this anchor won't be bound to an actual "
"anchor."
msgstr ""
+"ID jangkar tidak boleh 0 atau jangkar ini tidak akan terikat ke jangkar "
+"aslinya."
#: scene/3d/arvr_nodes.cpp
msgid "ARVROrigin requires an ARVRCamera child node."
-msgstr ""
+msgstr "ARVROrigin membutuhkan node anak ARVRCamera."
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
-msgstr ""
+msgstr "%d%%"
#: scene/3d/baked_lightmap.cpp
msgid "(Time Left: %d:%02d s)"
-msgstr ""
+msgstr "(Waktu tersisa: %d:%02d s)"
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Meshes: "
-msgstr ""
+msgstr "Plotting Meshes: "
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Lights:"
-msgstr ""
+msgstr "Plotting Lights:"
#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
msgid "Finishing Plot"
@@ -12642,6 +12680,10 @@ msgstr ""
"tidak, jadikan sebagai RenderTarget dan tetapkan tekstur internal nya ke "
"beberapa node untuk ditampilkan."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Sumber tidak sah untuk pratinjau."
@@ -12670,6 +12712,15 @@ msgstr "Variasi hanya bisa ditetapkan dalam fungsi vertex."
msgid "Constants cannot be modified."
msgstr "Konstanta tidak dapat dimodifikasi."
+#~ msgid "Issue Tracker"
+#~ msgstr "Pelacak Isu"
+
+#~ msgid "Request Docs"
+#~ msgstr "Minta Dokumentasi"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Bantu tingkatkan dokumentasi Godot dengan memberikan tanggapan."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "kejadian %d diganti."
diff --git a/editor/translations/is.po b/editor/translations/is.po
index 213e7d239b..bb865e255a 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -4,12 +4,13 @@
# This file is distributed under the same license as the Godot source code.
# Jóhannes G. Þorsteinsson <johannesg@johannesg.com>, 2017, 2018.
# Kaan Gül <qaantum@hotmail.com>, 2018.
+# Einar Magnús Einarsson <einar.m.einarsson@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-12-13 14:40+0100\n"
-"Last-Translator: Jóhannes G. Þorsteinsson <johannesg@johannesg.com>\n"
+"PO-Revision-Date: 2020-04-16 11:03+0000\n"
+"Last-Translator: Einar Magnús Einarsson <einar.m.einarsson@gmail.com>\n"
"Language-Team: Icelandic <https://hosted.weblate.org/projects/godot-engine/"
"godot/is/>\n"
"Language: is\n"
@@ -17,34 +18,35 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Poedit 2.2\n"
+"X-Generator: Weblate 4.0.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr ""
+msgstr "Ógild breyta send til convert(), notaðu TYPE_ * fasti."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "Búist var við streng með lengd 1 (a character)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr ""
+msgstr "Ekki nægt minni til að umskrá bæti eða ógilt snið."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr ""
+msgstr "Ógild inntak % i (ekki sent áfram)"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
msgstr ""
+"Ekki hægt að nota \"self\" vegna þess að tilvik er \"null\" (ekki samþykkt)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr ""
+msgstr "Ógilt reiknitákn notað í útreikningi % s,% s og% s."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
@@ -1441,7 +1443,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2852,7 +2854,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3878,7 +3884,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6689,14 +6695,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7127,6 +7125,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7215,13 +7217,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10588,6 +10590,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12215,6 +12223,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 738718a0fa..4ce247c712 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -44,12 +44,13 @@
# nickfla1 <lanterniniflavio@gmail.com>, 2019.
# Fabio Iotti <fabiogiopla@gmail.com>, 2020.
# Douglas Fiedler <dognew@gmail.com>, 2020.
+# E440QF <ettore.beltra@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-02-27 07:01+0000\n"
-"Last-Translator: Micila Micillotto <micillotto@gmail.com>\n"
+"PO-Revision-Date: 2020-04-08 16:36+0000\n"
+"Last-Translator: E440QF <ettore.beltra@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -1484,7 +1485,7 @@ msgstr "Sposta Autoload"
msgid "Remove Autoload"
msgstr "Rimuovi Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Abilita"
@@ -2983,8 +2984,13 @@ msgid "Q&A"
msgstr "Domande e risposte"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Tracciatore segnalazioni"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Reimporta"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4043,7 +4049,8 @@ msgid "Reimport"
msgstr "Reimporta"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Salva scene, importa nuovamente e riavvia"
#: editor/import_dock.cpp
@@ -6918,14 +6925,6 @@ msgid "Open Godot online documentation."
msgstr "Apri la documentazione online di Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Documentazione richiesta"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Aiutate a migliorare la documentazione di Godot fornendo feedback."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Cerca Riferimenti nella documentazione."
@@ -7361,6 +7360,11 @@ msgid "This operation requires a single selected node."
msgstr "Questa operazione richiede un solo nodo selezionato."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonale"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Blocca Rotazione Vista"
@@ -7449,6 +7453,10 @@ msgid "Freelook Slow Modifier"
msgstr "Modificatore Vista Libera Velocità Lenta"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Rotazione Vista Bloccata"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7458,10 +7466,6 @@ msgstr ""
"gioco."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Rotazione Vista Bloccata"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Finestra di XForm"
@@ -10975,6 +10979,12 @@ msgid "Script file already exists."
msgstr "Il file di script esiste già."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Nome Classe:"
@@ -12477,6 +12487,7 @@ msgstr ""
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
msgstr ""
+"ConcavePolygonShape non supporta RigidBody in modalità diverse da static."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
@@ -12774,6 +12785,10 @@ msgstr ""
"Control, in modo che possa ottenere una dimensione. Altrimenti, renderlo un "
"RenderTarget e assegnare alla sua texture interna qualche nodo da mostrare."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fonte non valida per l'anteprima."
@@ -12802,6 +12817,15 @@ msgstr "Varyings può essere assegnato soltanto nella funzione del vertice."
msgid "Constants cannot be modified."
msgstr "Le constanti non possono essere modificate."
+#~ msgid "Issue Tracker"
+#~ msgstr "Tracciatore segnalazioni"
+
+#~ msgid "Request Docs"
+#~ msgstr "Documentazione richiesta"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Aiutate a migliorare la documentazione di Godot fornendo feedback."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Rimpiazzate %d occorrenze."
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index 0bb76f1261..ab503d8294 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -35,8 +35,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-16 09:43+0000\n"
-"Last-Translator: Akihiro Ogoshi <technical@palsystem-game.com>\n"
+"PO-Revision-Date: 2020-04-15 14:29+0000\n"
+"Last-Translator: Wataru Onuki <bettawat@yahoo.co.jp>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/"
"godot/ja/>\n"
"Language: ja\n"
@@ -53,7 +53,7 @@ msgstr "convert() ã®å¼•æ•°ã®åž‹ãŒç„¡åйã§ã™ã€‚TYPE_* 定数を使ã£ã¦ãã
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "é•·ã•ãŒ1ã®æ–‡å­—列(文字)を予期ã—ã¾ã—ãŸã€‚"
+msgstr "é•·ã•1ã®æ–‡å­—列(文字)ãŒå¿…è¦ã§ã™ã€‚"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -63,19 +63,19 @@ msgstr "デコードã™ã‚‹ã«ã¯ãƒã‚¤ãƒˆãŒè¶³ã‚Šãªã„ã‹ã€ã¾ãŸã¯ç„¡åйãª
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr "入力ã•れãŸå¼ %i ã¯ç„¡åйã§ã™"
+msgstr "å¼ä¸­ã®ç„¡åйãªå…¥åŠ› %i (渡ã•れã¦ã„ã¾ã›ã‚“)"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "インスタンス㌠null ã®ãŸã‚ã€self ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
+msgstr "インスタンスãŒnull(渡ã•れãªã„)ã§ã‚ã‚‹ãŸã‚ã€selfã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr "æ¼”ç®—å­ %s, %s, %s ã«å¯¾ã™ã‚‹å€¤ãŒç„¡åйã§ã™ã€‚"
+msgstr "æ¼”ç®—å­ %s ã«å¯¾ã™ã‚‹ç„¡åйãªã‚ªãƒšãƒ©ãƒ³ãƒ‰ã§ã™ã€%s åŠã³ %s。"
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr "基本型 %s ã®åž‹ %s ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç„¡åйã§ã™"
+msgstr "タイプ %s ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç„¡åйã€ã“れã¯åŸºåº•åž‹ %s 用ã§ã™"
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
@@ -83,39 +83,39 @@ msgstr "インデックス '%s' (基底型 %s) ã¯ç„¡åйãªåå‰ã§ã™"
#: core/math/expression.cpp
msgid "Invalid arguments to construct '%s'"
-msgstr "'%s' ã®å¼•æ•°ã¯ç„¡åйã§ã™"
+msgstr "'%s' を構築ã™ã‚‹ãŸã‚ã®å¼•æ•°ãŒç„¡åйã§ã™"
#: core/math/expression.cpp
msgid "On call to '%s':"
-msgstr "'%s' ã¸ã®å‘¼ã³å‡ºã—:"
+msgstr "'%s' ã®å‘¼ã³å‡ºã—時:"
#: core/ustring.cpp
msgid "B"
-msgstr "\\ B"
+msgstr "B"
#: core/ustring.cpp
msgid "KiB"
-msgstr "\\ KiB"
+msgstr "KiB"
#: core/ustring.cpp
msgid "MiB"
-msgstr "\\ MiB"
+msgstr "MiB"
#: core/ustring.cpp
msgid "GiB"
-msgstr "\\ GiB"
+msgstr "GiB"
#: core/ustring.cpp
msgid "TiB"
-msgstr "\\ TiB"
+msgstr "TiB"
#: core/ustring.cpp
msgid "PiB"
-msgstr "\\ PiB"
+msgstr "PiB"
#: core/ustring.cpp
msgid "EiB"
-msgstr "\\ EiB"
+msgstr "EiB"
#: editor/animation_bezier_editor.cpp
msgid "Free"
@@ -330,11 +330,11 @@ msgstr "キュービック"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
-msgstr "ループインタプリタを抑ãˆè¾¼ã¿ï¼ˆclamp)"
+msgstr "ループインタプリタを抑ãˆè¾¼ã¿(clamp)"
#: editor/animation_track_editor.cpp
msgid "Wrap Loop Interp"
-msgstr "ループインタプリタをラップ(wrap)"
+msgstr "ループインタプリタをラップ(wrap)"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -721,11 +721,11 @@ msgstr "%d ã‚’ç½®æ›ã—ã¾ã—ãŸã€‚"
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr "ï¼…dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚"
+msgstr "%dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚"
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d matches."
-msgstr "ï¼…dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚"
+msgstr "%dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -1049,7 +1049,7 @@ msgstr "次ã®ã‚ªãƒ¼ãƒŠãƒ¼:"
#: editor/dependency_editor.cpp
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "é¸æŠžã—ãŸãƒ•ァイルをプロジェクトã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã‹? (å…ƒã«æˆ»ã›ã¾ã›ã‚“)"
+msgstr "é¸æŠžã—ãŸãƒ•ァイルをプロジェクトã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ(å…ƒã«æˆ»ã›ã¾ã›ã‚“)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1058,7 +1058,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
"除去ã—よã†ã¨ã—ã¦ã„るファイルã¯ä»–ã®ãƒªã‚½ãƒ¼ã‚¹ã®å‹•作ã«å¿…è¦ã§ã™ã€‚\n"
-"無視ã—ã¦é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿ (å…ƒã«æˆ»ã›ã¾ã›ã‚“)"
+"無視ã—ã¦é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿ(å…ƒã«æˆ»ã›ã¾ã›ã‚“)"
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1090,7 +1090,7 @@ msgstr "読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ï¼"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "%d 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’完全ã«å‰Šé™¤ã—ã¾ã™ã‹?ï¼ˆå…ƒã«æˆ»ã›ã¾ã›ã‚“!)"
+msgstr "%d 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’完全ã«å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ(å…ƒã«æˆ»ã›ã¾ã›ã‚“ï¼)"
#: editor/dependency_editor.cpp
msgid "Show Dependencies"
@@ -1299,7 +1299,7 @@ msgstr "ãƒã‚¹ã‚¨ãƒ•ェクトを削除"
#: editor/editor_audio_buses.cpp
msgid "Drag & drop to rearrange."
-msgstr "ドラッグ・アンド・ドロップã§ä¸¦ã³æ›¿ãˆã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+msgstr "ドラッグ&ドロップã§ä¸¦ã³æ›¿ãˆã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
#: editor/editor_audio_buses.cpp
msgid "Solo"
@@ -1340,7 +1340,7 @@ msgstr "オーディオãƒã‚¹ã‚’追加"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr "マスター ãƒã‚¹ã¯å‰Šé™¤ã§ãã¾ã›ã‚“!"
+msgstr "マスターãƒã‚¹ã¯å‰Šé™¤ã§ãã¾ã›ã‚“ï¼"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
@@ -1372,7 +1372,7 @@ msgstr "オーディオãƒã‚¹ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã‚’é–‹ã"
#: editor/editor_audio_buses.cpp
msgid "There is no '%s' file."
-msgstr "'ï¼…s' ファイルãŒã‚りã¾ã›ã‚“。"
+msgstr "'%s' ファイルãŒã‚りã¾ã›ã‚“。"
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
msgid "Layout"
@@ -1468,7 +1468,7 @@ msgstr "自動読込ã¿ã‚’移動"
msgid "Remove Autoload"
msgstr "自動読込ã¿ã‚’除去"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "有効"
@@ -1549,7 +1549,7 @@ msgstr "ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é¸æŠž"
#: editor/filesystem_dock.cpp editor/project_manager.cpp
#: scene/gui/file_dialog.cpp
msgid "Create Folder"
-msgstr "フォルダーを作æˆ"
+msgstr "フォルダを作æˆ"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
@@ -1777,7 +1777,7 @@ msgstr "エディタ機能ã®ãƒ—ロファイルã®ç®¡ç†"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
-msgstr "ç¾åœ¨ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠž"
+msgstr "ç¾åœ¨ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File Exists, Overwrite?"
@@ -1785,7 +1785,7 @@ msgstr "ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚上書ãã—ã¾ã™ã‹ï¼Ÿ"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select This Folder"
-msgstr "ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠž"
+msgstr "ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
@@ -2393,7 +2393,7 @@ msgstr "é–‰ã˜ã‚‹å‰ã«ã€'%s' ã¸ã®å¤‰æ›´ã‚’ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ"
#: editor/editor_node.cpp
msgid "Saved %s modified resource(s)."
-msgstr "ï¼…s個ã®å¤‰æ›´ã•れãŸãƒªã‚½ãƒ¼ã‚¹ã‚’ä¿å­˜ã—ã¾ã—ãŸã€‚"
+msgstr "%s個ã®å¤‰æ›´ã•れãŸãƒªã‚½ãƒ¼ã‚¹ã‚’ä¿å­˜ã—ã¾ã—ãŸã€‚"
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
@@ -2449,7 +2449,7 @@ msgstr "å…ƒã«æˆ»ã™"
#: editor/editor_node.cpp
msgid "This action cannot be undone. Revert anyway?"
-msgstr "ã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。ãれã§ã‚‚å…ƒã«æˆ»ã—ã¾ã™ã‹?"
+msgstr "ã“ã®æ“作ã¯å–り消ã›ã¾ã›ã‚“。ãれã§ã‚‚å…ƒã«æˆ»ã—ã¾ã™ã‹?"
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
@@ -2461,7 +2461,7 @@ msgstr "終了"
#: editor/editor_node.cpp
msgid "Exit the editor?"
-msgstr "エディターを終了ã—ã¾ã™ã‹ï¼Ÿ"
+msgstr "エディタを終了ã—ã¾ã™ã‹ï¼Ÿ"
#: editor/editor_node.cpp
msgid "Open Project Manager?"
@@ -2696,7 +2696,7 @@ msgstr "æ–°è¦ã‚·ãƒ¼ãƒ³"
#: editor/editor_node.cpp
msgid "New Inherited Scene..."
-msgstr "æ–°ã—ã„継承ã—ãŸã‚·ãƒ¼ãƒ³..."
+msgstr "æ–°ã—ã„継承シーン..."
#: editor/editor_node.cpp
msgid "Open Scene..."
@@ -2804,7 +2804,7 @@ msgid ""
"connect to the IP of this computer in order to be debugged."
msgstr ""
"エクスãƒãƒ¼ãƒˆã¾ãŸã¯ãƒ‡ãƒ—ロイを行ã†å ´åˆã€ç”Ÿæˆã•れãŸå®Ÿè¡Œãƒ•ァイルã¯ãƒ‡ãƒãƒƒã‚°ã®ãŸã‚"
-"ã«ã€ã“ã®ã‚³ãƒ³ãƒ”ューターã®ï¼©ï¼°ã«æŽ¥ç¶šã‚’試ã¿ã¾ã™ã€‚"
+"ã«ã€ã“ã®ã‚³ãƒ³ãƒ”ューターã®IPã«æŽ¥ç¶šã‚’è©¦ã¿ã¾ã™ã€‚"
#: editor/editor_node.cpp
msgid "Small Deploy with Network FS"
@@ -2951,8 +2951,13 @@ msgid "Q&A"
msgstr "Q&A"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "課題管ç†ã‚·ã‚¹ãƒ†ãƒ "
+#, fuzzy
+msgid "Report a Bug"
+msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3079,7 +3084,7 @@ msgid ""
"operation again."
msgstr ""
"Androidビルドテンプレートã¯ã™ã§ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ãŠã‚Šã€ä¸Šæ›¸ãã•れã¾ã›ã‚“。\n"
-"ã“ã®æ“作をå†è©¦è¡Œã™ã‚‹å‰ã«ã€ \"res://android/build\" ディレクトリを手動ã§å‰Šé™¤ã—"
+"ã“ã®æ“作をå†è©¦è¡Œã™ã‚‹å‰ã«ã€\"res://android/build\" ディレクトリを手動ã§å‰Šé™¤ã—"
"ã¦ãã ã•ã„。"
#: editor/editor_node.cpp
@@ -3096,7 +3101,7 @@ msgstr "ライブラリã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
#: editor/editor_node.cpp
msgid "Merge With Existing"
-msgstr "既存ã®ï¼ˆãƒ©ã‚¤ãƒ–ラリを)マージ"
+msgstr "既存ã®(ライブラリを)マージ"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
@@ -3193,11 +3198,11 @@ msgstr "測定:"
#: editor/editor_profiler.cpp
msgid "Frame Time (sec)"
-msgstr "フレーム時間(秒)"
+msgstr "フレーム時間(秒)"
#: editor/editor_profiler.cpp
msgid "Average Time (sec)"
-msgstr "平凿™‚間(秒)"
+msgstr "平凿™‚é–“(ç§’)"
#: editor/editor_profiler.cpp
msgid "Frame %"
@@ -3348,7 +3353,7 @@ msgstr "æ–°è¦ã®å€¤:"
#: editor/editor_properties_array_dict.cpp
msgid "Add Key/Value Pair"
-msgstr "キー・値ã®ãƒšã‚¢ã‚’追加"
+msgstr "キー/値ã®ãƒšã‚¢ã‚’追加"
#: editor/editor_run_native.cpp
msgid ""
@@ -3421,7 +3426,7 @@ msgstr "å…¬å¼ã®æ›¸ã出ã—テンプレートã¯é–‹ç™ºç”¨ãƒ“ルドã®å ´åˆã¯
#: editor/export_template_manager.cpp
msgid "(Missing)"
-msgstr "(見ã¤ã‹ã‚Šã¾ã›ã‚“)"
+msgstr "(見ã¤ã‹ã‚Šã¾ã›ã‚“)"
#: editor/export_template_manager.cpp
msgid "(Current)"
@@ -3607,7 +3612,7 @@ msgstr "テンプレートをダウンロード"
#: editor/export_template_manager.cpp
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
-msgstr "リストã‹ã‚‰ãƒŸãƒ©ãƒ¼ã‚’é¸æŠž: (Shift+クリック: ブラウザã§é–‹ã)"
+msgstr "リストã‹ã‚‰ãƒŸãƒ©ãƒ¼ã‚’é¸æŠž: (Shift+クリック: ブラウザã§é–‹ã)"
#: editor/filesystem_dock.cpp
msgid "Favorites"
@@ -3621,7 +3626,7 @@ msgstr ""
#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
-msgstr "ルートã®ãƒªã‚½ãƒ¼ã‚¹ã¯ç§»å‹•・リãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“。"
+msgstr "ルートã®ãƒªã‚½ãƒ¼ã‚¹ã¯ç§»å‹•/リãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“。"
#: editor/filesystem_dock.cpp
msgid "Cannot move a folder into itself."
@@ -3673,7 +3678,7 @@ msgstr "フォルダを複製:"
#: editor/filesystem_dock.cpp
msgid "New Inherited Scene"
-msgstr "æ–°ã—ã„継承ã—ãŸã‚·ãƒ¼ãƒ³"
+msgstr "æ–°ã—ã„継承シーン"
#: editor/filesystem_dock.cpp
msgid "Set As Main Scene"
@@ -3806,7 +3811,7 @@ msgstr "フォルダ:"
#: editor/find_in_files.cpp
msgid "Filters:"
-msgstr "フィルター:"
+msgstr "フィルタ:"
#: editor/find_in_files.cpp
msgid ""
@@ -3968,7 +3973,7 @@ msgstr "インãƒãƒ¼ãƒˆæ¸ˆã®ã‚¹ã‚¯ãƒªãƒ—トを読込ã‚ã¾ã›ã‚“ã§ã—ãŸï¼š"
#: editor/import/resource_importer_scene.cpp
msgid "Invalid/broken script for post-import (check console):"
-msgstr "無効・壊れãŸã‚¤ãƒ³ãƒãƒ¼ãƒˆæ¸ˆã‚¹ã‚¯ãƒªãƒ—ト(コンソールを確èªã—ã¦ãã ã•ã„):"
+msgstr "無効ã¾ãŸã¯å£Šã‚ŒãŸã‚¤ãƒ³ãƒãƒ¼ãƒˆæ¸ˆã‚¹ã‚¯ãƒªãƒ—ト(コンソールを確èªã—ã¦ãã ã•ã„):"
#: editor/import/resource_importer_scene.cpp
msgid "Error running post-import script:"
@@ -4003,7 +4008,8 @@ msgid "Reimport"
msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "シーンをä¿å­˜ã—ã¦ã€å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦å†èµ·å‹•ã—ã¦ãã ã•ã„"
#: editor/import_dock.cpp
@@ -4052,7 +4058,7 @@ msgstr "ビルトインを作æˆ"
#: editor/inspector_dock.cpp
msgid "Make Sub-Resources Unique"
-msgstr "ユニークãªã‚µãƒ–リソースを生æˆ"
+msgstr "サブリソースをユニーク化ã™ã‚‹"
#: editor/inspector_dock.cpp
msgid "Open in Help"
@@ -4166,7 +4172,7 @@ msgstr "ãƒã‚¤ãƒ³ãƒˆæŒ¿å…¥"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Edit Polygon (Remove Point)"
-msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)"
+msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Remove Polygon And Point"
@@ -4374,11 +4380,11 @@ msgstr "ノードを削除"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Toggle Filter On/Off"
-msgstr "フィルター㮠オン/オフ を切り替ãˆ"
+msgstr "フィルタ㮠オン/オフ を切り替ãˆ"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Change Filter"
-msgstr "フィルターを変更"
+msgstr "フィルタを変更"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
@@ -4506,27 +4512,27 @@ msgstr "編集ã™ã‚‹ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒã‚りã¾ã›ã‚“ï¼"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
-msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®ä½ç½®ã‹ã‚‰é€†å†ç”Ÿã™ã‚‹ã€‚(A)"
+msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®ä½ç½®ã‹ã‚‰é€†å†ç”Ÿã™ã‚‹ã€‚(A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from end. (Shift+A)"
-msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’最後ã‹ã‚‰é€†å†ç”Ÿã™ã‚‹ã€‚(Shift+A)"
+msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’最後ã‹ã‚‰é€†å†ç”Ÿã™ã‚‹ã€‚(Shift+A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Stop animation playback. (S)"
-msgstr "アニメーションã®å†ç”Ÿã‚’åœæ­¢ã™ã‚‹ã€‚(S)"
+msgstr "アニメーションã®å†ç”Ÿã‚’åœæ­¢ã™ã‚‹ã€‚(S)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from start. (Shift+D)"
-msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’最åˆã‹ã‚‰å†ç”Ÿã™ã‚‹ã€‚(Shift+D)"
+msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’最åˆã‹ã‚‰å†ç”Ÿã™ã‚‹ã€‚(Shift+D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from current pos. (D)"
-msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®ä½ç½®ã‹ã‚‰å†ç”Ÿã™ã‚‹ã€‚(D)"
+msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®ä½ç½®ã‹ã‚‰å†ç”Ÿã™ã‚‹ã€‚(D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation position (in seconds)."
-msgstr "アニメーションã®ä½ç½®ï¼ˆç§’)。"
+msgstr "アニメーションã®ä½ç½® (ç§’)。"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Scale animation playback globally for the node."
@@ -4629,7 +4635,7 @@ msgstr "ブレンド時間:"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Next (Auto Queue):"
-msgstr "次(自動キュー):"
+msgstr "次 (自動キュー):"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Cross-Animation Blend Times"
@@ -4678,7 +4684,7 @@ msgstr "サブトランジションã«ã¯ã€é–‹å§‹ãƒŽãƒ¼ãƒ‰ã¨çµ‚了ノードãŒ
#: editor/plugins/animation_state_machine_editor.cpp
msgid "No playback resource set at path: %s."
-msgstr "パス( %s )ã«å†ç”Ÿãƒªã‚½ãƒ¼ã‚¹ãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“。"
+msgstr "パス: %s ã«å†ç”Ÿãƒªã‚½ãƒ¼ã‚¹ãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“。"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Node Removed"
@@ -4793,7 +4799,7 @@ msgstr "ブレンド 1:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "X-Fade Time (s):"
-msgstr "クロスフェード時間(秒):"
+msgstr "クロスフェード時間 (秒):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Current:"
@@ -5386,7 +5392,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+RMB: Depth list selection"
-msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ã(被写界深度)リストã®é¸æŠž"
+msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ã(被写界深度)リストã®é¸æŠž"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5597,8 +5603,8 @@ msgid ""
"Keys are only added to existing tracks, no new tracks will be created.\n"
"Keys must be inserted manually for the first time."
msgstr ""
-"キーã®è‡ªå‹•挿入ã¯ï¼ˆãƒžã‚¹ã‚¯ã«åŸºã¥ã„ã¦ï¼‰ã‚ªãƒ–ジェクトãŒç§»å‹•ã€å›žè»¢ã€ã¾ãŸã¯æ‹¡å¤§ç¸®å°"
-"ã•れãŸéš›ã«è¡Œã‚れã¾ã™ã€‚\n"
+"キーã®è‡ªå‹•挿入ã¯(マスクã«åŸºã¥ã„ã¦)オブジェクトãŒç§»å‹•ã€å›žè»¢ã€ã¾ãŸã¯æ‹¡å¤§ç¸®å°ã•"
+"れãŸéš›ã«è¡Œã‚れã¾ã™ã€‚\n"
"ã‚­ãƒ¼ã¯æ—¢å­˜ã®ãƒˆãƒ©ãƒƒã‚¯ã«ã®ã¿è¿½åŠ ã•ã‚Œã€æ–°ã—ã„トラックã¯ä½œæˆã•れã¾ã›ã‚“。\n"
"åˆå›žã®ã‚­ãƒ¼æŒ¿å…¥ã¯æ‰‹å‹•ã§è¡Œã†å¿…è¦ãŒã‚りã¾ã™ã€‚"
@@ -5678,7 +5684,7 @@ msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集"
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly (Remove Point)"
-msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)"
+msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)"
#: editor/plugins/collision_shape_2d_editor_plugin.cpp
msgid "Set Handle"
@@ -6064,14 +6070,13 @@ msgstr "シーンã‹ã‚‰ã‚¢ãƒƒãƒ—デート"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and no MultiMesh set in node)."
msgstr ""
-"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“(ノードã«MultiMeshãŒè¨­å®šã•れã¦ã„ã¾ã›"
-"ん)。"
+"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“(ノードã«MultiMeshãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“)。"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and MultiMesh contains no Mesh)."
msgstr ""
-"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“(ãã—ã¦MultiMeshã«ã¯ãƒ¡ãƒƒã‚·ãƒ¥ãŒå«ã¾ã‚Œã¦ã„"
-"ã¾ã›ã‚“)。"
+"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“(ãã—ã¦MultiMeshã«ã¯ãƒ¡ãƒƒã‚·ãƒ¥ãŒå«ã¾ã‚Œã¦ã„"
+"ã¾ã›ã‚“)。"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (invalid path)."
@@ -6854,15 +6859,6 @@ msgid "Open Godot online documentation."
msgstr "Godotã®ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’é–‹ã。"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’è¦æ±‚"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-"フィードãƒãƒƒã‚¯ã‚’æä¾›ã—ã¦ã€Godotã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã®æ”¹å–„ã«å½¹ç«‹ã¦ã¦ãã ã•ã„。"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "リファレンス文書を探ã™."
@@ -6924,8 +6920,8 @@ msgstr "ターゲット"
msgid ""
"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
msgstr ""
-"ノード'ï¼…s'ã‹ã‚‰ãƒŽãƒ¼ãƒ‰'ï¼…s'ã¸é€ã‚‹ã‚·ã‚°ãƒŠãƒ«'ï¼…s'ã®ãƒ¡ã‚½ãƒƒãƒ‰'ï¼…s'ã¸ã®æŽ¥ç¶šãŒè¦‹ã¤ã‹"
-"りã¾ã›ã‚“。"
+"メソッド'%s' (シグナル'ï¼…s'用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€ã“れã¯ãƒŽãƒ¼ãƒ‰'%s'ã‹ã‚‰ãƒŽãƒ¼"
+"ド'%s'ã¸ã®ã‚·ã‚°ãƒŠãƒ«ç”¨ã§ã™ã€‚"
#: editor/plugins/script_text_editor.cpp
msgid "Line"
@@ -6947,8 +6943,8 @@ msgstr "ファイルシステムã®ãƒªã‚½ãƒ¼ã‚¹ã®ã¿ãƒ‰ãƒ­ãƒƒãƒ—ã§ãã¾ã™."
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't drop nodes because script '%s' is not used in this scene."
msgstr ""
-"スクリプト '%s' ã¯ã“ã®ã‚·ãƒ¼ãƒ³ã§ä½¿ã‚れã¦ã„ãªã„ãŸã‚ã€ãƒŽãƒ¼ãƒ‰ã‚’(ドラッグ&)ドロッ"
-"プã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。"
+"スクリプト '%s' ã¯ã“ã®ã‚·ãƒ¼ãƒ³ã§ä½¿ã‚れã¦ã„ãªã„ãŸã‚ã€ãƒŽãƒ¼ãƒ‰ã‚’(ドラッグ&)ドロップ"
+"ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。"
#: editor/plugins/script_text_editor.cpp
msgid "Lookup Symbol"
@@ -7112,7 +7108,7 @@ msgid ""
"This shader has been modified on on disk.\n"
"What action should be taken?"
msgstr ""
-"ã“ã®ã‚·ã‚§ãƒ¼ãƒ€ã¯ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã§ä¿®æ­£ã•れã¦ã„ã¾ã™ã€‚\n"
+"ã“ã®ã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ã¯ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã§ä¿®æ­£ã•れã¦ã„ã¾ã™ã€‚\n"
"ã©ã†ã—ã¾ã™ã‹?"
#: editor/plugins/shader_editor_plugin.cpp
@@ -7201,7 +7197,7 @@ msgstr "%s 度回転."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Keying is disabled (no key inserted)."
-msgstr "キーã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã¾ã™ï¼ˆã‚­ãƒ¼ã¯æŒ¿å…¥ã•れã¦ã„ã¾ã›ã‚“)."
+msgstr "キーã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã¾ã™(ã‚­ãƒ¼ã¯æŒ¿å…¥ã•れã¦ã„ã¾ã›ã‚“)。"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Animation Key Inserted."
@@ -7241,11 +7237,11 @@ msgstr "頂点"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View."
-msgstr "上é¢å›³."
+msgstr "上é¢å›³ã€‚"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View."
-msgstr "下é¢å›³."
+msgstr "下é¢å›³ã€‚"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom"
@@ -7269,7 +7265,7 @@ msgstr "å³å´é¢"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front View."
-msgstr "å‰é¢å›³."
+msgstr "å‰é¢å›³ã€‚"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front"
@@ -7300,6 +7296,11 @@ msgid "This operation requires a single selected node."
msgstr "å˜ä¸€ã®é¸æŠžã•れãŸãƒŽãƒ¼ãƒ‰ãŒãªã„ã¨ã€ã“ã®æ“作ã¯è¡Œãˆã¾ã›ã‚“。"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "平行投影"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "ビューã®å›žè»¢ã‚’固定"
@@ -7388,18 +7389,18 @@ msgid "Freelook Slow Modifier"
msgstr "ãƒ•ãƒªãƒ¼ãƒ«ãƒƒã‚¯ã®æ¸›é€Ÿã‚’調整"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "ビューã®å›žè»¢ã‚’固定中"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
-"注æ„:表示ã•れるFPS値ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã®ãƒ•レームレートã§ã™ã€‚\n"
+"注æ„: 表示ã•れるFPS値ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã®ãƒ•レームレートã§ã™ã€‚\n"
"ゲーム内ã®ãƒ‘フォーマンスを確実ã«ç¤ºã™ã‚‚ã®ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "ビューã®å›žè»¢ã‚’固定中"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Xformダイアログ"
@@ -7537,7 +7538,7 @@ msgstr "スナップを移動:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Snap (deg.):"
-msgstr "スナップã®å›žè»¢ï¼ˆåº¦ï¼‰:"
+msgstr "スナップã®å›žè»¢(度):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Snap (%):"
@@ -7569,7 +7570,7 @@ msgstr "移動:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate (deg.):"
-msgstr "回転(度):"
+msgstr "回転(度):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale (ratio):"
@@ -7593,7 +7594,7 @@ msgstr "ç„¡åã®ã‚®ã‚ºãƒ¢"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create Mesh2D"
-msgstr "Mesh2Dを作æˆã™ã‚‹"
+msgstr "Mesh2Dを作æˆ"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Mesh2D Preview"
@@ -7645,11 +7646,11 @@ msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚ãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Convert to Polygon2D"
-msgstr "Polygon2Dã«å¤‰æ›"
+msgstr "Polygon2Dã«å¤‰æ›ã™ã‚‹"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create collision polygon."
-msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚è¡çªãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。"
+msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚コリジョンãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create CollisionPolygon2D Sibling"
@@ -7725,7 +7726,7 @@ msgstr "アニメーションã®FPSを変更"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "(empty)"
-msgstr "(空)"
+msgstr "(空)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move Frame"
@@ -7866,7 +7867,7 @@ msgstr "テーマを編集"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme editing menu."
-msgstr "テーマ編集メニュー."
+msgstr "テーマ編集メニュー。"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add Class Items"
@@ -8036,7 +8037,7 @@ msgstr "タイルを検索ã™ã‚‹"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
-msgstr "行列(縦横)入れ替ãˆ"
+msgstr "行列(縦横)入れ替ãˆ"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
@@ -9282,9 +9283,9 @@ msgid ""
"output ports. This is a direct injection of code into the vertex/fragment/"
"light function, do not use it to write the function declarations inside."
msgstr ""
-"カスタムã®Godotシェーダ言語å¼ã€‚カスタムã®é‡ã®å…¥å‡ºåŠ›ãƒãƒ¼ãƒˆã‚’æŒã¡ã¾ã™ã€‚ ã“れã¯"
-"vertex / fragment / light関数ã¸ã®ã‚³ãƒ¼ãƒ‰ã®ç›´æŽ¥æ³¨å…¥ã§ã™ã€‚内部ã§é–¢æ•°å®£è¨€ã‚’書ããŸ"
-"ã‚ã«ãれを使用ã—ãªã„ã§ãã ã•ã„。"
+"カスタムã®Godotシェーダー言語å¼ã€‚カスタムã®é‡ã®å…¥å‡ºåŠ›ãƒãƒ¼ãƒˆã‚’æŒã¡ã¾ã™ã€‚ ã“れ"
+"ã¯vertex / fragment / light関数ã¸ã®ã‚³ãƒ¼ãƒ‰ã®ç›´æŽ¥æ³¨å…¥ã§ã™ã€‚内部ã§é–¢æ•°å®£è¨€ã‚’書ã"
+"ãŸã‚ã«ãれを使用ã—ãªã„ã§ãã ã•ã„。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9458,11 +9459,11 @@ msgstr "プロジェクト内ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’ã™ã¹ã¦ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
#: editor/project_export.cpp
msgid "Export selected scenes (and dependencies)"
-msgstr "é¸æŠžã—ãŸã‚·ãƒ¼ãƒ³ï¼ˆã¨ä¾å­˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®ï¼‰ã‚’エクスãƒãƒ¼ãƒˆ"
+msgstr "é¸æŠžã—ãŸã‚·ãƒ¼ãƒ³(ã¨ä¾å­˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®)をエクスãƒãƒ¼ãƒˆ"
#: editor/project_export.cpp
msgid "Export selected resources (and dependencies)"
-msgstr "é¸æŠžã—ãŸãƒªã‚½ãƒ¼ã‚¹ï¼ˆã¨ä¾å­˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®ï¼‰ã‚’エクスãƒãƒ¼ãƒˆ"
+msgstr "é¸æŠžã—ãŸãƒªã‚½ãƒ¼ã‚¹(ã¨ä¾å­˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®)をエクスãƒãƒ¼ãƒˆ"
#: editor/project_export.cpp
msgid "Export Mode:"
@@ -9594,7 +9595,7 @@ msgstr ""
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
-msgstr "空ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
+msgstr "空ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
#: editor/project_manager.cpp
msgid "Please choose a \"project.godot\" or \".zip\" file."
@@ -9622,7 +9623,7 @@ msgstr "フォルダを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
#: editor/project_manager.cpp
msgid "There is already a folder in this path with the specified name."
-msgstr "ã“ã®ãƒ‘スã«ã¯ã€æŒ‡å®šã•れãŸåå‰ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚"
+msgstr "ã“ã®ãƒ‘スã«ã¯ã€æŒ‡å®šã•れãŸåå‰ã®ãƒ•ã‚©ãƒ«ãƒ€ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚"
#: editor/project_manager.cpp
msgid "It would be a good idea to name your project."
@@ -9877,7 +9878,7 @@ msgstr "スキャン"
#: editor/project_manager.cpp
msgid "Select a Folder to Scan"
-msgstr "スキャンã™ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠž"
+msgstr "スキャンã™ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž"
#: editor/project_manager.cpp
msgid "New Project"
@@ -9928,8 +9929,8 @@ msgid ""
"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'"
msgstr ""
-"アクションåãŒç„¡åйã§ã™ã€‚空ã«ã—ãŸã‚Šã€ã€Œ/ ã€ã€ã€Œ: ã€ã€ã€Œ= ã€ã€ã€Œ\\ ã€ã‚’å«ã‚ã‚‹ã“"
-"ã¨ã¯ã§ãã¾ã›ã‚“"
+"アクションåãŒç„¡åйã§ã™ã€‚空ã«ã—ãŸã‚Šã€'/'ã€':'ã€'='ã€'\\'等をå«ã‚ã‚‹ã“ã¨ã¯ã§ãã¾"
+"ã›ã‚“"
#: editor/project_settings_editor.cpp
msgid "An action with the name '%s' already exists."
@@ -10041,11 +10042,11 @@ msgstr "中クリック"
#: editor/project_settings_editor.cpp
msgid "Wheel Up."
-msgstr "マウスホイールを上."
+msgstr "マウスホイールを上ã«ã€‚"
#: editor/project_settings_editor.cpp
msgid "Wheel Down."
-msgstr "マウスホイールを下."
+msgstr "マウスホイールを下ã«ã€‚"
#: editor/project_settings_editor.cpp
msgid "Add Global Property"
@@ -10072,8 +10073,8 @@ msgid ""
"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'."
msgstr ""
-"無効ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³åã§ã™ã€‚空もã—ãã¯'/', ':', '=', '\\' ã‚„ '\"'ã‚’å«ã‚ã‚‹ã“ã¨ã¯ã§"
-"ãã¾ã›ã‚“。"
+"無効ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³åã§ã™ã€‚空もã—ãã¯'/'ã€':'ã€'='ã€'\\' ã€'\"'等をå«ã‚ã‚‹ã“ã¨ã¯"
+"ã§ãã¾ã›ã‚“。"
#: editor/project_settings_editor.cpp
msgid "Add Input Action"
@@ -10081,11 +10082,11 @@ msgstr "入力アクションã®è¿½åŠ "
#: editor/project_settings_editor.cpp
msgid "Error saving settings."
-msgstr "設定をä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ."
+msgstr "設定をä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
#: editor/project_settings_editor.cpp
msgid "Settings saved OK."
-msgstr "設定ã®ä¿å­˜ã«æˆåŠŸã—ã¾ã—ãŸ."
+msgstr "設定ã®ä¿å­˜ã«æˆåŠŸã—ã¾ã—ãŸã€‚"
#: editor/project_settings_editor.cpp
msgid "Moved Input Action Event"
@@ -10201,7 +10202,7 @@ msgstr "ロケール"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
-msgstr "ロケールフィルター"
+msgstr "ロケールフィルタ"
#: editor/project_settings_editor.cpp
msgid "Show All Locales"
@@ -10213,7 +10214,7 @@ msgstr "é¸æŠžã—ãŸãƒ­ã‚±ãƒ¼ãƒ«ã®ã¿è¡¨ç¤º"
#: editor/project_settings_editor.cpp
msgid "Filter mode:"
-msgstr "フィルターモード:"
+msgstr "フィルタモード:"
#: editor/project_settings_editor.cpp
msgid "Locales:"
@@ -10790,7 +10791,7 @@ msgstr "ノードã®åå‰ã‚’変更"
#: editor/scene_tree_editor.cpp
msgid "Scene Tree (Nodes):"
-msgstr "シーンツリー(ノード):"
+msgstr "シーンツリー(ノード):"
#: editor/scene_tree_editor.cpp
msgid "Node Configuration Warning!"
@@ -10874,7 +10875,7 @@ msgstr "スクリプトã®ãƒ‘ス/åå‰ã¯æœ‰åйã§ã™ã€‚"
#: editor/script_create_dialog.cpp
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
-msgstr "使用å¯èƒ½: a-z, A-Z, 0-9 㨠."
+msgstr "使用å¯èƒ½: a-zã€A-Zã€0-9åŠã³_。"
#: editor/script_create_dialog.cpp
msgid "Built-in script (into scene file)."
@@ -10893,6 +10894,12 @@ msgid "Script file already exists."
msgstr "ã‚¹ã‚¯ãƒªãƒ—ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«ã‚りã¾ã™ã€‚"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "クラスå:"
@@ -11202,7 +11209,7 @@ msgstr "ライブラリ: "
#: modules/gdnative/register_types.cpp
msgid "GDNative"
-msgstr "\\ GDNative"
+msgstr "GDNative"
#: modules/gdscript/gdscript_functions.cpp
msgid "Step argument is zero!"
@@ -11384,7 +11391,7 @@ msgstr "NavMeshを焼ã込む"
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Clear the navigation mesh."
-msgstr "ãƒŠãƒ“ãƒ¡ãƒƒã‚·ãƒ¥ï¼ˆãƒŠãƒ“ã‚²ãƒ¼ã‚·ãƒ§ãƒ³ãƒ¡ãƒƒã‚·ãƒ¥ï¼‰ã®æ¶ˆåŽ»."
+msgstr "ナビメッシュ(ナビゲーションメッシュ)ã®æ¶ˆåŽ»ã€‚"
#: modules/recast/navigation_mesh_generator.cpp
msgid "Setting up Configuration..."
@@ -11428,7 +11435,7 @@ msgstr "ãƒã‚¤ãƒ†ã‚£ãƒ–ナビゲーションメッシュã«å¤‰æ›ã—ã¦ã„ã¾ã™
#: modules/recast/navigation_mesh_generator.cpp
msgid "Navigation Mesh Generator Setup:"
-msgstr "ナビメッシュ(ナビゲーションメッシュ)生æˆè¨­å®š:"
+msgstr "ナビメッシュ(ナビゲーションメッシュ)生æˆè¨­å®š:"
#: modules/recast/navigation_mesh_generator.cpp
msgid "Parsing Geometry..."
@@ -11586,34 +11593,33 @@ msgstr "VisualScriptノードを複製"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
msgstr ""
-"%sを押ã—ãŸã¾ã¾Getterを(ドラッグ&)ドロップã™ã‚‹ã€‚Shiftを押ã—ãŸã¾ã¾æ±Žç”¨ç½²åã‚’"
-"(ドラッグ&)ドロップã™ã‚‹ã€‚"
+"%sを押ã—ãŸã¾ã¾Getterã‚’(ドラッグ&)ドロップã™ã‚‹ã€‚Shiftを押ã—ãŸã¾ã¾æ±Žç”¨ç½²åã‚’"
+"(ドラッグ&)ドロップã™ã‚‹ã€‚"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
msgstr ""
-"Ctrlを押ã—ãŸã¾ã¾Getterを(ドラッグ&)ドロップã™ã‚‹ã€‚Shiftを押ã—ãŸã¾ã¾æ±Žç”¨ã‚·ã‚°"
-"ãƒãƒãƒ£ã‚’(ドラッグ&)ドロップã™ã‚‹."
+"Ctrlを押ã—ãŸã¾ã¾Getterã‚’(ドラッグ&)ドロップã™ã‚‹ã€‚Shiftを押ã—ãŸã¾ã¾æ±Žç”¨ã‚·ã‚°ãƒ"
+"ãƒãƒ£ã‚’(ドラッグ&)ドロップã™ã‚‹."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a simple reference to the node."
msgstr ""
-"%sを押ã—ãŸã¾ã¾ãƒŽãƒ¼ãƒ‰ã¸å˜ç´”å‚照(simple reference)を(ドラッグ&)ドロップã™"
-"る。"
+"%sを押ã—ãŸã¾ã¾ãƒŽãƒ¼ãƒ‰ã¸å˜ç´”å‚ç…§(simple reference)ã‚’(ドラッグ&)ドロップã™ã‚‹ã€‚"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a simple reference to the node."
msgstr ""
-"Ctrlを押ã—ãŸã¾ã¾ãƒŽãƒ¼ãƒ‰ã¸å˜ç´”å‚照(simple reference)を(ドラッグ&)ドロップã™"
+"Ctrlを押ã—ãŸã¾ã¾ãƒŽãƒ¼ãƒ‰ã¸å˜ç´”å‚ç…§(simple reference)ã‚’(ドラッグ&)ドロップã™"
"る。"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Variable Setter."
-msgstr "%sを押ã—ãŸã¾ã¾å¤‰æ•°ã®Setterを(ドラッグ&)ドロップã™ã‚‹ã€‚"
+msgstr "%sを押ã—ãŸã¾ã¾å¤‰æ•°ã®Setterã‚’(ドラッグ&)ドロップã™ã‚‹ã€‚"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a Variable Setter."
-msgstr "Ctrlを押ã—ãŸã¾ã¾å¤‰æ•°ã®Setterを(ドラッグ&)ドロップã™ã‚‹ã€‚"
+msgstr "Ctrlを押ã—ãŸã¾ã¾å¤‰æ•°ã®Setterã‚’(ドラッグ&)ドロップã™ã‚‹ã€‚"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Preload Node"
@@ -11890,7 +11896,7 @@ msgstr "ADB実行å¯èƒ½ãƒ•ァイルãŒã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§è¨­å®šã•れã¦ã„ã¾
#: platform/android/export/export.cpp
msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿ãƒ¼è¨­å®šã§è¨­å®šã•れã¦ã„ã¾ã›ã‚“。"
+msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§è¨­å®šã•れã¦ã„ã¾ã›ã‚“。"
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12127,8 +12133,8 @@ msgid ""
"A shape must be provided for CollisionShape2D to function. Please create a "
"shape resource for it!"
msgstr ""
-"関数ã«å¯¾ã—㦠CollisionShape2D ã®å½¢çŠ¶ï¼ˆã‚·ã‚§ã‚¤ãƒ—ï¼‰ã‚’æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ã"
-"ã®ãŸã‚ã®ã‚·ã‚§ã‚¤ãƒ—リソースを作æˆã—ã¦ãã ã•ã„!"
+"関数ã«å¯¾ã—㦠CollisionShape2D ã®å½¢çж(シェイプ)を指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ãã®"
+"ãŸã‚ã®ã‚·ã‚§ã‚¤ãƒ—リソースを作æˆã—ã¦ãã ã•ã„!"
#: scene/2d/cpu_particles_2d.cpp
msgid ""
@@ -12540,7 +12546,7 @@ msgstr "無効ãªã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³: '%s'。"
#: scene/animation/animation_tree.cpp
msgid "Nothing connected to input '%s' of node '%s'."
-msgstr "ノード 'ï¼…s'ã®å…¥åŠ› 'ï¼…s'ã«æŽ¥ç¶šã•れã¦ã„ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“。"
+msgstr "入力 'ï¼…s'(ノード 'ï¼…s')ã«æŽ¥ç¶šã•れã¦ã„ã‚‹ã‚‚ã®ã¯ã‚りã¾ã›ã‚“。"
#: scene/animation/animation_tree.cpp
msgid "No root AnimationNode for the graph is set."
@@ -12584,7 +12590,7 @@ msgstr "HSV"
#: scene/gui/color_picker.cpp
msgid "Raw"
-msgstr "ロー"
+msgstr "Raw"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -12670,6 +12676,10 @@ msgstr ""
"れ以外ã®å ´åˆã¯ã€RenderTarget ã«ã—ã¦ã€ãã®å†…部テクスãƒãƒ£ã‚’表示ã™ã‚‹ãƒŽãƒ¼ãƒ‰ã«å‰²ã‚Š"
"当ã¦ã¾ã™ã€‚"
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "プレビューã®ã‚½ãƒ¼ã‚¹ãŒç„¡åйã§ã™ã€‚"
@@ -12698,6 +12708,16 @@ msgstr "Varying変数ã¯é ‚点関数ã«ã®ã¿å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã
msgid "Constants cannot be modified."
msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
+#~ msgid "Issue Tracker"
+#~ msgstr "課題管ç†ã‚·ã‚¹ãƒ†ãƒ "
+
+#~ msgid "Request Docs"
+#~ msgstr "ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’è¦æ±‚"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr ""
+#~ "フィードãƒãƒƒã‚¯ã‚’æä¾›ã—ã¦ã€Godotã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã®æ”¹å–„ã«å½¹ç«‹ã¦ã¦ãã ã•ã„。"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d 箇所を置æ›ã—ã¾ã—ãŸã€‚"
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index 1aaa12d6a0..ad4d5072f6 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -1495,7 +1495,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2933,7 +2933,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3979,7 +3983,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6837,14 +6841,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7288,6 +7284,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7377,13 +7377,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10800,6 +10800,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12452,6 +12458,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index ec33599440..dd2d617eb8 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -15,12 +15,13 @@
# moolow <copyhyeon@gmail.com>, 2019.
# Jiyoon Kim <kimjiy@dickinson.edu>, 2019.
# Ervin <zetsmart@gmail.com>, 2019.
+# Tilto_ <tilto0822@develable.xyz>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-14 00:33+0000\n"
-"Last-Translator: Ch. <ccwpc@hanmail.net>\n"
+"PO-Revision-Date: 2020-03-27 07:42+0000\n"
+"Last-Translator: Tilto_ <tilto0822@develable.xyz>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
"Language: ko\n"
@@ -1449,7 +1450,7 @@ msgstr "오토로드 ì´ë™"
msgid "Remove Autoload"
msgstr "오토로드 삭제"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "켜기"
@@ -2923,8 +2924,13 @@ msgid "Q&A"
msgstr "Q&A"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "ì´ìŠˆ 트래커"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "다시 가져오기"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3970,7 +3976,8 @@ msgid "Reimport"
msgstr "다시 가져오기"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "씬 저장, 다시 가져오기 ë° ë‹¤ì‹œ 시작"
#: editor/import_dock.cpp
@@ -5836,9 +5843,8 @@ msgid "Couldn't create a single convex collision shape."
msgstr "ë‹¨ì¼ convex ì¶©ëŒ ëª¨ì–‘ì„ ë§Œë“¤ 수 없습니다."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Shape"
-msgstr "Convex 모양 만들기"
+msgstr "개별 Convex 모양 만들기"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create multiple convex collision shapes for the scene root."
@@ -5923,9 +5929,8 @@ msgstr ""
"ì´ ë°©ë²•ì€ ê°€ìž¥ 정확한 (하지만 가장 ëŠë¦°) ì¶©ëŒ íƒì§€ 방법입니다."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
-msgstr "Convex ì¶©ëŒ í˜•ì œ 만들기"
+msgstr "개별 Convex ì¶©ëŒ í˜•ì œ 만들기"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -5936,7 +5941,6 @@ msgstr ""
"ì´ ë°©ë²•ì€ ê°€ìž¥ 빠른 (하지만 ëœ ì •í™•í•œ) ì¶©ëŒ íƒì§€ 방법입니다."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Collision Siblings"
msgstr "다중 Convex ì¶©ëŒ í˜•ì œ 만들기"
@@ -6810,14 +6814,6 @@ msgid "Open Godot online documentation."
msgstr "Godot 온ë¼ì¸ 문서를 ì—´."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "문서 요청"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "피드백으로 Godot 문서를 ê°œì„ í•˜ëŠ”ë° ë„와주세요."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "참조 문서 검색."
@@ -7254,6 +7250,11 @@ msgid "This operation requires a single selected node."
msgstr "ì´ ìž‘ì—…ì€ í•˜ë‚˜ì˜ ë…¸ë“œë¥¼ ì„ íƒí•´ì•¼ 합니다."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "ì§êµë³´ê¸°"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "뷰 회전 잠금"
@@ -7342,6 +7343,10 @@ msgid "Freelook Slow Modifier"
msgstr "ìžìœ  ì‹œì  ëŠë¦° 수정ìž"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "뷰 회전 잠김"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7350,10 +7355,6 @@ msgstr ""
"ì´ê²ƒì´ 게임 ë‚´ ì„±ëŠ¥ì„ ë³´ìž¥í•  수 없습니다."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "뷰 회전 잠김"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XForm 대화 ìƒìž"
@@ -9530,9 +9531,8 @@ msgid "Please choose a \"project.godot\" or \".zip\" file."
msgstr "\"project.godot\" íŒŒì¼ ë˜ëŠ” \".zip\" 파ì¼ì„ ì„ íƒí•´ì£¼ì„¸ìš”."
#: editor/project_manager.cpp
-#, fuzzy
msgid "This directory already contains a Godot project."
-msgstr "ë””ë ‰í† ë¦¬ì— Godot 프로ì íŠ¸ê°€ ì´ë¯¸ 있습니다."
+msgstr "ë””ë ‰í† ë¦¬ì— Godot 프로ì íŠ¸ê°€ ì´ë¯¸ 존재합니다."
#: editor/project_manager.cpp
msgid "New Game Project"
@@ -10263,7 +10263,6 @@ msgstr ""
"ì¹´ìš´í„° 설정과 비êµí•©ë‹ˆë‹¤."
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Per-level Counter"
msgstr "단계별 카운터"
@@ -10817,6 +10816,12 @@ msgid "Script file already exists."
msgstr "스í¬ë¦½íЏ 파ì¼ì´ ì´ë¯¸ 있습니다."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "í´ëž˜ìФ ì´ë¦„:"
@@ -12565,6 +12570,10 @@ msgstr ""
"ìš°, í™”ë©´ì— í‘œì‹œí•˜ê¸° 위해서는 ë·°í¬íŠ¸ë¥¼ RenderTarget으로 만들고 ë‚´ë¶€ì ì¸ í…스처"
"를 다른 ë…¸ë“œì— ì§€ì •í•´ì•¼ 합니다."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "미리 ë³´ê¸°ì— ìž˜ëª»ëœ ì†ŒìŠ¤."
@@ -12593,6 +12602,15 @@ msgstr "Varyingì€ ê¼­ì§“ì  í•¨ìˆ˜ì—ë§Œ 지정할 수 있습니다."
msgid "Constants cannot be modified."
msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
+#~ msgid "Issue Tracker"
+#~ msgstr "ì´ìŠˆ 트래커"
+
+#~ msgid "Request Docs"
+#~ msgstr "문서 요청"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "피드백으로 Godot 문서를 ê°œì„ í•˜ëŠ”ë° ë„와주세요."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d개를 바꿨습니다."
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index 1f58c4a658..25cec6842f 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -1457,7 +1457,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2898,7 +2898,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3953,7 +3957,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6821,14 +6825,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7264,6 +7260,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7353,13 +7353,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10785,6 +10785,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Priedai"
@@ -12439,6 +12445,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index 14dfdff801..973e732e2d 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -1464,7 +1464,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Iespējot"
@@ -2896,7 +2896,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3944,7 +3948,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6795,14 +6799,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7245,6 +7241,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7334,13 +7334,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10751,6 +10751,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12405,6 +12411,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index 5ec6cc28e0..f0b661e381 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -1399,7 +1399,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2802,7 +2802,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3823,7 +3827,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6605,14 +6609,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7042,6 +7038,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7130,13 +7130,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10454,6 +10454,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12067,6 +12073,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index 7e7149e05e..92ffb6f097 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -1409,7 +1409,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2814,7 +2814,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3835,7 +3839,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6621,14 +6625,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7058,6 +7054,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7146,13 +7146,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10470,6 +10470,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12084,6 +12090,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/mr.po b/editor/translations/mr.po
index 4ae3df9f99..f368062a85 100644
--- a/editor/translations/mr.po
+++ b/editor/translations/mr.po
@@ -1405,7 +1405,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2809,7 +2809,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3830,7 +3834,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6612,14 +6616,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7049,6 +7045,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7137,13 +7137,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10461,6 +10461,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12074,6 +12080,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index bdb52e4845..dc18540ce3 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -1429,7 +1429,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2836,7 +2836,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3858,7 +3862,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6659,14 +6663,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7097,6 +7093,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7185,13 +7185,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10531,6 +10531,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12154,6 +12160,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index 90df4e7b4f..6ec911db7d 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -2,7 +2,7 @@
# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
-# Allan Nordhøy <epost@anotheragency.no>, 2017-2018, 2019.
+# Allan Nordhøy <epost@anotheragency.no>, 2017-2018, 2019, 2020.
# Anonymous <GentleSaucepan@protonmail.com>, 2017.
# Elias <eliasnykrem@gmail.com>, 2018.
# flesk <eivindkn@gmail.com>, 2017, 2019.
@@ -14,13 +14,13 @@
# Byzantin <kasper-hoel@hotmail.com>, 2018.
# Hans-Marius Øverås <hansmariusoveras@gmail.com>, 2019.
# Revolution <revosw@gmail.com>, 2019.
-# Petter Reinholdtsen <pere-weblate@hungry.com>, 2019.
+# Petter Reinholdtsen <pere-weblate@hungry.com>, 2019, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-10-29 12:49+0000\n"
-"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
+"PO-Revision-Date: 2020-04-16 11:03+0000\n"
+"Last-Translator: Petter Reinholdtsen <pere-weblate@hungry.com>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/godot-"
"engine/godot/nb_NO/>\n"
"Language: nb\n"
@@ -28,7 +28,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.9.1\n"
+"X-Generator: Weblate 4.0.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -37,7 +37,7 @@ msgstr "Ugyldig argumenttype til convert(), bruk TYPE_*-konstantene."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "Forventet en streng med lenge 1 (et tegn)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -243,7 +243,7 @@ msgstr "Legg til Spor"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Animation Looping"
-msgstr "Animasjons-zoom."
+msgstr "Animasjonsløkke"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -283,14 +283,12 @@ msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Remove this track."
-msgstr "Fjern valgt spor."
+msgstr "Fjern dette sporet."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Time (s): "
-msgstr "X-Fade Tid (s):"
+msgstr "Tid (s): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -309,9 +307,8 @@ msgid "Trigger"
msgstr "Avtrekker"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Capture"
-msgstr "Framtid"
+msgstr "Fang"
#: editor/animation_track_editor.cpp
msgid "Nearest"
@@ -340,14 +337,12 @@ msgid "Insert Key"
msgstr "Sett inn Nøkkel"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Duplicate Key(s)"
-msgstr "Anim Dupliser Nøkler"
+msgstr "Dupliser Nøkler"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Key(s)"
-msgstr "Anim Fjern Nøkler"
+msgstr "Fjern Nøkler"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -1181,7 +1176,7 @@ msgstr "Utviklingsleder"
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr "Prosjektleder "
+msgstr "Prosjektstyring "
#: editor/editor_about.cpp
msgid "Developers"
@@ -1284,7 +1279,7 @@ msgstr "Vellykket Installering av Pakke!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Success!"
-msgstr "Suksess!"
+msgstr "Vellykket!"
#: editor/editor_asset_installer.cpp
#, fuzzy
@@ -1524,7 +1519,7 @@ msgstr "Flytt Autoload"
msgid "Remove Autoload"
msgstr "Fjern Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Aktiver"
@@ -1588,7 +1583,7 @@ msgstr "Oppdaterer scene..."
#: editor/editor_data.cpp editor/editor_properties.cpp
msgid "[empty]"
-msgstr "[tom]"
+msgstr "[blank]"
#: editor/editor_data.cpp
msgid "[unsaved]"
@@ -1669,16 +1664,14 @@ msgstr ""
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Custom debug template not found."
-msgstr "Malfil ble ikke funnet:"
+msgstr "Tilpasset feilsøkingsmal ble ikke funnet."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Custom release template not found."
-msgstr "Tilpasset utgivelsesmal ikke funnet."
+msgstr "Fant ikke tilpasset utgivelsesmal."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
@@ -1699,9 +1692,8 @@ msgid "Script Editor"
msgstr "Ã…pne SkriptEditor"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Asset Library"
-msgstr "Ã…pne Assets-Bibliotek"
+msgstr "Ressursbibliotek"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
@@ -2024,7 +2016,7 @@ msgstr "MÃ¥ ha en gyldig filutvidelse."
#: editor/editor_file_system.cpp
msgid "ScanSources"
-msgstr "SkannKilder"
+msgstr "Gjennomsøk kilder"
#: editor/editor_file_system.cpp
msgid ""
@@ -2054,9 +2046,8 @@ msgid "Inherited by:"
msgstr "Arvet av:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "Beskrivelse:"
+msgstr "Beskrivelse"
#: editor/editor_help.cpp
#, fuzzy
@@ -2180,9 +2171,8 @@ msgid "Member Type"
msgstr "Medlemmer"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Class"
-msgstr "Klasse:"
+msgstr "Klasse"
#: editor/editor_help_search.cpp
#, fuzzy
@@ -2927,7 +2917,7 @@ msgstr "Avslutt til Prosjektliste"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
msgid "Debug"
-msgstr "Debug"
+msgstr "Feilsøk"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
@@ -2943,9 +2933,8 @@ msgstr ""
"koble til IP'en til denne datamaskinen for å bli debugget."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Small Deploy with Network FS"
-msgstr "Liten Deploy med Network FS"
+msgstr "Liten utrulling med Network FS"
#: editor/editor_node.cpp
msgid ""
@@ -2963,9 +2952,8 @@ msgstr ""
"alternativet gjør testing for spill med et stort fotavtrykk raskere."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Visible Collision Shapes"
-msgstr "Synlige Kollisjons-Former"
+msgstr "Synlige kollisjons-former"
#: editor/editor_node.cpp
msgid ""
@@ -2977,7 +2965,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Visible Navigation"
-msgstr "Synlig Navigasjon"
+msgstr "Synlig navigasjon"
#: editor/editor_node.cpp
msgid ""
@@ -2989,7 +2977,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Sync Scene Changes"
-msgstr "Synkroniser Sceneforandringer"
+msgstr "Synkroniser Sceneendringer"
#: editor/editor_node.cpp
msgid ""
@@ -3005,7 +2993,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Sync Script Changes"
-msgstr "Synkroniser Skriptforandringer"
+msgstr "Synkroniser Skriptendringer"
#: editor/editor_node.cpp
#, fuzzy
@@ -3021,7 +3009,6 @@ msgstr ""
"nettverksfilsystem."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
-#, fuzzy
msgid "Editor"
msgstr "Redigeringsverktøy"
@@ -3100,8 +3087,13 @@ msgid "Q&A"
msgstr "Spørsmål og Svar"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Problemtracker"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Reimporter"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3365,7 +3357,6 @@ msgid "Inclusive"
msgstr "Inklusiv"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Self"
msgstr "Selv"
@@ -3547,8 +3538,9 @@ msgid "Select Node(s) to Import"
msgstr "Velg Node(r) for Importering"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
+#, fuzzy
msgid "Browse"
-msgstr "Utforsk"
+msgstr "Bla gjennom"
#: editor/editor_sub_scene.cpp
msgid "Scene Path:"
@@ -3953,7 +3945,7 @@ msgstr "Lag mappe"
#: editor/filesystem_dock.cpp
msgid "Re-Scan Filesystem"
-msgstr "Re-Skann Filsystem"
+msgstr "Gjennomsøk filsystem på ny"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3970,8 +3962,8 @@ msgid ""
"Scanning Files,\n"
"Please Wait..."
msgstr ""
-"Skanner Filer,\n"
-"Vennligst Vent..."
+"Gjennomgår filer,\n"
+"Vent…"
#: editor/filesystem_dock.cpp
msgid "Move"
@@ -4225,7 +4217,8 @@ msgid "Reimport"
msgstr "Reimporter"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Lagre scener, om-importer og start om"
#: editor/import_dock.cpp
@@ -4670,9 +4663,8 @@ msgid "Audio Clips"
msgstr "Lydklipp:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Functions"
-msgstr "Funksjoner:"
+msgstr "Funksjoner"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
@@ -5021,9 +5013,8 @@ msgstr "Panorerings-Modus"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
-#, fuzzy
msgid "AnimationTree"
-msgstr "Animasjon"
+msgstr "Animasjontre"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
@@ -7256,14 +7247,6 @@ msgid "Open Godot online documentation."
msgstr "Ã…pne Godots nettbaserte dokumentasjon"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Søk i referanse-dokumentasjonen."
@@ -7297,7 +7280,7 @@ msgstr "Lagre på nytt"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
-msgstr "Feilretter"
+msgstr "Feilsøking"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7565,9 +7548,8 @@ msgid "Create physical bones"
msgstr ""
#: editor/plugins/skeleton_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton"
-msgstr "Singleton"
+msgstr "Skelett"
#: editor/plugins/skeleton_editor_plugin.cpp
#, fuzzy
@@ -7585,7 +7567,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective"
-msgstr ""
+msgstr "Perspektiv"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Aborted."
@@ -7724,6 +7706,10 @@ msgid "This operation requires a single selected node."
msgstr "Denne operasjonen krever én valgt node."
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Lock View Rotation"
msgstr "Vis Informasjon"
@@ -7780,7 +7766,7 @@ msgstr "Lager Forhåndsvisning av Mesh"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Not available when using the GLES2 renderer."
-msgstr ""
+msgstr "Ikke tilgjengelig ved bruk av GLES2-opptegner."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Left"
@@ -7815,17 +7801,17 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "Vis Informasjon"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "Vis Informasjon"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr ""
@@ -7879,7 +7865,7 @@ msgstr "Høyrevisning"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Switch Perspective/Orthogonal View"
-msgstr ""
+msgstr "Bytt perspektiv/ortogonal fremvisning"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Insert Animation Key"
@@ -7975,7 +7961,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective FOV (deg.):"
-msgstr ""
+msgstr "Perspektiv-synsv. (deg.):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Z-Near:"
@@ -9032,9 +9018,8 @@ msgid "Scalar"
msgstr "Skala:"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector"
-msgstr "Inspektør"
+msgstr "Vektor"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
@@ -10071,7 +10056,7 @@ msgstr ""
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
-msgstr ""
+msgstr "Velg en tom mappe."
#: editor/project_manager.cpp
msgid "Please choose a \"project.godot\" or \".zip\" file."
@@ -10144,9 +10129,8 @@ msgid "Create New Project"
msgstr "Opprett Nytt Prosjekt"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Create & Edit"
-msgstr "Opprett skript"
+msgstr "Opprett og rediger"
#: editor/project_manager.cpp
msgid "Install Project:"
@@ -10171,7 +10155,7 @@ msgstr "Prosjektsti:"
#: editor/project_manager.cpp
msgid "Renderer:"
-msgstr ""
+msgstr "Opptegner:"
#: editor/project_manager.cpp
msgid "OpenGL ES 3.0"
@@ -10184,6 +10168,10 @@ msgid ""
"Incompatible with older hardware\n"
"Not recommended for web games"
msgstr ""
+"Høyere visuell kvalitet\n"
+"All funksjonalitet tilgjengelig\n"
+"Fungerer ikke med eldre maskinvare\n"
+"Ikke anbefalt for nettsidebaserte spill"
#: editor/project_manager.cpp
msgid "OpenGL ES 2.0"
@@ -10196,10 +10184,14 @@ msgid ""
"Works on most hardware\n"
"Recommended for web games"
msgstr ""
+"Lavere visuell kvalitet\n"
+"Noe funksjonalitet er ikke tilgjengelig\n"
+"Virker på det meste av maskinvare\n"
+"Anbefalt for nettsidebaserte spill"
#: editor/project_manager.cpp
msgid "Renderer can be changed later, but scenes may need to be adjusted."
-msgstr ""
+msgstr "Rendrer kan endres senere, men scener må kanskje justeres."
#: editor/project_manager.cpp
msgid "Unnamed Project"
@@ -10304,22 +10296,21 @@ msgid ""
msgstr ""
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Are you sure to scan %s folders for existing Godot projects?\n"
"This could take a while."
msgstr ""
-"Du er i ferd med å skanne %s mapper for eksisterende Godotprosjekter. "
-"Bekrefter du?"
+"Er du sikker på at du vil søke gjennom %s mapper etter eksisterende "
+"Godotprosjekter.\n"
+"Det kan ta en stund."
#: editor/project_manager.cpp
msgid "Project Manager"
-msgstr "Prosjektleder"
+msgstr "Prosjektstyring"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Projects"
-msgstr "Prosjekt"
+msgstr "Prosjekter"
#: editor/project_manager.cpp
msgid "Last Modified"
@@ -10327,11 +10318,11 @@ msgstr ""
#: editor/project_manager.cpp
msgid "Scan"
-msgstr "Skann"
+msgstr "Gjennomsøk"
#: editor/project_manager.cpp
msgid "Select a Folder to Scan"
-msgstr "Velg en Mappe å Skanne"
+msgstr "Velg en mappe å søke gjennom"
#: editor/project_manager.cpp
msgid "New Project"
@@ -10344,7 +10335,7 @@ msgstr "Fjern punkt"
#: editor/project_manager.cpp
msgid "Templates"
-msgstr ""
+msgstr "Maler"
#: editor/project_manager.cpp
msgid "Restart Now"
@@ -10402,15 +10393,15 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "All Devices"
-msgstr ""
+msgstr "Alle enheter"
#: editor/project_settings_editor.cpp
msgid "Device"
-msgstr ""
+msgstr "Enhet"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Press a Key..."
-msgstr ""
+msgstr "Trykk en tast..."
#: editor/project_settings_editor.cpp
msgid "Mouse Button Index:"
@@ -10418,15 +10409,15 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Left Button"
-msgstr ""
+msgstr "Venstre knapp"
#: editor/project_settings_editor.cpp
msgid "Right Button"
-msgstr ""
+msgstr "Høyre knapp"
#: editor/project_settings_editor.cpp
msgid "Middle Button"
-msgstr ""
+msgstr "Midtknapp"
#: editor/project_settings_editor.cpp
msgid "Wheel Up Button"
@@ -10460,7 +10451,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Axis"
-msgstr ""
+msgstr "Akse"
#: editor/project_settings_editor.cpp
msgid "Joypad Button Index:"
@@ -10477,23 +10468,23 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Add Event"
-msgstr ""
+msgstr "Legg til hendelse"
#: editor/project_settings_editor.cpp
msgid "Button"
-msgstr ""
+msgstr "Knapp"
#: editor/project_settings_editor.cpp
msgid "Left Button."
-msgstr ""
+msgstr "Venstre knapp."
#: editor/project_settings_editor.cpp
msgid "Right Button."
-msgstr ""
+msgstr "Høyre knapp."
#: editor/project_settings_editor.cpp
msgid "Middle Button."
-msgstr ""
+msgstr "Midtknapp."
#: editor/project_settings_editor.cpp
msgid "Wheel Up."
@@ -10513,7 +10504,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "No property '%s' exists."
-msgstr ""
+msgstr "Egenskapen «%s» eksisterer ikke."
#: editor/project_settings_editor.cpp
msgid "Setting '%s' is internal, and it can't be deleted."
@@ -10553,11 +10544,11 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Add Translation"
-msgstr ""
+msgstr "Legg til oversettelse"
#: editor/project_settings_editor.cpp
msgid "Remove Translation"
-msgstr ""
+msgstr "Fjern oversettelse"
#: editor/project_settings_editor.cpp
msgid "Add Remapped Path"
@@ -10597,7 +10588,7 @@ msgstr "Generelt"
#: editor/project_settings_editor.cpp
msgid "Override For..."
-msgstr ""
+msgstr "Overstyr for..."
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "The editor must be restarted for changes to take effect."
@@ -10612,17 +10603,16 @@ msgid "Action:"
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Action"
-msgstr "Flytt Handling"
+msgstr "Handling"
#: editor/project_settings_editor.cpp
msgid "Deadzone"
-msgstr ""
+msgstr "Dødsone"
#: editor/project_settings_editor.cpp
msgid "Device:"
-msgstr ""
+msgstr "Enhet:"
#: editor/project_settings_editor.cpp
msgid "Index:"
@@ -10634,11 +10624,11 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Translations"
-msgstr ""
+msgstr "Oversettelser"
#: editor/project_settings_editor.cpp
msgid "Translations:"
-msgstr ""
+msgstr "Oversettelser:"
#: editor/project_settings_editor.cpp
msgid "Remaps"
@@ -10684,9 +10674,8 @@ msgid "AutoLoad"
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Plugins"
-msgstr "Plugins"
+msgstr "Innstikkmoduler"
#: editor/property_editor.cpp
#, fuzzy
@@ -10707,7 +10696,7 @@ msgstr ""
#: editor/property_editor.cpp
msgid "File..."
-msgstr ""
+msgstr "Fil..."
#: editor/property_editor.cpp
msgid "Dir..."
@@ -10715,12 +10704,11 @@ msgstr ""
#: editor/property_editor.cpp
msgid "Assign"
-msgstr ""
+msgstr "Tildel"
#: editor/property_editor.cpp
-#, fuzzy
msgid "Select Node"
-msgstr "Kutt Noder"
+msgstr "Velg node"
#: editor/property_editor.cpp
msgid "Error loading file: Not a resource!"
@@ -11031,9 +11019,8 @@ msgid "New Scene Root"
msgstr "Lagre Scene"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Create Root Node:"
-msgstr "Lag Node"
+msgstr "Opprett rot-node:"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -11047,12 +11034,11 @@ msgstr "Scene"
#: editor/scene_tree_dock.cpp
msgid "User Interface"
-msgstr ""
+msgstr "Brukergrensesnitt"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Other Node"
-msgstr "Kutt Noder"
+msgstr "Andre noder"
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes from a foreign scene!"
@@ -11161,6 +11147,8 @@ msgid ""
"Instance a scene file as a Node. Creates an inherited scene if no root node "
"exists."
msgstr ""
+"Opprett en scenefil som en node. Oppretter en arvet scene hvis det ikke "
+"finnes en rot-node."
#: editor/scene_tree_dock.cpp
msgid "Attach a new or existing script for the selected node."
@@ -11381,6 +11369,12 @@ msgid "Script file already exists."
msgstr "Eksisterer allerede"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Klasse:"
@@ -11487,9 +11481,8 @@ msgid "Profiler"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Network Profiler"
-msgstr "Eksporter Prosjekt"
+msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Monitor"
@@ -12209,11 +12202,11 @@ msgstr "Endre CanvasItem"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't copy the function node."
-msgstr ""
+msgstr "Kan ikke kopiere funksjonsnoden."
#: modules/visual_script/visual_script_editor.cpp
msgid "Clipboard is empty!"
-msgstr ""
+msgstr "Utklippsbordet er tomt!"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -13084,6 +13077,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -13114,6 +13111,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanter kan ikke endres."
+#~ msgid "Issue Tracker"
+#~ msgstr "Problemtracker"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Erstattet %d forekomst(er)."
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index a729ea6119..d270e51f6f 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -40,11 +40,12 @@
# Tirrin <lensenjoe@gmail.com>, 2019.
# Filip Van Raemdonck <arrawn@gmail.com>, 2019.
# Julian <jdhoogvorst@gmail.com>, 2019, 2020.
+# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-16 09:43+0000\n"
+"PO-Revision-Date: 2020-04-15 14:29+0000\n"
"Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/"
"nl/>\n"
@@ -1466,7 +1467,7 @@ msgstr "Autoload '%s' bestaat al!"
#: editor/editor_autoload_settings.cpp
msgid "Rename Autoload"
-msgstr "Autoload Hernoemen"
+msgstr "Naam Autoload-script wijzigen"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
@@ -1480,7 +1481,7 @@ msgstr "Autoload verplaatsen"
msgid "Remove Autoload"
msgstr "Autoload verwijderen"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Inschakelen"
@@ -1748,7 +1749,7 @@ msgstr "Nieuw"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
msgid "Import"
-msgstr "Import"
+msgstr "Importeren"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
@@ -2966,8 +2967,13 @@ msgid "Q&A"
msgstr "Vragen en antwoorden"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Issue Tracker"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Opnieuw importeren"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3641,7 +3647,7 @@ msgstr ""
#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
-msgstr "Kan de hoofdmap voor bronnen niet verplaatsen of hernoemen."
+msgstr "Kan de hoofdmap voor bronnen niet verplaatsen of van naam veranderen."
#: editor/filesystem_dock.cpp
msgid "Cannot move a folder into itself."
@@ -3681,7 +3687,7 @@ msgstr "Bestandsnaam wijzigen:"
#: editor/filesystem_dock.cpp
msgid "Renaming folder:"
-msgstr "Hernoemen folder:"
+msgstr "Mapnaam wijzigen:"
#: editor/filesystem_dock.cpp
msgid "Duplicating file:"
@@ -3762,7 +3768,7 @@ msgstr "Alles inklappen"
#: editor/project_manager.cpp editor/rename_dialog.cpp
#: editor/scene_tree_dock.cpp
msgid "Rename"
-msgstr "Hernoemen"
+msgstr "Naam wijzigen"
#: editor/filesystem_dock.cpp
msgid "Previous Folder/File"
@@ -4024,7 +4030,8 @@ msgid "Reimport"
msgstr "Opnieuw importeren"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Opnieuw importeren en herstarten (alle scènes worden opgeslagen)"
#: editor/import_dock.cpp
@@ -5997,9 +6004,8 @@ msgstr ""
"Dit is de meest preciese (maar langzaamste) optie voor botsingsberekeningen."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
-msgstr "Een enkele convexe botsingsonderelement aanmaken"
+msgstr "Maak een enkel convex botsingselement als subelement"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6888,14 +6894,6 @@ msgid "Open Godot online documentation."
msgstr "Open Godot online documentatie."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Verzoek documentatie"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Help de Godot-documentatie te verbeteren door feedback te geven."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Zoek in de referentie documentatie."
@@ -7330,6 +7328,11 @@ msgid "This operation requires a single selected node."
msgstr "Deze bewerking vereist één geselecteerde knoop."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Orthogonaal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Beeldrotatie vergrendelen"
@@ -7418,6 +7421,10 @@ msgid "Freelook Slow Modifier"
msgstr "Vrijekijk Snelheid Modificator"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Beeldrotatie vergrendeld"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7427,10 +7434,6 @@ msgstr ""
"Het is geen betrouwbare indicatie voor werkelijke spelprestaties."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Beeldrotatie vergrendeld"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XForm Dialoog"
@@ -8169,7 +8172,7 @@ msgstr "Selecteer de vorige shape, subtegel of Tegel."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Region"
-msgstr "Bereik"
+msgstr "Gebied"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Collision"
@@ -8197,7 +8200,7 @@ msgstr "Z Index"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Region Mode"
-msgstr "Bereikmodus"
+msgstr "Gebiedmodus"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Collision Mode"
@@ -8249,7 +8252,7 @@ msgstr "Nieuwe veelhoek aanmaken."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
-msgstr "Hou de veelhoek binnen een rechthoekig bereik."
+msgstr "Houd de veelhoek binnen het rechthoekige gebied."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
@@ -9877,7 +9880,7 @@ msgid ""
"The project folders' contents won't be modified."
msgstr ""
"%d projecten uit de lijst verwijderen?\n"
-"De inhoud van de projectmappen wordt niet geraakt."
+"De inhoud van de projectmappen wordt niet gewijzigd."
#: editor/project_manager.cpp
msgid ""
@@ -9885,7 +9888,7 @@ msgid ""
"The project folder's contents won't be modified."
msgstr ""
"Project uit de lijst verwijderen?\n"
-"De inhoud van de projectmap wordt niet geraakt."
+"De inhoud van de projectmap wordt niet gewijzigd."
#: editor/project_manager.cpp
msgid ""
@@ -10338,7 +10341,7 @@ msgstr "Selecteer Method"
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
-msgstr "Hernoemen meerdere"
+msgstr "Bulk hernoemen"
#: editor/rename_dialog.cpp
msgid "Prefix"
@@ -10647,7 +10650,7 @@ msgstr "Kan niet werken aan knopen waar de huidige scène van erft!"
#: editor/scene_tree_dock.cpp
msgid "Attach Script"
-msgstr "Verbind Script"
+msgstr "Script toevoegen"
#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
@@ -10950,6 +10953,12 @@ msgid "Script file already exists."
msgstr "Scriptbestand bestaat al."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Klasse Naam:"
@@ -12733,6 +12742,10 @@ msgstr ""
"maken, zodat het een grootte kan ontvangen. Anders, maak er een RenderTarget "
"van en wijs zijn interne textuur toe aan een knoop om te tonen."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Ongeldige bron voor voorvertoning."
@@ -12761,6 +12774,15 @@ msgstr "Varyings kunnen alleen worden toegewezenin vertex functies."
msgid "Constants cannot be modified."
msgstr "Constanten kunnen niet worden aangepast."
+#~ msgid "Issue Tracker"
+#~ msgstr "Issue Tracker"
+
+#~ msgid "Request Docs"
+#~ msgstr "Verzoek documentatie"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Help de Godot-documentatie te verbeteren door feedback te geven."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d voorgekomen waarde(s) vervangen."
diff --git a/editor/translations/or.po b/editor/translations/or.po
index 6819e53f38..1858bad087 100644
--- a/editor/translations/or.po
+++ b/editor/translations/or.po
@@ -1405,7 +1405,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2808,7 +2808,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3829,7 +3833,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6611,14 +6615,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7048,6 +7044,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7136,13 +7136,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10460,6 +10460,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12073,6 +12079,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index de1d6d5375..eb40e7ecaa 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -42,7 +42,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-16 09:43+0000\n"
+"PO-Revision-Date: 2020-03-26 05:19+0000\n"
"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
@@ -1474,7 +1474,7 @@ msgstr "Przemieść Autoload"
msgid "Remove Autoload"
msgstr "Usuń Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Włącz"
@@ -2952,8 +2952,13 @@ msgid "Q&A"
msgstr "Pytania i odpowiedzi"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Lista problemów"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Importuj ponownie"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4008,7 +4013,8 @@ msgid "Reimport"
msgstr "Importuj ponownie"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Zapisz sceny, re-importuj i zrestartuj"
#: editor/import_dock.cpp
@@ -6867,14 +6873,6 @@ msgid "Open Godot online documentation."
msgstr "Otwórz dokumentację Godota online."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "PoproÅ› o dokumentacjÄ™"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Pomóż polepszyć dokumentację Godota przesyłając opinię."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Poszukaj w dokumentacji referencyjnej."
@@ -7311,6 +7309,11 @@ msgid "This operation requires a single selected node."
msgstr "Ta operacja wymaga pojedynczego wybranego węzła."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonalna"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Zablokuj obrót widoku"
@@ -7399,6 +7402,10 @@ msgid "Freelook Slow Modifier"
msgstr "Wolny modyfikator swobodnego widoku"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Obroty widoku zablokowane"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7407,10 +7414,6 @@ msgstr ""
"Nie może być używana jako miarodajny wskaźnik wydajności w grze."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Obroty widoku zablokowane"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Okno dialogowe XForm"
@@ -8040,7 +8043,7 @@ msgstr "Wypełnienie"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase TileMap"
-msgstr "Wyczyść TileMap"
+msgstr "Usuń TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Find Tile"
@@ -10914,6 +10917,12 @@ msgid "Script file already exists."
msgstr "Plik skryptu już istnieje."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Nazwa klasy:"
@@ -12697,6 +12706,10 @@ msgstr ""
"otrzymał jakiś rozmiar. W przeciwnym wypadku ustawi opcję RenderTarget i "
"przyporządkuj jego teksturę dla któregoś węzła."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Nieprawidłowe źródło do podglądu."
@@ -12725,6 +12738,15 @@ msgstr "Varying może być przypisane tylko w funkcji wierzchołków."
msgid "Constants cannot be modified."
msgstr "Stałe nie mogą być modyfikowane."
+#~ msgid "Issue Tracker"
+#~ msgstr "Lista problemów"
+
+#~ msgid "Request Docs"
+#~ msgstr "PoproÅ› o dokumentacjÄ™"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Pomóż polepszyć dokumentację Godota przesyłając opinię."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Zastąpiono %d wystąpień."
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 873a2d506b..70a061783c 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -1453,7 +1453,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2897,7 +2897,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3956,7 +3960,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6823,14 +6827,6 @@ msgid "Open Godot online documentation."
msgstr "Yer functions:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7277,6 +7273,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7366,13 +7366,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10812,6 +10812,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12501,6 +12507,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index a96186e434..82bd304311 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -84,12 +84,13 @@
# Leonardo Dimano <leodimano@live.com>, 2020.
# anonymous <noreply@weblate.org>, 2020.
# Guilherme Souza Reis de Melo Lopes <gsrmlopes@gmail.com>, 2020.
+# Richard Urban <redasuio1@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2020-03-08 22:32+0000\n"
-"Last-Translator: Guilherme Souza Reis de Melo Lopes <gsrmlopes@gmail.com>\n"
+"PO-Revision-Date: 2020-04-16 11:03+0000\n"
+"Last-Translator: Richard Urban <redasuio1@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -97,7 +98,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -1519,7 +1520,7 @@ msgstr "Mover Autoload"
msgid "Remove Autoload"
msgstr "Remover Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Habilitar"
@@ -3005,8 +3006,13 @@ msgid "Q&A"
msgstr "Perguntas & Respostas"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Rastreador de Problemas"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Reimportar"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4065,7 +4071,8 @@ msgid "Reimport"
msgstr "Reimportar"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Salvar cenas, reimportar e reiniciar"
#: editor/import_dock.cpp
@@ -6038,7 +6045,6 @@ msgstr ""
"Este é a opção mais precisa (mas lenta) para detecção de colisão."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
msgstr "Criar Simples Colisão Convexa Irmã(s)"
@@ -6930,14 +6936,6 @@ msgid "Open Godot online documentation."
msgstr "Abrir a documentação online da Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Solicitar documentos"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Ajude a melhorar a documentação do Godot dando seu feedback."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Pesquise a documentação de referência."
@@ -7372,6 +7370,11 @@ msgid "This operation requires a single selected node."
msgstr "Essa operação requer um único nó selecionado."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Bloquear Rotação da Visão"
@@ -7460,6 +7463,10 @@ msgid "Freelook Slow Modifier"
msgstr "Modificador de velocidade lenta da Visão Livre"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Ver Rotação Bloqueada"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7468,10 +7475,6 @@ msgstr ""
"Ele não deve ser usado como indicação confiável de desempenho do jogo."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Ver Rotação Bloqueada"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Diálogo XForm"
@@ -10972,6 +10975,12 @@ msgid "Script file already exists."
msgstr "O arquivo de script já existe."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Nome da Classe:"
@@ -12453,7 +12462,7 @@ msgstr ""
#: scene/3d/collision_shape.cpp
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
-msgstr ""
+msgstr "Lol."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
@@ -12753,6 +12762,10 @@ msgstr ""
"para que ele possa ter um tamanho. Caso contrário, defina-o como destino de "
"render e atribua sua textura interna a algum nó para exibir."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fonte inválida para a prévia."
@@ -12781,6 +12794,15 @@ msgstr "Variáveis só podem ser atribuídas na função de vértice."
msgid "Constants cannot be modified."
msgstr "Constantes não podem serem modificadas."
+#~ msgid "Issue Tracker"
+#~ msgstr "Rastreador de Problemas"
+
+#~ msgid "Request Docs"
+#~ msgstr "Solicitar documentos"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Ajude a melhorar a documentação do Godot dando seu feedback."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d ocorrência(s) substituída(s)."
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po
index d7532e38d4..f3b1014123 100644
--- a/editor/translations/pt_PT.po
+++ b/editor/translations/pt_PT.po
@@ -15,12 +15,13 @@
# Vinicius Gonçalves <viniciusgoncalves21@gmail.com>, 2017.
# ssantos <ssantos@web.de>, 2018, 2019.
# Gonçalo Dinis Guerreiro João <goncalojoao205@gmail.com>, 2019.
+# Manuela Silva <mmsrs@sky.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-16 09:43+0000\n"
-"Last-Translator: João Lopes <linux-man@hotmail.com>\n"
+"PO-Revision-Date: 2020-04-07 13:38+0000\n"
+"Last-Translator: Manuela Silva <mmsrs@sky.com>\n"
"Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_PT/>\n"
"Language: pt_PT\n"
@@ -33,18 +34,18 @@ msgstr ""
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "Tipo de argumento inválido para convert(), use constantes TYPE_*."
+msgstr "Tipo de argumento inválido para convert(), utilize constantes TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "Esperado um string de comprimento 1 (um carácter)."
+msgstr "Esperado uma \"string\" de comprimento 1 (um caráter)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
msgstr ""
-"Número de bytes insuficientes para descodificar, ou o formato é inválido."
+"Número de \"bytes\" insuficientes para descodificar, ou o formato é inválido."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -1454,7 +1455,7 @@ msgstr "Mover Carregamento Automático"
msgid "Remove Autoload"
msgstr "Remover Carregamento Automático"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Ativar"
@@ -2939,8 +2940,13 @@ msgid "Q&A"
msgstr "Perguntas & Respostas"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Rastreador de Problemas"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Reimportar"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3994,7 +4000,8 @@ msgid "Reimport"
msgstr "Reimportar"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Guardar cenas, reimportar e reiniciar"
#: editor/import_dock.cpp
@@ -6844,14 +6851,6 @@ msgid "Open Godot online documentation."
msgstr "Abrir documentação online do Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Requisitar Docs"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Dê a sua opinião para ajudar a melhorar a documentação Godot."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Procurar na documentação de referência."
@@ -7285,6 +7284,11 @@ msgid "This operation requires a single selected node."
msgstr "Esta operação requer um único nó selecionado."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ortogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Bloquear Rotação da Vista"
@@ -7373,6 +7377,10 @@ msgid "Freelook Slow Modifier"
msgstr "Modificador de Velocidade Freelook"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Rotação da Vista Bloqueada"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7381,10 +7389,6 @@ msgstr ""
"Não é uma indicação fiável do desempenho do jogo."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Rotação da Vista Bloqueada"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Diálogo XForm"
@@ -10881,6 +10885,12 @@ msgid "Script file already exists."
msgstr "Ficheiro Script já existe."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Nome de Classe:"
@@ -12659,6 +12669,10 @@ msgstr ""
"Control de modo a que obtenha um tamanho. Caso contrário, torne-a um "
"RenderTarget e atribua a sua textura interna a outro nó para visualizar."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fonte inválida para pré-visualização."
@@ -12687,6 +12701,15 @@ msgstr "Variações só podem ser atribuídas na função vértice."
msgid "Constants cannot be modified."
msgstr "Constantes não podem ser modificadas."
+#~ msgid "Issue Tracker"
+#~ msgstr "Rastreador de Problemas"
+
+#~ msgid "Request Docs"
+#~ msgstr "Requisitar Docs"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Dê a sua opinião para ajudar a melhorar a documentação Godot."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Substituído %d ocorrência(s)."
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index d52127fd95..28d33d4609 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -1437,7 +1437,7 @@ msgstr "Mutați Autoload"
msgid "Remove Autoload"
msgstr "Eliminați Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Activați"
@@ -2935,8 +2935,13 @@ msgid "Q&A"
msgstr "Întrebări și Răspunsuri"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Agent de Monitorizare al Problemelor"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Reimportă"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4026,7 +4031,7 @@ msgid "Reimport"
msgstr "Reimportă"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7030,14 +7035,6 @@ msgid "Open Godot online documentation."
msgstr "Deschide Recente"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7489,6 +7486,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Lock View Rotation"
msgstr "Curăță Rotația Cursorului"
@@ -7580,17 +7581,17 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "Curăță Rotația Cursorului"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "Curăță Rotația Cursorului"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr ""
@@ -11107,6 +11108,12 @@ msgid "Script file already exists."
msgstr "AutoLoad '%s' există deja!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Clasă:"
@@ -12779,6 +12786,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
@@ -12807,6 +12818,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Issue Tracker"
+#~ msgstr "Agent de Monitorizare al Problemelor"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "ÃŽnlocuit %d potriviri."
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index d3402fd63e..a0e80d0ce8 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -67,12 +67,15 @@
# Smadjavul <o1985af@gmail.com>, 2020.
# anonymous <noreply@weblate.org>, 2020.
# Vinsent Insaider_red <vinsent.in7aider@gmail.com>, 2020.
+# TMF <themysticalfox@mail.ru>, 2020.
+# Ivan Kuzmenko <kuzmenko.ivan2002@yandex.com>, 2020.
+# Super Pracion <superpracion2@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-11 12:20+0000\n"
-"Last-Translator: Vinsent Insaider_red <vinsent.in7aider@gmail.com>\n"
+"PO-Revision-Date: 2020-04-10 09:09+0000\n"
+"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -96,7 +99,7 @@ msgstr "ОжидалаÑÑŒ Ñтрока длиной 1 (Ñимвол)."
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr "ÐедоÑтаточно байтов Ð´Ð»Ñ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±Ð°Ð¹Ñ‚Ð¾Ð² или неверный формат."
+msgstr "ÐедоÑтаточно байтов Ð´Ð»Ñ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ неверный формат."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -232,9 +235,8 @@ msgid "Anim Multi Change Transition"
msgstr "Многократное изменение перехода"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transform"
-msgstr "Ðнимационное многоÑменное преобразование"
+msgstr "Ðнимационное многократное изменение положениÑ"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Value"
@@ -1505,7 +1507,7 @@ msgstr "ПеремеÑтить автозагрузку"
msgid "Remove Autoload"
msgstr "Удалить автозагрузку"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Включить"
@@ -2988,8 +2990,13 @@ msgid "Q&A"
msgstr "ВопроÑÑ‹ и ответы"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "СиÑтема отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Переимпортировать"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4043,7 +4050,8 @@ msgid "Reimport"
msgstr "Переимпортировать"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Сохранить Ñцены, переимпортировать и перезапуÑтить"
#: editor/import_dock.cpp
@@ -5241,8 +5249,9 @@ msgid ""
msgstr "Ð¯ÐºÐ¾Ñ€Ñ Ð¸ отÑтупы дочерних контейнеров переопределÑÑŽÑ‚ÑÑ Ð¸Ñ… родителÑми."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Presets for the anchors and margins values of a Control node."
-msgstr "ПредуÑтановки Ð´Ð»Ñ Ñкорей и Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ñтупов контрольного узла."
+msgstr "ПреÑеты значений Ð´Ð»Ñ Ñкорей и отÑтупов узла Control."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5653,7 +5662,7 @@ msgstr "ÐвтовÑтавка ключа"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Animation Key and Pose Options"
-msgstr "Ключ анимации вÑтавлен."
+msgstr "Опции анимационных Ключей и Позы"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key (Existing Tracks)"
@@ -5764,9 +5773,8 @@ msgstr "МаÑка излучениÑ"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Solid Pixels"
-msgstr "Твёрдые пикÑели"
+msgstr "Сплошные пикÑели"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5775,9 +5783,8 @@ msgstr "Граничные пикÑели"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Directed Border Pixels"
-msgstr "Ðаправленные граничные пикÑели"
+msgstr "Ðаправленные пограничные пикÑели"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5912,22 +5919,21 @@ msgid "This doesn't work on scene root!"
msgstr "Это не работает на корне Ñцены!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Trimesh Static Shape"
-msgstr "Создать вогнутую форму"
+msgstr "Создать треугольную Ñетку ÑтатичеÑкой формы"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create a single convex collision shape for the scene root."
msgstr ""
+"Ðе удаетÑÑ Ñоздать единÑтвенную выпуклую форму ÑÑ‚Ð¾Ð»ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð½Ñ Ñцены."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Couldn't create a single convex collision shape."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ Ñоздать одну выпуклую форму Ñтолкновений."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Shape"
-msgstr "Создать выпуклую форму(ы)"
+msgstr "Создать одну выпуклую форму"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create multiple convex collision shapes for the scene root."
@@ -5935,14 +5941,12 @@ msgstr ""
"Ðевозможно Ñоздать неÑколько выпуклых форм ÑÑ‚Ð¾Ð»ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð½Ñ Ñцены."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Couldn't create any collision shapes."
-msgstr "Ðе удалоÑÑŒ Ñоздать папку."
+msgstr "Ðе удалоÑÑŒ Ñоздать ни одной форму ÑтолкновениÑ."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Shapes"
-msgstr "Создать выпуклую форму(ы)"
+msgstr "Создать неÑколько выпуклых форм"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
@@ -5986,7 +5990,7 @@ msgstr "Создать контур"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "МаÑÑив"
+msgstr "Меш"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -6015,9 +6019,8 @@ msgstr ""
"Это Ñамый точный (но Ñамый медленный) ÑпоÑоб Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ñтолкновений."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
-msgstr "Создать выпуклую облаÑть ÑтолкновениÑ"
+msgstr "Создать одну выпуклую облаÑть ÑтолкновениÑ"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6028,9 +6031,8 @@ msgstr ""
"Это Ñамый быÑтрый (но наименее точный) ÑпоÑоб Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ñтолкновений."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Collision Siblings"
-msgstr "Создать выпуклую облаÑть ÑтолкновениÑ"
+msgstr "Создать неÑколько ÑоÑедних выпуклых форм ÑтолкновениÑ"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6045,12 +6047,17 @@ msgid "Create Outline Mesh..."
msgstr "Создать полиÑетку обводки..."
#: editor/plugins/mesh_instance_editor_plugin.cpp
+#, fuzzy
msgid ""
"Creates a static outline mesh. The outline mesh will have its normals "
"flipped automatically.\n"
"This can be used instead of the SpatialMaterial Grow property when using "
"that property isn't possible."
msgstr ""
+"Создаёт Ñтатичную контурную полиÑетку. Её нормали будут перевёрнуты "
+"автоматичеÑки.\n"
+"Она может быть заменой ÑвойÑтву Grow реÑурÑа SpatialMaterial, когда Ñто "
+"ÑвойÑтво невозможно иÑпользовать."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "View UV1"
@@ -6900,14 +6907,6 @@ msgid "Open Godot online documentation."
msgstr "Открыть онлайн-документацию Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Проблема"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Помогите улучшить документацию Godot, оÑтавьте Ñообщение об ошибке."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "ПоиÑк Ñправочной документации."
@@ -7344,6 +7343,11 @@ msgid "This operation requires a single selected node."
msgstr "Эта Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ одного выбранного узла."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ортогональный"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Блокировать вращение камеры"
@@ -7432,6 +7436,10 @@ msgid "Freelook Slow Modifier"
msgstr "Медленный модификатор Ñвободного проÑмотра"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Блокировать вращение камеры"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7441,10 +7449,6 @@ msgstr ""
"игры."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Блокировать вращение камеры"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XForm диалоговое окно"
@@ -7662,7 +7666,7 @@ msgstr "ПредпроÑмотр CollisionPolygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create LightOccluder2D"
-msgstr "Создан LightOccluder2D"
+msgstr "Создать LightOccluder2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "LightOccluder2D Preview"
@@ -8436,14 +8440,12 @@ msgid "Edit Tile Z Index"
msgstr "Редактирование Z индекÑа плитки"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Convex"
-msgstr "Сделать Convex"
+msgstr "Сделать выпуклым"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Concave"
-msgstr "Сделать Concave"
+msgstr "Сделать вогнутым"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create Collision Polygon"
@@ -8708,9 +8710,8 @@ msgid "Dodge operator."
msgstr "Оператор выцветаниÑ."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "HardLight operator."
-msgstr "Оператор жёÑткого Ñвета."
+msgstr "Оператор HardLight."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
@@ -9114,12 +9115,12 @@ msgstr "Изменить текÑтурную единицу"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "2D texture uniform lookup."
-msgstr "Изменить текÑтурную единицу"
+msgstr "Равномерный поиÑк 2D-текÑтур."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "2D texture uniform lookup with triplanar."
-msgstr "Изменить текÑтурную единицу"
+msgstr "Форменный поиÑк 2d текÑтуры Ñ Ñ‚Ñ€Ð¸Ð¿Ð»Ð°Ð½Ð°Ñ€Ð¾Ð¼."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform function."
@@ -9229,9 +9230,8 @@ msgid "Linear interpolation between two vectors."
msgstr "Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»ÑÑ†Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ð´Ð²ÑƒÐ¼Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð°Ð¼Ð¸."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Linear interpolation between two vectors using scalar."
-msgstr "Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»ÑÑ†Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ð´Ð²ÑƒÐ¼Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð°Ð¼Ð¸."
+msgstr "Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»ÑÑ†Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ð´Ð²ÑƒÐ¼Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð°Ð¼Ð¸ Ñ Ð¸Ñпользованием ÑкалÑра."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
@@ -9352,17 +9352,16 @@ msgstr ""
"Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±Ð·Ð¾Ñ€Ð° камеры (пропуÑтите ÑоответÑтвующие входы к ней)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid ""
"Custom Godot Shader Language expression, which is placed on top of the "
"resulted shader. You can place various function definitions inside and call "
"it later in the Expressions. You can also declare varyings, uniforms and "
"constants."
msgstr ""
-"ПользовательÑкое выражение Ñзыка шейдеров Godot, которое помещаетÑÑ Ð¿Ð¾Ð²ÐµÑ€Ñ… "
-"шейдера. Ð’Ñ‹ можете размеÑтить внутри различные объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¹ и вызвать "
-"их позже в ВыражениÑÑ…. Ð’Ñ‹ также можете объÑвить varyings, uniforms и "
-"конÑтанты."
+"ПользовательÑкое выражение на Ñзыке шейдеров Godot, которое помещаетÑÑ "
+"поверх шейдера. Ð’Ñ‹ можете размеÑтить внутри различные объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¹ и "
+"вызвать их позже в ВыражениÑÑ…. Ð’Ñ‹ также можете объÑвить переменные типа "
+"varying, uniform и конÑтанты."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(Fragment/Light mode only) Scalar derivative function."
@@ -9637,35 +9636,30 @@ msgid "Export With Debug"
msgstr "ЭкÑпорт в режиме отладки"
#: editor/project_manager.cpp
-#, fuzzy
msgid "The path specified doesn't exist."
-msgstr "Путь не ÑущеÑтвует."
+msgstr "Указанный путь не ÑущеÑтвует."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file (it's not in ZIP format)."
-msgstr "Ошибка при открытии файла пакета, не в формате zip."
+msgstr "Ошибка при открытии файла пакета (Ðе ÑвлÑетÑÑ ZIP форматом)."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."
msgstr ""
-"ÐедейÑтвительный '.zip' файл проекта, не Ñодержит файл 'project.godot'."
+"ÐедейÑтвительный \".zip\" файл проекта; не Ñодержит файл \"project.godot\"."
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
msgstr "ПожалуйÑта, выберите пуÑтую папку."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Please choose a \"project.godot\" or \".zip\" file."
-msgstr "ПожалуйÑта, выберите файл 'project.godot' или '.zip'."
+msgstr "ПожалуйÑта, выберите файл \"project.godot\" или \".zip\"."
#: editor/project_manager.cpp
-#, fuzzy
msgid "This directory already contains a Godot project."
-msgstr "Каталог уже Ñодержит проект Godot."
+msgstr "Этот каталог уже Ñодержит проект Godot."
#: editor/project_manager.cpp
msgid "New Game Project"
@@ -10362,9 +10356,8 @@ msgid "Suffix"
msgstr "СуффикÑ"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Use Regular Expressions"
-msgstr "РегулÑрное выражение"
+msgstr "ИÑпользовать регулÑрные выражениÑ"
#: editor/rename_dialog.cpp
msgid "Advanced Options"
@@ -10446,14 +10439,12 @@ msgid "Keep"
msgstr "ОÑтавить оригинал"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "PascalCase to snake_case"
-msgstr "CamelCase в under_scored"
+msgstr "ВерблюжийРегиÑтр в змеиный_региÑтр"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "snake_case to PascalCase"
-msgstr "under_scored к CamelCase"
+msgstr "змеиный_региÑтр в ВерблюжийРегиÑтр"
#: editor/rename_dialog.cpp
msgid "Case"
@@ -10472,9 +10463,8 @@ msgid "Reset"
msgstr "СброÑить"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Regular Expression Error"
-msgstr "РегулÑрное выражение"
+msgstr "Ошибка в регулÑрном выражении"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10947,7 +10937,7 @@ msgstr "Ðеверное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ путь наÑледуемого преÐ
#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Script path/name is valid."
-msgstr "Скрипт корректен."
+msgstr "Путь/Ð¸Ð¼Ñ Ñкрипта дейÑтвителен."
#: editor/script_create_dialog.cpp
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
@@ -10970,6 +10960,12 @@ msgid "Script file already exists."
msgstr "Файл Ñкрипта уже ÑущеÑтвует."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Ð˜Ð¼Ñ ÐºÐ»Ð°ÑÑа:"
@@ -12452,7 +12448,7 @@ msgstr ""
#: scene/3d/collision_shape.cpp
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
-msgstr ""
+msgstr "ConcavePolygonShape поддерживает RigidBody только в Ñтатичном режиме."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
@@ -12752,6 +12748,10 @@ msgstr ""
"Ñделайте её целью рендеринга и назначьте её внутреннюю текÑтуру какому-либо "
"узлу Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Ðеверный иÑточник Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра."
@@ -12780,6 +12780,15 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть назначены только Ð
msgid "Constants cannot be modified."
msgstr "КонÑтанты не могут быть изменены."
+#~ msgid "Issue Tracker"
+#~ msgstr "СиÑтема отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
+
+#~ msgid "Request Docs"
+#~ msgstr "Проблема"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Помогите улучшить документацию Godot, оÑтавьте Ñообщение об ошибке."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Заменено %d Ñовпадений."
diff --git a/editor/translations/si.po b/editor/translations/si.po
index 119818e11f..f46a3ca292 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -1428,7 +1428,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2832,7 +2832,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3856,7 +3860,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6662,14 +6666,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7100,6 +7096,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7188,13 +7188,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10539,6 +10539,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12165,6 +12171,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 50cf59efdc..d0fe10184e 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -5,15 +5,17 @@
# J08nY <johnenter@gmail.com>, 2016.
# MineGame 159 <minegame459@gmail.com>, 2018.
# Zuzana Palenikova <sousana.is@gmail.com>, 2019.
-# MineGame159 <petulko08@gmail.com>, 2019.
+# MineGame159 <petulko08@gmail.com>, 2019, 2020.
# Michal <alladinsiffon@gmail.com>, 2019.
# Richard <rgarlik@gmail.com>, 2019.
+# Richard Urban <redasuio1@gmail.com>, 2020.
+# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-02 10:51+0000\n"
-"Last-Translator: Richard <rgarlik@gmail.com>\n"
+"PO-Revision-Date: 2020-04-16 11:03+0000\n"
+"Last-Translator: Richard Urban <redasuio1@gmail.com>\n"
"Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/"
"godot/sk/>\n"
"Language: sk\n"
@@ -21,7 +23,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 3.8-dev\n"
+"X-Generator: Weblate 4.0.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -30,7 +32,7 @@ msgstr "Chybný argument convert(), použite TYPE_* konštanty."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "OÄakávaná dĺžka stringu 1 (písmeno)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -40,12 +42,11 @@ msgstr "Nedostatok bajtov na dekódovanie, možný chybný formát."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr ""
+msgstr "Nesprávny vstup %i (chýba) vo výraze"
#: core/math/expression.cpp
-#, fuzzy
msgid "self can't be used because instance is null (not passed)"
-msgstr "self nemožno použiť lebo inštancia je rovná null (not passed)"
+msgstr "self sa nedá použiť lebo inštancia je null (neprešiel)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -69,31 +70,31 @@ msgstr "Pri volaní '%s':"
#: core/ustring.cpp
msgid "B"
-msgstr ""
+msgstr "B"
#: core/ustring.cpp
msgid "KiB"
-msgstr ""
+msgstr "KiB"
#: core/ustring.cpp
msgid "MiB"
-msgstr ""
+msgstr "MiB"
#: core/ustring.cpp
msgid "GiB"
-msgstr ""
+msgstr "GiB"
#: core/ustring.cpp
msgid "TiB"
-msgstr ""
+msgstr "TiB"
#: core/ustring.cpp
msgid "PiB"
-msgstr ""
+msgstr "PiB"
#: core/ustring.cpp
msgid "EiB"
-msgstr ""
+msgstr "EiB"
#: editor/animation_bezier_editor.cpp
msgid "Free"
@@ -153,41 +154,35 @@ msgstr "Animácia zmeniť prechod"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transform"
-msgstr ""
+msgstr "Zmeniť Veľkosť Animácie"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Value"
msgstr "Animácia Zmeniť Keyframe Hodnotu"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Change Call"
-msgstr "Animácia Zmeniť Hovor"
+msgstr "Animácia zmenila Hovor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Keyframe Time"
-msgstr "Animácia Zmeniť Keyframe Čas"
+msgstr "Animácia ZmeniÅ¥ Äas Keyframe-u"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transition"
-msgstr "Animácia zmeniť prechod"
+msgstr "Zmeniť Transition Animácie"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transform"
-msgstr "Animácia zmeniť prechod"
+msgstr "Animácia zmeniť Transform"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Keyframe Value"
-msgstr "Animácia Zmeniť Keyframe Hodnotu"
+msgstr "Animácia Zmeniť hodnotu Keyframe-u"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Call"
-msgstr "Animácia Zmeniť Hovor"
+msgstr "Animácia Zmenila Hovor"
#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
@@ -200,45 +195,43 @@ msgstr "Zmeniť Dĺžku Animácie"
#: editor/animation_track_editor.cpp
msgid "Property Track"
-msgstr ""
+msgstr "Property Track"
#: editor/animation_track_editor.cpp
msgid "3D Transform Track"
-msgstr ""
+msgstr "3D Transform Track"
#: editor/animation_track_editor.cpp
msgid "Call Method Track"
-msgstr ""
+msgstr "Call Method Track"
#: editor/animation_track_editor.cpp
msgid "Bezier Curve Track"
-msgstr ""
+msgstr "Krivka Bezier Track"
#: editor/animation_track_editor.cpp
msgid "Audio Playback Track"
-msgstr ""
+msgstr "Audio Playback Track"
#: editor/animation_track_editor.cpp
msgid "Animation Playback Track"
-msgstr ""
+msgstr "Playback Track Animácie"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (frames)"
msgstr "Dĺžka Času Animácie (v sekundách)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (seconds)"
msgstr "Dĺžka Času Animácie (v sekundách)"
#: editor/animation_track_editor.cpp
msgid "Add Track"
-msgstr ""
+msgstr "Pridať Track"
#: editor/animation_track_editor.cpp
msgid "Animation Looping"
-msgstr ""
+msgstr "Opakovanie Animácie"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -255,15 +248,15 @@ msgstr "Klipy Animácie:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
-msgstr ""
+msgstr "Zmeniť cestu Tracku"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr ""
+msgstr "Zapnúť/Vypnúť tento track."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr ""
+msgstr "Update Mode (ako je nastavená táto možnosť)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
@@ -271,12 +264,11 @@ msgstr "Režim Interpolácie"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
-msgstr ""
+msgstr "Loop Wrap Mode (interpoluje koniec zo zaÄiatkom opakovania)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Remove this track."
-msgstr "Všetky vybrané"
+msgstr "Vymazať tento track."
#: editor/animation_track_editor.cpp
msgid "Time (s): "
@@ -284,7 +276,7 @@ msgstr "ÄŒas (s): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
-msgstr ""
+msgstr "Zmena Tracku Povolená"
#: editor/animation_track_editor.cpp
msgid "Continuous"
@@ -317,11 +309,11 @@ msgstr "Kubický"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
-msgstr ""
+msgstr "Clamp Loop Interp"
#: editor/animation_track_editor.cpp
msgid "Wrap Loop Interp"
-msgstr ""
+msgstr "Wrap Loop Interp"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -329,38 +321,36 @@ msgid "Insert Key"
msgstr "VložiÅ¥ KľúÄ"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Duplicate Key(s)"
-msgstr "Duplikovať výber"
+msgstr "Duplikovanie KľúÄov"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Key(s)"
-msgstr "Všetky vybrané"
+msgstr "Vymazanie kľúÄa(ov)"
#: editor/animation_track_editor.cpp
msgid "Change Animation Update Mode"
-msgstr ""
+msgstr "Zmeniť Update Mode Animácie"
#: editor/animation_track_editor.cpp
msgid "Change Animation Interpolation Mode"
-msgstr ""
+msgstr "Zmeniť Interpolacný Mód Animácie"
#: editor/animation_track_editor.cpp
msgid "Change Animation Loop Mode"
-msgstr ""
+msgstr "Zmeniť Loop Mode Animacie"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
-msgstr ""
+msgstr "Vymazať Track Animácie"
#: editor/animation_track_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr ""
+msgstr "VytvoriÅ¥ NOVà track za %s a vložiÅ¥ kľúÄ?"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr ""
+msgstr "VytvoriÅ¥ %d NOVÉ track-y a vložiÅ¥ kľúÄe?"
#: editor/animation_track_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
@@ -388,25 +378,23 @@ msgstr "Animácia Vytvoriť & Vložiť"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr ""
+msgstr "Anim VložiÅ¥ Track & kľúÄ"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Key"
msgstr "Animácia VložiÅ¥ KľúÄ"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Step"
-msgstr "Animácia zmeniť prechod"
+msgstr "Zmeniť krok Animácie"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rearrange Tracks"
-msgstr "Vložiť"
+msgstr "Preskupiť Track-y"
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr ""
+msgstr "Transformovať track-y a aplikovať do Spatial-based node-ov."
#: editor/animation_track_editor.cpp
msgid ""
@@ -422,73 +410,72 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr ""
+msgstr "Track-y Animácií môžu ukazovať iba na node-y AnimationPlayer."
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
-msgstr ""
+msgstr "Animation player sa nemôže naanimovať sám, iba ostatné player-y."
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr ""
+msgstr "Není možné pridať nový track bez root-u"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr ""
+msgstr "Neplatný track pre Bezier (niesu vhodné sub-properties)"
#: editor/animation_track_editor.cpp
msgid "Add Bezier Track"
-msgstr ""
+msgstr "Pridať Bezier Track"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr ""
+msgstr "Cesta Track-u je neplatná, takže sa nedá pridaÅ¥ kľúÄ."
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
-msgstr ""
+msgstr "Track není typ Spatial, nedá sa vložiÅ¥ kľúÄ"
#: editor/animation_track_editor.cpp
msgid "Add Transform Track Key"
-msgstr ""
+msgstr "Pridať Transform Track Key"
#: editor/animation_track_editor.cpp
msgid "Add Track Key"
-msgstr ""
+msgstr "Pridať Track Key"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
-msgstr ""
+msgstr "Cesta track-u je neplatná, takže sa nedá pridať do method key."
#: editor/animation_track_editor.cpp
msgid "Add Method Track Key"
-msgstr ""
+msgstr "Pridať Method Track Key"
#: editor/animation_track_editor.cpp
msgid "Method not found in object: "
-msgstr ""
+msgstr "Metóda nebola nájdená v objekte: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
-msgstr ""
+msgstr "Pohybové kľúÄe Animácie"
#: editor/animation_track_editor.cpp
msgid "Clipboard is empty"
-msgstr ""
+msgstr "Schránka je prázdna"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Paste Tracks"
-msgstr "Vložiť"
+msgstr "Vložiť Track-y"
#: editor/animation_track_editor.cpp
msgid "Anim Scale Keys"
-msgstr ""
+msgstr "Scale keys Animácie"
#: editor/animation_track_editor.cpp
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
-msgstr ""
+msgstr "Táto možnosť nefunguje pre Bezier editovanie, lebo je to jeden track."
#: editor/animation_track_editor.cpp
msgid ""
@@ -502,38 +489,47 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"Táto Animácia patrí importovanej scéne, takže zmeny pre importované track-y "
+"nebudú uložené.\n"
+" \n"
+"Na povolenie abilite pridať vlastné track-y, prejdite na nastavenia importu "
+"scén a nastavte\n"
+"\" Animation > Storage\" na \"Files\", povolte \"Animation > Keep Custom "
+"Tracks\", a potom re-import.\n"
+"Alternatívne, použite import preset ktorý importuje animácie pre oddelenie "
+"file-ov."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
-msgstr ""
+msgstr "Upozornenie: Editovanie importovaných animácií"
#: editor/animation_track_editor.cpp
msgid "Select an AnimationPlayer node to create and edit animations."
-msgstr ""
+msgstr "OznaÄte AnimationPlayer node aby ste vytvorili a upravili animácie."
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
-msgstr ""
+msgstr "Iba show track-y z node-ov oznaÄené v strome."
#: editor/animation_track_editor.cpp
msgid "Group tracks by node or display them as plain list."
-msgstr ""
+msgstr "Zoskupte track-y pomocou node-u alebo ich zobrazte ako plain list."
#: editor/animation_track_editor.cpp
msgid "Snap:"
-msgstr ""
+msgstr "Snap:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
-msgstr ""
+msgstr "Hodnota kroku Animácie."
#: editor/animation_track_editor.cpp
msgid "Seconds"
-msgstr ""
+msgstr "Sekundy"
#: editor/animation_track_editor.cpp
msgid "FPS"
-msgstr ""
+msgstr "FPS"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -543,15 +539,15 @@ msgstr ""
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Edit"
-msgstr ""
+msgstr "Edit"
#: editor/animation_track_editor.cpp
msgid "Animation properties."
-msgstr ""
+msgstr "Vlastnosti Animácie."
#: editor/animation_track_editor.cpp
msgid "Copy Tracks"
-msgstr ""
+msgstr "Kopírovať track-y"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
@@ -567,87 +563,83 @@ msgstr "Duplikovať výber"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr ""
+msgstr "Duplikovanie transponovaných"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Selection"
-msgstr "Všetky vybrané"
+msgstr "Vymazať výber"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Next Step"
msgstr "PrejsÅ¥ na Äalší krok"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Previous Step"
msgstr "Prejsť na predchádzajúci krok"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
-msgstr ""
+msgstr "Optimalizácia Animacie"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation"
-msgstr ""
+msgstr "VyÄistenie Animácie"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
-msgstr ""
+msgstr "Vyberte node ktorý bude animovaný:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
-msgstr ""
+msgstr "Použiť Bezier Curves"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
-msgstr ""
+msgstr "Optimalizér Animácií"
#: editor/animation_track_editor.cpp
msgid "Max. Linear Error:"
-msgstr ""
+msgstr "Max. Linear Error:"
#: editor/animation_track_editor.cpp
msgid "Max. Angular Error:"
-msgstr ""
+msgstr "Max. Angular Error:"
#: editor/animation_track_editor.cpp
msgid "Max Optimizable Angle:"
-msgstr ""
+msgstr "Maximálny Optimalizovatelný Uhol:"
#: editor/animation_track_editor.cpp
msgid "Optimize"
-msgstr ""
+msgstr "Optimalizácia"
#: editor/animation_track_editor.cpp
msgid "Remove invalid keys"
-msgstr ""
+msgstr "VymazaÅ¥ neplatné kľúÄe"
#: editor/animation_track_editor.cpp
msgid "Remove unresolved and empty tracks"
-msgstr ""
+msgstr "Vymazať nevyriešené a prázdne track-y"
#: editor/animation_track_editor.cpp
msgid "Clean-up all animations"
-msgstr ""
+msgstr "VyÄistiÅ¥ vÅ¡etky animácie"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr ""
+msgstr "VyÄistenie Animácií (NIEJE KROK SPÄŤ!)"
#: editor/animation_track_editor.cpp
msgid "Clean-Up"
-msgstr ""
+msgstr "VyÄistenie"
#: editor/animation_track_editor.cpp
msgid "Scale Ratio:"
-msgstr ""
+msgstr "Pomer mierky:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select Tracks to Copy"
-msgstr "Nastaviť prechody na:"
+msgstr "Vybrať Track-y na skopírovanie"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
@@ -659,136 +651,133 @@ msgid "Copy"
msgstr "Kopírovať"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select All/None"
-msgstr "Všetky vybrané"
+msgstr "VybraÅ¥ vÅ¡etko/niÄ"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
-msgstr ""
+msgstr "Pridať Audio Track Clip"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr ""
+msgstr "Zmeniť Audio Track Clip spustiť Offset"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
-msgstr ""
+msgstr "Zmeniť Audio Track Clip koniec Offset-u"
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr ""
+msgstr "Zmeniť veľkosť Array-u"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr ""
+msgstr "Zmeniť hodnotu Array-u"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
-msgstr ""
+msgstr "Zmeniť hodnotu Array-u"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr ""
+msgstr "ChoÄte na Líniu"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr ""
+msgstr "Číslo línie:"
#: editor/code_editor.cpp
msgid "%d replaced."
-msgstr ""
+msgstr "%d náhradené."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr ""
+msgstr "%d sa zhoduje."
#: editor/code_editor.cpp editor/editor_help.cpp
-#, fuzzy
msgid "%d matches."
-msgstr "Zhody:"
+msgstr "%d zhody."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
-msgstr ""
+msgstr "Match Case"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Whole Words"
-msgstr ""
+msgstr "Celé slová"
#: editor/code_editor.cpp editor/rename_dialog.cpp
msgid "Replace"
-msgstr ""
+msgstr "Nahradiť"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr ""
+msgstr "Nahradiť Všetko"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr ""
+msgstr "Iba Výber"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
msgid "Standard"
-msgstr ""
+msgstr "Å tandard"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
-msgstr ""
+msgstr "Vypnúť Panel Script-ov"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom In"
-msgstr ""
+msgstr "Priblížiť"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom Out"
-msgstr ""
+msgstr "Oddialiť"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr ""
+msgstr "Resetovať priblíženie"
#: editor/code_editor.cpp
msgid "Warnings"
-msgstr ""
+msgstr "Varovania"
#: editor/code_editor.cpp
msgid "Line and column numbers."
-msgstr ""
+msgstr "Čísla riadkov a stĺpcov."
#: editor/connections_dialog.cpp
msgid "Method in target node must be specified."
-msgstr ""
+msgstr "Metóda v target node-e musí byť špecifikovaná."
#: editor/connections_dialog.cpp
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
+"Metóda Target sa nenašla. Špecifikujte platnú metódu alebo pripojte script k "
+"target node-u."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Node:"
-msgstr "Pripojiť k Node:"
+msgstr "Pripojiť k Node-u:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Script:"
-msgstr "Pripojiť k Node:"
+msgstr "Pripojiť k Scriptu:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "From Signal:"
-msgstr "Signály:"
+msgstr "Zo Signálu:"
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
-msgstr ""
+msgstr "Scéna neobsahuje žiadny script."
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
@@ -809,43 +798,40 @@ msgstr "Odstrániť"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr ""
+msgstr "Pridajte Extra Call Argument:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr ""
+msgstr "Extra Call Argumenty:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Receiver Method:"
-msgstr "Filter:"
+msgstr "Metóda PrijímaÄa:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Advanced"
-msgstr "Vyvážený"
+msgstr "PokroÄilé"
#: editor/connections_dialog.cpp
msgid "Deferred"
-msgstr ""
+msgstr "Odložené"
#: editor/connections_dialog.cpp
msgid ""
"Defers the signal, storing it in a queue and only firing it at idle time."
-msgstr ""
+msgstr "Odloží signál, uloží ho do queue a vystrelí ho iba cez idle time."
#: editor/connections_dialog.cpp
msgid "Oneshot"
-msgstr ""
+msgstr "Oneshot"
#: editor/connections_dialog.cpp
msgid "Disconnects the signal after its first emission."
-msgstr ""
+msgstr "Odpojí signál po jeho prvej emisii."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Cannot connect signal"
-msgstr "Pripojiť Signál: "
+msgstr "Nedá sa pripojiť signál"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/export_template_manager.cpp editor/groups_editor.cpp
@@ -867,9 +853,8 @@ msgid "Connect"
msgstr "Pripojiť"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Signály:"
+msgstr "Signál:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -893,14 +878,12 @@ msgid "Disconnect"
msgstr "Odpojiť"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect a Signal to a Method"
-msgstr "Pripojiť Signál: "
+msgstr "Pripojiť Signál k Metóde"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Edit Connection:"
-msgstr "Upraviť Pripojenie: "
+msgstr "Upraviť Pripojenie:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
@@ -976,22 +959,20 @@ msgid "Dependencies For:"
msgstr "Závislosti pre:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Scene '%s' is currently being edited.\n"
"Changes will only take effect when reloaded."
msgstr ""
"Scéna '%s' sa práve upravuje.\n"
-"Zmeny sa neprejavia, pokiaľ znovu naÄítané."
+"Zmeny sa prejavia iba keÄ sa znovu naÄítajú."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Resource '%s' is in use.\n"
"Changes will only take effect when reloaded."
msgstr ""
"Scéna '%s' sa práve upravuje.\n"
-"Zmeny sa neprejavia, pokiaľ znovu naÄítané."
+"Zmeny sa prejavia iba keÄ sa znovu naÄítajú."
#: editor/dependency_editor.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -1038,7 +1019,6 @@ msgid "Owners Of:"
msgstr "Majitelia:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
msgstr "Odstrániť vybraté súbory z projektu? (nedá sa vrátiť späť)"
@@ -1084,13 +1064,12 @@ msgid "Permanently delete %d item(s)? (No undo!)"
msgstr "Natrvalo odstrániť %d položky? (Nedá sa vrátiť späť!)"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Show Dependencies"
-msgstr "Závislostí"
+msgstr "Zobraziť Závislosťi"
#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
-msgstr ""
+msgstr "Orphan Resource Explorer"
#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
@@ -1177,7 +1156,6 @@ msgid "License"
msgstr "Licencia"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Third-party Licenses"
msgstr "Thirdparty Licencie"
@@ -1188,13 +1166,16 @@ msgid ""
"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
+"Godot Engine sa spolieha na množstvo bezplatných a otvorených knižníc "
+"tretích strán, ktoré sú kompatibilné s podmienkami licencie MIT. Nasleduje "
+"vyÄerpávajúci zoznam vÅ¡etkých takýchto komponentov tretích strán s ich "
+"prísluÅ¡nými prehláseniami o autorských právach a licenÄnými podmienkami."
#: editor/editor_about.cpp
msgid "All Components"
msgstr "Všetky Komponenty"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Components"
msgstr "Komponenty"
@@ -1203,26 +1184,24 @@ msgid "Licenses"
msgstr "Licencie"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file, not in ZIP format."
msgstr "Chyba pri otváraní súboru balíka, nie je vo formáte zip."
#: editor/editor_asset_installer.cpp
msgid "%s (Already Exists)"
-msgstr ""
+msgstr "%s (Už Existuje)"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
-msgstr ""
+msgstr "Dekompresia Prostriedkov"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "The following files failed extraction from package:"
-msgstr ""
+msgstr "Nasledovné súbory sa nepodarilo extrahovať z balíka:"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "And %s more files."
-msgstr "Vytvoriť adresár"
+msgstr "A %s viac súborov."
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
@@ -1234,9 +1213,8 @@ msgid "Success!"
msgstr "Úspech!"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Package Contents:"
-msgstr "Konštanty:"
+msgstr "BalíÄek Obsahu:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1255,46 +1233,44 @@ msgid "Add Effect"
msgstr "Pridať Efekt"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Rename Audio Bus"
-msgstr "Všetky vybrané"
+msgstr "Premenovať Audio Bus"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Change Audio Bus Volume"
-msgstr "Všetky vybrané"
+msgstr "Zmeniť hlasitosť Audio Bus-u"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
-msgstr ""
+msgstr "Prepnúť Audio Bus Solo"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Mute"
-msgstr ""
+msgstr "Prepnúť Audio Bus Mute"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Bypass Effects"
-msgstr ""
+msgstr "Prepnúť Audio Bus Bypass Effects"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr ""
+msgstr "Vybrať Audio Bus Send"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
-msgstr ""
+msgstr "Pridať Audio Bus Effect"
#: editor/editor_audio_buses.cpp
msgid "Move Bus Effect"
-msgstr ""
+msgstr "Posunúť Bus Effect"
#: editor/editor_audio_buses.cpp
msgid "Delete Bus Effect"
-msgstr ""
+msgstr "Vymazať Bus Effect"
#: editor/editor_audio_buses.cpp
msgid "Drag & drop to rearrange."
-msgstr ""
+msgstr "Zoberte a položte(drag & drop) pre rearandžovanie."
#: editor/editor_audio_buses.cpp
msgid "Solo"
@@ -1310,7 +1286,7 @@ msgstr "Obísť"
#: editor/editor_audio_buses.cpp
msgid "Bus options"
-msgstr ""
+msgstr "Možnosti pre Bus"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -1331,64 +1307,63 @@ msgstr "Audio"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
-msgstr ""
+msgstr "Pridať Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr ""
+msgstr "Master bus nemôžete vymazať!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr ""
+msgstr "Vymazať Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Duplicate Audio Bus"
-msgstr ""
+msgstr "Duplikovať Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
-msgstr ""
+msgstr "Resetovať hlasitosť Bus-u"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
-msgstr ""
+msgstr "Presunúť Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr ""
+msgstr "Uložiť Audio Bus Layaut Ako..."
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
-msgstr ""
+msgstr "Lokácia pre Nový Layout..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr ""
+msgstr "Otvoriť Audio Bus Layout"
#: editor/editor_audio_buses.cpp
msgid "There is no '%s' file."
-msgstr ""
+msgstr "Není tu žiadny '%s' súbor."
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
msgid "Layout"
-msgstr ""
+msgstr "Layout"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
-msgstr ""
+msgstr "Neplatný súbor, není audio bus layout."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Error saving file: %s"
-msgstr "Chyba pri naÄítaní:"
+msgstr "Chyba uloženia súbora: %s"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
-msgstr ""
+msgstr "Pridať Bus"
#: editor/editor_audio_buses.cpp
msgid "Add a new Audio Bus to this layout."
-msgstr ""
+msgstr "Pridať nový Audio Bus do tohoto layout-u."
#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
@@ -1397,9 +1372,8 @@ msgid "Load"
msgstr "NaÄítaÅ¥"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Load an existing Bus Layout."
-msgstr "Popis:"
+msgstr "NaÄítaÅ¥ existujúci Bus Layout."
#: editor/editor_audio_buses.cpp
msgid "Save As"
@@ -1407,7 +1381,7 @@ msgstr "Uložiť Ako"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr ""
+msgstr "Uložiť tento Bus Layout do súboru."
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
@@ -1415,11 +1389,11 @@ msgstr "NaÄítaÅ¥ predvolené"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr ""
+msgstr "NaÄítaÅ¥ základný Bus Layout."
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
-msgstr ""
+msgstr "Vytvoriť nový Bus Layout."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -1427,68 +1401,67 @@ msgstr "Neplatný Názov."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
-msgstr ""
+msgstr "Platné písmená:"
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing engine class name."
-msgstr ""
+msgstr "Nesmie kolidovať(collide) s existujúcim názvom engine class-u."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing built-in type name."
-msgstr ""
+msgstr "Nesmie kolidovať(collide) s existujúcim menom pre built-in-type."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing global constant name."
-msgstr ""
+msgstr "Nesmie kolidovať s existujúcim menom pre global constant."
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
-msgstr ""
+msgstr "KľúÄové slovo nemožno použiÅ¥ ako AutoLoad názvu."
#: editor/editor_autoload_settings.cpp
msgid "Autoload '%s' already exists!"
-msgstr ""
+msgstr "AutoLoad '%s' už existujuje!"
#: editor/editor_autoload_settings.cpp
msgid "Rename Autoload"
-msgstr ""
+msgstr "Premenovať AutoLoad"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
-msgstr ""
+msgstr "Prepnúť globálne AutoLoad-y"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
-msgstr ""
+msgstr "Presunúť AutoLoad-y"
#: editor/editor_autoload_settings.cpp
msgid "Remove Autoload"
-msgstr ""
+msgstr "Vymazať AutoLoad"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
-msgstr ""
+msgstr "Povoliť"
#: editor/editor_autoload_settings.cpp
msgid "Rearrange Autoloads"
-msgstr ""
+msgstr "Rearandžovať AutoLoad-y"
#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid path."
-msgstr "Neplatný Názov."
+msgstr "Neplatná cesta."
#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
msgid "File does not exist."
-msgstr ""
+msgstr "Súbor neexistuje."
#: editor/editor_autoload_settings.cpp
msgid "Not in resource path."
-msgstr ""
+msgstr "Nieje v resource path."
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
-msgstr ""
+msgstr "Pridať AutoLoad"
#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp
@@ -1499,49 +1472,49 @@ msgstr "Cesta:"
#: editor/editor_autoload_settings.cpp
msgid "Node Name:"
-msgstr ""
+msgstr "Meno Node-u:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
#: editor/editor_profiler.cpp editor/project_manager.cpp
#: editor/settings_config_dialog.cpp
msgid "Name"
-msgstr ""
+msgstr "Meno"
#: editor/editor_autoload_settings.cpp
msgid "Singleton"
-msgstr ""
+msgstr "Singleton"
#: editor/editor_data.cpp editor/inspector_dock.cpp
msgid "Paste Params"
-msgstr ""
+msgstr "Vložiť Params"
#: editor/editor_data.cpp
msgid "Updating Scene"
-msgstr ""
+msgstr "Aktualizovať Scénu"
#: editor/editor_data.cpp
msgid "Storing local changes..."
-msgstr ""
+msgstr "Ukladanie lokálnych zmien..."
#: editor/editor_data.cpp
msgid "Updating scene..."
-msgstr ""
+msgstr "Aktualizovanie scény..."
#: editor/editor_data.cpp editor/editor_properties.cpp
msgid "[empty]"
-msgstr ""
+msgstr "[Prázdne]"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr ""
+msgstr "[Neuložené]"
#: editor/editor_dir_dialog.cpp
msgid "Please select a base directory first."
-msgstr ""
+msgstr "Najprv vyberte základný adresár."
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
-msgstr ""
+msgstr "Vyberte adresár"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
@@ -1559,35 +1532,39 @@ msgstr "Meno:"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
msgid "Could not create folder."
-msgstr ""
+msgstr "PrieÄinok sa nepodarilo vytvoriÅ¥."
#: editor/editor_dir_dialog.cpp
msgid "Choose"
-msgstr ""
+msgstr "Vyberte"
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr ""
+msgstr "Ukladanie súboru:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
-msgstr ""
+msgstr "Na oÄakávanej ceste sa nenaÅ¡la žiadna exportná cesta:"
#: editor/editor_export.cpp
msgid "Packing"
-msgstr ""
+msgstr "Zabalovanie"
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
"Etc' in Project Settings."
msgstr ""
+"Target platforma potrebuje 'ETC' kompresor textúr pre GLES2. Povoliť 'Import "
+"Etc' v Nastaveniach Projektu."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' texture compression for GLES3. Enable "
"'Import Etc 2' in Project Settings."
msgstr ""
+"Target platforma potrebuje 'ETC2' kompresor textúr pre GLES3. Povoliť'Import "
+"Etc 2' v Nastaveniach Projektu."
#: editor/editor_export.cpp
msgid ""
@@ -1596,107 +1573,106 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"Target platform potrebuje'ETC' kompresor textúr pre driver fallback do "
+"GLES2.\n"
+"Povoľte 'Import Etc' v Nastaveniach Projektu, alebo vipnite 'Driver Fallback "
+"Enabled'."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
msgid "Custom debug template not found."
-msgstr ""
+msgstr "Vlastná debug šablóna sa nenašla."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
msgid "Custom release template not found."
-msgstr ""
+msgstr "Vlastná release šablóna sa nenašla."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
-msgstr ""
+msgstr "Súbor Šablóny sa nenašiel:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "Pri 32-bitovom exporte nemôže byÅ¥ vložená PCK väÄÅ¡ia ako 4 GiB."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "3D Editor"
-msgstr "Otvorit prieÄinok"
+msgstr "3D Editor"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Script Editor"
-msgstr "Otvorit prieÄinok"
+msgstr "Script Editor"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr ""
+msgstr "Asset Library"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
-msgstr ""
+msgstr "Editovanie Stromu Scén"
#: editor/editor_feature_profile.cpp
msgid "Import Dock"
-msgstr ""
+msgstr "Importovať Dock"
#: editor/editor_feature_profile.cpp
msgid "Node Dock"
-msgstr ""
+msgstr "Node Dock"
#: editor/editor_feature_profile.cpp
msgid "FileSystem and Import Docks"
-msgstr ""
+msgstr "Systém súborov a Import Dock-y"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
-msgstr ""
+msgstr "Vymazať profil '%s'? (Nedá sa vrátiť späť)"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
-msgstr ""
+msgstr "Profil musí mať platný názov súboru a musí obsahovať '.'"
#: editor/editor_feature_profile.cpp
msgid "Profile with this name already exists."
-msgstr ""
+msgstr "Profil s týmto menom už existuje."
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled, Properties Disabled)"
-msgstr ""
+msgstr "(Editor je vypnutý, Vlastnosti sú vypnuté)"
#: editor/editor_feature_profile.cpp
msgid "(Properties Disabled)"
-msgstr ""
+msgstr "(Vlastnosi sú vypnuté)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Editor Disabled)"
-msgstr "Vypnuté"
+msgstr "(Editor je vypnutý)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options:"
-msgstr "Popis:"
+msgstr "Možnosti pre Class:"
#: editor/editor_feature_profile.cpp
msgid "Enable Contextual Editor"
-msgstr ""
+msgstr "Povoliť Kontextuálny Editor"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Properties:"
-msgstr "Filter:"
+msgstr "Povolené Vlastnosti:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Features:"
-msgstr ""
+msgstr "Povolené Funkcie:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Classes:"
-msgstr ""
+msgstr "Povolené Class-y:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
-msgstr ""
+msgstr "Formát súboru '%s' je neplatny, Import bol prerušený."
#: editor/editor_feature_profile.cpp
msgid ""
@@ -2841,7 +2817,7 @@ msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
-msgstr ""
+msgstr "Editor"
#: editor/editor_node.cpp
#, fuzzy
@@ -2912,7 +2888,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3972,7 +3952,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -4518,7 +4498,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation"
-msgstr ""
+msgstr "Animácie"
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
@@ -6858,14 +6838,6 @@ msgid "Open Godot online documentation."
msgstr "Popis:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7310,6 +7282,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7400,13 +7376,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10198,7 +10174,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Plugins"
-msgstr ""
+msgstr "Pluginy"
#: editor/property_editor.cpp
msgid "Preset..."
@@ -10860,6 +10836,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Trieda:"
@@ -12542,6 +12524,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index e8a0b4c2a1..8145e5e5d9 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -1515,7 +1515,7 @@ msgstr "Premakni SamodejnoNalaganje"
msgid "Remove Autoload"
msgstr "Odstrani SamodejnoNalaganje"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "OmogoÄi"
@@ -3066,8 +3066,13 @@ msgid "Q&A"
msgstr "V&O"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Sledilnik Napak"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Ponovno Uvozi"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4155,7 +4160,7 @@ msgid "Reimport"
msgstr "Ponovno Uvozi"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7140,14 +7145,6 @@ msgid "Open Godot online documentation."
msgstr "Odpri Nedavne"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7599,6 +7596,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7689,13 +7690,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -11215,6 +11216,12 @@ msgid "Script file already exists."
msgstr "SamodejnoNalaganje '%s' že obstaja!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Razred:"
@@ -12926,6 +12933,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -12956,6 +12967,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstante ni možno spreminjati."
+#~ msgid "Issue Tracker"
+#~ msgstr "Sledilnik Napak"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Zamenjana %d ponovitev/e."
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index 60ac25f6f4..19b13a126b 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -1452,7 +1452,7 @@ msgstr "Lëviz Autoload-in"
msgid "Remove Autoload"
msgstr "Hiq Autoload-in"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Lejo"
@@ -2991,8 +2991,13 @@ msgid "Q&A"
msgstr "Pyetje&Përgjigje"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Gjurmuesi i Problemeve"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Ri-importo"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4066,7 +4071,8 @@ msgid "Reimport"
msgstr "Ri-importo"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Ruaj skenat, ri-importo dhe rifillo"
#: editor/import_dock.cpp
@@ -6897,14 +6903,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7343,6 +7341,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7432,13 +7434,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10835,6 +10837,12 @@ msgid "Script file already exists."
msgstr "Emri i grupit ekziston që më parë."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Klasa:"
@@ -12481,6 +12489,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
@@ -12509,6 +12521,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Issue Tracker"
+#~ msgstr "Gjurmuesi i Problemeve"
+
#~ msgid ""
#~ "There are currently no tutorials for this class, you can [color=$color]"
#~ "[url=$url]contribute one[/url][/color] or [color=$color][url="
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index 5f5f3786a7..f83bc8bcd1 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -1516,7 +1516,7 @@ msgstr "Помери аутоматÑко учитавање"
msgid "Remove Autoload"
msgstr "Обриши аутоматÑко учитавање"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Укључи"
@@ -3073,8 +3073,13 @@ msgid "Q&A"
msgstr "Питања и одговори"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Пратилац грешака"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Поново увези"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4181,7 +4186,7 @@ msgid "Reimport"
msgstr "Поново увези"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7191,14 +7196,6 @@ msgid "Open Godot online documentation."
msgstr "Отвори Godot онлајн документацију"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Претражи документацију."
@@ -7666,6 +7663,11 @@ msgstr "Ова операција захтева један изабран чвÐ
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ортогонална пројекција"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Lock View Rotation"
msgstr "Прикажи информације"
@@ -7757,17 +7759,17 @@ msgid "Freelook Slow Modifier"
msgstr "Брзина Ñлободног погледа"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "Прикажи информације"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "Прикажи информације"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XForm дијалог"
@@ -11343,6 +11345,12 @@ msgid "Script file already exists."
msgstr "ÐутоматÑко учитавање '%s' већ поÑтоји!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "КлаÑа:"
@@ -13031,6 +13039,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -13062,6 +13074,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Issue Tracker"
+#~ msgstr "Пратилац грешака"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Замени %d појаве/а."
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index c36e64d459..80ff3bc4fa 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -1437,7 +1437,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2848,7 +2848,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3873,7 +3877,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6698,14 +6702,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7142,6 +7138,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7230,13 +7230,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10621,6 +10621,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12253,6 +12259,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index 3f7fee23b7..cb1d4c22d6 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -1507,7 +1507,7 @@ msgstr "Flytta Autoload"
msgid "Remove Autoload"
msgstr "Ta bort Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Aktivera"
@@ -3043,7 +3043,12 @@ msgid "Q&A"
msgstr "Frågor och svar"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Importera om"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -4139,7 +4144,7 @@ msgid "Reimport"
msgstr "Importera om"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7086,14 +7091,6 @@ msgid "Open Godot online documentation."
msgstr "Öppna Senaste"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7550,6 +7547,10 @@ msgid "This operation requires a single selected node."
msgstr "Åtgärden kräver en enstaka vald Node."
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Lock View Rotation"
msgstr "Visa Information"
@@ -7640,17 +7641,17 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "Visa Information"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "Visa Information"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr ""
@@ -11166,6 +11167,12 @@ msgid "Script file already exists."
msgstr "Autoload '%s' finns redan!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Klassnamn"
@@ -12871,6 +12878,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index 5300f984bb..b93e16a597 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -1429,7 +1429,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2836,7 +2836,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3860,7 +3864,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6663,14 +6667,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7101,6 +7097,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7189,13 +7189,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10537,6 +10537,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12160,6 +12166,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index d76be13ec1..38d8b80709 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -1407,7 +1407,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2810,7 +2810,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3831,7 +3835,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6613,14 +6617,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7050,6 +7046,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7138,13 +7138,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10463,6 +10463,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12076,6 +12082,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index a56f6338ab..3ad01b7d05 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -5,11 +5,12 @@
# Kaveeta Vivatchai <goodytong@gmail.com>, 2017.
# Poommetee Ketson (Noshyaar) <poommetee@protonmail.com>, 2017-2018.
# Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020.
+# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-01-03 21:21+0000\n"
+"PO-Revision-Date: 2020-03-31 02:26+0000\n"
"Last-Translator: Thanachart Monpassorn <nunf_2539@hotmail.com>\n"
"Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/"
"th/>\n"
@@ -18,7 +19,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.10\n"
+"X-Generator: Weblate 4.0-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -41,30 +42,27 @@ msgstr "ค่าอินพุตผิดพลาด %i (ไม่ผ่าà
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "self ไม่สามารถใช้ได้เนื่องจาภinstance มีค่า null (ไม่ผ่าน)"
+msgstr "self ไม่สามารถใช้ได้เนื่องจาà¸à¸­à¸´à¸™à¸ªà¹à¸•นซ์มีค่า null (ไม่ผ่าน)"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid operands to operator %s, %s and %s."
-msgstr "ไม่พบคุณสมบัติ '%s' ในโหนด %s"
+msgstr "ดำเนินà¸à¸²à¸£à¸œà¸´à¸”พลาดที่ตัวดำเนินà¸à¸²à¸£ %s, %s à¹à¸¥à¸° %s"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid index of type %s for base type %s"
-msgstr "ไม่พบคุณสมบัติ '%s' ในโหนด %s"
+msgstr "ดัชนีของชนิด '%s' ผิดพลาด ในชนิดà¸à¸²à¸™ %s"
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
-msgstr ""
+msgstr "ชื่อดัชนีของ '%s' ผิดพลาด สำหรับà¸à¸²à¸™ %s"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid arguments to construct '%s'"
-msgstr ": ประเภทตัวà¹à¸›à¸£à¹„ม่ถูà¸à¸•้อง: "
+msgstr "อาà¸à¸´à¸§à¹€à¸¡à¸™à¸•์ไม่ถูà¸à¸•้องในคอนสตรัภ'%s'"
#: core/math/expression.cpp
msgid "On call to '%s':"
-msgstr ""
+msgstr "เรียภ'%s':"
#: core/ustring.cpp
msgid "B"
@@ -103,9 +101,8 @@ msgid "Balanced"
msgstr "สมดุล"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Mirror"
-msgstr "สะท้อนซ้ายขวา"
+msgstr "à¸à¸£à¸°à¸ˆà¸"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
@@ -116,29 +113,24 @@ msgid "Value:"
msgstr "ค่า:"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Insert Key Here"
-msgstr "เพิ่มคีย์"
+msgstr "เพิ่มคีย์ที่นี่"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Duplicate Selected Key(s)"
-msgstr "ทำซ้ำที่เลือà¸"
+msgstr "ทำซ้ำคีย์ที่เลือà¸"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Delete Selected Key(s)"
-msgstr "ลบสิ่งที่เลือà¸"
+msgstr "ลบคีย์ที่เลือà¸"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Add Bezier Point"
-msgstr "เพิ่มจุด"
+msgstr "เพิ่มจุดเบซิเยร์"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Move Bezier Points"
-msgstr "ย้ายจุด"
+msgstr "ย้ายจุดเบซิเยร์"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -169,34 +161,28 @@ msgid "Anim Change Call"
msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Keyframe Time"
-msgstr "à¹à¸à¹‰à¹„ขเวลาคีย์เฟรมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¹à¸à¹‰à¹„ขเวลาคีย์เฟรมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transition"
-msgstr "à¹à¸à¹‰à¹„ขทรานสิชันà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¹à¸à¹‰à¹„ขทรานสิชันà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transform"
-msgstr "เคลื่อนย้ายà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Keyframe Value"
-msgstr "à¹à¸à¹‰à¹„ขค่าคีย์เฟรมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¹à¸à¹‰à¹„ขคีย์เฟรมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Call"
-msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Length"
-msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¹à¸à¹‰à¹„ขความยาวà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -204,51 +190,44 @@ msgid "Change Animation Loop"
msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Property Track"
-msgstr "คุณสมบัติ:"
+msgstr "คุณสมบัติà¹à¸—ร็à¸"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "3D Transform Track"
-msgstr "ประเภทà¸à¸²à¸£à¹€à¸„ลื่อนย้าย"
+msgstr "à¹à¸—ร็ภ3D Transform"
#: editor/animation_track_editor.cpp
msgid "Call Method Track"
-msgstr ""
+msgstr "เรียà¸à¹à¸—ร็à¸à¹€à¸¡à¸˜à¸­à¸”"
#: editor/animation_track_editor.cpp
msgid "Bezier Curve Track"
-msgstr ""
+msgstr "à¹à¸—ร็à¸à¹€à¸ªà¹‰à¸™à¹‚ค้งเบซิเยร์"
#: editor/animation_track_editor.cpp
msgid "Audio Playback Track"
-msgstr ""
+msgstr "à¹à¸—ร็à¸à¸à¸²à¸£à¹€à¸¥à¹ˆà¸™à¹€à¸ªà¸µà¸¢à¸‡"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Playback Track"
-msgstr "หยุดà¸à¸²à¸£à¹€à¸¥à¹ˆà¸™à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™ (S)"
+msgstr "à¹à¸—ร็à¸à¸à¸²à¸£à¹€à¸¥à¹ˆà¸™à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (frames)"
-msgstr "ความยาวà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™ (วินาที)"
+msgstr "ความยาวà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™ (เฟรม)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (seconds)"
msgstr "ความยาวà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™ (วินาที)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track"
-msgstr "เพิ่มà¹à¸—ร็à¸à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เพิ่มà¹à¸—ร็à¸"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Looping"
-msgstr "ซูมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -256,52 +235,44 @@ msgid "Functions:"
msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Audio Clips:"
-msgstr "ตัวรับเสียง"
+msgstr "คลิปเสียง:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Clips:"
-msgstr "คลิป"
+msgstr "คลิปà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Track Path"
-msgstr "เปลี่ยนค่าในอาร์เรย์"
+msgstr "เปลี่ยนที่อยู่à¹à¸—ร็à¸"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Toggle this track on/off."
-msgstr "โหมดไร้สิ่งรบà¸à¸§à¸™"
+msgstr "เปิด/ปิดà¸à¸²à¸£à¸•ิดตามà¹à¸—ร็à¸à¸™à¸µà¹‰"
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr ""
+msgstr "โหมดอัพเดท (วิธีตั้งค่าคุณสมบัตินี้)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Interpolation Mode"
-msgstr "โหนดà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "โหมดà¸à¸²à¸£à¹à¸à¹‰à¹„ข"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
-msgstr ""
+msgstr "โหมดวนรอบ (ต่อจุดสิ้นสุดด้วยจุดเริ่มต้นของลูป)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Remove this track."
-msgstr "ลบà¹à¸—ร็à¸à¸—ี่เลือà¸"
+msgstr "ลบà¹à¸—ร็à¸à¸™à¸µà¹‰"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Time (s): "
-msgstr "ระยะเวลาเฟด (วิ):"
+msgstr "เวลา (วินาที): "
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Toggle Track Enabled"
-msgstr "เปิดดอปเพลอร์"
+msgstr "เปิดà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸à¸²à¸£à¸•ิดตามà¹à¸—ร็à¸"
#: editor/animation_track_editor.cpp
msgid "Continuous"
@@ -316,13 +287,12 @@ msgid "Trigger"
msgstr "ทริà¸à¹€à¸à¸­à¸£à¹Œ"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Capture"
-msgstr "ฟีเจอร์"
+msgstr "จับ"
#: editor/animation_track_editor.cpp
msgid "Nearest"
-msgstr ""
+msgstr "ใà¸à¸¥à¹‰à¸—ี่สุด"
#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
#: editor/property_editor.cpp
@@ -331,15 +301,15 @@ msgstr "เส้นตรง"
#: editor/animation_track_editor.cpp
msgid "Cubic"
-msgstr ""
+msgstr "ลูà¸à¸šà¸²à¸¨à¸à¹Œ"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
-msgstr ""
+msgstr "à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”à¸à¸²à¸£à¸§à¸™à¸¥à¸¹à¸›"
#: editor/animation_track_editor.cpp
msgid "Wrap Loop Interp"
-msgstr ""
+msgstr "ล้อมà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -347,19 +317,16 @@ msgid "Insert Key"
msgstr "เพิ่มคีย์"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Duplicate Key(s)"
-msgstr "ทำซ้ำโหนด"
+msgstr "สร้างคีย์ซ้ำอีà¸à¸­à¸±à¸™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Key(s)"
-msgstr "ลบโหนด"
+msgstr "ลบคีย์"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Update Mode"
-msgstr "เปลี่ยนชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™:"
+msgstr "เปลี่ยนโหมดà¸à¸²à¸£à¸­à¸±à¸žà¹€à¸”ทà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -367,9 +334,8 @@ msgid "Change Animation Interpolation Mode"
msgstr "โหนดà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Loop Mode"
-msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เปลี่ยนโหมดà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
@@ -401,7 +367,7 @@ msgstr "à¹à¸—รà¸à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
msgid "AnimationPlayer can't animate itself, only other players."
-msgstr ""
+msgstr "ตัวเล่นอนิเมชั่นไม่สามารถเล่นอนิเมชั่นด้วยตัวมันเองได้ เล่นได้เฉพาะตัวเล่นอื่นเท่านั้น"
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
@@ -421,9 +387,8 @@ msgid "Change Animation Step"
msgstr "à¹à¸à¹‰à¹„ขความเร็วà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rearrange Tracks"
-msgstr "จัดลำดับออโต้โหลด"
+msgstr "จัดเรียงà¹à¸—ร็à¸"
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
@@ -436,73 +401,70 @@ msgid ""
"-AudioStreamPlayer2D\n"
"-AudioStreamPlayer3D"
msgstr ""
+"à¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡à¸ªà¸²à¸¡à¸²à¸£à¸–ติดไว้บนโหนดชนิดเหล่านี้เท่านั้น:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr ""
+msgstr "à¹à¸—ร็à¸à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¸ªà¸²à¸¡à¸²à¸£à¸–ติดไว้บนโหนด AnimationPlayer เท่านั้น"
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
-msgstr ""
+msgstr "à¹à¸—ร็à¸à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¹„ม่สามารถเล่นตัวมันเองได้ à¹à¸•่สามารถเล่นตัวเล่นอื่นได้"
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr ""
+msgstr "ไม่สามารถที่จะเพิ่มà¹à¸—ร็à¸à¹ƒà¸«à¸¡à¹ˆà¹‚ดยที่ไม่มีรูท"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr ""
+msgstr "à¹à¸—ร็à¸à¸œà¸´à¸”พลาดสำหรับเบซิเยร์ (ไม่มีคุณสมบัติย่อยที่เข้าà¸à¸±à¸™à¹„ด้)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Bezier Track"
-msgstr "เพิ่มà¹à¸—ร็à¸à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เพิ่มà¹à¸—ร็à¸à¹€à¸šà¸‹à¸´à¹€à¸¢à¸£à¹Œ"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr ""
+msgstr "ที่อยู่à¹à¸—ร็à¸à¸œà¸´à¸”พลาด ไม่สามารถเพิ่มคีย์ได้"
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
-msgstr ""
+msgstr "à¹à¸—ร็à¸à¹„ม่ใช่ชนิด Spatial, ไม่สามารถเพิ่มคีย์ได้"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Transform Track Key"
-msgstr "ประเภทà¸à¸²à¸£à¹€à¸„ลื่อนย้าย"
+msgstr "เพิ่มคีย์à¹à¸—ร็à¸à¸à¸²à¸£à¹à¸›à¸¥à¸‡"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track Key"
-msgstr "เพิ่มà¹à¸—ร็à¸à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เพิ่มà¹à¸—ร็à¸à¸„ีย์"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
-msgstr ""
+msgstr "ที่อยู่à¹à¸—ร็à¸à¸œà¸´à¸”พลาด ไม่สามารถเพิ่มคีย์เมธอดได้"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Method Track Key"
-msgstr "เพิ่มà¹à¸—ร็à¸à¹à¸¥à¸°à¸„ีย์à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เพิ่มคีย์à¹à¸—ร็à¸à¹€à¸¡à¸˜à¸­à¸”"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Method not found in object: "
-msgstr "ไม่พบ VariableGet ในสคริปต์: "
+msgstr "ไม่พบเมธอดในออบเจà¸à¸•์: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
msgstr "ย้ายคีย์à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Clipboard is empty"
-msgstr "คลิปบอร์ดว่างเปล่า!"
+msgstr "คลิปบอร์ดว่างเปล่า"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Paste Tracks"
-msgstr "วางตัวà¹à¸›à¸£"
+msgstr "วางà¹à¸—ร็à¸"
#: editor/animation_track_editor.cpp
msgid "Anim Scale Keys"
@@ -511,7 +473,7 @@ msgstr "ปรับคีย์à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
-msgstr ""
+msgstr "ตัวเลือà¸à¸™à¸µà¹‰à¹„ม่สามารถทำงานà¸à¸±à¸šà¹à¸—ร็à¸à¹€à¸šà¸‹à¸´à¹€à¸¢à¸£à¹Œ เนื่องจาà¸à¹€à¸›à¹‡à¸™à¹à¸„่à¹à¸—ร็à¸à¹€à¸”ี่ยว"
#: editor/animation_track_editor.cpp
msgid ""
@@ -528,16 +490,15 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
-msgstr ""
+msgstr "คำเตือน: à¸à¸³à¸¥à¸±à¸‡à¹à¸à¹‰à¹„ขà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸—ี่นำเข้ามา"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select an AnimationPlayer node to create and edit animations."
-msgstr "เลือภAnimationPlayer จาà¸à¸œà¸±à¸‡à¸‰à¸²à¸à¹€à¸žà¸·à¹ˆà¸­à¹à¸à¹‰à¹„ขà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เลือà¸à¹‚หนด AnimationPlayer เพื่อสร้างà¹à¸¥à¸°à¹à¸à¹‰à¹„ขà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
-msgstr ""
+msgstr "โชว์à¹à¸—ร็à¸à¸ˆà¸²à¸à¹‚หนดที่เลือà¸à¹ƒà¸™à¸œà¸±à¸‡à¹€à¸—่านั้น"
#: editor/animation_track_editor.cpp
msgid "Group tracks by node or display them as plain list."
@@ -555,11 +516,11 @@ msgstr "ผังà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸–ูà¸à¸•้อง"
#: editor/animation_track_editor.cpp
msgid "Seconds"
-msgstr ""
+msgstr "วินาที"
#: editor/animation_track_editor.cpp
msgid "FPS"
-msgstr "เฟรมต่อวินาที"
+msgstr "เฟรมเรท"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -572,14 +533,12 @@ msgid "Edit"
msgstr "à¹à¸à¹‰à¹„ข"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation properties."
-msgstr "ผังà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "คุณสมบัติà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Copy Tracks"
-msgstr "คัดลอà¸à¸•ัวà¹à¸›à¸£"
+msgstr "คัดลอà¸à¹à¸—ร็à¸"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
@@ -598,19 +557,16 @@ msgid "Duplicate Transposed"
msgstr "ทำซ้ำเปลี่ยนà¹à¸—ร็à¸"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Selection"
-msgstr "ลบสิ่งที่เลือà¸"
+msgstr "ลบที่เลือà¸"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Next Step"
-msgstr "ถัดไป"
+msgstr "ไปยังขั้นถัดไป"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Previous Step"
-msgstr "à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
+msgstr "ไปยังขั้นà¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
@@ -622,11 +578,11 @@ msgstr "เà¸à¹‡à¸šà¸à¸§à¸²à¸”à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
-msgstr ""
+msgstr "เลือà¸à¹‚หนดที่จะให้เคลื่อนไหว:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
-msgstr ""
+msgstr "ใช้เส้นโค้งเบซิเยร์"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
@@ -673,9 +629,8 @@ msgid "Scale Ratio:"
msgstr "อัตราส่วนเวลา:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select Tracks to Copy"
-msgstr "เลือà¸à¸„ุณสมบัติ"
+msgstr "เลือà¸à¹à¸—ร็à¸à¸—ี่จะคัดลอà¸"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
@@ -687,22 +642,20 @@ msgid "Copy"
msgstr "คัดลอà¸"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select All/None"
-msgstr "ไม่เลือà¸"
+msgstr "เลือà¸à¸—ั้งหมด/ไม่เลือà¸"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "ตัวรับเสียง"
+msgstr "เพิ่มคลิปà¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr ""
+msgstr "เปลี่ยนออฟเซ็ตเริ่มต้นของคลิปà¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
-msgstr ""
+msgstr "เปลี่ยนออฟเซ็ตตอนจบของคลิปà¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡"
#: editor/array_property_edit.cpp
msgid "Resize Array"
@@ -725,18 +678,16 @@ msgid "Line Number:"
msgstr "บรรทัดที่:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "à¹à¸—นที่..."
+msgstr "à¹à¸—นที่ %d"
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr ""
+msgstr "จับคู่ %d"
#: editor/code_editor.cpp editor/editor_help.cpp
-#, fuzzy
msgid "%d matches."
-msgstr "ไม่พบ"
+msgstr "%d ตรงà¸à¸±à¸™"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -761,7 +712,7 @@ msgstr "เฉพาะที่à¸à¸³à¸¥à¸±à¸‡à¹€à¸¥à¸·à¸­à¸"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
msgid "Standard"
-msgstr ""
+msgstr "มาตรà¸à¸²à¸™"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
@@ -789,39 +740,33 @@ msgstr "คำเตือน"
#: editor/code_editor.cpp
msgid "Line and column numbers."
-msgstr ""
+msgstr "เลขบรรทัดà¹à¸¥à¸°à¸„อลัมน์"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method in target node must be specified."
-msgstr "ต้องระบุเมท็อดในโหนดปลายทาง!"
+msgstr "ต้องระบุเมธอดในโหนดเป้าหมาย"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
-msgstr "ไม่พบเมท็อดปลายทาง! ระบุเมท็อดให้ถูà¸à¸•้องหรือเพิ่มสคริปต์ในโหนดปลายทาง"
+msgstr "ไม่พบโหนดเป้าหมาย ระบุเมธอดที่ถูà¸à¸•้องหรือเพิ่มสคริปต์ในโหนดเป้าหมาย"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Node:"
-msgstr "เชื่อมไปยังโหนด:"
+msgstr "เชื่อมต่อà¸à¸±à¸šà¹‚หนด:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Script:"
-msgstr "ไม่สามารถเชื่อมต่อà¸à¸±à¸šà¹‚ฮสต์:"
+msgstr "เชื่อมต่อสคริปต์:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "From Signal:"
-msgstr "สัà¸à¸à¸²à¸“:"
+msgstr "จาà¸à¸ªà¸±à¸à¸à¸²à¸“:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Scene does not contain any script."
-msgstr "โหนดไม่มี geometry"
+msgstr "ไม่มีสคริปต์ในฉาà¸"
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
@@ -849,14 +794,12 @@ msgid "Extra Call Arguments:"
msgstr "ตัวà¹à¸›à¸£à¹€à¸žà¸´à¹ˆà¸¡à¹€à¸•ิม:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Receiver Method:"
-msgstr "เลือà¸à¹€à¸¡à¸—็อด"
+msgstr "ตัวรับเมธอด:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Advanced"
-msgstr "ตัวเลือà¸à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”"
+msgstr "ขั้นสูง"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -876,9 +819,8 @@ msgid "Disconnects the signal after its first emission."
msgstr ""
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Cannot connect signal"
-msgstr "เชื่อมโยงสัà¸à¸à¸²à¸“:"
+msgstr "ไม่สามารถเชื่อมต่อสัà¸à¸à¸²à¸“"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/export_template_manager.cpp editor/groups_editor.cpp
@@ -900,7 +842,6 @@ msgid "Connect"
msgstr "เชื่อม"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
msgstr "สัà¸à¸à¸²à¸“:"
@@ -910,12 +851,11 @@ msgstr "เชื่อม '%s' à¸à¸±à¸š '%s'"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
-msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยง '%s' à¸à¸±à¸š '%s'"
+msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ '%s' à¸à¸±à¸š '%s'"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Disconnect all from signal: '%s'"
-msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยง '%s' à¸à¸±à¸š '%s'"
+msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อทั้งหมดจาà¸à¸ªà¸±à¸à¸à¸²à¸“: '%s'"
#: editor/connections_dialog.cpp
msgid "Connect..."
@@ -927,19 +867,16 @@ msgid "Disconnect"
msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยง"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect a Signal to a Method"
-msgstr "เชื่อมโยงสัà¸à¸à¸²à¸“:"
+msgstr "เชื่อมต่อสัà¸à¸à¸²à¸“ไปยังเมธอด"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Edit Connection:"
-msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยง"
+msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
-msgstr "ยืนยันà¸à¸²à¸£à¸£à¸±à¸™à¹‚ปรเจà¸à¸•์มาà¸à¸à¸§à¹ˆà¸² 1 โปรเจà¸à¸•์?"
+msgstr "ยืนยันà¸à¸²à¸£à¸¥à¸šà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อสัà¸à¸à¸²à¸“จาภ\"%s\"?"
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
@@ -950,19 +887,16 @@ msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Disconnect All"
-msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยง"
+msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อทั้งหมด"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Edit..."
-msgstr "à¹à¸à¹‰à¹„ข"
+msgstr "à¹à¸à¹‰à¹„ข..."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Go To Method"
-msgstr "รายชื่อเมท็อด"
+msgstr "ไปยังเมธอด"
#: editor/create_dialog.cpp
msgid "Change %s Type"
@@ -1014,7 +948,6 @@ msgid "Dependencies For:"
msgstr "à¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¸‚อง:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Scene '%s' is currently being edited.\n"
"Changes will only take effect when reloaded."
@@ -1023,12 +956,11 @@ msgstr ""
"à¸à¸²à¸£à¹à¸à¹‰à¹„ขจะไม่ส่งผลจนà¸à¸§à¹ˆà¸²à¸ˆà¸°à¹‚หลดใหม่"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Resource '%s' is in use.\n"
"Changes will only take effect when reloaded."
msgstr ""
-"รีซอร์ส '%s' à¸à¸³à¸¥à¸±à¸‡à¸–ูà¸à¹ƒà¸Šà¹‰à¸‡à¸²à¸™\n"
+"ทรัพยาà¸à¸£ '%s' à¸à¸³à¸¥à¸±à¸‡à¸–ูà¸à¹ƒà¸Šà¹‰à¸‡à¸²à¸™\n"
"à¸à¸²à¸£à¹à¸à¹‰à¹„ขจะไม่ส่งผลจนà¸à¸§à¹ˆà¸²à¸ˆà¸°à¹‚หลดใหม่"
#: editor/dependency_editor.cpp
@@ -1038,12 +970,12 @@ msgstr "à¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡"
#: editor/dependency_editor.cpp
msgid "Resource"
-msgstr "รีซอร์ส"
+msgstr "ทรัพยาà¸à¸£"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
-msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡"
+msgstr "เส้นทาง"
#: editor/dependency_editor.cpp
msgid "Dependencies:"
@@ -1059,7 +991,7 @@ msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
-msgstr "ค้นหารีซอร์สมาà¹à¸—นที่:"
+msgstr "ค้นหาทรัพยาà¸à¸£à¸¡à¸²à¹à¸—นที่:"
#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
#: editor/editor_help_search.cpp editor/editor_node.cpp
@@ -1076,9 +1008,8 @@ msgid "Owners Of:"
msgstr "เจ้าของของ:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "ลบไฟล์ที่เลือà¸à¸­à¸­à¸à¸ˆà¸²à¸à¹‚ปรเจà¸à¸•์? (ย้อนà¸à¸¥à¸±à¸šà¹„ม่ได้)"
+msgstr "ลบไฟล์ที่เลือà¸à¸­à¸­à¸à¸ˆà¸²à¸à¹‚ปรเจà¸à¸•์? (à¸à¸¹à¹‰à¸„ืนไม่ได้)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1086,8 +1017,8 @@ msgid ""
"work.\n"
"Remove them anyway? (no undo)"
msgstr ""
-"มีรีซอร์สอื่นต้องà¸à¸²à¸£à¹„ฟล์ที่à¸à¸³à¸¥à¸±à¸‡à¸¥à¸š\n"
-"ยืนยันจะลบหรือไม่? (ย้อนà¸à¸¥à¸±à¸šà¹„ม่ได้)"
+"ไฟล์ที่à¸à¸³à¸¥à¸±à¸‡à¸ˆà¸°à¸¥à¸š จำเป็นสำหรับใช้งานโดยทรัพยาà¸à¸£à¸­à¸±à¸™à¸­à¸·à¹ˆà¸™\n"
+"จะทำà¸à¸²à¸£à¸¥à¸šà¸«à¸£à¸·à¸­à¹„ม่? (คืนà¸à¸¥à¸±à¸šà¹„ม่ได้)"
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1098,9 +1029,8 @@ msgid "Error loading:"
msgstr "ผิดพลาดขณะโหลด:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Load failed due to missing dependencies:"
-msgstr "โหลดฉาà¸à¹„ม่ได้เนื่องจาà¸à¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¸ªà¸¹à¸à¸«à¸²à¸¢:"
+msgstr "โหลดผิดพลาดเนื่องจาà¸à¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¸ªà¸¹à¸à¸«à¸²à¸¢:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Open Anyway"
@@ -1120,16 +1050,15 @@ msgstr "ผิดพลาดขณะโหลด!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "ลบ %d ไฟล์ถาวร? (ย้อนà¸à¸¥à¸±à¸šà¹„ม่ได้!)"
+msgstr "ลบไอเทม %d ถาวรหรือไม่? (ย้อนà¸à¸¥à¸±à¸šà¹„ม่ได้!)"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Show Dependencies"
-msgstr "à¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡"
+msgstr "à¹à¸ªà¸”งà¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡"
#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
-msgstr "ตัวจัดà¸à¸²à¸£à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ªà¸—ี่ไม่มีเจ้าของ"
+msgstr "ทรัพยาà¸à¸£à¸—ี่ไม่ได้ใช้"
#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
@@ -1216,12 +1145,10 @@ msgid "License"
msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Third-party Licenses"
-msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•ไลบรารี"
+msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•จาà¸à¸šà¸¸à¸„คลที่สาม"
#: editor/editor_about.cpp
-#, fuzzy
msgid ""
"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
@@ -1229,8 +1156,8 @@ msgid ""
"respective copyright statements and license terms."
msgstr ""
"Godot Engine อาศัยไลบรารีต่าง ๆ ที่นำมาใช้ได้อย่างเสรีà¹à¸¥à¸°à¹€à¸›à¸´à¸”เผยโค้ดเป็นจำนวนมาภ"
-"ซึ่งเข้าà¸à¸±à¸™à¹„ด้à¸à¸±à¸šà¸ªà¸±à¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸• MIT ต่อไปนี้เป็นรายชื่อของไลบรารีทั้งหมด รวมถึงข้อความลิขสิทธิ์ "
-"à¹à¸¥à¸°à¸‚้อà¸à¸³à¸«à¸™à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸‚องà¹à¸•่ละไลบรารี"
+"ซึ่งเข้าà¸à¸±à¸™à¹„ด้à¸à¸±à¸šà¸ªà¸±à¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸• MIT ต่อไปนี้เป็นรายชื่อของไลบรารีทั้งหมดของบุคคลที่สาม "
+"รวมถึงข้อความลิขสิทธิ์ à¹à¸¥à¸°à¸‚้อà¸à¸³à¸«à¸™à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸‚องà¹à¸•่ละไลบรารี"
#: editor/editor_about.cpp
msgid "All Components"
@@ -1245,14 +1172,12 @@ msgid "Licenses"
msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file, not in ZIP format."
msgstr "ผิดพลาดขณะเปิดไฟล์à¹à¸žà¸„เà¸à¸ˆ, ไม่ใช่รูปà¹à¸šà¸š zip"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "%s (Already Exists)"
-msgstr "มีอยู่à¸à¹ˆà¸­à¸™à¹à¸¥à¹‰à¸§"
+msgstr "%s (มีอยู่à¸à¹ˆà¸­à¸™à¹à¸¥à¹‰à¸§)"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
@@ -1263,12 +1188,10 @@ msgid "The following files failed extraction from package:"
msgstr "ผิดพลาดขณะà¹à¸¢à¸à¹„ฟล์ต่อไปนี้จาà¸à¹à¸žà¸„เà¸à¸ˆ:"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "And %s more files."
msgstr "à¹à¸¥à¸°à¸­à¸µà¸ %d ไฟล์"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Package installed successfully!"
msgstr "ติดตั้งà¹à¸žà¸„เà¸à¸ˆà¹€à¸ªà¸£à¹‡à¸ˆà¸ªà¸¡à¸šà¸¹à¸£à¸“์!"
@@ -1278,9 +1201,8 @@ msgid "Success!"
msgstr "สำเร็จ!"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Package Contents:"
-msgstr "ประà¸à¸­à¸šà¸”้วย:"
+msgstr "เนื้อหาà¹à¸žà¸„เà¸à¸ˆ:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1296,7 +1218,7 @@ msgstr "ลำโพง"
#: editor/editor_audio_buses.cpp
msgid "Add Effect"
-msgstr "เอฟเฟà¸à¸•์"
+msgstr "เพิ่มเอฟเฟà¸à¸•์"
#: editor/editor_audio_buses.cpp
msgid "Rename Audio Bus"
@@ -1324,20 +1246,19 @@ msgstr "เลือภAudio Bus ที่ส่งต่อ"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
-msgstr "เพิ่มเอฟเฟà¸à¸•์เสียง"
+msgstr "เพิ่มเอฟเฟà¸à¸•์บัสเสียง"
#: editor/editor_audio_buses.cpp
msgid "Move Bus Effect"
-msgstr "ย้ายเอฟเฟà¸à¸•์เสียง"
+msgstr "ย้ายเอฟเฟà¸à¸•์บัสเสียง"
#: editor/editor_audio_buses.cpp
msgid "Delete Bus Effect"
-msgstr "ลบเอฟเฟà¸à¸•์เสียง"
+msgstr "ลบเอฟเฟà¸à¸•์บัสเสียง"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Drag & drop to rearrange."
-msgstr "Audio Bus ลาà¸à¹à¸¥à¸°à¸§à¸²à¸‡à¹€à¸žà¸·à¹ˆà¸­à¸¢à¹‰à¸²à¸¢à¸•ำà¹à¸«à¸™à¹ˆà¸‡"
+msgstr "ลาà¸à¹à¸¥à¸°à¸§à¸²à¸‡à¹€à¸žà¸·à¹ˆà¸­à¸ˆà¸±à¸”เรียง"
#: editor/editor_audio_buses.cpp
msgid "Solo"
@@ -1378,15 +1299,15 @@ msgstr "เพิ่ม Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr "ลบ Bus หลัà¸à¹„ม่ได้!"
+msgstr "ลบบัสหลัà¸à¹„ม่ได้!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr "ลบ Audio Bus"
+msgstr "ลบบัสเสียง"
#: editor/editor_audio_buses.cpp
msgid "Duplicate Audio Bus"
-msgstr "ทำซ้ำ Audio Bus"
+msgstr "ทำซ้ำบัสเสียง"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
@@ -1394,11 +1315,11 @@ msgstr "รีเซ็ตระดับเสียงบัส"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
-msgstr "ย้าย Audio Bus"
+msgstr "ย้ายบัสเสียง"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸­à¸²à¸•์ของ Audio Bus เป็น..."
+msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸­à¸²à¸•์ของบัสเสียงเป็น..."
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
@@ -1406,11 +1327,11 @@ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸‚องเลย์เอาต์ใหม่...
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr "เปิดเลย์เอาต์ของ Audio Bus"
+msgstr "เปิดเลย์เอาต์ของบัสเสียง"
#: editor/editor_audio_buses.cpp
msgid "There is no '%s' file."
-msgstr ""
+msgstr "ไม่มีไฟล์ '%s'"
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
msgid "Layout"
@@ -1421,18 +1342,16 @@ msgid "Invalid file, not an audio bus layout."
msgstr "ไฟล์ไม่ถูà¸à¸•้อง ไม่ใช่เลย์เอาต์ของ Audio Bus"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Error saving file: %s"
-msgstr "ผิดพลาดขณะบันทึภTileSet!"
+msgstr "ผิดพลาดขณะบันทึà¸à¹„ฟล์: %s"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
-msgstr "เพิ่ม Bus"
+msgstr "เพิ่มบัส"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Add a new Audio Bus to this layout."
-msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸­à¸²à¸•์ของ Audio Bus เป็น..."
+msgstr "เพิ่มบัสเสียงไปยังเลย์เอาต์นี้"
#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
@@ -1442,7 +1361,7 @@ msgstr "โหลด"
#: editor/editor_audio_buses.cpp
msgid "Load an existing Bus Layout."
-msgstr "โหลดเลย์เอาต์ Bus จาà¸à¸”ิสà¸à¹Œ"
+msgstr "โหลดเลย์เอาต์บัสจาà¸à¸”ิสà¸à¹Œ"
#: editor/editor_audio_buses.cpp
msgid "Save As"
@@ -1450,7 +1369,7 @@ msgstr "บันทึà¸à¹€à¸›à¹‡à¸™"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸­à¸²à¸•์ของ Bus นี้เป็นไฟล์"
+msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸­à¸²à¸•์ของบัสนี้เป็นไฟล์"
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
@@ -1458,11 +1377,11 @@ msgstr "โหลดค่าเริ่มต้น"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr "โหลดค่าเริ่มต้นเลย์เอาต์ Bus"
+msgstr "โหลดค่าเริ่มต้นเลย์เอาต์บัส"
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
-msgstr "สร้างเลย์เอาต์ Bus ใหม่"
+msgstr "สร้างเลย์เอาต์บัสใหม่"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -1473,19 +1392,16 @@ msgid "Valid characters:"
msgstr "ตัวอัà¸à¸©à¸£à¸—ี่ใช้ได้:"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing engine class name."
-msgstr "ชื่อผิดพลาด ต้องไม่ใช้ชื่อเดียวà¸à¸±à¸šà¸„ลาสของโปรà¹à¸à¸£à¸¡"
+msgstr "ต้องไม่ใช้ชื่อเดียวà¸à¸±à¸šà¸Šà¸·à¹ˆà¸­à¸„ลาสของโปรà¹à¸à¸£à¸¡"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing built-in type name."
-msgstr "ชื่อผิดพลาด ต้องไม่ใช้ชื่อเดียวà¸à¸±à¸šà¸Šà¸™à¸´à¸”ตัวà¹à¸›à¸£"
+msgstr "ต้องไม่ใช้ชื่อเดียวà¸à¸±à¸šà¸Šà¸·à¹ˆà¸­à¸Šà¸™à¸´à¸”บิวท์อินที่มีอยู่à¹à¸¥à¹‰à¸§"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing global constant name."
-msgstr "ชื่อผิดพลาด ต้องไม่ใช้ชื่อเดียวà¸à¸±à¸šà¸„่าคงที่"
+msgstr "ต้องไม่ใช้ชื่อเดียวà¸à¸±à¸šà¸Šà¸·à¹ˆà¸­à¸„่าคงที่โà¸à¸¥à¸šà¸­à¸¥"
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
@@ -1511,7 +1427,7 @@ msgstr "เลื่อนออโต้โหลด"
msgid "Remove Autoload"
msgstr "ลบออโต้โหลด"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "เปิด"
@@ -1520,7 +1436,6 @@ msgid "Rearrange Autoloads"
msgstr "จัดลำดับออโต้โหลด"
#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid path."
msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸œà¸´à¸”พลาด"
@@ -1582,7 +1497,6 @@ msgid "[unsaved]"
msgstr "[ไฟล์ใหม่]"
#: editor/editor_dir_dialog.cpp
-#, fuzzy
msgid "Please select a base directory first."
msgstr "à¸à¸£à¸¸à¸“าเลือà¸à¹‚ฟลเดอร์เริ่มต้นà¸à¹ˆà¸­à¸™"
@@ -1617,11 +1531,8 @@ msgid "Storing File:"
msgstr "เà¸à¹‡à¸šà¹„ฟล์:"
#: editor/editor_export.cpp
-#, fuzzy
msgid "No export template found at the expected path:"
-msgstr ""
-"ไม่มีà¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¸³à¸«à¸£à¸±à¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸\n"
-"ดาวน์โหลดà¹à¸¥à¸°à¸•ิดตั้งà¹à¸¡à¹ˆà¹à¸šà¸š"
+msgstr "ไม่พบà¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸à¸—ี่ที่อยู่ที่คาดไว้:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1632,12 +1543,16 @@ msgid ""
"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
"Etc' in Project Settings."
msgstr ""
+"à¹à¸žà¸¥à¸•ฟอร์มเป้าหมายต้องà¸à¸²à¸£à¸à¸²à¸£à¸šà¸µà¸šà¸­à¸±à¸”เทà¸à¹€à¸ˆà¸­à¸£à¹Œ 'ETC' สำหรับ GLES2 เปิด 'Import Etc' "
+"ในตั้งค่าโปรเจ็ค"
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' texture compression for GLES3. Enable "
"'Import Etc 2' in Project Settings."
msgstr ""
+"à¹à¸žà¸¥à¸•ฟอร์มเป้าหมายต้องà¸à¸²à¸£à¸à¸²à¸£à¸šà¸µà¸šà¸­à¸±à¸”เทà¸à¹€à¸ˆà¸­à¸£à¹Œ 'ETC2' สำหรับ GLES3 เปิด 'Import Etc 2' "
+"ในตั้งค่าโปรเจ็ค"
#: editor/editor_export.cpp
msgid ""
@@ -1646,13 +1561,14 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"à¹à¸žà¸¥à¸•ฟอร์มเป้าหมายต้องà¸à¸²à¸£à¸à¸²à¸£à¸šà¸µà¸šà¸­à¸±à¸”เทà¸à¹€à¸ˆà¸­à¸£à¹Œ 'ETC' สำหรับà¸à¸²à¸£à¸à¸¥à¸±à¸šà¸¡à¸²à¹ƒà¸Šà¹‰ GLES2\n"
+"เปิด 'Import Etc' ในตั้งค่าโปรเจ็คหรือปิด 'Driver Fallback Enabled'"
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Custom debug template not found."
-msgstr "ไม่พบà¹à¸žà¸„เà¸à¸ˆà¸”ีบัคที่à¸à¸³à¸«à¸™à¸”"
+msgstr "ไม่พบà¹à¸¡à¹ˆà¹à¸šà¸šà¸à¸²à¸£à¸”ีบัà¸à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เอง"
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -1663,31 +1579,27 @@ msgstr "ไม่พบà¹à¸žà¸„เà¸à¸ˆà¸ˆà¸³à¸«à¸™à¹ˆà¸²à¸¢à¸—ี่à¸à¸³à¸«
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
-msgstr "ไม่พบà¹à¸¡à¹ˆà¹à¸šà¸š:"
+msgstr "ไม่พบไฟล์à¹à¸¡à¹ˆà¹à¸šà¸š:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "à¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸à¹à¸šà¸š 32 bit PCK à¹à¸šà¸šà¸à¸±à¸‡à¸•ัวไม่สามารถใหà¸à¹ˆà¹„ด้เà¸à¸´à¸™ 4 GiB"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "3D Editor"
-msgstr "โปรà¹à¸à¸£à¸¡"
+msgstr "เอดิเตอร์ 3D"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Script Editor"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ขสคริปต์"
+msgstr "เอดิเตอร์สคริปต์"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Asset Library"
-msgstr "เปิดà¹à¸«à¸¥à¹ˆà¸‡à¸£à¸§à¸¡à¸—รัพยาà¸à¸£"
+msgstr "ไลบรารีทรัพยาà¸à¸£"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Scene Tree Editing"
-msgstr "ผังฉาภ(โหนด):"
+msgstr "à¹à¸à¹‰à¹„ขผังฉาà¸"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1705,92 +1617,80 @@ msgid "FileSystem and Import Docks"
msgstr "ระบบไฟล์"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Erase profile '%s'? (no undo)"
-msgstr "à¹à¸—นที่ทั้งหมด"
+msgstr "ลบโปรไฟล์ '%s' หรือไม่? (ทำà¸à¸¥à¸±à¸šà¹„ม่ได้)"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
-msgstr ""
+msgstr "โปรไฟล์จะต้องมีชื่อไฟล์ที่ถูà¸à¸•้อง à¹à¸¥à¸°à¸•้องไม่มี '.'"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Profile with this name already exists."
-msgstr "มีชื่อà¸à¸¥à¸¸à¹ˆà¸¡à¸™à¸µà¹‰à¸­à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§"
+msgstr "มีโปรไฟล์ที่มีชื่อนี้อยู๋à¹à¸¥à¹‰à¸§"
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled, Properties Disabled)"
-msgstr ""
+msgstr "(เอดิเตอร์ถูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™, คุณสมบัติถูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Properties Disabled)"
-msgstr "คุณสมบัติ"
+msgstr "(ปิดà¸à¸²à¸£à¸—ำงานคุณสมบัติ)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Editor Disabled)"
-msgstr "ปิดà¸à¸²à¸£à¸•ัด"
+msgstr "(เอดิเตอร์ถูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options:"
-msgstr "รายละเอียด:"
+msgstr "ตั้งค่าคลาส:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enable Contextual Editor"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ขถัดไป"
+msgstr "เปิดà¸à¸²à¸£à¸—ำงานเอดิเตอร์ตามบริบท"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Properties:"
-msgstr "คุณสมบัติ:"
+msgstr "เปิดà¸à¸²à¸£à¸—ำงานคุณสมบัติ:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Features:"
-msgstr "ฟีเจอร์"
+msgstr "เปิดà¸à¸²à¸£à¸—ำงานฟีเจอร์:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Classes:"
-msgstr "ค้นหาคลาส"
+msgstr "เปิดà¸à¸²à¸£à¸—ำงานคลาส:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
-msgstr ""
+msgstr "นามสà¸à¸¸à¸¥à¸‚องไฟล์ '%s' ผิดพลาด ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸™à¸³à¹€à¸‚้า"
#: editor/editor_feature_profile.cpp
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
-msgstr ""
+msgstr "มีโปรไฟล์ '%s' อยู่à¹à¸¥à¹‰à¸§ à¸à¸£à¸¸à¸“าลบà¸à¹ˆà¸­à¸™à¸—ี่จะนำเข้า, à¸à¸²à¸£à¸™à¸³à¹€à¸‚้าถูà¸à¸¢à¸à¹€à¸¥à¸´à¸"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Error saving profile to path: '%s'."
-msgstr "ผิดพลาดขณะโหลดà¹à¸¡à¹ˆà¹à¸šà¸š '%s'"
+msgstr "ผิดพลาดขณะบันทึà¸à¹‚ปรไฟล์ไปยังà¹à¸žà¸—ช์: '%s'"
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸•ั้งค่า"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "รุ่นปัจจุบัน:"
+msgstr "โปรไฟล์ปัจจุบัน:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Make Current"
-msgstr "ปัจจุบัน:"
+msgstr "ทำให้เป็นปัจจุบัน"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/version_control_editor_plugin.cpp
msgid "New"
-msgstr "ไฟล์ใหม่"
+msgstr "ใหม่"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
@@ -1802,44 +1702,36 @@ msgid "Export"
msgstr "ส่งออà¸"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "โหนดที่มีให้ใช้:"
+msgstr "โปรไฟล์ที่มีให้ใช้:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options"
-msgstr "รายละเอียด"
+msgstr "ตั้งค่าคลาส"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "New profile name:"
-msgstr "ชื่อใหม่:"
+msgstr "ชื่อโปรไฟล์ใหม่:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Erase Profile"
-msgstr "ลบพื้นที่"
+msgstr "ลบโปรไฟล์"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Godot Feature Profile"
-msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
+msgstr "รายละเอียดคุณสมบัติ Godot"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Import Profile(s)"
-msgstr "นำเข้าโปรเจà¸à¸•์à¹à¸¥à¹‰à¸§"
+msgstr "นำเข้าโปรไฟล์"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Export Profile"
-msgstr "ส่งออà¸à¹‚ปรเจà¸à¸•์"
+msgstr "ส่งออà¸à¹‚ปรไฟล์"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Manage Editor Feature Profiles"
-msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
+msgstr "จัดà¸à¸²à¸£à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”คุณสมบัติเอดิเตอร์"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -1850,7 +1742,6 @@ msgid "File Exists, Overwrite?"
msgstr "มีไฟล์นี้อยู่à¹à¸¥à¹‰à¸§ จะเขียนทับหรือไม่?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Select This Folder"
msgstr "เลือà¸à¹‚ฟลเดอร์นี้"
@@ -1859,13 +1750,11 @@ msgid "Copy Path"
msgstr "คัดลอà¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open in File Manager"
-msgstr "à¹à¸ªà¸”งในตัวจัดà¸à¸²à¸£à¹„ฟล์"
+msgstr "เปิดโฟลเดอร์"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Show in File Manager"
msgstr "à¹à¸ªà¸”งในตัวจัดà¸à¸²à¸£à¹„ฟล์"
@@ -1950,44 +1839,36 @@ msgid "Move Favorite Down"
msgstr "เลื่อนโฟลเดอร์ที่ชอบลง"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to previous folder."
-msgstr "ไปยังโฟลเดอร์หลัà¸"
+msgstr "ไปยังโฟลเดอร์à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to next folder."
-msgstr "ไปยังโฟลเดอร์หลัà¸"
+msgstr "ไปยังโฟลเดอร์ถัดไป"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Go to parent folder."
msgstr "ไปยังโฟลเดอร์หลัà¸"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Refresh files."
-msgstr "ค้นหาคลาส"
+msgstr "รีเฟรชไฟล์"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "(Un)favorite current folder."
-msgstr "ไม่สามารถสร้างโฟลเดอร์"
+msgstr "เพิ่ม/ลบโฟลเดอร์ปัจจุบันไปยังที่ชื่นชอบ"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Toggle the visibility of hidden files."
-msgstr "เปิด/ปิดไฟล์ที่ซ่อน"
+msgstr "เปิด/ปิดà¸à¸²à¸£à¹à¸ªà¸”งไฟล์ที่ซ่อน"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "View items as a grid of thumbnails."
-msgstr "à¹à¸ªà¸”งเป็นภาพตัวอย่าง"
+msgstr "à¹à¸ªà¸”งไอเทมในรูปà¹à¸šà¸šà¸•าราง"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "View items as a list."
-msgstr "à¹à¸ªà¸”งเป็นรายชื่อไฟล์"
+msgstr "à¹à¸ªà¸”งไอเทมในรูปà¹à¸šà¸šà¸¥à¸´à¸ªà¸•์รายชื่อ"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Directories & Files:"
@@ -2015,7 +1896,7 @@ msgstr "สà¹à¸à¸™à¸•้นฉบับ"
msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
-msgstr ""
+msgstr "มีà¸à¸²à¸£à¸™à¸³à¹€à¸‚้าไฟล์ %s หลายอัน à¸à¸²à¸£à¸™à¸³à¹€à¸‚้าถูà¸à¸¢à¸à¹€à¸¥à¸´à¸"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
@@ -2039,55 +1920,48 @@ msgid "Inherited by:"
msgstr "สืบทอดโดย:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "รายละเอียด:"
+msgstr "รายละเอียด"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Online Tutorials"
-msgstr "สอนใช้งานออนไลน์:"
+msgstr "บทสอนออนไลน์"
#: editor/editor_help.cpp
msgid "Properties"
msgstr "คุณสมบัติ"
#: editor/editor_help.cpp
-#, fuzzy
msgid "override:"
-msgstr "à¸à¸³à¸«à¸™à¸”เฉพาะ..."
+msgstr "à¹à¸—นที่:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "default:"
-msgstr "ค่าเริ่มต้น"
+msgstr "ค่าเริ่มต้น:"
#: editor/editor_help.cpp
msgid "Methods"
msgstr "รายชื่อเมท็อด"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Theme Properties"
-msgstr "คุณสมบัติ"
+msgstr "คุณสมบัติธีม"
#: editor/editor_help.cpp
msgid "Enumerations"
-msgstr "ค่าคงที่"
+msgstr "อีนัม"
#: editor/editor_help.cpp
msgid "Constants"
msgstr "ค่าคงที่"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Property Descriptions"
-msgstr "รายละเอียดตัวà¹à¸›à¸£:"
+msgstr "รายละเอียดของคุณสมบัติ"
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "ค่า"
+msgstr "(ค่า)"
#: editor/editor_help.cpp
msgid ""
@@ -2096,9 +1970,8 @@ msgid ""
msgstr "คุณสมบัตินี้ยังไม่มีคำอธิบาย โปรดช่วย[color=$color][url=$url]à¹à¸à¹‰à¹„ข[/url][/color]!"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Method Descriptions"
-msgstr "รายละเอียดเมท็อด:"
+msgstr "รายละเอียดเมท็อด"
#: editor/editor_help.cpp
msgid ""
@@ -2116,62 +1989,50 @@ msgid "Case Sensitive"
msgstr "ตรงตามอัà¸à¸©à¸£à¸žà¸´à¸¡à¸žà¹Œà¹€à¸¥à¹‡à¸-ใหà¸à¹ˆ"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Show Hierarchy"
-msgstr "à¹à¸ªà¸”งตัวช่วย"
+msgstr "à¹à¸ªà¸”งลำดับชั้น"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Display All"
-msgstr "à¹à¸ªà¸”งปà¸à¸•ิ"
+msgstr "à¹à¸ªà¸”งทั้งหมด"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Classes Only"
-msgstr "คลาส"
+msgstr "คลาสเท่านั้น"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Methods Only"
-msgstr "รายชื่อเมท็อด"
+msgstr "เมท็อดเท่านั้น"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Signals Only"
-msgstr "สัà¸à¸à¸²à¸“"
+msgstr "สัà¸à¸à¸²à¸“เท่านั้น"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Constants Only"
-msgstr "ค่าคงที่"
+msgstr "ค่าคงที่เท่านั้น"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Properties Only"
-msgstr "คุณสมบัติ"
+msgstr "คุณสมบัติเท่านั้น"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Properties Only"
-msgstr "คุณสมบัติ"
+msgstr "คุณสมบัติธีมเท่านั้น"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Member Type"
-msgstr "ตัวà¹à¸›à¸£"
+msgstr "ชนิดสมาชิà¸"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Class"
-msgstr "คลาส:"
+msgstr "คลาส"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Method"
-msgstr "รายชื่อเมท็อด"
+msgstr "เมธอด"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
msgstr "สัà¸à¸à¸²à¸“"
@@ -2180,14 +2041,12 @@ msgid "Constant"
msgstr "คงที่"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Property"
-msgstr "คุณสมบัติ:"
+msgstr "คุณสมบัติ"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Property"
-msgstr "คุณสมบัติ"
+msgstr "คุณสมบัติธีม"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
@@ -2203,12 +2062,11 @@ msgstr ""
#: editor/editor_log.cpp
msgid "Output:"
-msgstr "ข้อความ:"
+msgstr "เอาท์พุต:"
#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Copy Selection"
-msgstr "ลบที่เลือà¸"
+msgstr "คัดลอà¸à¸—ี่เลือà¸"
#: editor/editor_log.cpp editor/editor_network_profiler.cpp
#: editor/editor_profiler.cpp editor/editor_properties.cpp
@@ -2218,7 +2076,7 @@ msgstr "ลบที่เลือà¸"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr "ลบ"
+msgstr "เคลียร์"
#: editor/editor_log.cpp
msgid "Clear Output"
@@ -2231,13 +2089,12 @@ msgstr "หยุด"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
-#, fuzzy
msgid "Start"
-msgstr "เริ่ม!"
+msgstr "เริ่ม"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s/s"
#: editor/editor_network_profiler.cpp
msgid "Down"
@@ -2268,13 +2125,12 @@ msgid "Outgoing RSET"
msgstr ""
#: editor/editor_node.cpp editor/project_manager.cpp
-#, fuzzy
msgid "New Window"
-msgstr "หน้าต่าง"
+msgstr "หน้าต่างใหม่"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr ""
+msgstr "ทรัพยาà¸à¸£à¸—ี่นำเข้ามา ไม่สามารถบันทึà¸à¹„ด้"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
@@ -2283,7 +2139,7 @@ msgstr "ตà¸à¸¥à¸‡"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr "บันทึà¸à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ªà¸œà¸´à¸”พลาด!"
+msgstr "บันทึà¸à¸—รัพยาà¸à¸£à¸œà¸´à¸”พลาด!"
#: editor/editor_node.cpp
msgid ""
@@ -2301,7 +2157,7 @@ msgstr "เปิดไฟล์เพื่อเขียนไม่ได้
#: editor/editor_node.cpp
msgid "Requested file format unknown:"
-msgstr "ไม่ทราบรูปà¹à¸šà¸šà¹„ฟล์ที่ร้องขอ:"
+msgstr "ไม่ทราบนามสà¸à¸¸à¸¥à¹„ฟล์ที่ร้องขอ:"
#: editor/editor_node.cpp
msgid "Error while saving."
@@ -2309,7 +2165,7 @@ msgstr "ผิดพลาดขณะบันทึà¸"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Can't open '%s'. The file could have been moved or deleted."
-msgstr ""
+msgstr "ไม่สามารถเปิด '%s' เนื่องจาà¸à¹„ฟล์ถูà¸à¸¢à¹‰à¸²à¸¢à¸«à¸£à¸·à¸­à¸–ูà¸à¸¥à¸š"
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
@@ -2357,23 +2213,23 @@ msgstr "บันทึà¸à¸‰à¸²à¸à¹„ม่ได้ อาจจะมีà¸à¸
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
-msgstr ""
+msgstr "ไม่สามารถเขียนทับฉาà¸à¸—ี่à¸à¸³à¸¥à¸±à¸‡à¹€à¸›à¸´à¸”อยู่ได้!"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
-msgstr "โหลด MeshLibrary เพื่อรวมไม่ได้!"
+msgstr "ไม่สามารถโหลดไลบรารี Mesh เพื่อควบรวม!"
#: editor/editor_node.cpp
msgid "Error saving MeshLibrary!"
-msgstr "ผิดพลาดขณะบันทึภMeshLibrary!"
+msgstr "ผิดพลาดขณะบันทึà¸à¹„ลบรารี Mesh!"
#: editor/editor_node.cpp
msgid "Can't load TileSet for merging!"
-msgstr "โหลด TileSet เพื่อรวมไม่ได้!"
+msgstr "โหลดไทล์เซตเพื่อรวมไม่ได้!"
#: editor/editor_node.cpp
msgid "Error saving TileSet!"
-msgstr "ผิดพลาดขณะบันทึภTileSet!"
+msgstr "ผิดพลาดขณะบันทึà¸à¹„ทล์เซต!"
#: editor/editor_node.cpp
msgid "Error trying to save layout!"
@@ -2401,13 +2257,12 @@ msgstr ""
"อ่านรายละเอียดเพิ่มเติมได้จาà¸à¸„ู่มือในส่วนของà¸à¸²à¸£à¸™à¸³à¹€à¸‚้าฉาà¸"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"This resource belongs to a scene that was instanced or inherited.\n"
"Changes to it won't be kept when saving the current scene."
msgstr ""
-"รีซอร์สนี้เป็นของฉาà¸à¸—ี่ถูà¸à¸­à¸´à¸™à¸ªà¹à¸•นซ์หรือสืบทอด\n"
-"à¸à¸²à¸£à¹à¸à¹‰à¹„ขจะไม่ถูà¸à¸šà¸±à¸™à¸—ึà¸"
+"ทรัพยาà¸à¸£à¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¸‰à¸²à¸à¸—ี่เป็นอินสà¹à¸•นซ์หรือสืบทอด\n"
+"à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ˆà¸°à¹„ม่ถูà¸à¹€à¸à¹‡à¸šà¹„ว้ เมื่อบันทึà¸à¸‰à¸²à¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™"
#: editor/editor_node.cpp
msgid ""
@@ -2458,17 +2313,16 @@ msgid "Open Base Scene"
msgstr "เปิดไฟล์ฉาà¸à¸—ี่ใช้สืบทอด"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Quick Open..."
-msgstr "เปิดไฟล์ฉาà¸à¸”่วน..."
+msgstr "เปิดด่วน..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
-msgstr "เปิดไฟล์ฉาà¸à¸”่วน..."
+msgstr "เปิดฉาà¸à¸”่วน..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr "เปิดไฟล์สคริปต์ด่วน..."
+msgstr "เปิดสคริปต์ด่วน..."
#: editor/editor_node.cpp
msgid "Save & Close"
@@ -2479,14 +2333,12 @@ msgid "Save changes to '%s' before closing?"
msgstr "บันทึภ'%s' à¸à¹ˆà¸­à¸™à¸›à¸´à¸”โปรà¹à¸à¸£à¸¡à¸«à¸£à¸·à¸­à¹„ม่?"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Saved %s modified resource(s)."
-msgstr "โหลดรีซอร์สไม่ได้"
+msgstr "บันทึà¸à¸—รัพยาà¸à¸£ %s ที่ถูà¸à¹à¸à¹‰à¹„ขสำเร็จ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "A root node is required to save the scene."
-msgstr "Texture ขนาดใหà¸à¹ˆà¸•้องà¸à¸²à¸£à¹à¸„่ไฟล์เดียว"
+msgstr "โหนดà¹à¸¡à¹ˆà¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้องทำà¸à¸²à¸£à¸šà¸±à¸™à¸—ึà¸à¸‰à¸²à¸"
#: editor/editor_node.cpp
msgid "Save Scene As..."
@@ -2510,11 +2362,11 @@ msgstr "ทำไม่ได้ถ้าไม่มีฉาà¸"
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr "ส่งออภMesh Library"
+msgstr "ส่งออà¸à¹„ลบรารี Mesh"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
-msgstr "ทำไม่ได้ถ้าไม่มีโหนดราà¸"
+msgstr "ไม่สามารถà¸à¸£à¸°à¸—ำได้สำเร็จถ้าไม่มีโหนดà¹à¸¡à¹ˆ"
#: editor/editor_node.cpp
msgid "Export Tile Set"
@@ -2584,9 +2436,8 @@ msgid "Close Scene"
msgstr "ปิดไฟล์ฉาà¸"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reopen Closed Scene"
-msgstr "ปิดไฟล์ฉาà¸"
+msgstr "เปิดไฟล์ฉาà¸à¸—ี่ปิดไปใหม่"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
@@ -2601,11 +2452,12 @@ msgid "Unable to load addon script from path: '%s'."
msgstr "ไม่สามารถโหลดสคริปต์จาà¸: '%s'"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
-msgstr "ไม่สามารถโหลดสคริปต์จาà¸: '%s' ไม่ใช่สคริปต์ tool"
+msgstr ""
+"ไม่สามารถโหลดสคริปต์ส่วนเสริมจาà¸: '%s' เหมือนว่าจะเà¸à¸´à¸”ข้อผิดพลาดขึ้นในโค้ด "
+"à¸à¸£à¸¸à¸“าเช็ตรูปà¹à¸šà¸šà¸à¸²à¸£à¹€à¸‚ียนโค้ด"
#: editor/editor_node.cpp
msgid ""
@@ -2682,24 +2534,20 @@ msgstr "ค่าเริ่มต้น"
#: editor/editor_node.cpp editor/editor_properties.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
-#, fuzzy
msgid "Show in FileSystem"
-msgstr "เปิดในตัวจัดà¸à¸²à¸£à¹„ฟล์"
+msgstr "à¹à¸ªà¸”งในรูปà¹à¸šà¸šà¹„ฟล์"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Play This Scene"
-msgstr "เล่น"
+msgstr "เล่นฉาà¸à¸™à¸µà¹‰"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close Tab"
-msgstr "ปิดà¹à¸—็บอื่น"
+msgstr "ปิดà¹à¸—็บ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Undo Close Tab"
-msgstr "ปิดà¹à¸—็บอื่น"
+msgstr "เลิà¸à¸—ำà¹à¸—็บที่ปิด"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
@@ -2707,12 +2555,11 @@ msgstr "ปิดà¹à¸—็บอื่น"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "ปิดà¹à¸—็บทางด้านขวา"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close All Tabs"
-msgstr "ปิดทั้งหมด"
+msgstr "ปิดà¹à¸—็บทั้งหมด"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
@@ -2755,9 +2602,8 @@ msgid "Go to previously opened scene."
msgstr "ไปยังฉาà¸à¸—ี่เพิ่งเปิด"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Copy Text"
-msgstr "คัดลอà¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡"
+msgstr "คัดลอà¸à¸‚้อความ"
#: editor/editor_node.cpp
msgid "Next tab"
@@ -2796,9 +2642,8 @@ msgid "Save Scene"
msgstr "บันทึà¸à¸‰à¸²à¸"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save All Scenes"
-msgstr "บันทึà¸à¸—ุà¸à¸‰à¸²à¸"
+msgstr "บันทึà¸à¸‰à¸²à¸à¸—ั้งหมด"
#: editor/editor_node.cpp
msgid "Convert To..."
@@ -2806,11 +2651,11 @@ msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr "MeshLibrary..."
+msgstr "ไลบรารี Mesh..."
#: editor/editor_node.cpp
msgid "TileSet..."
-msgstr "TileSet..."
+msgstr "ไทล์เซต..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -2836,22 +2681,20 @@ msgid "Project"
msgstr "โปรเจà¸à¸•์"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Project Settings..."
-msgstr "ตัวเลือà¸à¹‚ปรเจà¸à¸•์"
+msgstr "ตั้งค่าโปรเจà¸à¸•์"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Version Control"
-msgstr "รุ่น:"
+msgstr "เวอร์ชันคอนโทรล"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "ตั้งเวอร์ชันคอนโทรน"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "ปิดเวอร์ชันคอนโทรล"
#: editor/editor_node.cpp
msgid "Export..."
@@ -2859,21 +2702,19 @@ msgstr "ส่งออà¸..."
#: editor/editor_node.cpp
msgid "Install Android Build Template..."
-msgstr ""
+msgstr "ติดตั้งà¹à¸¡à¹ˆà¹à¸šà¸šà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸‚องà¹à¸­à¸™à¸”รอยด์"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Project Data Folder"
-msgstr "เปิดตัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์?"
+msgstr "เปิดโฟลเดอร์ข้อมูลโปรเจà¸à¸•์"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
msgstr "เครื่องมือ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Orphan Resource Explorer..."
-msgstr "ตัวจัดà¸à¸²à¸£à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ªà¸—ี่ไม่มีเจ้าของ"
+msgstr "à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸—รัพยาà¸à¸£"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2882,7 +2723,7 @@ msgstr "ปิดà¹à¸¥à¸°à¸à¸¥à¸±à¸šà¸ªà¸¹à¹ˆà¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­à¹‚ปรเ
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
msgid "Debug"
-msgstr "à¹à¸à¹‰à¸ˆà¸¸à¸”บà¸à¸žà¸£à¹ˆà¸­à¸‡"
+msgstr "ดีบัà¸"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
@@ -2913,7 +2754,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
-msgstr "รูปทรงà¸à¸²à¸¢à¸ à¸²à¸žà¸¡à¸­à¸‡à¹€à¸«à¹‡à¸™à¹„ด้"
+msgstr "ขอบเขตà¸à¸²à¸£à¸Šà¸™à¸—ี่มองเห็นได้"
#: editor/editor_node.cpp
msgid ""
@@ -2923,7 +2764,7 @@ msgstr "รูปทรงà¸à¸²à¸¢à¸ à¸²à¸žà¹à¸¥à¸°à¸£à¸±à¸‡à¸ªà¸µ (2D à¹à¸¥à
#: editor/editor_node.cpp
msgid "Visible Navigation"
-msgstr "เส้นนำทางมองเห็นได้"
+msgstr "à¹à¸ªà¸”งà¸à¸²à¸£à¸™à¸³à¸—าง"
#: editor/editor_node.cpp
msgid ""
@@ -2947,7 +2788,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Sync Script Changes"
-msgstr "ซิงค์à¸à¸²à¸£à¹à¸à¹‰à¹„ขสคริปต์"
+msgstr "ซิงค์à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ªà¸„ริปต์"
#: editor/editor_node.cpp
msgid ""
@@ -2961,59 +2802,51 @@ msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
-msgstr "โปรà¹à¸à¸£à¸¡"
+msgstr "เอดิเตอร์"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "ตัวเลือà¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡"
+msgstr "ตั้งค่าเอดิเตอร์"
#: editor/editor_node.cpp
msgid "Editor Layout"
-msgstr "เลย์เอาต์โปรà¹à¸à¸£à¸¡"
+msgstr "เลย์เอาต์เอดิเตอร์"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "เข้าใจ!"
+msgstr "ถ่ายภาพหน้าจอ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr "ตัวเลือà¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡"
+msgstr "ภาพหน้าจอจะถูà¸à¹€à¸à¹‡à¸šà¹„ว้ในโฟลเดอร์ข้อมูล/à¸à¸²à¸£à¸•ั้งค่าของเอดิเตอร์"
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr "สลับเต็มจอ"
+msgstr "เปิด/ปิด โหมดเต็มหน้าจอ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Toggle System Console"
-msgstr "ซ่อน/à¹à¸ªà¸”งโหนด CanvasItem"
+msgstr "เปิด/ปิด คอนโซลระบบ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
-msgstr "ตัวเลือà¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡"
+msgstr "เปิดโฟลเดอร์ข้อมูล/ตั้งค่าของเอดิเตอร์"
#: editor/editor_node.cpp
msgid "Open Editor Data Folder"
-msgstr ""
+msgstr "เปิดโฟลเดอร์ของเอดิเตอร์"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Settings Folder"
-msgstr "ตัวเลือà¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡"
+msgstr "เปิดโฟลเดอร์à¸à¸²à¸£à¸•ั้งค่าของเอดิเตอร์"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Editor Features..."
-msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
+msgstr "จัดà¸à¸²à¸£à¸Ÿà¸µà¹€à¸ˆà¸­à¸£à¹Œà¸‚องเอดิเตอร์..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Export Templates..."
-msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
+msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸..."
#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
@@ -3038,8 +2871,13 @@ msgid "Q&A"
msgstr "ถาม/ตอบ"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "ระบบติดตามบัค"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "นำเข้าใหม่"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3087,13 +2925,12 @@ msgstr "เลือà¸à¹€à¸¥à¹ˆà¸™à¸‰à¸²à¸"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
-msgstr ""
+msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹„ดรเวอร์à¸à¸²à¸£à¹Œà¸”จอจำเป็นต้องเริ่มเอดิเตอร์ใหม่"
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Save & Restart"
-msgstr "บันทึà¸à¹à¸¥à¸°à¸™à¸³à¹€à¸‚้าอีà¸à¸„รั้ง"
+msgstr "บันทึà¸à¹à¸¥à¸°à¹€à¸£à¸´à¹ˆà¸¡à¹ƒà¸«à¸¡à¹ˆ"
#: editor/editor_node.cpp
#, fuzzy
@@ -3101,19 +2938,16 @@ msgid "Spins when the editor window redraws."
msgstr "หมุนเมื่อมีà¸à¸²à¸£à¸§à¸²à¸”หน้าต่างโปรà¹à¸à¸£à¸¡à¹ƒà¸«à¸¡à¹ˆ!"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "ต่อเนื่อง"
+msgstr "อัพเดทอย่างต่อเนื่อง"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
msgstr "อัพเดทเมื่อเปลี่ยนà¹à¸›à¸¥à¸‡"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "ปิดà¸à¸²à¸£à¸­à¸±à¸žà¹€à¸”ทตัวหมุน"
+msgstr "ซ่อนตัวหมุนà¸à¸²à¸£à¸­à¸±à¸žà¹€à¸”ท"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -3124,9 +2958,8 @@ msgid "Inspector"
msgstr "คุณสมบัติ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Expand Bottom Panel"
-msgstr "ขยายโฟลเดอร์"
+msgstr "ขยายà¹à¸œà¸‡à¸¥à¹ˆà¸²à¸‡"
#: editor/editor_node.cpp
msgid "Output"
@@ -3141,9 +2974,8 @@ msgid "Android build template is missing, please install relevant templates."
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Templates"
-msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
+msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸š"
#: editor/editor_node.cpp
msgid ""
@@ -3169,9 +3001,8 @@ msgid "Import Templates From ZIP File"
msgstr "นำเข้าà¹à¸¡à¹ˆà¹à¸šà¸šà¸ˆà¸²à¸à¹„ฟล์ ZIP"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Template Package"
-msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
+msgstr "à¹à¸žà¸„เà¸à¸ˆà¹à¸¡à¹ˆà¹à¸šà¸š"
#: editor/editor_node.cpp
msgid "Export Library"
@@ -3199,15 +3030,15 @@ msgstr "เลือà¸"
#: editor/editor_node.cpp
msgid "Open 2D Editor"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ข 2 มิติ"
+msgstr "เปิดเอดิเตอร์ 2D"
#: editor/editor_node.cpp
msgid "Open 3D Editor"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ข 3 มิติ"
+msgstr "เปิดเอดิเตอร์ 3D"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ขสคริปต์"
+msgstr "เปิดเอดิเตอร์สคริปต์"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
@@ -3215,16 +3046,15 @@ msgstr "เปิดà¹à¸«à¸¥à¹ˆà¸‡à¸£à¸§à¸¡à¸—รัพยาà¸à¸£"
#: editor/editor_node.cpp
msgid "Open the next Editor"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ขถัดไป"
+msgstr "เปิดเอดิเตอร์ถัดไป"
#: editor/editor_node.cpp
msgid "Open the previous Editor"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ขà¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
+msgstr "เปิดเอดิเตอร์à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
#: editor/editor_node.h
-#, fuzzy
msgid "Warning!"
-msgstr "คำเตือน"
+msgstr "คำเตือน!"
#: editor/editor_path.cpp
#, fuzzy
@@ -3240,14 +3070,12 @@ msgid "Thumbnail..."
msgstr "รูปตัวอย่าง..."
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Main Script:"
-msgstr "เปิดสคริปต์"
+msgstr "สคริปต์หลัà¸:"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Edit Plugin"
-msgstr "à¹à¸à¹‰à¹„ขรูปหลายเหลี่ยม"
+msgstr "à¹à¸à¹‰à¹„ขปลั๊à¸à¸­à¸´à¸™"
#: editor/editor_plugin_settings.cpp
msgid "Installed Plugins:"
@@ -3264,16 +3092,15 @@ msgstr "รุ่น:"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
msgid "Author:"
-msgstr "โดย:"
+msgstr "ผู้สร้าง:"
#: editor/editor_plugin_settings.cpp
msgid "Status:"
msgstr "สถานะ:"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Edit:"
-msgstr "à¹à¸à¹‰à¹„ข"
+msgstr "à¹à¸à¹‰à¹„ข:"
#: editor/editor_profiler.cpp
msgid "Measure:"
@@ -3289,7 +3116,7 @@ msgstr "เวลาเฉลี่ย (วินาที)"
#: editor/editor_profiler.cpp
msgid "Frame %"
-msgstr "% ของเฟรม"
+msgstr "เฟรม %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
@@ -3316,9 +3143,8 @@ msgid "Calls"
msgstr "จำนวนครั้ง"
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Edit Text:"
-msgstr "à¹à¸à¹‰à¹„ขธีม..."
+msgstr "à¹à¸à¹‰à¹„ขข้อความ:"
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
@@ -3326,10 +3152,9 @@ msgstr "เปิด"
#: editor/editor_properties.cpp
msgid "Layer"
-msgstr ""
+msgstr "เลเยอร์"
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Bit %d, value %d"
msgstr "บิต %d, ค่า %d"
@@ -3338,14 +3163,12 @@ msgid "[Empty]"
msgstr "[ว่างเปล่า]"
#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Assign..."
-msgstr "ระบุ"
+msgstr "à¸à¸³à¸«à¸™à¸”..."
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Invalid RID"
-msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸œà¸´à¸”พลาด"
+msgstr "RID ผิดพลาด"
#: editor/editor_properties.cpp
msgid ""
@@ -3376,9 +3199,8 @@ msgid "New Script"
msgstr "สคริปต์ใหม่"
#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Extend Script"
-msgstr "เปิดสคริปต์"
+msgstr "สคริปต์เสริม"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New %s"
@@ -3411,13 +3233,12 @@ msgid "Selected node is not a Viewport!"
msgstr "โหนดที่เลือà¸à¹„ม่ใช่ Viewport!"
#: editor/editor_properties_array_dict.cpp
-#, fuzzy
msgid "Size: "
-msgstr "ขนาดเซลล์:"
+msgstr "ขนาด: "
#: editor/editor_properties_array_dict.cpp
msgid "Page: "
-msgstr ""
+msgstr "หน้า: "
#: editor/editor_properties_array_dict.cpp
#: editor/plugins/theme_editor_plugin.cpp
@@ -3425,18 +3246,16 @@ msgid "Remove Item"
msgstr "ลบไอเทม"
#: editor/editor_properties_array_dict.cpp
-#, fuzzy
msgid "New Key:"
-msgstr "ชื่อใหม่:"
+msgstr "คีย์ใหม่:"
#: editor/editor_properties_array_dict.cpp
-#, fuzzy
msgid "New Value:"
-msgstr "ชื่อใหม่:"
+msgstr "ค่าใหม่:"
#: editor/editor_properties_array_dict.cpp
msgid "Add Key/Value Pair"
-msgstr ""
+msgstr "เพิ่มคู่ของคีย์/ค่า"
#: editor/editor_run_native.cpp
msgid ""
@@ -3456,7 +3275,7 @@ msgstr "มีฉาà¸à¸—ี่à¹à¸à¹‰à¹„ขอยู่à¹à¸¥à¹‰à¸§"
#: editor/editor_run_script.cpp
msgid "Couldn't instance script:"
-msgstr "สร้างอินสà¹à¸•นซ์ของสคริปต์ไม่ได้:"
+msgstr "ไม่สามารถอินสà¹à¸•นซ์สคริปต์ได้:"
#: editor/editor_run_script.cpp
msgid "Did you forget the 'tool' keyword?"
@@ -3476,7 +3295,7 @@ msgstr "เลือà¸à¹‚หนดเพื่อนำเข้า"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
msgid "Browse"
-msgstr "เลือà¸"
+msgstr "ค้นหา"
#: editor/editor_sub_scene.cpp
msgid "Scene Path:"
@@ -3487,7 +3306,6 @@ msgid "Import From Node:"
msgstr "นำเข้าจาà¸à¹‚หนด:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Redownload"
msgstr "ดาวน์โหลดอีà¸à¸„รั้ง"
@@ -3529,9 +3347,8 @@ msgid "Can't open export templates zip."
msgstr "เปิดไฟล์ zip à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸à¹„ม่ได้"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Invalid version.txt format inside templates: %s."
-msgstr "รูปà¹à¸šà¸šà¸‚อง version.txt ในà¹à¸¡à¹ˆà¹à¸šà¸šà¹„ม่ถูà¸à¸•้อง"
+msgstr "รูปà¹à¸šà¸šà¸‚อง version.txt ในà¹à¸¡à¹ˆà¹à¸šà¸š %s ไม่ถูà¸à¸•้อง"
#: editor/export_template_manager.cpp
msgid "No version.txt found inside templates."
@@ -3550,9 +3367,8 @@ msgid "Importing:"
msgstr "นำเข้า:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error getting the list of mirrors."
-msgstr "ผิดพลาดขณะสร้าง signature object"
+msgstr "ผิดพลาดขณะà¸à¸³à¸¥à¸±à¸‡à¸£à¸±à¸šà¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­à¸‚อง mirrors"
#: editor/export_template_manager.cpp
msgid "Error parsing JSON of mirror list. Please report this issue!"
@@ -3597,9 +3413,8 @@ msgid "Download Complete."
msgstr "ดาวน์โหลดเสร็จสิ้น"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Cannot remove temporary file:"
-msgstr "บันทึà¸à¸˜à¸µà¸¡à¹„ม่ได้:"
+msgstr "ไม่สามารถลบไฟล์ชั่วคราวได้:"
#: editor/export_template_manager.cpp
msgid ""
@@ -3608,17 +3423,16 @@ msgid ""
msgstr ""
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error requesting URL:"
-msgstr "ผิดพลาดขณะร้องขอที่อยู่: "
+msgstr "ผิดพลาดขณะà¸à¸³à¸¥à¸±à¸‡à¸£à¹‰à¸­à¸‡à¸‚อ URL:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
-msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ..."
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อà¸à¸±à¸š Mirror"
#: editor/export_template_manager.cpp
msgid "Disconnected"
-msgstr "à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อสิ้นสุด"
+msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อà¹à¸¥à¹‰à¸§"
#: editor/export_template_manager.cpp
msgid "Resolving"
@@ -3659,9 +3473,8 @@ msgid "SSL Handshake Error"
msgstr "à¸à¸²à¸£à¸£à¸±à¸šà¸£à¸­à¸‡à¸„วามปลอดภัยผิดพลาด"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Uncompressing Android Build Sources"
-msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„ลายบีบอัด"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„ลาย Android Build Sources"
#: editor/export_template_manager.cpp
msgid "Current Version:"
@@ -3680,14 +3493,12 @@ msgid "Remove Template"
msgstr "ลบà¹à¸¡à¹ˆà¹à¸šà¸š"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Select Template File"
msgstr "เลือà¸à¹„ฟล์à¹à¸¡à¹ˆà¹à¸šà¸š"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Godot Export Templates"
-msgstr "à¸à¸³à¸¥à¸±à¸‡à¹‚หลดà¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
+msgstr "à¹à¸¡à¹ˆà¹à¸šà¸šà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸ Godot"
#: editor/export_template_manager.cpp
msgid "Export Template Manager"
@@ -3698,14 +3509,12 @@ msgid "Download Templates"
msgstr "ดาวน์โหลดà¹à¸¡à¹ˆà¹à¸šà¸š"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
-msgstr "เลือà¸à¸¥à¸´à¸‡à¸à¹Œà¸”าวน์โหลด: "
+msgstr "เลือภmirror จาà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­: (Shift+คลิà¸: เปิดในเบราเซอร์)"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Favorites"
-msgstr "ที่ชื่นชอบ:"
+msgstr "ที่ชื่นชอบ"
#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
@@ -3736,9 +3545,8 @@ msgid "No name provided."
msgstr "ไม่ได้ระบุชื่อ"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Provided name contains invalid characters."
-msgstr "ไม่สามารถใช้อัà¸à¸©à¸£à¸šà¸²à¸‡à¸•ัวในชื่อได้"
+msgstr "ชื่อที่ระบุประà¸à¸­à¸šà¹„ปด้วยตัวอัà¸à¸©à¸£à¸—ี่ไม่ถูà¸à¸•้อง"
#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
@@ -3765,33 +3573,28 @@ msgid "Duplicating folder:"
msgstr "ทำซ้ำโฟลเดอร์:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Inherited Scene"
-msgstr "สืบทอดฉาà¸à¹ƒà¸«à¸¡à¹ˆ..."
+msgstr "ฉาà¸à¸ªà¸·à¸šà¸—อดใหม่"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Set As Main Scene"
-msgstr "ฉาà¸à¸«à¸¥à¸±à¸"
+msgstr "ตั้งเป็นฉาà¸à¸«à¸¥à¸±à¸"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open Scenes"
-msgstr "เปิดไฟล์ฉาà¸"
+msgstr "เปิดฉาà¸"
#: editor/filesystem_dock.cpp
msgid "Instance"
msgstr "อินสà¹à¸•นซ์"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Add to Favorites"
-msgstr "ที่ชื่นชอบ:"
+msgstr "เพิ่มไปยังที่ชื่นชอบ"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Remove from Favorites"
-msgstr "ลบออà¸à¸ˆà¸²à¸à¸à¸¥à¸¸à¹ˆà¸¡"
+msgstr "ลบจาà¸à¸—ี่่ชื่นชอบ"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
@@ -3814,9 +3617,8 @@ msgid "Move To..."
msgstr "ย้ายไป..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Scene..."
-msgstr "ฉาà¸à¹ƒà¸«à¸¡à¹ˆ"
+msgstr "ฉาà¸à¹ƒà¸«à¸¡à¹ˆ..."
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
@@ -3861,9 +3663,8 @@ msgid "Toggle Split Mode"
msgstr "สลับโหมด"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Search files"
-msgstr "ค้นหาคลาส"
+msgstr "ค้นหาไฟล์"
#: editor/filesystem_dock.cpp
msgid ""
@@ -3886,9 +3687,8 @@ msgid "Overwrite"
msgstr "เขียนทับ"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Create Scene"
-msgstr "สร้างจาà¸à¸‰à¸²à¸"
+msgstr "สร้างฉาà¸"
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
@@ -3900,16 +3700,15 @@ msgstr "ค้นหาในไฟล์"
#: editor/find_in_files.cpp
msgid "Find:"
-msgstr "ค้นหา: "
+msgstr "ค้นหา:"
#: editor/find_in_files.cpp
msgid "Folder:"
-msgstr "โฟลเดอร์: "
+msgstr "โฟลเดอร์:"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Filters:"
-msgstr "ตัวà¸à¸£à¸­à¸‡"
+msgstr "ตัวà¸à¸£à¸­à¸‡:"
#: editor/find_in_files.cpp
msgid ""
@@ -4084,9 +3883,8 @@ msgid "Saving..."
msgstr "à¸à¸³à¸¥à¸±à¸‡à¸šà¸±à¸™à¸—ึà¸..."
#: editor/import_dock.cpp
-#, fuzzy
msgid "%d Files"
-msgstr " ไฟล์"
+msgstr "ไฟล์ %d"
#: editor/import_dock.cpp
msgid "Set as Default for '%s'"
@@ -4101,21 +3899,21 @@ msgid "Import As:"
msgstr "นำเข้าเป็น:"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Preset"
-msgstr "à¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸"
+msgstr "ตั้งล่วงหน้า"
#: editor/import_dock.cpp
msgid "Reimport"
msgstr "นำเข้าใหม่"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
-msgstr ""
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
+msgstr "บันทึà¸à¸‰à¸²à¸, นำเข้าà¹à¸¥à¸°à¹€à¸£à¸´à¹ˆà¸¡à¸•้นใหม่"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
-msgstr ""
+msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸Šà¸™à¸´à¸”ของไฟล์ที่นำเข้า จำเป็นต้องเริ่มเอดิเตอร์ใหม่"
#: editor/import_dock.cpp
msgid ""
@@ -4124,15 +3922,13 @@ msgstr ""
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
-msgstr "โหลดรีซอร์สไม่ได้"
+msgstr "โหลดทรัพยาà¸à¸£à¹„ม่ได้"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Expand All Properties"
msgstr "ขยายคุณสมบัติทั้งหมด"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Collapse All Properties"
msgstr "ยุบคุณสมบัติทั้งหมด"
@@ -4143,12 +3939,11 @@ msgstr "บันทึà¸à¹€à¸›à¹‡à¸™..."
#: editor/inspector_dock.cpp
msgid "Copy Params"
-msgstr "คัดลอà¸à¸•ัวà¹à¸›à¸£"
+msgstr "คัดลอà¸à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Edit Resource Clipboard"
-msgstr "คลิปบอร์ดไม่มีรีซอร์ส!"
+msgstr "à¹à¸à¹‰à¹„ขคลิปบอร์ดทรัพยาà¸à¸£"
#: editor/inspector_dock.cpp
msgid "Copy Resource"
@@ -4195,9 +3990,8 @@ msgid "Object properties."
msgstr "คุณสมบัติวัตถุ"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Filter properties"
-msgstr "ตัวà¸à¸£à¸­à¸‡"
+msgstr "คุà¸à¸ªà¸¡à¸šà¸±à¸•ิตัวà¸à¸£à¸­à¸‡"
#: editor/inspector_dock.cpp
msgid "Changes may be lost!"
@@ -4222,15 +4016,15 @@ msgstr "สร้างปลั๊à¸à¸­à¸´à¸™"
#: editor/plugin_config_dialog.cpp
msgid "Plugin Name:"
-msgstr "ชื่อปลั๊à¸à¸­à¸´à¸™"
+msgstr "ชื่อปลั๊à¸à¸­à¸´à¸™:"
#: editor/plugin_config_dialog.cpp
msgid "Subfolder:"
-msgstr "โฟลเดอร์ย่อย: "
+msgstr "โฟลเดอร์ย่อย:"
#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp
msgid "Language:"
-msgstr "ภาษา: "
+msgstr "ภาษา:"
#: editor/plugin_config_dialog.cpp
msgid "Script Name:"
@@ -4238,7 +4032,7 @@ msgstr "ชื่อสคริปต์:"
#: editor/plugin_config_dialog.cpp
msgid "Activate now?"
-msgstr ""
+msgstr "เปิดใช้งานตอนนี้?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -4252,25 +4046,21 @@ msgid "Create points."
msgstr "สร้างจุด"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid ""
"Edit points.\n"
"LMB: Move Point\n"
"RMB: Erase Point"
msgstr ""
-"à¹à¸à¹‰à¹„ขรูปหลายเหลี่ยม:\n"
-"เมาส์ซ้าย: ย้ายจุด\n"
-"Ctrl+เมาส์ซ้าย: à¹à¸¢à¸à¸ªà¹ˆà¸§à¸™\n"
-"เมาส์ขวา: ลบจุด"
+"à¹à¸à¹‰à¹„ขจุด:\n"
+"คลิà¸à¸‹à¹‰à¸²à¸¢: ย้ายจุด\n"
+"คลิà¸à¸‚วา: ลบจุด"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Erase points."
-msgstr "คลิà¸à¸‚วา: ลบจุด"
+msgstr "ลบจุด"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Edit Polygon"
msgstr "à¹à¸à¹‰à¹„ขรูปหลายเหลี่ยม"
@@ -4279,12 +4069,10 @@ msgid "Insert Point"
msgstr "à¹à¸—รà¸à¸ˆà¸¸à¸”"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Edit Polygon (Remove Point)"
msgstr "à¹à¸à¹‰à¹„ขรูปหลายเหลี่ยม (ลบจุด)"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Remove Polygon And Point"
msgstr "ลบรูปหลายเหลี่ยมà¹à¸¥à¸°à¸ˆà¸¸à¸”"
@@ -4300,52 +4088,45 @@ msgstr "เพิ่มà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Load..."
-msgstr "โหลด"
+msgstr "โหลด..."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Move Node Point"
-msgstr "ย้ายจุด"
+msgstr "สร้างจุดโหนด"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace1D Limits"
-msgstr "à¹à¸à¹‰à¹„ขระยะเวลาà¸à¸²à¸£à¸œà¸ªà¸²à¸™"
+msgstr "เปลี่ยนค่าจำà¸à¸±à¸”ของ BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace1D Labels"
-msgstr "à¹à¸à¹‰à¹„ขระยะเวลาà¸à¸²à¸£à¸œà¸ªà¸²à¸™"
+msgstr "เปลี่ยนป้ายà¸à¸³à¸à¸±à¸š BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_state_machine_editor.cpp
msgid "This type of node can't be used. Only root nodes are allowed."
-msgstr ""
+msgstr "โหนดชนิดนี้ไม่สามารถใช้ได้ มีà¹à¸„่โหนดà¹à¸¡à¹ˆà¹€à¸—่านั้นที่สามารถใช้ได้"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Node Point"
-msgstr "เพิ่มโหนด"
+msgstr "เพิ่มจุดโหนด"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Animation Point"
-msgstr "เพิ่มà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เพิ่มจุดà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace1D Point"
-msgstr "ลบจุด"
+msgstr "ลบจุด BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
msgid "Move BlendSpace1D Node Point"
-msgstr ""
+msgstr "ย้ายจุดโหนด BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4369,38 +4150,33 @@ msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
msgid "Enable snap and show grid."
-msgstr ""
+msgstr "เปิà¸à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸à¸²à¸£à¹€à¸‚้าหาà¹à¸¥à¹à¸ªà¸”งเส้นà¸à¸£à¸´à¸”"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Point"
-msgstr "ย้ายจุด"
+msgstr "จุด"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Open Editor"
-msgstr "เปิดในโปรà¹à¸à¸£à¸¡à¹à¸à¹‰à¹„ข"
+msgstr "เปิดเอดิเตอร์"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Open Animation Node"
-msgstr "โหนดà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เปิดโหนดà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Triangle already exists."
-msgstr "มีà¸à¸²à¸£à¸à¸£à¸°à¸—ำ '%s' อยู่à¹à¸¥à¹‰à¸§!"
+msgstr "มีสามเหลี่ยมอยู่à¹à¸¥à¹‰à¸§"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Triangle"
-msgstr "เพิ่มตัวà¹à¸›à¸£"
+msgstr "เพิ่มสามเหลี่ยม"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#, fuzzy
@@ -4440,9 +4216,8 @@ msgid "Create triangles by connecting points."
msgstr ""
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Erase points and triangles."
-msgstr "วิเคราะห์สามเหลี่ยม %d อัน:"
+msgstr "ลบจุดà¹à¸¥à¸°à¸ªà¸²à¸¡à¹€à¸«à¸¥à¸µà¹ˆà¸¢à¸¡"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Generate blend triangles automatically (instead of manually)"
@@ -4491,9 +4266,8 @@ msgid "Nodes Disconnected"
msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อโหนดà¹à¸¥à¹‰à¸§"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Set Animation"
-msgstr "à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "ตั้งà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -4512,9 +4286,8 @@ msgid "Toggle Filter On/Off"
msgstr "โหมดไร้สิ่งรบà¸à¸§à¸™"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Change Filter"
-msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸­à¸‡à¸ à¸¹à¸¡à¸´à¸ à¸²à¸„"
+msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸­à¸‡"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
@@ -4532,31 +4305,26 @@ msgid ""
msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Anim Clips"
-msgstr "คลิป"
+msgstr "คลิปà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Audio Clips"
-msgstr "ตัวรับเสียง"
+msgstr "คลิปเสียง"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Functions"
-msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™:"
+msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Renamed"
-msgstr "ชื่อโหนด:"
+msgstr "เปลี่ยนชื่อโหนดà¹à¸¥à¹‰à¸§"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Node..."
-msgstr "เพิ่มโหนด"
+msgstr "เพิ่มโหนด..."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
@@ -4565,9 +4333,8 @@ msgid "Edit Filtered Tracks:"
msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸­à¸‡"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Enable Filtering"
-msgstr "à¹à¸à¹‰à¹„ขโหนดลูà¸à¹„ด้"
+msgstr "เปิดà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸•ัวà¸à¸£à¸­à¸‡"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Toggle Autoplay"
@@ -4596,14 +4363,12 @@ msgid "Remove Animation"
msgstr "ลบà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Invalid animation name!"
-msgstr "ผิดพลาด: ชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹„ม่ถูà¸à¸•้อง!"
+msgstr "ชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹„ม่ถูà¸à¸•้อง!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Animation name already exists!"
-msgstr "ผิดพลาด: มีชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸™à¸µà¹‰à¸­à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§!"
+msgstr "ชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸™à¸µà¹‰ มีอยู่à¹à¸¥à¹‰à¸§!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -4627,14 +4392,12 @@ msgid "Duplicate Animation"
msgstr "ทำซ้ำà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to copy!"
-msgstr "ผิดพลาด: ไม่มีà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¹‰à¸„ัดลอà¸!"
+msgstr "ไม่มีà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¹‰à¸„ัดลอà¸!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation resource on clipboard!"
-msgstr "ผิดพลาด: ไม่มีà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸™à¸„ลิปบอร์ด!"
+msgstr "ไม่มีà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸™à¸„ลิปบอร์ด!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
@@ -4645,9 +4408,8 @@ msgid "Paste Animation"
msgstr "วางà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to edit!"
-msgstr "ผิดพลาด: ไม่มีà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¹‰à¹à¸à¹‰à¹„ข!"
+msgstr "ไม่มีà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¹‰à¹à¸à¹‰à¹„ข!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
@@ -4753,9 +4515,8 @@ msgid "Include Gizmos (3D)"
msgstr "รวมสัà¸à¸¥à¸±à¸à¸©à¸“์ (3D)"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Pin AnimationPlayer"
-msgstr "วางà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "ปัà¸à¸«à¸¡à¸¸à¸” AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Create New Animation"
@@ -4785,9 +4546,8 @@ msgid "Cross-Animation Blend Times"
msgstr "ระยะเวลาà¸à¸²à¸£à¸œà¸ªà¸²à¸™ Cross-Animation"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Move Node"
-msgstr "โหมดเคลื่อนย้าย"
+msgstr "เคลื่อนย้ายโหนด"
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -4815,7 +4575,7 @@ msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Sync"
-msgstr ""
+msgstr "ซิงค์"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "At End"
@@ -4835,9 +4595,8 @@ msgid "No playback resource set at path: %s."
msgstr "ไม่อยู่ในโฟลเดอร์รีซอร์ส"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Removed"
-msgstr "ลบ:"
+msgstr "ลบโหนดà¹à¸¥à¹‰à¸§"
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -4856,9 +4615,8 @@ msgid ""
msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Create new nodes."
-msgstr "สร้าง %s ใหม่"
+msgstr "สร้างโหนดใหม่"
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -4884,9 +4642,8 @@ msgid "Transition: "
msgstr "ทรานสิชัน"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Play Mode:"
-msgstr "โหมดมุมมอง"
+msgstr "โหมดà¸à¸²à¸£à¹€à¸¥à¹ˆà¸™:"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -5058,7 +4815,6 @@ msgid "Request failed, return code:"
msgstr "à¸à¸²à¸£à¸£à¹‰à¸­à¸‡à¸‚อผิดพลาด รหัส:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Request failed."
msgstr "ร้องขอผิดพลาด"
@@ -5069,7 +4825,7 @@ msgstr "บันทึà¸à¸˜à¸µà¸¡à¹„ม่ได้:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Write error."
-msgstr ""
+msgstr "à¸à¸²à¸£à¹€à¸‚ียนผิดพลาด"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
@@ -5086,9 +4842,8 @@ msgid "Request failed, timeout"
msgstr "à¸à¸²à¸£à¸£à¹‰à¸­à¸‡à¸‚อผิดพลาด รหัส:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Timeout."
-msgstr "เวลา"
+msgstr "หมดเวลา"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
@@ -5111,9 +4866,8 @@ msgid "Asset Download Error:"
msgstr "ดาวน์โหลดทรัพยาà¸à¸£à¸œà¸´à¸”พลาด:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Downloading (%s / %s)..."
-msgstr "à¸à¸³à¸¥à¸±à¸‡à¸”าวน์โหลด"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸”าวน์โหลด (%s / %s)..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Downloading..."
@@ -5149,32 +4903,29 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸”าวน์โหลดไฟล์นี้อยู
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Recently Updated"
-msgstr ""
+msgstr "อัพเดทล่าสุด"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Least Recently Updated"
-msgstr ""
+msgstr "อัพเดทน้อยสุด"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (A-Z)"
-msgstr ""
+msgstr "ชื่อ (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (Z-A)"
-msgstr ""
+msgstr "ชื่อ (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (A-Z)"
-msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•"
+msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸• (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (Z-A)"
-msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•"
+msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸• (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "First"
msgstr "à¹à¸£à¸à¸ªà¸¸à¸”"
@@ -5196,7 +4947,7 @@ msgstr "ทั้งหมด"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No results for \"%s\"."
-msgstr ""
+msgstr "ไม่มีผลลัพธ์สำหรับ \"%s\""
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Import..."
@@ -5237,7 +4988,7 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¹‚หลด..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
-msgstr "ไฟล์ ZIP"
+msgstr "ทรัพยาà¸à¸£à¹„ฟล์ ZIP"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5278,7 +5029,7 @@ msgstr "จุดà¸à¸³à¹€à¸™à¸´à¸”ตาราง:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Step:"
-msgstr "ระยะห่างเส้น:"
+msgstr "ระยะห่างเส้นà¸à¸£à¸´à¸”:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Primary Line Every:"
@@ -5384,63 +5135,52 @@ msgid ""
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Left"
-msgstr "ซ้าย"
+msgstr "บนซ้าย"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Right"
-msgstr "ขวา"
+msgstr "บนขวา"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Right"
-msgstr "ย้ายไปขวา"
+msgstr "ล่างขวา"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Left"
-msgstr "มุมล่าง"
+msgstr "ล่างซ้าย"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Left"
-msgstr "ย่อหน้าซ้าย"
+msgstr "à¸à¸¥à¸²à¸‡à¸‹à¹‰à¸²à¸¢"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Top"
-msgstr "ให้สิ่งที่เลือà¸à¸­à¸¢à¸¹à¹ˆà¸à¸¥à¸²à¸‡à¸ˆà¸­"
+msgstr "à¸à¸¥à¸²à¸‡à¸šà¸™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Right"
-msgstr "ย่อหน้าขวา"
+msgstr "à¸à¸¥à¸²à¸‡à¸‚วา"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Bottom"
-msgstr "ล่าง"
+msgstr "à¸à¸¥à¸²à¸‡à¸¥à¹ˆà¸²à¸‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center"
-msgstr ""
+msgstr "à¸à¸¥à¸²à¸‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Left Wide"
-msgstr "มุมซ้าย"
+msgstr "ความà¸à¸§à¹‰à¸²à¸‡à¸‹à¹‰à¸²à¸¢"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Wide"
-msgstr "มุมบน"
+msgstr "ความà¸à¸§à¹‰à¸²à¸‡à¸šà¸™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Right Wide"
-msgstr "มุมขวา"
+msgstr "ความà¸à¸§à¹‰à¸²à¸‡à¸‚วา"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5449,11 +5189,11 @@ msgstr "มุมล่าง"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "VCenter Wide"
-msgstr ""
+msgstr "ความà¸à¸§à¹‰à¸²à¸‡ VCenter"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "HCenter Wide"
-msgstr ""
+msgstr "ความà¸à¸§à¹‰à¸²à¸‡ HCenter"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5461,9 +5201,8 @@ msgid "Full Rect"
msgstr "ชื่อเต็ม"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Keep Ratio"
-msgstr "อัตราส่วนเวลา:"
+msgstr "รัà¸à¸©à¸²à¸­à¸±à¸•ราส่วน"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
@@ -5483,6 +5222,8 @@ msgid ""
"Game Camera Override\n"
"Overrides game camera with editor viewport camera."
msgstr ""
+"เขียนทับà¸à¸¥à¹‰à¸­à¸‡à¸‚องเà¸à¸¡à¸ªà¹Œ\n"
+"เขียนทับà¸à¸¥à¹‰à¸­à¸‡à¸‚องเà¸à¸¡à¸ªà¹Œà¸”้วยเอดิเตอร์ของวิวพอร์ตของà¸à¸¥à¹‰à¸­à¸‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5490,18 +5231,18 @@ msgid ""
"Game Camera Override\n"
"No game instance running."
msgstr ""
+"เขียนทับà¸à¸¥à¹‰à¸­à¸‡à¸‚องเà¸à¸¡à¸ªà¹Œ\n"
+"ไม่มีอินสà¹à¸•นซ์ของเà¸à¸¡à¸ªà¹Œà¸—ำงานอยู่"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected"
-msgstr "เครื่องมือเลือà¸"
+msgstr "ล็อà¸à¸—ี่เลือà¸"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected"
-msgstr "ลบสิ่งที่เลือà¸"
+msgstr "ปลดล็อคที่เลือà¸"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5551,7 +5292,6 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
-#, fuzzy
msgid "Zoom Reset"
msgstr "รีเซ็ตà¸à¸²à¸£à¸‹à¸¹à¸¡"
@@ -5588,9 +5328,8 @@ msgstr "โหมดหมุน"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scale Mode"
-msgstr "โหมดปรับขนาด (R)"
+msgstr "โหมดปรับขนาด"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5610,9 +5349,8 @@ msgid "Pan Mode"
msgstr "โหมดมุมมอง"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Ruler Mode"
-msgstr "โหมดà¸à¸²à¸£à¸—ำงาน:"
+msgstr "โหมดไม้บรรทัด"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5630,9 +5368,8 @@ msgid "Toggle grid snapping."
msgstr "เปิด/ปิด à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Grid Snap"
-msgstr "จำà¸à¸±à¸”ด้วยเส้นตาราง"
+msgstr "ใช้à¸à¸²à¸£à¹€à¸‚้าหาเส้นà¸à¸£à¸´à¸”"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5709,12 +5446,12 @@ msgstr "ปลดล็อควัตถุที่เลือà¸"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Makes sure the object's children are not selectable."
-msgstr "ทำให้เลือà¸à¹‚หนดลูà¸à¹„ม่ได้"
+msgstr "เลือà¸à¹‚หนดลูà¸à¹„ม่ได้"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Restores the object's children's ability to be selected."
-msgstr "ทำให้เลือà¸à¹‚หนดลูà¸à¹„ด้เหมือนเดิม"
+msgstr "เลือà¸à¹‚หนดลูà¸à¹„ด้"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5740,9 +5477,8 @@ msgid "View"
msgstr "มุมมอง"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Always Show Grid"
-msgstr "à¹à¸ªà¸”งเส้นตาราง"
+msgstr "à¹à¸ªà¸”งเส้นà¸à¸£à¸´à¸”"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
@@ -5768,7 +5504,7 @@ msgstr "1 มุมมอง"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Group And Lock Icons"
-msgstr ""
+msgstr "à¹à¸ªà¸”งà¸à¸¥à¸¸à¹ˆà¸¡à¹à¸¥à¸°à¸¥à¹‡à¸­à¸„ไอคอน"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Selection"
@@ -5832,11 +5568,11 @@ msgstr "ลบท่าทาง"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Multiply grid step by 2"
-msgstr "เพิ่มความถี่เส้นตารางขึ้น 2 เท่า"
+msgstr "เพิ่มความถี่เส้นà¸à¸£à¸´à¸”ขึ้น 2 เท่า"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Divide grid step by 2"
-msgstr "ลดความถี่เส้นตารางลงครึ่งหนึ่ง"
+msgstr "ลดความถี่à¸à¸£à¸´à¸”ลงครึ่งหนึ่ง"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5853,7 +5589,7 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸žà¸´à¹ˆà¸¡ %s..."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Cannot instantiate multiple nodes without root."
-msgstr "อินสà¹à¸•นซ์หลาย ๆ โหนดโดยที่ไม่มีโหนดราà¸à¹„ม่ได้"
+msgstr "อินสà¹à¸•นซ์หลาย ๆ โหนดโดยที่ไม่มีโหนดà¹à¸¡à¹ˆà¹„ม่ได้"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -5879,9 +5615,8 @@ msgstr ""
"ลาภ& วาง + Alt: เปลี่ยนประเภทโหนด"
#: editor/plugins/collision_polygon_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon3D"
-msgstr "สร้างรูปหลายเหลี่ยม"
+msgstr "สร้าง Polygon3D"
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly"
@@ -5904,9 +5639,8 @@ msgstr "โหลด Mask à¸à¸²à¸£à¸›à¸°à¸—ุ"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "เริ่มใหม่ทันที"
+msgstr "เริ่มใหม่"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5938,7 +5672,7 @@ msgstr "Snap (พิà¸à¹€à¸‹à¸¥):"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Border Pixels"
-msgstr ""
+msgstr "พิà¸à¹€à¸‹à¸¥à¸‚อบ"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -6006,12 +5740,10 @@ msgid "Load Curve Preset"
msgstr "โหลดเส้นโค้งตัวอย่าง"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Add Point"
msgstr "เพิ่มจุด"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Remove Point"
msgstr "ลบจุด"
@@ -6053,7 +5785,7 @@ msgstr "สร้าง GI Probe"
#: editor/plugins/gradient_editor_plugin.cpp
msgid "Gradient Edited"
-msgstr ""
+msgstr "à¹à¸à¹‰à¹„ขเà¸à¸£à¹€à¸”ียนต์"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
@@ -6408,7 +6140,7 @@ msgstr "โหนดไม่มี geometry (หน้า)"
#: editor/plugins/particles_editor_plugin.cpp
msgid "\"%s\" doesn't inherit from Spatial."
-msgstr ""
+msgstr "\"%s\" ไม่ได้สืบทอดมาจาภSpatial"
#: editor/plugins/particles_editor_plugin.cpp
#, fuzzy
@@ -6610,6 +6342,8 @@ msgid ""
"No texture in this polygon.\n"
"Set a texture to be able to edit UV."
msgstr ""
+"ไม่มีเทà¸à¹€à¸ˆà¸­à¸£à¹Œà¹ƒà¸™à¸£à¸¹à¸›à¸«à¸¥à¸²à¸¢à¹€à¸«à¸¥à¸µà¹ˆà¸¢à¸¡à¸™à¸µà¹‰\n"
+"ตั้งเทà¸à¹€à¸ˆà¸­à¸£à¹Œà¹€à¸žà¸·à¹ˆà¸­à¸—ี่จะà¹à¸à¹‰à¹„ข UV ได้"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create UV Map"
@@ -6622,9 +6356,8 @@ msgid ""
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon & UV"
-msgstr "สร้างรูปหลายเหลี่ยม"
+msgstr "สร้าง Polygon à¹à¸¥à¸° UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6674,7 +6407,7 @@ msgstr "à¹à¸à¹‰à¹„ข UV รูปหลายเหลี่ยม 2D"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "UV"
-msgstr ""
+msgstr "UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6722,13 +6455,15 @@ msgstr "ปรับขนาดรูปหลายเหลี่ยม"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create a custom polygon. Enables custom polygon rendering."
-msgstr ""
+msgstr "สร้างรูปหลายเหลี่ยมà¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เอง เปิดà¸à¸²à¸£à¹€à¸£à¸™à¹€à¸”อร์รูปหลายเหลี่ยมà¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เอง"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"Remove a custom polygon. If none remain, custom polygon rendering is "
"disabled."
msgstr ""
+"ลบรูปหลายเหลี่ยมà¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เอง "
+"ถ้าไม่มีรูปหลายเหลี่ยมอยู่จะปิดà¸à¸²à¸£à¹€à¸£à¸™à¹€à¸”อร์รูปหลายเหลี่ยมà¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เอง"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Paint weights with specified intensity."
@@ -6740,7 +6475,7 @@ msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Radius:"
-msgstr ""
+msgstr "รัศมี:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon->UV"
@@ -6755,9 +6490,8 @@ msgid "Clear UV"
msgstr "ลบ UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Settings"
-msgstr "à¸à¸²à¸£à¸•ั้งค่า GridMap"
+msgstr "ตั้งค่าเส้นà¸à¸£à¸´à¸”"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Snap"
@@ -6769,36 +6503,31 @@ msgstr "จำà¸à¸±à¸”à¸à¸²à¸£à¹€à¸„ลื่อนย้าย"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid"
-msgstr "เส้นตาราง"
+msgstr "เส้นà¸à¸£à¸´à¸”"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Show Grid"
-msgstr "à¹à¸ªà¸”งเส้นตาราง"
+msgstr "à¹à¸ªà¸”งเส้นà¸à¸£à¸´à¸”"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Configure Grid:"
-msgstr "ตั้งค่าà¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”"
+msgstr "ตั้งค่าเส้นà¸à¸£à¸´à¸”:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Offset X:"
-msgstr "จุดà¸à¸³à¹€à¸™à¸´à¸”ตาราง:"
+msgstr "จุดเริ่มเส้นà¸à¸£à¸´à¸”à¹à¸à¸™ X:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Offset Y:"
-msgstr "จุดà¸à¸³à¹€à¸™à¸´à¸”ตาราง:"
+msgstr "จุดเริ่มเส้นà¸à¸£à¸´à¸”à¹à¸à¸™ Y:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Step X:"
-msgstr "ระยะห่างเส้น:"
+msgstr "ระยะห่างà¸à¸£à¸´à¸”à¹à¸à¸™ X:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Step Y:"
-msgstr "ระยะห่างเส้น:"
+msgstr "ระยะห่างà¸à¸£à¸´à¸”à¹à¸à¸™ Y:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6898,33 +6627,28 @@ msgid "Error Saving"
msgstr "ผิดพลาดขณะบันทึà¸"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error importing theme."
msgstr "ผิดพลาดขณะนำเข้าธีม"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Importing"
msgstr "ผิดพลาดขณะนำเข้า"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "New Text File..."
-msgstr "สร้างโฟลเดอร์..."
+msgstr "สร้างไฟล์ข้อความใหม่"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open File"
msgstr "เปิดไฟล์"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Save File As..."
-msgstr "บันทึà¸à¹€à¸›à¹‡à¸™..."
+msgstr "บันทึà¸à¹„ฟล์เป็น..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Can't obtain the script for running."
-msgstr ""
+msgstr "ไม่สามารถเรียà¸à¹ƒà¸Šà¹‰à¸ªà¸„ริปต์ได้"
#: editor/plugins/script_editor_plugin.cpp
msgid "Script failed reloading, check console for errors."
@@ -6956,9 +6680,8 @@ msgid "Save Theme As..."
msgstr "บันทึà¸à¸˜à¸µà¸¡à¹€à¸›à¹‡à¸™"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "%s Class Reference"
-msgstr " ตำราอ้างอิงคลาส"
+msgstr "%s อ้างอิงคลาส"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
@@ -7013,9 +6736,8 @@ msgid "File"
msgstr "ไฟล์"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open..."
-msgstr "เปิด"
+msgstr "เปิด..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Reopen Closed Script"
@@ -7047,9 +6769,8 @@ msgid "Theme"
msgstr "ธีม"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Import Theme..."
-msgstr "นำเข้าธีม"
+msgstr "นำเข้าธีม..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Reload Theme"
@@ -7069,7 +6790,7 @@ msgstr "ปิดคู่มือ"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
-msgstr "รัน"
+msgstr "เริ่ม"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
@@ -7090,25 +6811,15 @@ msgstr "ทำต่อไป"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ขจุดบà¸à¸žà¸£à¹ˆà¸­à¸‡à¸„้างไว้"
+msgstr "เปิดตัวดีบัà¸à¸„้างไว้"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Debug with External Editor"
-msgstr "à¹à¸à¹‰à¸ˆà¸¸à¸”บà¸à¸žà¸£à¹ˆà¸­à¸‡à¸”้วยโปรà¹à¸à¸£à¸¡à¸­à¸·à¹ˆà¸™"
+msgstr "ดีบัà¸à¸”้วยเอดิเตอร์อื่น"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open Godot online documentation."
-msgstr "เปิดคู่มือ"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
+msgstr "เปิดคู่มือออนไลน์"
#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
@@ -7146,22 +6857,19 @@ msgstr "บันทึà¸à¸­à¸µà¸à¸„รั้ง"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
-msgstr "ตัวà¹à¸à¹‰à¹„ขจุดบà¸à¸žà¸£à¹ˆà¸­à¸‡"
+msgstr "ตัวดีบัà¸"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Search Results"
-msgstr "ค้นหาในคู่มือ"
+msgstr "ผลà¸à¸²à¸£à¸„้นหา"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Clear Recent Scripts"
-msgstr "ล้างรายà¸à¸²à¸£à¸‰à¸²à¸à¸¥à¹ˆà¸²à¸ªà¸¸à¸”"
+msgstr "เคลียร์สคริปต์ล่าสุด"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Connections to method:"
-msgstr "เชื่อมไปยังโหนด:"
+msgstr "เชื่อมไปยังเมธอด:"
#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp
#, fuzzy
@@ -7169,9 +6877,8 @@ msgid "Source"
msgstr "ต้นฉบับ:"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Target"
-msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่อยู่:"
+msgstr "เป้าหมาย"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7186,7 +6893,7 @@ msgstr "บรรทัด:"
#: editor/plugins/script_text_editor.cpp
msgid "(ignore)"
-msgstr ""
+msgstr "(ละเว้น)"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7229,17 +6936,17 @@ msgstr "อัà¸à¸©à¸£à¹à¸£à¸à¸žà¸´à¸¡à¸žà¹Œà¹ƒà¸«à¸à¹ˆ"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Syntax Highlighter"
-msgstr ""
+msgstr "ไฮไลท์ไวยาà¸à¸£à¸“์"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "ไปยัง"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Bookmarks"
-msgstr ""
+msgstr "บุ๊คมาร์ค"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7576,6 +7283,11 @@ msgstr "ต้องเลือà¸à¹€à¸žà¸µà¸¢à¸‡à¹‚หนดเดียว"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "ขนาน"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Lock View Rotation"
msgstr "à¹à¸ªà¸”งข้อมูล"
@@ -7667,17 +7379,17 @@ msgid "Freelook Slow Modifier"
msgstr "ปรับความเร็วมุมมองอิสระ"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "à¹à¸ªà¸”งข้อมูล"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "à¹à¸ªà¸”งข้อมูล"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "เครื่องมือเคลื่อนย้าย"
@@ -7807,9 +7519,8 @@ msgstr "à¹à¸ªà¸”งเส้นตาราง"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Settings..."
-msgstr "ตัวเลือà¸"
+msgstr "ตั้งค่า..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7915,9 +7626,8 @@ msgid "LightOccluder2D Preview"
msgstr "สร้างรูปหลายเหลี่ยมà¸à¸±à¹‰à¸™à¹à¸ªà¸‡"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Sprite is empty!"
-msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸šà¸±à¸™à¸—ึà¸à¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²!"
+msgstr "สไปรต์ว่างเปล่า!"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Can't convert a sprite using animation frames to mesh."
@@ -7937,9 +7647,8 @@ msgid "Invalid geometry, can't create polygon."
msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to Polygon2D"
-msgstr "ย้ายรูปหลายเหลี่ยม"
+msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ Polygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create collision polygon."
@@ -7960,23 +7669,20 @@ msgid "Create LightOccluder2D Sibling"
msgstr "สร้างรูปหลายเหลี่ยมà¸à¸±à¹‰à¸™à¹à¸ªà¸‡"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Sprite"
-msgstr "SpriteFrames"
+msgstr "สไปรต์"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Simplification: "
-msgstr ""
+msgstr "ลดความซับซ้อน: "
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Shrink (Pixels): "
-msgstr "Snap (พิà¸à¹€à¸‹à¸¥):"
+msgstr "หด (พิà¸à¹€à¸‹à¸¥): "
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Grow (Pixels): "
-msgstr "Snap (พิà¸à¹€à¸‹à¸¥):"
+msgstr "ขยาย (พิà¸à¹€à¸‹à¸¥): "
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7984,28 +7690,24 @@ msgid "Update Preview"
msgstr "ตัวอย่าง Atlas"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Settings:"
-msgstr "ตัวเลือà¸"
+msgstr "ตั้งค่า:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "No Frames Selected"
-msgstr "ให้สิ่งที่เลือà¸à¹€à¸•็มจอ"
+msgstr "ไม่มีเฟรมที่เลือà¸"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Add %d Frame(s)"
-msgstr "เพิ่มเฟรม"
+msgstr "เพิ่ม %d เฟรม(วินาที)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
msgstr "เพิ่มเฟรม"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Unable to load images"
-msgstr "โหลดรูปไม่ได้:"
+msgstr "โหลดรูปไม่ได้"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
@@ -8032,19 +7734,16 @@ msgid "(empty)"
msgstr "(ว่างเปล่า)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Move Frame"
-msgstr "วางเฟรม"
+msgstr "เลื่อนเฟรม"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animations:"
-msgstr "à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "New Animation"
-msgstr "à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¸¡à¹ˆ"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Speed (FPS):"
@@ -8055,18 +7754,16 @@ msgid "Loop"
msgstr "วน"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animation Frames:"
-msgstr "เฟรมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "เฟรมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Add a Texture from File"
-msgstr "เพิ่มโหนดจาà¸à¸œà¸±à¸‡"
+msgstr "เพิ่มเทà¸à¹€à¸ˆà¸­à¸£à¹Œà¸ˆà¸²à¸à¹„ฟล์"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
-msgstr ""
+msgstr "เพิ่มเฟรมจาà¸à¸ªà¹„ปรต์ชีต"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
@@ -8085,32 +7782,28 @@ msgid "Move (After)"
msgstr "ย้าย (หลัง)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select Frames"
-msgstr "สà¹à¸•ค"
+msgstr "เลือà¸à¹€à¸Ÿà¸£à¸¡"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
-msgstr ""
+msgstr "à¹à¸™à¸§à¸™à¸­à¸™:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Vertical:"
-msgstr "มุมรูปทรง"
+msgstr "à¹à¸™à¸§à¸•ั้ง:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select/Clear All Frames"
-msgstr "เลือà¸à¸—ั้งหมด"
+msgstr "เลือà¸/เคลียร์เฟรมทั้งหมด"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Create Frames from Sprite Sheet"
-msgstr "สร้างจาà¸à¸‰à¸²à¸"
+msgstr "สร้างเฟรมจาà¸à¸ªà¹„ปรต์ชีต"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "SpriteFrames"
-msgstr "SpriteFrames"
+msgstr "สไปรต์เฟรม"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Region Rect"
@@ -8127,9 +7820,8 @@ msgstr "โหมดà¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”:"
#: editor/plugins/texture_region_editor_plugin.cpp
#: scene/resources/visual_shader.cpp
-#, fuzzy
msgid "None"
-msgstr "<ไม่มี>"
+msgstr "ไม่มี"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Pixel Snap"
@@ -8137,7 +7829,7 @@ msgstr "จำà¸à¸±à¸”ให้ย้ายเป็นพิà¸à¹€à¸‹à¸¥"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Grid Snap"
-msgstr "จำà¸à¸±à¸”ด้วยเส้นตาราง"
+msgstr "เข้าหาเส้นà¸à¸£à¸´à¸”"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Auto Slice"
@@ -8177,9 +7869,8 @@ msgid "Remove All"
msgstr "ลบทั้งหมด"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Edit Theme"
-msgstr "à¹à¸à¹‰à¹„ขธีม..."
+msgstr "à¹à¸à¹‰à¹„ขธีม"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme editing menu."
@@ -8211,9 +7902,8 @@ msgid "Toggle Button"
msgstr "ปุ่มเมาส์"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled Button"
-msgstr "เมาส์à¸à¸¥à¸²à¸‡"
+msgstr "ปิดà¸à¸²à¸£à¸—ำงานปุ่ม"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Item"
@@ -8248,17 +7938,15 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
-msgstr ""
+msgstr "เมนูย่อย"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Subitem 1"
-msgstr "ไอเทม"
+msgstr "ไอเทมย่อย 1"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Subitem 2"
-msgstr "ไอเทม"
+msgstr "ไอเทมย่อย 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
@@ -8286,18 +7974,16 @@ msgid "Tab 3"
msgstr "à¹à¸—็บ 3"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Editable Item"
-msgstr "à¹à¸à¹‰à¹„ขโหนดลูà¸à¹„ด้"
+msgstr "ไอเทมที่สามารถà¹à¸à¹‰à¹„ขได้"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
-msgstr ""
+msgstr "ผังย่อย"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Has,Many,Options"
-msgstr "มี,มาà¸à¸¡à¸²à¸¢,หลาย,ตัวเลือà¸!"
+msgstr "มี,หลาย,ตัวเลือà¸"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Data Type:"
@@ -8321,28 +8007,25 @@ msgid "Color"
msgstr "สี"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Theme File"
-msgstr "ธีม"
+msgstr "ไฟล์ธีม"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase Selection"
msgstr "ลบที่เลือà¸"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Fix Invalid Tiles"
-msgstr "ชื่อผิดพลาด"
+msgstr "à¹à¸à¹‰à¹„ขไทล์ที่ไม่ถูà¸à¸•้อง"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Cut Selection"
-msgstr "ให้สิ่งที่เลือà¸à¸­à¸¢à¸¹à¹ˆà¸à¸¥à¸²à¸‡à¸ˆà¸­"
+msgstr "ตัดที่เลือà¸"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint TileMap"
-msgstr "วาด TileMap"
+msgstr "วาดไทล์à¹à¸¡à¸ž"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Line Draw"
@@ -8354,16 +8037,15 @@ msgstr "วาดสี่เหลี่ยม"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Bucket Fill"
-msgstr "ถมเต็ม"
+msgstr "เทสี"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase TileMap"
-msgstr "ลบ TileMap"
+msgstr "ลบไทล์à¹à¸¡à¸ž"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Find Tile"
-msgstr "ค้นหา tile"
+msgstr "ค้นหาไทล์"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
@@ -8375,14 +8057,12 @@ msgid "Disable Autotile"
msgstr "Autotiles"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Enable Priority"
-msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸­à¸‡"
+msgstr "เปิดà¸à¸²à¸£à¸ˆà¸±à¸”ลำดับความสำคัà¸"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Filter tiles"
-msgstr "คัดà¸à¸£à¸­à¸‡à¹„ฟล์..."
+msgstr "ตัวà¸à¸£à¸­à¸‡à¹„ทล์"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Give a TileSet resource to this TileMap to use its tiles."
@@ -8390,35 +8070,35 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
-msgstr "วาด Tile"
+msgstr "วาดไทล์"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
"Shift+LMB: Line Draw\n"
"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
+"Shift+LMB: วาดเส้น\n"
+"Shift+Ctrl+LMB: วาดสี่เหลี่ยม"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
-msgstr "เลือภTile"
+msgstr "เลือà¸à¹„ทล์"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Left"
-msgstr "โหมดหมุน"
+msgstr "หมุนซ้าย"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Right"
-msgstr "ย้ายไปขวา"
+msgstr "หมุนขวา"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Horizontally"
-msgstr ""
+msgstr "พลิà¸à¹à¸™à¸§à¸™à¸­à¸™"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Vertically"
-msgstr ""
+msgstr "พลิà¸à¹à¸™à¸§à¸•ั้ง"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8426,14 +8106,12 @@ msgid "Clear Transform"
msgstr "เคลื่อนย้าย"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Add Texture(s) to TileSet."
-msgstr "เพิ่มโหนดจาà¸à¸œà¸±à¸‡"
+msgstr "เพิ่มเทà¸à¹€à¸ˆà¸­à¸£à¹Œà¹ƒà¸«à¹‰à¹„ทล์เซต"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected Texture from TileSet."
-msgstr "ลบรายà¸à¸²à¸£"
+msgstr "ลบเทà¸à¹€à¸ˆà¸­à¸£à¹Œà¸—ี่เลือà¸à¸ˆà¸²à¸à¹„ทล์เซต"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
@@ -8445,7 +8123,7 @@ msgstr "รวมจาà¸à¸‰à¸²à¸"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "New Single Tile"
-msgstr ""
+msgstr "ไทล์เดี่ยวใหม่"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8458,22 +8136,20 @@ msgid "New Atlas"
msgstr "%s ใหม่"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Next Coordinate"
-msgstr "ไปชั้นบน"
+msgstr "พิà¸à¸±à¸”ถัดไป"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the next shape, subtile, or Tile."
-msgstr ""
+msgstr "เลือà¸à¸£à¸¹à¸›à¸£à¹ˆà¸²à¸‡, ไทล์ย่อย หรือไทล์อันถัดไป"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Previous Coordinate"
-msgstr "ไปชั้นล่าง"
+msgstr "พิà¸à¸±à¸”à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the previous shape, subtile, or Tile."
-msgstr ""
+msgstr "เลือà¸à¸£à¸¹à¸›à¸£à¹ˆà¸²à¸‡, ไทล์ย่อยหรือไทล์à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8481,9 +8157,8 @@ msgid "Region"
msgstr "โหมดà¸à¸²à¸£à¸—ำงาน:"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision"
-msgstr "โหนดà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "ขอบเขตà¸à¸²à¸£à¸Šà¸™"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8501,9 +8176,8 @@ msgid "Bitmask"
msgstr "โหมดหมุน"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority"
-msgstr "วิธีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸:"
+msgstr "à¸à¸²à¸£à¸ˆà¸±à¸”ลำดับความสำคัà¸"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8516,9 +8190,8 @@ msgid "Region Mode"
msgstr "โหมดà¸à¸²à¸£à¸—ำงาน:"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision Mode"
-msgstr "โหนดà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "โหมดขอบเขตà¸à¸²à¸£à¸Šà¸™"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8536,14 +8209,12 @@ msgid "Bitmask Mode"
msgstr "โหมดหมุน"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority Mode"
-msgstr "วิธีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸:"
+msgstr "โหมดà¸à¸²à¸£à¸ˆà¸±à¸”ลำดับความสำคัà¸"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Icon Mode"
-msgstr "โหมดมุมมอง"
+msgstr "โหมดไอคอน"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8565,26 +8236,24 @@ msgid "Erase bitmask."
msgstr "คลิà¸à¸‚วา: ลบจุด"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new rectangle."
-msgstr "สร้าง %s ใหม่"
+msgstr "สร้างสี่เหลี่ยมใหม่"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new polygon."
-msgstr "สร้างรูปหลายเหลี่ยมจาà¸à¸„วามว่างเปล่า"
+msgstr "สร้างรูปหลายเหลี่ยมใหม่"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
-msgstr ""
+msgstr "ให้รูปหลายเหลี่ยมอยู่ในขอบเขตของสี่เหลี่ยม"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
-msgstr ""
+msgstr "โชว์เส้นà¸à¸£à¸´à¸” à¹à¸¥à¸° จุดตามà¸à¸£à¸´à¸” (ตั้งค่าใน Inspector)"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Display Tile Names (Hold Alt Key)"
-msgstr ""
+msgstr "à¹à¸ªà¸”งชื่อไทล์ (à¸à¸”Altค้างไว้)"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8609,13 +8278,12 @@ msgid "Merge from scene?"
msgstr "รวมจาà¸à¸‰à¸²à¸?"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Texture"
-msgstr "ลบà¹à¸¡à¹ˆà¹à¸šà¸š"
+msgstr "ลบเทà¸à¹€à¸ˆà¸­à¸£à¹Œ"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "%s file(s) were not added because was already on the list."
-msgstr ""
+msgstr "%s ไฟล์ไม่สามารถเพิ่มเข้าได้ เนื่องจาà¸à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸¥à¸´à¸ªà¸•์เรียบร้อยà¹à¸¥à¹‰à¸§"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8636,20 +8304,20 @@ msgid ""
msgstr "เลือà¸à¹„ทล์ย่อยที่à¸à¸³à¸¥à¸±à¸‡à¸›à¸£à¸±à¸šà¹à¸•่ง"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete polygon."
-msgstr "ลบจุด"
+msgstr "ลบรูปหลายเหลี่ยม"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"LMB: Set bit on.\n"
"RMB: Set bit off.\n"
"Shift+LMB: Set wildcard bit.\n"
"Click on another Tile to edit it."
msgstr ""
-"คลิà¸à¸‹à¹‰à¸²à¸¢: à¸à¸³à¸«à¸™à¸”ค่าบิต เปิด\n"
-"คลิà¸à¸‚วา: à¸à¸³à¸«à¸™à¸”ค่าบิต ปิด"
+"คลิà¸à¸‹à¹‰à¸²à¸¢: เปิด bit.\n"
+"คลิà¸à¸‚วา: ปิด bit.\n"
+"Shift+คลิà¸à¸‹à¹‰à¸²à¸¢: ตั้ง wildcard bit.\n"
+"คลิà¸à¹„ทล์อันอื่นเพื่อปรับà¹à¸•่ง"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8660,11 +8328,12 @@ msgid ""
msgstr "เลือà¸à¸£à¸¹à¸›à¸ à¸²à¸žà¸¢à¹ˆà¸­à¸¢à¹€à¸žà¸·à¹ˆà¸­à¸—ำเป็นไอคอน ภาพนี้จะใช้à¹à¸ªà¸”งเมื่อà¸à¸²à¸£"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select sub-tile to change its priority.\n"
"Click on another Tile to edit it."
-msgstr "เลือà¸à¹„ทล์ย่อยเพื่อจัดลำดับความสำคัà¸"
+msgstr ""
+"เลือà¸à¹„ทล์ย่อยเพื่อจัดลำดับความสำคัà¸\n"
+"คลิà¸à¹„ทล์อันอื่นเพื่อà¹à¸à¹‰à¹„ขไทล์นั้น"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8674,18 +8343,16 @@ msgid ""
msgstr "เลือà¸à¹„ทล์ย่อยเพื่อจัดลำดับความสำคัà¸"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Set Tile Region"
-msgstr "à¸à¸³à¸«à¸™à¸”ขอบเขต Texture"
+msgstr "ตั้งขอบเขตไทล์"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Tile"
-msgstr "สร้างโฟลเดอร์"
+msgstr "สร้างไทล์"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Icon"
-msgstr ""
+msgstr "ตั้งไอคอนไทล์"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8727,9 +8394,8 @@ msgid "Make Polygon Convex"
msgstr "ย้ายรูปหลายเหลี่ยม"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Tile"
-msgstr "ลบà¹à¸¡à¹ˆà¹à¸šà¸š"
+msgstr "ลบไทล์"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8747,13 +8413,12 @@ msgid "Remove Navigation Polygon"
msgstr "สร้างรูปทรงนำทาง"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Tile Priority"
-msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸­à¸‡"
+msgstr "à¹à¸à¹‰à¸¥à¸³à¸”ับความสำคัà¸à¸‚องไทล์"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Tile Z Index"
-msgstr ""
+msgstr "à¹à¸à¹‰à¹„ขดัชนี Z ของไทล์"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8761,14 +8426,12 @@ msgid "Make Convex"
msgstr "ย้ายรูปหลายเหลี่ยม"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Concave"
-msgstr "ย้ายรูปหลายเหลี่ยม"
+msgstr "ทำให้เว้า"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Collision Polygon"
-msgstr "สร้างรูปทรงนำทาง"
+msgstr "สร้างรูปหลายเหลี่ยมของเขตà¸à¸²à¸£à¸Šà¸™"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8776,18 +8439,16 @@ msgid "Create Occlusion Polygon"
msgstr "สร้างรูปหลายเหลี่ยมà¸à¸±à¹‰à¸™à¹à¸ªà¸‡"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "This property can't be changed."
-msgstr "ทำไม่ได้ถ้าไม่มีฉาà¸"
+msgstr "ไม่สามารถเปลี่ยนà¹à¸›à¸¥à¸‡à¸„ุณสมบัติได้"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "TileSet"
-msgstr "Tile Set"
+msgstr "ไทล์เซต"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No VCS addons are available."
-msgstr ""
+msgstr "ไม่พบส่วนเสริม VCS"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Error"
@@ -8816,9 +8477,8 @@ msgid "Version Control System"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Initialize"
-msgstr "อัà¸à¸©à¸£à¹à¸£à¸à¸žà¸´à¸¡à¸žà¹Œà¹ƒà¸«à¸à¹ˆ"
+msgstr "เริ่มต้น"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Staging area"
@@ -8830,7 +8490,6 @@ msgid "Detect new changes"
msgstr "สร้าง %s ใหม่"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Changes"
msgstr "เปลี่ยน"
@@ -8839,14 +8498,12 @@ msgid "Modified"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Renamed"
-msgstr "เปลี่ยนชื่อ"
+msgstr "เปลี่ยนชื่อà¹à¸¥à¹‰à¸§"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Deleted"
-msgstr "ลบ"
+msgstr "ลบà¹à¸¥à¹‰à¸§"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -8892,26 +8549,23 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
-msgstr ""
+msgstr "(GLES3 เท่านั้น)"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Output"
-msgstr "เพิ่มอินพุต"
+msgstr "เพิ่มเอาท์พุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar"
-msgstr "อัตราส่วน:"
+msgstr "สเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector"
-msgstr "คุณสมบัติ"
+msgstr "เวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
-msgstr ""
+msgstr "บูลีน"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8919,43 +8573,36 @@ msgid "Sampler"
msgstr "ไฟล์เสียง"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add input port"
-msgstr "เพิ่มอินพุต"
+msgstr "เพิ่มพอร์ตอินพุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add output port"
-msgstr ""
+msgstr "เพิ่มพอร์ตเอาต์พุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port type"
-msgstr "เปลี่ยนประเภท"
+msgstr "เปลี่ยนชนิดพอร์ตอินพุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port type"
-msgstr "เปลี่ยนประเภท"
+msgstr "เปลี่ยนชนิดพอร์ตเอาต์พุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port name"
-msgstr "เปลี่ยนชื่ออินพุต"
+msgstr "เปลี่ยนชื่อพอร์ตอินพุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port name"
-msgstr "เปลี่ยนชื่ออินพุต"
+msgstr "เปลี่ยนชื่อพอร์ตเอาต์พุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove input port"
-msgstr "ลบจุด"
+msgstr "ลบพอร์ตอินพุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove output port"
-msgstr "ลบจุด"
+msgstr "ลบพอร์ตเอาต์พุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8963,26 +8610,22 @@ msgid "Set expression"
msgstr "à¹à¸à¹‰à¹„ขสมà¸à¸²à¸£"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Resize VisualShader node"
-msgstr "Shader"
+msgstr "ปรับขนาดโหนดเวอร์ชวลเชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Set Uniform Name"
-msgstr ""
+msgstr "ตั้งชื่อยูนิฟอร์ม"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Set Input Default Port"
-msgstr "à¸à¸³à¸«à¸™à¸”เป็นค่าเริ่มต้นของ '%s'"
+msgstr "à¸à¸³à¸«à¸™à¸”พอร์ตอินพุตเริ่มต้น"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Node to Visual Shader"
-msgstr "Shader"
+msgstr "เพิ่มโหนดไปยังเวอร์ชวลเชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Duplicate Nodes"
msgstr "ทำซ้ำโหนด"
@@ -8992,13 +8635,12 @@ msgid "Paste Nodes"
msgstr "วางโหนด"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Nodes"
msgstr "ลบโหนด"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Visual Shader Input Type Changed"
-msgstr ""
+msgstr "เปลี่ยนชนิดของอินพุตเวอร์ชวลเชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9006,9 +8648,8 @@ msgid "Vertex"
msgstr "มุมรูปทรง"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Fragment"
-msgstr "ตัวà¹à¸›à¸£:"
+msgstr "à¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9021,44 +8662,40 @@ msgid "Show resulted shader code."
msgstr "สร้างโหนด"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Create Shader Node"
-msgstr "สร้างโหนด"
+msgstr "สร้างโหนดเชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color function."
-msgstr "ไปยังฟังà¸à¹Œà¸Šà¸±à¸™..."
+msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¸ªà¸µ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
-msgstr ""
+msgstr "à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸ªà¸µ"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Grayscale function."
-msgstr "สร้างฟังà¸à¹Œà¸Šà¸±à¸™"
+msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¸‚าว-ดำ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts HSV vector to RGB equivalent."
-msgstr ""
+msgstr "à¹à¸›à¸¥à¸‡à¹€à¸§à¸à¹€à¸•อร์ HSV เป็น RGB"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts RGB vector to HSV equivalent."
-msgstr ""
+msgstr "à¹à¸›à¸¥à¸‡à¹€à¸§à¸à¹€à¸•อร์ RGB เป็น HSV"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sepia function."
-msgstr "เปลี่ยนชื่อฟังà¸à¹Œà¸Šà¸±à¸™"
+msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¸‹à¸µà¹€à¸›à¸µà¸¢"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Burn operator."
-msgstr ""
+msgstr "ดำเนินà¸à¸²à¸£ Burn"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Darken operator."
-msgstr ""
+msgstr "ดำเนินà¸à¸²à¸£ Darken"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9067,7 +8704,7 @@ msgstr "เฉพาะที่à¹à¸•à¸à¸•่าง"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Dodge operator."
-msgstr ""
+msgstr "ดำเนินà¸à¸²à¸£ Dodge"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9076,19 +8713,19 @@ msgstr "à¹à¸à¹‰à¹„ขเครื่องหมายสเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
-msgstr ""
+msgstr "ดำเนินà¸à¸²à¸£ Lighten"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Overlay operator."
-msgstr ""
+msgstr "ดำเนินà¸à¸²à¸£ Overlay"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Screen operator."
-msgstr ""
+msgstr "ดำเนินà¸à¸²à¸£ Screen"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "SoftLight operator."
-msgstr ""
+msgstr "ดำเนินà¸à¸²à¸£ SoftLight"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9102,165 +8739,161 @@ msgstr "เคลื่อนย้าย"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the %s comparison between two parameters."
-msgstr ""
+msgstr "คืนค่าผลบูลีนจาà¸à¸à¸²à¸£à¹€à¸›à¸£à¸µà¸¢à¸šà¹€à¸—ียบระหว่างสองตัวà¹à¸›à¸£à¸‚อง %s"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Equal (==)"
-msgstr ""
+msgstr "เทียบเท่า (==)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than (>)"
-msgstr ""
+msgstr "มาà¸à¸à¸§à¹ˆà¸² (>)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than or Equal (>=)"
-msgstr ""
+msgstr "มาà¸à¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸­à¹€à¸—่าà¸à¸±à¸š (>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
-msgstr ""
+msgstr "คืนค่าเวà¸à¹€à¸•อร์ที่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้องถ้าสเà¸à¸¥à¸²à¸£à¹Œà¸—ี่ให้มีค่าเท่าà¸à¸±à¸š มาà¸à¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸­à¸™à¹‰à¸­à¸¢à¸à¸§à¹ˆà¸²"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the boolean result of the comparison between INF and a scalar "
"parameter."
-msgstr ""
+msgstr "คืนค่าบูลีนจาà¸à¸à¸²à¸£à¹€à¸›à¸£à¸µà¸¢à¸šà¹€à¸—ียบค่า INF à¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์ชนิดสเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the boolean result of the comparison between NaN and a scalar "
"parameter."
-msgstr ""
+msgstr "คืนค่าบูลีนซึ่งเปรียบเทียบค่าระหว่าง NaN à¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์สเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than (<)"
-msgstr ""
+msgstr "น้อยà¸à¸§à¹ˆà¸²(<)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than or Equal (<=)"
-msgstr ""
+msgstr "น้อยà¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸­à¹€à¸—่าà¸à¸±à¸š(<=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Not Equal (!=)"
-msgstr ""
+msgstr "ไม่เท่าà¸à¸±à¸š (!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided boolean value is true or false."
-msgstr ""
+msgstr "คืนค่าเวà¸à¹€à¸•อร์ที่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้องถ้าบูลีนที่ให้มีค่าเท่าà¸à¸±à¸š true หรือ false"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated scalar if the provided boolean value is true or false."
-msgstr ""
+msgstr "คืนค่าสเà¸à¸¥à¸²à¸£à¹Œà¸—ี่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้องถ้าต่าบูลีนที่ให้มีค่า true หรือ false"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the comparison between two parameters."
-msgstr ""
+msgstr "คืนค่าบูลีนจาà¸à¸à¸²à¸£à¹€à¸›à¸£à¸µà¸¢à¸šà¹€à¸—ียบพารามิเตอร์สองตัว"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the boolean result of the comparison between INF (or NaN) and a "
"scalar parameter."
-msgstr ""
+msgstr "คืนค่าบูลีนจาà¸à¸à¸²à¸£à¹€à¸›à¸£à¸µà¸¢à¸šà¹€à¸—ียบค่า INF (หรือ NaN) à¹à¸¥à¸°à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์สเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Boolean constant."
-msgstr "à¹à¸à¹‰à¹„ขค่าคงที่เวà¸à¹€à¸•อร์"
+msgstr "ค่าคงที่บูลีน"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
-msgstr ""
+msgstr "ยูนิฟอร์มบูลีน"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "'%s' พารามิเตอร์ของอินพุตสำหรับโหมดเชดเดอร์ทั้งหมด"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "จำà¸à¸±à¸”ด้วยโหนดà¹à¸¡à¹ˆ"
+msgstr "พารามิเตอร์อินพุต"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr ""
+msgstr "'%s' พารามิเตอร์อินพุตสำหรับโหมดเวอร์เท็à¸à¸‹à¹Œà¹€à¸Šà¸”เดอร์à¹à¸¥à¸°à¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์เชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr ""
+msgstr "'%s' พารามิเตอร์อินพุตสำหรับโหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์เชดเดอร์à¹à¸¥à¸°à¹‚หมดไลท์เชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "'%s' พารามิเตอร์อินพุตสำหรับโหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์เชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "'%s' พารามิเตอร์อินพุตสำหรับโหมดไลท์เชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "'%s' พารามิเตอร์อินพุตสำหรับโหมดเวอร์เท็à¸à¸‹à¹Œà¹€à¸Šà¸”เดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr ""
+msgstr "'%s' พารามิเตอร์อินพุตสำหรับโหมดเวอร์เท็à¸à¸‹à¹Œà¹€à¸Šà¸”เดอร์à¹à¸¥à¸°à¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์เชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "à¹à¸à¹‰à¹„ขฟังà¸à¹Œà¸Šà¸±à¸™à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ"
+msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar operator."
-msgstr "à¹à¸à¹‰à¹„ขเครื่องหมายสเà¸à¸¥à¸²à¸£à¹Œ"
+msgstr "ตัวดำเนินà¸à¸²à¸£à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
-msgstr ""
+msgstr "ค่าคงที่ E (2.718282) à¹à¸ªà¸”งในรูปลอà¸à¸²à¸¥à¸´à¸—ึมà¸à¸²à¸™à¸˜à¸£à¸£à¸¡à¸Šà¸²à¸•ิ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Epsilon constant (0.00001). Smallest possible scalar number."
-msgstr ""
+msgstr "ค่าคงที่เอพซิลอน (0.00001) ค่าที่เล็à¸à¸—ี่สุดของสเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Phi constant (1.618034). Golden ratio."
-msgstr ""
+msgstr "ค่าฟาย (1.618034) สัดส่วนทองคำ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/4 constant (0.785398) or 45 degrees."
-msgstr ""
+msgstr "ค่าพายส่วน 4 (0.785398) หรือ 45องศา"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/2 constant (1.570796) or 90 degrees."
-msgstr ""
+msgstr "ค่าพายส่วน2 (1.570796) หรือ 90 องศา"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi constant (3.141593) or 180 degrees."
-msgstr ""
+msgstr "ค่าพาย (3.141593) หรือ 180 องศา"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Tau constant (6.283185) or 360 degrees."
-msgstr ""
+msgstr "ค่าเทา (6.283185) หรือ 360 องศา"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Sqrt2 constant (1.414214). Square root of 2."
-msgstr ""
+msgstr "ค่ารูท2 (1.414214)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
-msgstr ""
+msgstr "คืนค่าสัมบูรณ์ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
-msgstr ""
+msgstr "คืนค่า arc-cosine ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic cosine of the parameter."
-msgstr ""
+msgstr "คืนค่า arc cosh ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
@@ -9276,121 +8909,121 @@ msgstr "คืนค่า arc tan ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameters."
-msgstr ""
+msgstr "คืนค่า arc tan ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic tangent of the parameter."
-msgstr ""
+msgstr "คืนค่า tanh ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
-msgstr ""
+msgstr "หาจำนวนเต็มใà¸à¸¥à¹‰à¸—ี่สุดที่มาà¸à¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸­à¹€à¸—่าà¸à¸±à¸šà¸„่าพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Constrains a value to lie between two further values."
-msgstr ""
+msgstr "จำà¸à¸±à¸”ค่าไว้ระหว่างอีà¸à¸ªà¸­à¸‡à¸„่า"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the cosine of the parameter."
-msgstr ""
+msgstr "คืนค่า cos ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic cosine of the parameter."
-msgstr ""
+msgstr "คืนค่า cosh ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
-msgstr ""
+msgstr "à¹à¸›à¸¥à¸‡à¹€à¸£à¹€à¸”ียนเป็นองศา"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
-msgstr ""
+msgstr "เลขยà¸à¸à¸³à¸¥à¸±à¸‡à¸à¸²à¸™ e"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 Exponential."
-msgstr ""
+msgstr "เลขยà¸à¸à¸³à¸¥à¸±à¸‡à¸à¸²à¸™ 2"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer less than or equal to the parameter."
-msgstr ""
+msgstr "หาค่าจำนวนเต็มที่ใà¸à¸¥à¹‰à¸—ี่สุดที่น้อยà¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸­à¹€à¸—่าà¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Computes the fractional part of the argument."
-msgstr ""
+msgstr "คำนวณสัดส่วนจาà¸à¸­à¸²à¸à¸´à¸§à¹€à¸¡à¸™à¸•์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse of the square root of the parameter."
-msgstr ""
+msgstr "คืนค่ารูทสองของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Natural logarithm."
-msgstr ""
+msgstr "ลอà¸à¸²à¸¥à¸´à¸—ึมà¸à¸²à¸™à¸˜à¸£à¸£à¸¡à¸Šà¸²à¸•ิ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 logarithm."
-msgstr ""
+msgstr "ลอà¸à¸²à¸¥à¸´à¸—ึมà¸à¸²à¸™ 2"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the greater of two values."
-msgstr ""
+msgstr "คืนค่ามาà¸à¸ªà¸¸à¸” จาà¸à¸ªà¸­à¸‡à¸„่า"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the lesser of two values."
-msgstr ""
+msgstr "คืนค่าน้อยสุด จาà¸à¸ªà¸­à¸‡à¸„่า"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two scalars."
-msgstr ""
+msgstr "ค่าประมาณเชิงเส้นระหว่างสเà¸à¸¥à¸²à¸£à¹Œà¸ªà¸­à¸‡à¸„่า"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the opposite value of the parameter."
-msgstr ""
+msgstr "คืนค่าตรงà¸à¸±à¸™à¸‚้ามจาà¸à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - scalar"
-msgstr ""
+msgstr "1.0 - สเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the value of the first parameter raised to the power of the second."
-msgstr ""
+msgstr "คืนค่าพารามิเตอร์ตัวà¹à¸£à¸à¸¢à¸à¸à¸³à¸¥à¸±à¸‡à¸”้วยพารามิเตอร์ตัวที่สอง"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in degrees to radians."
-msgstr ""
+msgstr "à¹à¸›à¸¥à¸‡à¸„่าองศาเป็นเรเดียน"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / scalar"
-msgstr ""
+msgstr "1.0 / สเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer to the parameter."
-msgstr ""
+msgstr "หาจำนวนเต็มที่ใà¸à¸¥à¹‰à¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์มาà¸à¸—ี่สุด"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest even integer to the parameter."
-msgstr ""
+msgstr "หาเลขคู่ที่ใà¸à¸¥à¹‰à¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์มาà¸à¸—ี่สุด"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
-msgstr ""
+msgstr "จำà¸à¸±à¸”ค่าให้อยู๋ระหว่าง 0.0 à¸à¸±à¸š 1.0"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Extracts the sign of the parameter."
-msgstr ""
+msgstr "หาเครื่องหมายของพาราพิเตอร์ (บวà¸/ลบ)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the sine of the parameter."
-msgstr ""
+msgstr "คืนค่า sine ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic sine of the parameter."
-msgstr ""
+msgstr "คืนค่า sinh ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
-msgstr ""
+msgstr "คืนค่ารูทสองของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9400,6 +9033,10 @@ msgid ""
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( สเà¸à¸¥à¸²à¸£à¹Œ(edge0), สเà¸à¸¥à¸²à¸£à¹Œ(edge1), สเà¸à¸¥à¸²à¸£à¹Œ(x) )\n"
+"\n"
+"คืนค่า 0.0 ถ้า x น้อยà¸à¸§à¹ˆà¸² 'edge0' à¹à¸¥à¸° 1.0 ถ้ามาà¸à¸à¸§à¹ˆà¸² 'edge1' หรือคืนค่าระหว่าง 0.0 - "
+"1.0 โดยใช้ Hermite polynomials"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9407,56 +9044,57 @@ msgid ""
"\n"
"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( สเà¸à¸¥à¸²à¸£à¹Œ(edge), สเà¸à¸¥à¸²à¸£à¹Œ(x) )\n"
+"\n"
+"คืนค่า 0.0 ถ้า x น้อยà¸à¸§à¹ˆà¸² edge ถ้าไม่ใช่จะคืนค่า 1.0"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
-msgstr ""
+msgstr "คืนค่า tan ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic tangent of the parameter."
-msgstr ""
+msgstr "คืนค่า tanh ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the truncated value of the parameter."
-msgstr ""
+msgstr "หาค่าตัดหลัà¸à¸—ศนิยม(truncated value) ของพารามิเตอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
-msgstr ""
+msgstr "บวà¸à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œà¸”้วยสเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides scalar by scalar."
-msgstr ""
+msgstr "หารสเà¸à¸¥à¸²à¸£à¹Œà¸”้วยสเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies scalar by scalar."
-msgstr ""
+msgstr "คูณสเà¸à¸¥à¸²à¸£à¹Œà¸”้วยสเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two scalars."
-msgstr ""
+msgstr "คืนค่าเศษผลหารของสเà¸à¸¥à¸²à¸£à¹Œà¸ªà¸­à¸‡à¸­à¸±à¸™"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts scalar from scalar."
-msgstr ""
+msgstr "ลบสเà¸à¸¥à¸²à¸£à¹Œà¸”้วยสเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar constant."
-msgstr "à¹à¸à¹‰à¹„ขค่าคงที่สเà¸à¸¥à¸²à¸£à¹Œ"
+msgstr "ค่าคงที่สเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "à¹à¸à¹‰à¹„ขสเà¸à¸¥à¸²à¸£à¹Œ Uniform"
+msgstr "ยูนิฟอร์มสเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
-msgstr ""
+msgstr "ทำà¸à¸²à¸£à¸„้นหาเทà¸à¹€à¸ˆà¸­à¸£à¹Œà¸¥à¸¹à¸à¸šà¸²à¸¨à¸à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the texture lookup."
-msgstr ""
+msgstr "ทำà¸à¸²à¸£à¸„้นหาเทà¸à¹€à¸ˆà¸­à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9499,23 +9137,23 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the determinant of a transform."
-msgstr ""
+msgstr "คำนวณดีเทอร์มิà¹à¸™à¸™à¸•์ของทรานฟอร์ม"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the inverse of a transform."
-msgstr ""
+msgstr "คำนวณอินเวอร์สของทรานฟอร์ม"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the transpose of a transform."
-msgstr ""
+msgstr "คำนวณทรานสโพสของทรานฟอร์ม"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
-msgstr ""
+msgstr "คูณทรานฟอร์มด้วยทรานฟอร์ม"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by transform."
-msgstr ""
+msgstr "คูณเวà¸à¹€à¸•อร์ด้วยทรานฟอร์ม"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9528,34 +9166,32 @@ msgid "Transform uniform."
msgstr "ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¹€à¸„ลื่อนย้าย"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "ไปยังฟังà¸à¹Œà¸Šà¸±à¸™..."
+msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¹€à¸§à¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector operator."
-msgstr "à¹à¸à¹‰à¹„ขเครื่องหมายเวà¸à¹€à¸•อร์"
+msgstr "ตัวดำเนินà¸à¸²à¸£à¹€à¸§à¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes vector from three scalars."
-msgstr ""
+msgstr "สร้างเวà¸à¹€à¸•อร์จาà¸à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œà¸ªà¸²à¸¡à¸•ัว"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes vector to three scalars."
-msgstr ""
+msgstr "สร้างสเà¸à¸¥à¸²à¸£à¹Œà¸ªà¸²à¸¡à¸•ัวจาà¸à¹€à¸§à¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the cross product of two vectors."
-msgstr ""
+msgstr "หาผลคูณเชิงเวà¸à¹€à¸•อร์(cross product) ของเวà¸à¹€à¸•อร์สองตัว"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the distance between two points."
-msgstr ""
+msgstr "คืนค่าระยะห่างระหว่างสองจุด"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the dot product of two vectors."
-msgstr ""
+msgstr "คำนวณผลคูณเชิงสเà¸à¸¥à¸¥à¸²à¸£à¹Œ (dot) ของเวà¸à¹€à¸•อร์สองตัว"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9567,27 +9203,27 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
-msgstr ""
+msgstr "หาขนาดเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors."
-msgstr ""
+msgstr "à¸à¸²à¸£à¸›à¸£à¸°à¸¡à¸²à¸“ค่าเชิงเส้นระหว่างสองเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors using scalar."
-msgstr ""
+msgstr "à¸à¸²à¸£à¸›à¸£à¸°à¸¡à¸²à¸“ค่าเชิงเส้นระหว่างสองเวà¸à¹€à¸•อร์โดยใช้สเà¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
-msgstr ""
+msgstr "คำนวณหาเวà¸à¹€à¸•อร์หน่วยของเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - vector"
-msgstr ""
+msgstr "1.0 - เวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / vector"
-msgstr ""
+msgstr "1.0 / เวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9597,7 +9233,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the vector that points in the direction of refraction."
-msgstr ""
+msgstr "คืนค่าเวà¸à¹€à¸•อร์ที่มีทิศทางที่เà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸«à¸±à¸à¹€à¸«"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9607,6 +9243,10 @@ msgid ""
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( เวà¸à¹€à¸•อร์(edge0), เวà¸à¹€à¸•อร์(edge1), เวà¸à¹€à¸•อร์(x) ).\n"
+"\n"
+"คืนค่า 0.0 ถ้า 'x' น้อยà¸à¸§à¹ˆà¸² 'edge0' à¹à¸¥à¸° 1.0 ถ้า 'x' มาà¸à¸à¸§à¹ˆà¸² 'edge1' "
+"นอà¸à¸™à¸±à¹‰à¸™à¸ˆà¸°à¸„ืนค่าระหว่าง 0.0 à¸à¸±à¸š 1.0 โดยใช้สูตรพหุนามเฮอไมท์ (Hermite polynomials)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9616,6 +9256,10 @@ msgid ""
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( สเà¸à¸¥à¸²à¸£à¹Œ(edge0), สเà¸à¸¥à¸²à¸£à¹Œ(edge1), เวà¸à¹€à¸•อร์(x) )\n"
+"\n"
+"คืนค่า 0.0 ถ้า 'x' น้อยà¸à¸§à¹ˆà¸² 'edge0' à¹à¸¥à¸° 1.0 ถ้า 'x' มาà¸à¸à¸§à¹ˆà¸² 'edge1' "
+"นอà¸à¸™à¸±à¹‰à¸™à¸ˆà¸°à¸„ืนค่าระหว่าง 0.0 à¸à¸±à¸š 1.0 โดยใช้สูตรพหุนามเฮอไมท์ (Hermite polynomials)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9623,6 +9267,9 @@ msgid ""
"\n"
"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( เวà¸à¹€à¸•อร์(edge), เวà¸à¹€à¸•อร์(x) ).\n"
+"\n"
+"คืนค่า 0.0 ถ้า x น้อยà¸à¸§à¹ˆà¸² edge ถ้าไม่ใช่ คืนค่า 1.0"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9630,36 +9277,37 @@ msgid ""
"\n"
"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( สเà¸à¸¥à¸²à¸£à¹Œ(edge), เวà¸à¹€à¸•อร์(x) ).\n"
+"\n"
+"คืนค่า 0.0 ถ้า 'x' น้อยà¸à¸§à¹ˆà¸² 'edge' ถ้าไม่ใช่จะคืนค่า 1.0"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds vector to vector."
-msgstr ""
+msgstr "บวà¸à¹€à¸§à¸à¹€à¸•อร์ด้วยเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides vector by vector."
-msgstr ""
+msgstr "หารเวà¸à¹€à¸•อร์ด้วยเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by vector."
-msgstr ""
+msgstr "คูณเวà¸à¹€à¸•อร์ด้วยเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two vectors."
-msgstr ""
+msgstr "คืนค่าเศษหารของเวà¸à¹€à¸•อร์สองเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts vector from vector."
-msgstr ""
+msgstr "ลบเวà¸à¹€à¸•อร์ด้วยเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector constant."
-msgstr "à¹à¸à¹‰à¹„ขค่าคงที่เวà¸à¹€à¸•อร์"
+msgstr "ค่าคงที่เวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector uniform."
-msgstr "à¹à¸à¹‰à¹„ขเวà¸à¹€à¸•อร์ Uniform"
+msgstr "ยูนิฟอร์มเวà¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9684,11 +9332,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(Fragment/Light mode only) Scalar derivative function."
-msgstr ""
+msgstr "(โหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์/à¹à¸ªà¸‡ เท่านั้น) ฟังà¸à¹Œà¸Šà¸±à¸™à¸­à¸™à¸¸à¸žà¸±à¸™à¸˜à¹Œà¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(Fragment/Light mode only) Vector derivative function."
-msgstr ""
+msgstr "(โหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์/à¹à¸ªà¸‡ เท่านั้น) ฟังà¸à¹Œà¸Šà¸±à¸™à¸­à¸™à¸¸à¸žà¸±à¸™à¸˜à¹Œà¹€à¸§à¸à¹€à¸•อร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9718,41 +9366,37 @@ msgstr ""
msgid ""
"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
"'y'."
-msgstr ""
+msgstr "(โหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์/à¹à¸ªà¸‡ เท่านั้น) (เวà¸à¹€à¸•อร์) ผลรวมของอนุพันธ์สัมบูรณ์ใน 'x' à¹à¸¥à¸° 'y'"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
"'y'."
-msgstr ""
+msgstr "(โหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์/à¹à¸ªà¸‡ เท่านั้น) (สเà¸à¸¥à¸²à¸£à¹Œ) ผลรวมของอนุพันธ์สัมบูรณ์ใน 'x' à¹à¸¥à¸° 'y'"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "VisualShader"
-msgstr "Shader"
+msgstr "เวอร์ชวลเชดเดอร์"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Edit Visual Property"
-msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸­à¸‡"
+msgstr "à¹à¸à¹‰à¹„ขคุณสมบัติเวอร์ชวล"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Visual Shader Mode Changed"
-msgstr "จำนวนครั้งที่เปลี่ยน Shader"
+msgstr "เปลี่ยนโหมดเวอร์ชวลเชดเดอร์à¹à¸¥à¹‰à¸§"
#: editor/project_export.cpp
msgid "Runnable"
-msgstr "รันได้"
+msgstr "สามารถรันได้"
#: editor/project_export.cpp
-#, fuzzy
msgid "Add initial export..."
-msgstr "เพิ่มอินพุต"
+msgstr "เพิ่มà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸à¹€à¸£à¸´à¹ˆà¸¡à¸•้น..."
#: editor/project_export.cpp
msgid "Add previous patches..."
-msgstr ""
+msgstr "เพิ่มà¹à¸žà¸—ช์à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²..."
#: editor/project_export.cpp
msgid "Delete patch '%s' from list?"
@@ -9776,19 +9420,16 @@ msgid ""
msgstr ""
#: editor/project_export.cpp
-#, fuzzy
msgid "Release"
-msgstr "เพิ่งปล่อย"
+msgstr "เผยà¹à¸žà¸£à¹ˆ"
#: editor/project_export.cpp
-#, fuzzy
msgid "Exporting All"
-msgstr "ส่งออà¸à¸ªà¸³à¸«à¸£à¸±à¸š %s"
+msgstr "ส่งออà¸à¸—ั้งหมด"
#: editor/project_export.cpp
-#, fuzzy
msgid "The given export path doesn't exist:"
-msgstr "ไม่พบไฟล์"
+msgstr "ไม่พบที่อยู่ส่งออà¸:"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing/corrupted:"
@@ -9809,17 +9450,16 @@ msgid ""
msgstr ""
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Path"
-msgstr "ส่งออà¸à¹‚ปรเจà¸à¸•์"
+msgstr "ไดเรà¸à¸—อรีส่งออà¸"
#: editor/project_export.cpp
msgid "Resources"
-msgstr "รีซอร์ส"
+msgstr "ทรัพยาà¸à¸£"
#: editor/project_export.cpp
msgid "Export all resources in the project"
-msgstr "ส่งออà¸à¸—ุà¸à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ªà¹ƒà¸™à¹‚ปรเจà¸à¸•์"
+msgstr "ส่งออà¸à¸—รัพยาà¸à¸£à¸—ั้งหมดในโปรเจà¸à¸•์"
#: editor/project_export.cpp
msgid "Export selected scenes (and dependencies)"
@@ -9877,9 +9517,8 @@ msgid "Feature List:"
msgstr "รายชื่อฟีเจอร์:"
#: editor/project_export.cpp
-#, fuzzy
msgid "Script"
-msgstr "สคริปต์ใหม่"
+msgstr "สคริปต์"
#: editor/project_export.cpp
msgid "Script Export Mode:"
@@ -9899,7 +9538,7 @@ msgstr "เข้ารหัส (ใส่คีย์ด้านล่าง)
#: editor/project_export.cpp
msgid "Invalid Encryption Key (must be 64 characters long)"
-msgstr ""
+msgstr "คีย์เข้ารหัสไม่ถูà¸à¸•้อง (ต้องมี 64 อัà¸à¸©à¸£)"
#: editor/project_export.cpp
msgid "Script Encryption Key (256-bits as hex):"
@@ -9914,23 +9553,20 @@ msgid "Export Project"
msgstr "ส่งออà¸à¹‚ปรเจà¸à¸•์"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export mode?"
-msgstr "วิธีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸:"
+msgstr "ส่งออà¸à¹‚หมด?"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export All"
-msgstr "ส่งออà¸"
+msgstr "ส่งออà¸à¸—ั้งหมด"
#: editor/project_export.cpp editor/project_manager.cpp
-#, fuzzy
msgid "ZIP File"
-msgstr " ไฟล์"
+msgstr "ไฟล์ ZIP"
#: editor/project_export.cpp
msgid "Godot Game Pack"
-msgstr ""
+msgstr "Godot เà¸à¸¡à¹à¸žà¹‡à¸„"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing:"
@@ -9945,50 +9581,45 @@ msgid "Export With Debug"
msgstr "ส่งออà¸à¸žà¸£à¹‰à¸­à¸¡à¸à¸²à¸£à¹à¸à¹‰à¹„ขจุดบà¸à¸žà¸£à¹ˆà¸­à¸‡"
#: editor/project_manager.cpp
-#, fuzzy
msgid "The path specified doesn't exist."
-msgstr "ไม่พบไฟล์"
+msgstr "ไม่พบที่อยู่ที่ระบุเอาไว้"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file (it's not in ZIP format)."
-msgstr "ผิดพลาดขณะเปิดไฟล์à¹à¸žà¸„เà¸à¸ˆ, ไม่ใช่รูปà¹à¸šà¸š zip"
+msgstr "ผิดพลาดขณะเปิดไฟล์à¹à¸žà¸„เà¸à¸ˆ (ไม่ใช่ไฟล์นามสà¸à¸¸à¸¥ zip)"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."
-msgstr "à¸à¸£à¸¸à¸“าเลือà¸à¹‚ฟลเดอร์ที่ไม่มีไฟล์ 'project.godot'"
+msgstr "ไฟล์โปรเจà¸à¸•์ \".zip\" ผิดพลาด เนื่องจาà¸à¹„ม่มีไฟล์ \"project.godot\""
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
msgstr "à¸à¸£à¸¸à¸“าเลือà¸à¹‚ฟลเดอร์ว่างเปล่า"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Please choose a \"project.godot\" or \".zip\" file."
-msgstr "à¸à¸£à¸¸à¸“าเลือà¸à¹„ฟล์ 'project.godot'"
+msgstr "à¸à¸£à¸¸à¸“าเลือà¸à¹„ฟล์ \"project.godot\" หรือไฟล์ \".zip\""
#: editor/project_manager.cpp
msgid "This directory already contains a Godot project."
-msgstr ""
+msgstr "ไดเรà¸à¸—อรีนี้มีโปรเจà¸à¸•์ Godot อยู่à¹à¸¥à¹‰à¸§"
#: editor/project_manager.cpp
msgid "New Game Project"
-msgstr "โปรเจà¸à¸•์ใหม่"
+msgstr "โปรเจà¸à¸•์เà¸à¸¡à¹ƒà¸«à¸¡à¹ˆ"
#: editor/project_manager.cpp
msgid "Imported Project"
msgstr "นำเข้าโปรเจà¸à¸•์à¹à¸¥à¹‰à¸§"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid Project Name."
-msgstr "ชื่อโปรเจà¸à¸•์:"
+msgstr "ชื่อโปรเจà¸à¸•์ไม่ถูà¸à¸•้อง"
#: editor/project_manager.cpp
msgid "Couldn't create folder."
-msgstr "ไม่สามารถสร้างโฟลเดอร์"
+msgstr "ไม่สามารถสร้างโฟลเดอร์ได้"
#: editor/project_manager.cpp
msgid "There is already a folder in this path with the specified name."
@@ -10054,17 +9685,16 @@ msgid "Project Path:"
msgstr "ที่อยู่โปรเจà¸à¸•์:"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Project Installation Path:"
-msgstr "ที่อยู่โปรเจà¸à¸•์:"
+msgstr "ที่อยู่ที่ใช้ติดตั้งโปรเจà¸à¸•์:"
#: editor/project_manager.cpp
msgid "Renderer:"
-msgstr ""
+msgstr "ตัวเรนเดอร์:"
#: editor/project_manager.cpp
msgid "OpenGL ES 3.0"
-msgstr ""
+msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid ""
@@ -10073,10 +9703,14 @@ msgid ""
"Incompatible with older hardware\n"
"Not recommended for web games"
msgstr ""
+"à¸à¸²à¸£à¹à¸ªà¸”งผลที่ดีà¸à¸§à¹ˆà¸²\n"
+"คุณสมบัติที่มาà¸à¸à¸§à¹ˆà¸²\n"
+"ไม่รองรับฮาร์ดà¹à¸§à¸£à¹Œà¸£à¸¸à¹ˆà¸™à¹€à¸à¹ˆà¸²\n"
+"ไม่เหมาะสำหรับเà¸à¸¡à¸ªà¹Œà¸šà¸™à¹€à¸§à¹‡à¸š"
#: editor/project_manager.cpp
msgid "OpenGL ES 2.0"
-msgstr ""
+msgstr "OpenGL ES 2.0"
#: editor/project_manager.cpp
msgid ""
@@ -10085,28 +9719,30 @@ msgid ""
"Works on most hardware\n"
"Recommended for web games"
msgstr ""
+"คุณภาพà¸à¸²à¸£à¹à¸ªà¸”งผลน้อยà¸à¸§à¹ˆà¸²\n"
+"ระบบที่น้อยà¸à¸§à¹ˆà¸²\n"
+"ทำงานได้บนฮาร์ดà¹à¸§à¸£à¹Œà¸ªà¹ˆà¸§à¸™à¹ƒà¸«à¸à¹ˆ\n"
+"เหมาะสำหรับสร้างเà¸à¸¡à¸ªà¹Œà¸šà¸™à¹€à¸§à¹‡à¸š"
#: editor/project_manager.cpp
msgid "Renderer can be changed later, but scenes may need to be adjusted."
-msgstr ""
+msgstr "ตัวเรนเดอร์สามารถเปลี่ยนทีหลังได้ à¹à¸•่ฉาà¸à¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้องปรับà¹à¸•่ง"
#: editor/project_manager.cpp
msgid "Unnamed Project"
msgstr "โปรเจà¸à¸•์ไม่มีชื่อ"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Missing Project"
-msgstr "นำเข้าโปรเจà¸à¸•์ที่มีอยู่เดิม"
+msgstr "โปรเจà¸à¸•์หายไป"
#: editor/project_manager.cpp
msgid "Error: Project is missing on the filesystem."
-msgstr ""
+msgstr "Error:โปรเจà¸à¸•์หายไปจาà¸à¸£à¸°à¸šà¸šà¹„ฟล์"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Can't open project at '%s'."
-msgstr "ไม่สามารถเปิดโปรเจà¸à¸•์"
+msgstr "ไม่สามารถเปิดโปรเจà¸à¸•์ที่ '%s'"
#: editor/project_manager.cpp
msgid "Are you sure to open more than one project?"
@@ -10142,6 +9778,7 @@ msgid ""
"The project settings were created by a newer engine version, whose settings "
"are not compatible with this version."
msgstr ""
+"à¸à¸²à¸£à¸•ั้งค่าโปรเจà¸à¸•์ถูà¸à¸ªà¸£à¹‰à¸²à¸‡à¹‚ดยโดยเอนจิ้นรุ่นใหม่à¸à¸§à¹ˆà¸² ซึ่งà¸à¸²à¸£à¸•ั้งค่านี้ไม่สามารถเข้าà¸à¸±à¸™à¹„ด้à¸à¸±à¸šà¹€à¸­à¸™à¸ˆà¸´à¹‰à¸™à¸£à¸¸à¹ˆà¸™à¸™à¸µà¹‰"
#: editor/project_manager.cpp
#, fuzzy
@@ -10162,9 +9799,8 @@ msgstr ""
"à¸à¸£à¸¸à¸“าเปิดà¹à¸à¹‰à¹„ขโปรเจà¸à¸•์เพื่อนำเข้าไฟล์"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Are you sure to run %d projects at once?"
-msgstr "ยืนยันà¸à¸²à¸£à¸£à¸±à¸™à¹‚ปรเจà¸à¸•์มาà¸à¸à¸§à¹ˆà¸² 1 โปรเจà¸à¸•์?"
+msgstr "ยืนยันà¸à¸²à¸£à¸£à¸±à¸™à¹‚ปรเจà¸à¸•์ %d โปรเจà¸à¸•์ทีเดียว?"
#: editor/project_manager.cpp
#, fuzzy
@@ -10181,40 +9817,40 @@ msgid ""
msgstr "ลบโปรเจà¸à¸•์ออà¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­? (โฟลเดอร์จะไม่ถูà¸à¸¥à¸š)"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove all missing projects from the list?\n"
"The project folders' contents won't be modified."
-msgstr "ลบโปรเจà¸à¸•์ออà¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­? (โฟลเดอร์จะไม่ถูà¸à¸¥à¸š)"
+msgstr ""
+"ลบโปรเจà¸à¸•์ที่หายไปออà¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­à¸«à¸£à¸·à¸­à¹„ม่?\n"
+"เนื้อหาโฟลเดอร์โปรเจà¸à¸•์จะไม่ถูà¸à¹à¸à¹‰à¹„ข"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Language changed.\n"
"The interface will update after restarting the editor or project manager."
msgstr ""
"เปลี่ยนภาษาà¹à¸¥à¹‰à¸§\n"
-"à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ˆà¸°à¸¡à¸µà¸œà¸¥à¹€à¸¡à¸·à¹ˆà¸­à¹€à¸›à¸´à¸”โปรà¹à¸à¸£à¸¡à¹à¸à¹‰à¹„ขหรือตัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์ใหม่"
+"à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ˆà¸°à¸¡à¸µà¸œà¸¥à¹€à¸¡à¸·à¹ˆà¸­à¹€à¸›à¸´à¸”เอดิเตอร์หรือตัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์ใหม่"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Are you sure to scan %s folders for existing Godot projects?\n"
"This could take a while."
-msgstr "จะทำà¸à¸²à¸£à¸ªà¹à¸à¸™à¸«à¸²à¹‚ปรเจà¸à¸•์ใน %s โฟลเดอร์ ยืนยัน?"
+msgstr ""
+"ทำà¸à¸²à¸£à¸ªà¹à¸à¸™à¸«à¸²à¹‚ปรเจà¸à¸•์ ในโฟลเดอร์ %s หรือไม่?\n"
+"อาจจะใช้เวลาสัà¸à¸„รู่"
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "ตัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Projects"
msgstr "โปรเจà¸à¸•์"
#: editor/project_manager.cpp
msgid "Last Modified"
-msgstr ""
+msgstr "à¹à¸à¹‰à¹„ขล่าสุด"
#: editor/project_manager.cpp
msgid "Scan"
@@ -10229,9 +9865,8 @@ msgid "New Project"
msgstr "โปรเจà¸à¸•์ใหม่"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "ลบจุด"
+msgstr "ลบที่หายไป"
#: editor/project_manager.cpp
msgid "Templates"
@@ -10295,9 +9930,8 @@ msgid "Add Input Action Event"
msgstr "เพิ่มปุ่มà¸à¸”ของà¸à¸²à¸£à¸à¸£à¸°à¸—ำ"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "All Devices"
-msgstr "อุปà¸à¸£à¸“์"
+msgstr "อุปà¸à¸£à¸“์ทั้งหมด"
#: editor/project_settings_editor.cpp
msgid "Device"
@@ -10342,14 +9976,12 @@ msgid "Wheel Right Button"
msgstr "เมาส์ขวา"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 1"
-msgstr "ปุ่ม 6"
+msgstr "X ปุ่ม 1"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 2"
-msgstr "ปุ่ม 6"
+msgstr "X ปุ่ม 2"
#: editor/project_settings_editor.cpp
msgid "Joypad Axis Index:"
@@ -10435,7 +10067,7 @@ msgstr "ผิดพลาดขณะบันทึà¸à¸„่า"
#: editor/project_settings_editor.cpp
msgid "Settings saved OK."
-msgstr "บันทึà¸à¹à¸¥à¹‰à¸§"
+msgstr "บันทึà¸à¸à¸²à¸£à¸•ั้งค่าà¹à¸¥à¹‰à¸§"
#: editor/project_settings_editor.cpp
#, fuzzy
@@ -10496,7 +10128,7 @@ msgstr "à¸à¸³à¸«à¸™à¸”เฉพาะ..."
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "The editor must be restarted for changes to take effect."
-msgstr ""
+msgstr "ต้องเปิดเอดิเตอร์ใหม่เพื่อให้à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸¡à¸µà¸œà¸¥"
#: editor/project_settings_editor.cpp
msgid "Input Map"
@@ -10507,9 +10139,8 @@ msgid "Action:"
msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ:"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Action"
-msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ:"
+msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ"
#: editor/project_settings_editor.cpp
msgid "Deadzone"
@@ -10541,7 +10172,7 @@ msgstr "à¸à¸²à¸£à¹à¸—นที่"
#: editor/project_settings_editor.cpp
msgid "Resources:"
-msgstr "รีซอร์ส:"
+msgstr "ทรัพยาà¸à¸£:"
#: editor/project_settings_editor.cpp
msgid "Remaps by Locale:"
@@ -10556,7 +10187,6 @@ msgid "Locales Filter"
msgstr "ตัวà¸à¸£à¸­à¸‡à¸ à¸¹à¸¡à¸´à¸ à¸²à¸„"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
msgstr "à¹à¸ªà¸”งทุà¸à¸ à¸¹à¸¡à¸´à¸ à¸²à¸„"
@@ -10603,7 +10233,7 @@ msgstr "ไฟล์..."
#: editor/property_editor.cpp
msgid "Dir..."
-msgstr "โฟลเดอร์..."
+msgstr "ไดเรà¸à¸—อรี..."
#: editor/property_editor.cpp
msgid "Assign"
@@ -10644,11 +10274,11 @@ msgstr "เปลี่ยนชื่อ"
#: editor/rename_dialog.cpp
msgid "Prefix"
-msgstr ""
+msgstr "คำนำหน้า"
#: editor/rename_dialog.cpp
msgid "Suffix"
-msgstr ""
+msgstr "คำต่อท้าย"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10656,37 +10286,32 @@ msgid "Use Regular Expressions"
msgstr "à¹à¸à¹‰à¹„ขสมà¸à¸²à¸£"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
-msgstr "ตัวเลือà¸à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”"
+msgstr "ตัวเลือà¸à¸‚ั้นสูง"
#: editor/rename_dialog.cpp
msgid "Substitute"
-msgstr ""
+msgstr "à¸à¸²à¸£à¹à¸—นที่"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node name"
-msgstr "ชื่อโหนด:"
+msgstr "ชื่อโหนด"
#: editor/rename_dialog.cpp
msgid "Node's parent name, if available"
-msgstr ""
+msgstr "ชื่อโหนดà¹à¸¡à¹ˆ (ถ้ามี)"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node type"
-msgstr "หาประเภทของโหนด"
+msgstr "ชนิดโหนด"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Current scene name"
-msgstr "ฉาà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™"
+msgstr "ชื่อฉาà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Root node name"
-msgstr "ชื่อโหนดราà¸:"
+msgstr "ชื่อโหนดà¹à¸¡à¹ˆ"
#: editor/rename_dialog.cpp
msgid ""
@@ -10696,7 +10321,7 @@ msgstr ""
#: editor/rename_dialog.cpp
msgid "Per-level Counter"
-msgstr ""
+msgstr "ตัวนับต่อเลเวล"
#: editor/rename_dialog.cpp
msgid "If set the counter restarts for each group of child nodes"
@@ -10704,12 +10329,11 @@ msgstr ""
#: editor/rename_dialog.cpp
msgid "Initial value for the counter"
-msgstr ""
+msgstr "ค่าเริ่มต้นในà¸à¸²à¸£à¸™à¸±à¸š"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Step"
-msgstr "ขนาด:"
+msgstr "ขั้น"
#: editor/rename_dialog.cpp
msgid "Amount by which counter is incremented for each node"
@@ -10747,14 +10371,12 @@ msgid "Case"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "To Lowercase"
-msgstr "ตัวพิมพ์เล็à¸"
+msgstr "ไปตัวพิมพ์เล็à¸"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "To Uppercase"
-msgstr "ตัวพิมพ์ใหà¸à¹ˆ"
+msgstr "ไปตัวพิมพ์ใหà¸à¹ˆ"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10767,9 +10389,8 @@ msgid "Regular Expression Error"
msgstr "à¹à¸à¹‰à¹„ขสมà¸à¸²à¸£"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "At character %s"
-msgstr "ตัวอัà¸à¸©à¸£à¸—ี่ใช้ได้:"
+msgstr "ตัวอัà¸à¸©à¸£à¸—ี่ใช้ได้ %s"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent Node"
@@ -10826,9 +10447,8 @@ msgid "Instance Scene(s)"
msgstr "อินสà¹à¸•นซ์ฉาà¸"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Replace with Branch Scene"
-msgstr "บันทึà¸à¸à¸´à¹ˆà¸‡à¹€à¸›à¹‡à¸™à¸‰à¸²à¸"
+msgstr "à¹à¸—นที่ด้วยฉาà¸à¸¢à¹ˆà¸­à¸¢"
#: editor/scene_tree_dock.cpp
msgid "Instance Child Scene"
@@ -10867,32 +10487,28 @@ msgid "Instantiated scenes can't become root"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make node as Root"
-msgstr "เข้าใจ!"
+msgstr "ทำโหนดให้เป็นโหนดà¹à¸¡à¹ˆ"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes?"
-msgstr "ลบโหนด"
+msgstr "ลบโหนด %d ?"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete the root node \"%s\"?"
-msgstr "ลบโหนด"
+msgstr "ลบโหนดà¹à¸¡à¹ˆ \"%s\"?"
#: editor/scene_tree_dock.cpp
msgid "Delete node \"%s\" and its children?"
-msgstr ""
+msgstr "ลบโหนด \"%s\" à¹à¸¥à¸°à¹‚หนดลูà¸?"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete node \"%s\"?"
-msgstr "ลบโหนด"
+msgstr "ลบโหนด \"%s\"?"
#: editor/scene_tree_dock.cpp
msgid "Can not perform with the root node."
-msgstr "ทำà¸à¸±à¸šà¹‚หนดราà¸à¹„ม่ได้"
+msgstr "ไม่สามารถà¸à¸£à¸°à¸—ำà¸à¸±à¸šà¹‚หนดà¹à¸¡à¹ˆà¹„ด้"
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on instanced scenes."
@@ -10920,34 +10536,28 @@ msgid "Make Local"
msgstr "ระยะใà¸à¸¥à¹‰"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "New Scene Root"
-msgstr "เข้าใจ!"
+msgstr "ฉาà¸à¹à¸¡à¹ˆà¹ƒà¸«à¸¡à¹ˆ"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Create Root Node:"
-msgstr "สร้างโหนด"
+msgstr "สร้างโหนดà¹à¸¡à¹ˆ:"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "2D Scene"
-msgstr "ฉาà¸"
+msgstr "ฉาภ2D"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "3D Scene"
-msgstr "ฉาà¸"
+msgstr "ฉาภ3D"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "User Interface"
-msgstr "ลบà¸à¸²à¸£à¸ªà¸·à¸šà¸—อด"
+msgstr "อินเตอร์เฟส"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Other Node"
-msgstr "ลบโหนด"
+msgstr "โหนดอื่นๆ"
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes from a foreign scene!"
@@ -10959,16 +10569,15 @@ msgstr "ทำà¸à¸±à¸šà¹‚หนดที่ฉาà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™à¸ª
#: editor/scene_tree_dock.cpp
msgid "Attach Script"
-msgstr "เชื่อมสคริปต์"
+msgstr "à¹à¸™à¸šà¸ªà¸„ริปต์"
#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "ลบโหนด"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Change type of node(s)"
-msgstr "เปลี่ยนชื่ออินพุต"
+msgstr "เปลี่ยนชนิดของโหนด"
#: editor/scene_tree_dock.cpp
msgid ""
@@ -11001,7 +10610,6 @@ msgid "Load As Placeholder"
msgstr "โหลดเป็นตัวà¹à¸—น"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Open Documentation"
msgstr "เปิดคู่มือ"
@@ -11010,23 +10618,20 @@ msgid "Add Child Node"
msgstr "เพิ่มโหนดลูà¸"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "ยุบโฟลเดอร์"
+msgstr "ขยาย/ยุบทั้งหมด"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
-msgstr "เปลี่ยนประเภท"
+msgstr "เปลี่ยนชนิด"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Reparent to New Node"
msgstr "หาโหนดà¹à¸¡à¹ˆà¹ƒà¸«à¸¡à¹ˆ"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make Scene Root"
-msgstr "เข้าใจ!"
+msgstr "ตั้งเป็นฉาà¸à¹à¸¡à¹ˆ"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
@@ -11045,7 +10650,6 @@ msgid "Delete (No Confirm)"
msgstr "ลบ (ไม่ยืนยัน)"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
msgstr "เพิ่ม/สร้างโหนดใหม่"
@@ -11057,7 +10661,7 @@ msgstr "อินสà¹à¸•นซ์ฉาà¸à¹€à¸›à¹‡à¸™à¹‚หนด สร้à¸
#: editor/scene_tree_dock.cpp
msgid "Attach a new or existing script for the selected node."
-msgstr "เชื่อมสคริปต์ใหม่หรือที่มีอยู่เดิมให้à¸à¸±à¸šà¹‚หนดที่เลือà¸"
+msgstr "สร้างสคริปต์ให้โหนดที่เลือà¸"
#: editor/scene_tree_dock.cpp
msgid "Clear a script for the selected node."
@@ -11081,9 +10685,8 @@ msgid "Toggle Visible"
msgstr "ซ่อน/à¹à¸ªà¸”ง"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Unlock Node"
-msgstr "เลือà¸à¹‚หนด"
+msgstr "ปลดล็อคโหนด"
#: editor/scene_tree_editor.cpp
#, fuzzy
@@ -11091,9 +10694,8 @@ msgid "Button Group"
msgstr "ปุ่ม 7"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "(Connecting From)"
-msgstr "เชื่อมต่อผิดพลาด"
+msgstr "(เชื่อมต่อจาà¸)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
@@ -11127,12 +10729,10 @@ msgstr ""
"คลิà¸à¹€à¸žà¸·à¹ˆà¸­à¹à¸ªà¸”งà¹à¸œà¸‡à¸à¸¥à¸¸à¹ˆà¸¡"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "เปิดสคริปต์"
+msgstr "เปิดสคริปต์:"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid ""
"Node is locked.\n"
"Click to unlock it."
@@ -11158,6 +10758,8 @@ msgid ""
"AnimationPlayer is pinned.\n"
"Click to unpin."
msgstr ""
+"ปัà¸à¸«à¸¡à¸¸à¸” AnimationPlayer à¹à¸¥à¹‰à¸§\n"
+"คลิà¸à¹€à¸žà¸·à¹ˆà¸­à¹€à¸¥à¸´à¸à¸›à¸±à¸à¸«à¸¡à¸¸à¸”"
#: editor/scene_tree_editor.cpp
msgid "Invalid node name, the following characters are not allowed:"
@@ -11180,14 +10782,12 @@ msgid "Select a Node"
msgstr "เลือà¸à¹‚หนด"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is empty."
-msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่อยู่ว่างเปล่า"
+msgstr "ที่อยู่ว่างเปล่า"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Filename is empty."
-msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸šà¸±à¸™à¸—ึà¸à¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²!"
+msgstr "ชื่อไฟล์ว่างเปล่า"
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11200,9 +10800,8 @@ msgid "Invalid base path."
msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¹€à¸£à¸´à¹ˆà¸¡à¸•้นไม่ถูà¸à¸•้อง"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "มีโฟลเดอร์ชื่อนี้อยู่à¹à¸¥à¹‰à¸§"
+msgstr "มีไดเรà¸à¸—อรีชื่อนี้อยู่à¹à¸¥à¹‰à¸§"
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11227,21 +10826,18 @@ msgid "Error loading script from %s"
msgstr "ผิดพลาดขณะโหลดสคริปต์จาภ%s"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Overrides"
-msgstr "à¸à¸³à¸«à¸™à¸”เฉพาะ..."
+msgstr "à¹à¸—นที่"
#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "ไม่มี"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script / Choose Location"
-msgstr "เปิดตัวà¹à¸à¹‰à¹„ขสคริปต์"
+msgstr "เปิดสคริปต์ / เลือà¸à¸—ี่อยู่"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script"
msgstr "เปิดสคริปต์"
@@ -11251,19 +10847,16 @@ msgid "File exists, it will be reused."
msgstr "มีไฟล์นี้อยู่à¹à¸¥à¹‰à¸§ จะนำมาใช้"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid class name."
msgstr "ชื่อคลาสไม่ถูà¸à¸•้อง"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid inherited parent name or path."
msgstr "ชื่อหรือตำà¹à¸«à¸™à¹ˆà¸‡à¸—ีสืบทอดไม่ถูà¸à¸•้อง"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script path/name is valid."
-msgstr "สคริปต์ถูà¸à¸•้อง"
+msgstr "ที่อยู่/ชื่อของสคริปต์ถูà¸à¸•้อง"
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11276,29 +10869,30 @@ msgid "Built-in script (into scene file)."
msgstr "à¸à¸±à¸‡à¸ªà¸„ริปต์ในไฟล์ฉาà¸"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will create a new script file."
-msgstr "สร้างสคริปต์ใหม่"
+msgstr "จะทำà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸„ริปต์ใหม่"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will load an existing script file."
-msgstr "โหลดสคริปต์จาà¸à¸”ิสà¸à¹Œ"
+msgstr "จะทำà¸à¸²à¸£à¹‚หลดไฟล์สคริปต์ที่มีอยู่"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script file already exists."
-msgstr "มีà¸à¸²à¸£à¸à¸£à¸°à¸—ำ '%s' อยู่à¹à¸¥à¹‰à¸§!"
+msgstr "ไฟล์สคริปต์มีอยู่à¹à¸¥à¹‰à¸§"
+
+#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Class Name:"
-msgstr "ชื่อคลาส"
+msgstr "ชื่อคลาส:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Template:"
-msgstr "à¹à¸¡à¹ˆà¹à¸šà¸š"
+msgstr "à¹à¸¡à¹ˆà¹à¸šà¸š:"
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11318,38 +10912,32 @@ msgid "Bytes:"
msgstr "ไบต์:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Warning:"
-msgstr "คำเตือน"
+msgstr "คำเตือน:"
#: editor/script_editor_debugger.cpp
msgid "Error:"
msgstr "ผิดพลาด:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error"
-msgstr "คัดลอà¸à¸œà¸´à¸”พลาด"
+msgstr "C++ ผิดพลาด"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error:"
-msgstr "ผิดพลาด:"
+msgstr "C++ ผิดพลาด:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Source"
-msgstr "ต้นฉบับ:"
+msgstr "C++ ต้นฉบับ"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Source:"
msgstr "ต้นฉบับ:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Source:"
-msgstr "ต้นฉบับ:"
+msgstr "C++ ต้นฉบับ:"
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -11375,9 +10963,8 @@ msgid "Video RAM"
msgstr "หน่วยความจำวีดีโอ"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Skip Breakpoints"
-msgstr "ลบจุด"
+msgstr "ข้ามเบรà¸à¸žà¸­à¸¢à¸•์"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
@@ -11393,7 +10980,7 @@ msgstr "สà¹à¸•ค"
#: editor/script_editor_debugger.cpp
msgid "Profiler"
-msgstr "ประสิทธิภาพ"
+msgstr "ตัวตรวจวิเคราะห์ประสิทธิภาพ (Profiler)"
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -11430,7 +11017,7 @@ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ª"
#: editor/script_editor_debugger.cpp
msgid "Type"
-msgstr "ประเภท"
+msgstr "ชนิด"
#: editor/script_editor_debugger.cpp
msgid "Format"
@@ -11438,7 +11025,7 @@ msgstr "รูปà¹à¸šà¸š"
#: editor/script_editor_debugger.cpp
msgid "Usage"
-msgstr "ใช้"
+msgstr "à¸à¸²à¸£à¹ƒà¸Šà¹‰"
#: editor/script_editor_debugger.cpp
msgid "Misc"
@@ -11462,26 +11049,23 @@ msgstr "à¸à¸³à¸«à¸™à¸”จาà¸à¸œà¸±à¸‡"
#: editor/script_editor_debugger.cpp
msgid "Export measures as CSV"
-msgstr ""
+msgstr "ส่งออà¸à¸„่าเป็น CSV"
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Erase Shortcut"
-msgstr "ออà¸à¸™à¸¸à¹ˆà¸¡à¸™à¸§à¸¥"
+msgstr "ลบทางลัด"
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Restore Shortcut"
-msgstr "ทางลัด"
+msgstr "คืนค่าทางลัด"
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Change Shortcut"
-msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸•รึง"
+msgstr "à¹à¸à¹‰à¹„ขทางลัด"
#: editor/settings_config_dialog.cpp
msgid "Editor Settings"
-msgstr "ตัวเลือà¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡"
+msgstr "ตั้งค่าเอดิเตอร์"
#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
@@ -11501,11 +11085,11 @@ msgstr "à¹à¸à¹‰à¹„ของศาà¸à¸²à¸£à¹€à¸›à¸¥à¹ˆà¸‡à¹€à¸ªà¸µà¸¢à¸‡à¸‚อ
#: editor/spatial_editor_gizmos.cpp
msgid "Change Camera FOV"
-msgstr "ปรับขอบเขตà¸à¸²à¸£à¸¡à¸­à¸‡à¹€à¸«à¹‡à¸™à¸‚องà¸à¸¥à¹‰à¸­à¸‡"
+msgstr "ปรับà¸à¸¥à¹‰à¸­à¸‡ FOV"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Camera Size"
-msgstr "ปรับขนาดà¸à¸¥à¹‰à¸­à¸‡"
+msgstr "เปลี่ยนขนาดà¸à¸¥à¹‰à¸­à¸‡"
#: editor/spatial_editor_gizmos.cpp
#, fuzzy
@@ -11537,7 +11121,6 @@ msgid "Change Capsule Shape Height"
msgstr "ปรับความสูงทรงà¹à¸„ปซูล"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Shape Radius"
msgstr "ปรับรัศมีทรงà¹à¸„ปซูล"
@@ -11551,14 +11134,12 @@ msgid "Change Ray Shape Length"
msgstr "ปรับความยาวรังสี"
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Radius"
-msgstr "ปรับรัศมีà¹à¸ªà¸‡"
+msgstr "ปรับรัศมีทรงà¸à¸£à¸°à¸šà¸­à¸"
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Height"
-msgstr "ปรับความสูงทรงà¹à¸„ปซูล"
+msgstr "ปรับความสูงทรงà¸à¸£à¸°à¸šà¸­à¸"
#: modules/csg/csg_gizmos.cpp
#, fuzzy
@@ -11608,12 +11189,11 @@ msgstr "GDNativeLibrary"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Enabled GDNative Singleton"
-msgstr ""
+msgstr "เปิดà¸à¸²à¸£à¸—ำงานซิงเà¸à¸´à¸¥à¸•ัน GDNative"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Disabled GDNative Singleton"
-msgstr "ปิดà¸à¸²à¸£à¸­à¸±à¸žà¹€à¸”ทตัวหมุน"
+msgstr "ปิดà¸à¸²à¸£à¸—ำงานซิงเà¸à¸´à¸¥à¸•ัน GDNative"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
@@ -11628,9 +11208,8 @@ msgid "GDNative"
msgstr "GDNative"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Step argument is zero!"
-msgstr "ตัวà¹à¸›à¸£ step เป็นศูนย์!"
+msgstr "ช่วงอาà¸à¸´à¸§à¹€à¸¡à¸™à¸•์เป็นศูนย์!"
#: modules/gdscript/gdscript_functions.cpp
msgid "Not a script with an instance"
@@ -11658,7 +11237,7 @@ msgstr "รูปà¹à¸šà¸šà¸”ิà¸à¸Šà¸±à¸™à¸™à¸²à¸£à¸µà¸—ี่เà¸à¹‡à¸šà¸­
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary (invalid subclasses)"
-msgstr "ดิà¸à¸Šà¸±à¸™à¸™à¸²à¸£à¸µà¸—ี่เà¸à¹‡à¸šà¸­à¸´à¸™à¸ªà¹à¸•นซ์ผิดพลาด (คลาสย่อยผิดพลาด)"
+msgstr "ดิà¸à¸Šà¸±à¸™à¸™à¸²à¸£à¸µà¸­à¸´à¸™à¸ªà¹à¸•นซ์ผิดพลาด (คลาสย่อยผิดพลาด)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Object can't provide a length."
@@ -11767,18 +11346,16 @@ msgid "Cursor Clear Rotation"
msgstr "เคอร์เซอร์ลบà¸à¸²à¸£à¸«à¸¡à¸¸à¸™"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Paste Selects"
-msgstr "ลบที่เลือà¸"
+msgstr "วางที่เลือà¸"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Clear Selection"
msgstr "ลบที่เลือà¸"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Fill Selection"
-msgstr "เลือà¸à¸—ั้งหมด"
+msgstr "เติมส่วนที่เลือà¸"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Settings"
@@ -11819,7 +11396,7 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ˆà¸±à¸”à¸à¸²à¸£à¹‚ครงร่าง..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Calculating grid size..."
-msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„ำนวณขนาดตาราง..."
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„ำนวณขนาดà¸à¸£à¸´à¸”..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Creating heightfield..."
@@ -11917,42 +11494,36 @@ msgid "Set Variable Type"
msgstr "à¹à¸à¹‰à¹„ขประเภทตัวà¹à¸›à¸£"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Input Port"
-msgstr "เพิ่มอินพุต"
+msgstr "เพิ่มพอร์ตอินพุต"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Output Port"
-msgstr "เพิ่มอินพุต"
+msgstr "เพิ่มพอร์ตเอาท์พุต"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Override an existing built-in function."
-msgstr "ชื่อผิดพลาด ต้องไม่ใช้ชื่อเดียวà¸à¸±à¸šà¸Šà¸™à¸´à¸”ตัวà¹à¸›à¸£"
+msgstr "เขียนทับฟังà¸à¹Œà¸Šà¸±à¸™à¸šà¸´à¸§à¸—์อินที่มีอยู่"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new function."
-msgstr "สร้าง %s ใหม่"
+msgstr "สร้างฟังà¸à¹Œà¸Šà¸±à¸™à¹ƒà¸«à¸¡à¹ˆ"
#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "ตัวà¹à¸›à¸£:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new variable."
-msgstr "สร้าง %s ใหม่"
+msgstr "สร้างตัวà¹à¸›à¸£à¹ƒà¸«à¸¡à¹ˆ"
#: modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
msgstr "สัà¸à¸à¸²à¸“:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new signal."
-msgstr "สร้างรูปหลายเหลี่ยมจาà¸à¸„วามว่างเปล่า"
+msgstr "สร้างสัà¸à¸à¸²à¸“ใหม่"
#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
@@ -11979,9 +11550,8 @@ msgid "Add Function"
msgstr "เพิ่มฟังà¸à¹Œà¸Šà¸±à¸™"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Delete input port"
-msgstr "ลบจุด"
+msgstr "ลบพอร์ตอินพุต"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Variable"
@@ -11992,14 +11562,12 @@ msgid "Add Signal"
msgstr "เพิ่มสัà¸à¸à¸²à¸“"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Input Port"
-msgstr "ลบจุด"
+msgstr "ลบพอร์ตอินพุต"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Output Port"
-msgstr "ลบจุด"
+msgstr "ลบพอร์ตเอาต์พุต"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Expression"
@@ -12007,11 +11575,11 @@ msgstr "à¹à¸à¹‰à¹„ขสมà¸à¸²à¸£"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Nodes"
-msgstr "ลบโหนด"
+msgstr "ลบโหนด VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Duplicate VisualScript Nodes"
-msgstr "ทำซ้ำโหนด"
+msgstr "ทำซ้ำโหนด VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
@@ -12069,26 +11637,23 @@ msgstr "ย้ายโหนด"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Node"
-msgstr "ลบโหนด"
+msgstr "ลบโหนด VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Connect Nodes"
msgstr "เชื่อมโหนด"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Disconnect Nodes"
msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อโหนด"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Node Data"
-msgstr "เชื่อมโหนด"
+msgstr "เชื่อมต่อข้อมูลโหนด"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Node Sequence"
-msgstr "เชื่อมโหนด"
+msgstr "เชื่อมต่อà¸à¸±à¸šà¸¥à¸³à¸”ับของโหนด"
#: modules/visual_script/visual_script_editor.cpp
msgid "Script already has function '%s'"
@@ -12099,9 +11664,8 @@ msgid "Change Input Value"
msgstr "à¹à¸à¹‰à¹„ขค่าอินพุต"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Resize Comment"
-msgstr "à¹à¸à¹‰à¹„ข CanvasItem"
+msgstr "à¹à¸à¹‰à¸‚นาดคอมเม้นต์"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't copy the function node."
@@ -12113,12 +11677,11 @@ msgstr "คลิปบอร์ดว่างเปล่า!"
#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
-msgstr "วางโหนด"
+msgstr "วางโหนด VisualScript"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Can't create function with a function node."
-msgstr "คัดลอà¸à¹‚หนดฟังà¸à¹Œà¸Šà¸±à¸™à¹„ม่ได้"
+msgstr "ไม่สามารถสร้างฟังà¸à¹Œà¸Šà¸±à¸™à¹„ด้จาà¸à¹‚หนดฟังà¸à¹Œà¸Šà¸±à¸™"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't create function of nodes from nodes of multiple functions."
@@ -12133,9 +11696,8 @@ msgid "Try to only have one sequence input in selection."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create Function"
-msgstr "เปลี่ยนชื่อฟังà¸à¹Œà¸Šà¸±à¸™"
+msgstr "สร้างฟังà¸à¹Œà¸Šà¸±à¸™"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Function"
@@ -12158,33 +11720,28 @@ msgid "Editing Signal:"
msgstr "à¹à¸à¹‰à¹„ขสัà¸à¸à¸²à¸“:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Tool:"
-msgstr "ระยะใà¸à¸¥à¹‰"
+msgstr "เครื่องมือสร้าง:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Members:"
-msgstr "ตัวà¹à¸›à¸£:"
+msgstr "สมาชิà¸:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Base Type:"
-msgstr "เปลี่ยนประเภท"
+msgstr "เปลี่ยนประเภทà¸à¸²à¸™:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Nodes..."
-msgstr "เพิ่มโหนด"
+msgstr "เพิ่มโหนด..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Function..."
-msgstr "เพิ่มฟังà¸à¹Œà¸Šà¸±à¸™"
+msgstr "เพิ่มฟังà¸à¹Œà¸Šà¸±à¸™..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "function_name"
-msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™:"
+msgstr "ชื่อฟังà¸à¹Œà¸Šà¸±à¹ˆà¸™"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -12208,19 +11765,16 @@ msgid "Cut Nodes"
msgstr "ตัดโหนด"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Function"
-msgstr "เปลี่ยนชื่อฟังà¸à¹Œà¸Šà¸±à¸™"
+msgstr "สร้างฟังà¸à¹Œà¸Šà¸±à¸™"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Refresh Graph"
-msgstr "รีเฟรช"
+msgstr "รีเฟรชà¸à¸£à¸²à¸Ÿ"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
-msgstr "ตัวà¹à¸›à¸£"
+msgstr "à¹à¸à¹‰à¹„ขสมาชิà¸"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
@@ -12277,41 +11831,40 @@ msgid ""
msgstr "ค่าคืนจาภ_step() ผิดพลาด ต้องเป็นจำนวนเต็ม (ลำดับ) หรือสตริง (ข้อผิดพลาด)"
#: modules/visual_script/visual_script_property_selector.cpp
-#, fuzzy
msgid "Search VisualScript"
-msgstr "ลบโหนด"
+msgstr "ค้นหาโหนด VisualScript"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Get %s"
-msgstr ""
+msgstr "รับ %s"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
-msgstr ""
+msgstr "ตั้ง %s"
#: platform/android/export/export.cpp
msgid "Package name is missing."
-msgstr ""
+msgstr "ชื่อà¹à¸žà¹‡à¸„เà¸à¸ˆà¸«à¸²à¸¢à¹„ป"
#: platform/android/export/export.cpp
msgid "Package segments must be of non-zero length."
-msgstr ""
+msgstr "ส่วนของà¹à¸žà¹‡à¸„เà¸à¸ˆà¸ˆà¸°à¸•้องมีความยาวไม่เป็นศูนย์"
#: platform/android/export/export.cpp
msgid "The character '%s' is not allowed in Android application package names."
-msgstr ""
+msgstr "ตัวอัà¸à¸©à¸£ '%s' ไม่อนุà¸à¸²à¸•ให้ใช้ในชื่อของ Android application package"
#: platform/android/export/export.cpp
msgid "A digit cannot be the first character in a package segment."
-msgstr ""
+msgstr "ไม่สามารถใช้ตัวเลขเป็นตัวà¹à¸£à¸à¹ƒà¸™à¸ªà¹ˆà¸§à¸™à¸‚องà¹à¸žà¹‡à¸„เà¸à¸ˆ"
#: platform/android/export/export.cpp
msgid "The character '%s' cannot be the first character in a package segment."
-msgstr ""
+msgstr "ตัวอัà¸à¸©à¸£ '%s' ไม่สามารถเป็นตัวอัà¸à¸©à¸£à¸•ัวà¹à¸£à¸à¹ƒà¸™à¸ªà¹ˆà¸§à¸™à¸‚องà¹à¸žà¹‡à¸„เà¸à¸ˆ"
#: platform/android/export/export.cpp
msgid "The package must have at least one '.' separator."
-msgstr ""
+msgstr "à¹à¸žà¹‡à¸„เà¸à¸ˆà¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้องมี '.' อย่างน้อยหนึ่งตัว"
#: platform/android/export/export.cpp
msgid "Select device from the list"
@@ -12319,11 +11872,11 @@ msgstr "เลือà¸à¸­à¸¸à¸›à¸à¸£à¸“์จาà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­"
#: platform/android/export/export.cpp
msgid "ADB executable not configured in the Editor Settings."
-msgstr ""
+msgstr "ADB executable ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเอดิเตอร์"
#: platform/android/export/export.cpp
msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr ""
+msgstr "OpenJDK jarsigner ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเอดิเตอร์"
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12348,9 +11901,8 @@ msgid "Invalid public key for APK expansion."
msgstr ""
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Invalid package name:"
-msgstr "ชื่อคลาสไม่ถูà¸à¸•้อง"
+msgstr "ชื่อà¹à¸žà¹‡à¸„เà¸à¸ˆà¸œà¸´à¸”พลาด:"
#: platform/android/export/export.cpp
msgid ""
@@ -12368,7 +11920,7 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr ""
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡à¹‚ปรเจคà¹à¸­à¸™à¸”รอยด์ (gradle)"
#: platform/android/export/export.cpp
msgid ""
@@ -12391,7 +11943,7 @@ msgstr "ไม่สามารถใช้ชื่อนี้ได้:"
#: platform/iphone/export/export.cpp
msgid "App Store Team ID not specified - cannot configure the project."
-msgstr ""
+msgstr "App Store Team ID ยังไม่ได้ระบุ - ไม่สามารถà¸à¸³à¸«à¸™à¸”ค่าให้โปรเจà¸à¸•์ได้"
#: platform/iphone/export/export.cpp
#, fuzzy
@@ -12404,7 +11956,7 @@ msgstr ""
#: platform/javascript/export/export.cpp
msgid "Stop HTTP Server"
-msgstr ""
+msgstr "หยุดเซิฟเวอร์ HTTP"
#: platform/javascript/export/export.cpp
msgid "Run in Browser"
@@ -12449,9 +12001,8 @@ msgid "Invalid package unique name."
msgstr "ชื่อเฉพาะไม่ถูà¸à¸•้อง"
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package publisher display name."
-msgstr "ชื่อเฉพาะไม่ถูà¸à¸•้อง"
+msgstr "ชื่อà¹à¸ªà¸”งผู้จัดจำหน่ายà¹à¸žà¸„เà¸à¸ˆà¹„ม่ถูà¸à¸•้อง"
#: platform/uwp/export/export.cpp
msgid "Invalid product GUID."
@@ -12505,7 +12056,7 @@ msgid ""
"Only one visible CanvasModulate is allowed per scene (or set of instanced "
"scenes). The first created one will work, while the rest will be ignored."
msgstr ""
-"จะมี CanvasModulate ที่มองเห็นได้เพียงโหนดเดียวในฉาภ(หรือà¸à¸¥à¸¸à¹ˆà¸¡à¸‚องฉาà¸à¸—ี่เป็นอินสà¹à¸•นซ์) "
+"จะมี CanvasModulate ที่มองเห็นได้ เพียงโหนดเดียวในฉาภ(หรือà¸à¸¥à¸¸à¹ˆà¸¡à¸‚องฉาà¸à¸—ี่เป็นอินสà¹à¸•นซ์) "
"โหนดà¹à¸£à¸à¹€à¸—่านั้นที่จะทำงานได้ปà¸à¸•ิ ที่เหลือจะไม่ทำงาน"
#: scene/2d/collision_object_2d.cpp
@@ -12584,7 +12135,7 @@ msgid ""
"node. It only provides navigation data."
msgstr ""
"NavigationPolygonInstance ต้องเป็นโหนดลูà¸/หลานของโหนด Navigation2D "
-"เนื่องจาà¸à¹‚หนดนี้ใช้เà¸à¹‡à¸šà¸‚้อมูลà¸à¸²à¸£à¸™à¸³à¸—างเท่านั้น"
+"โดยจะให้ข้อมูลà¸à¸²à¸£à¸™à¸³à¸—างเท่านั้น"
#: scene/2d/parallax_layer.cpp
msgid ""
@@ -12633,7 +12184,7 @@ msgstr ""
#: scene/2d/skeleton_2d.cpp
msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
-msgstr ""
+msgstr "Bone2D สามารถทำงานได้à¸à¸±à¸š Skeleton2D หรือ Bone2D ตัวอื่นโดยเป็นโหนดà¹à¸¡à¹ˆ"
#: scene/2d/skeleton_2d.cpp
msgid ""
@@ -12676,9 +12227,8 @@ msgid ""
msgstr "Controller id ต้องไม่เป็น 0 ไม่เช่นนั้นตัวควบคุมนี้จะไม่เชื่อมà¸à¸±à¸šà¸­à¸¸à¸›à¸à¸£à¸“์จริง"
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr "ARVRAnchor ต้องมี ARVROrigin เป็นโหนดà¹à¸¡à¹ˆ"
+msgstr "ARVRAnchor ต้องมีโหนด ARVROrigin เป็นโหนดà¹à¸¡à¹ˆ"
#: scene/3d/arvr_nodes.cpp
#, fuzzy
@@ -12688,9 +12238,8 @@ msgid ""
msgstr "Anchor id ต้องไม่เป็น 0 ไม่เช่นนั้น anchor นี้จะไม่เชื่อมà¸à¸±à¸š anchor จริง"
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVROrigin requires an ARVRCamera child node."
-msgstr "ARVROrigin ต้องมี ARVRCamera เป็นโหนดลูà¸"
+msgstr "ARVROrigin จำเป็นต้องมี ARVRCamera เป็นโหนดลูà¸"
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
@@ -12786,6 +12335,8 @@ msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
msgstr ""
+"ไดรเวอร์วีดีโอ GLES2 ไม่สนับสนุน GIProbe\n"
+"ใช้ BakedLightmap à¹à¸—น"
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
@@ -12801,7 +12352,7 @@ msgid ""
"It only provides navigation data."
msgstr ""
"NavigationMeshInstance ต้องเป็นโหนดลูà¸/หลานของโหนด Navigation "
-"โหนดนี้ใช้เพื่อเป็นข้อมูลในà¸à¸²à¸£à¸™à¸³à¸—างเท่านั้น"
+"โดยจะให้ข้อมูลà¸à¸²à¸£à¸™à¸³à¸—างเท่านั้น"
#: scene/3d/particles.cpp
msgid ""
@@ -12884,7 +12435,7 @@ msgstr ""
#: scene/3d/world_environment.cpp
msgid ""
"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
-msgstr "จะมี WorldEnvironment ได้เพียงโหนดเดียวในฉาภ(หรือà¸à¸¥à¸¸à¹ˆà¸¡à¸‚องฉาà¸à¸—ี่เป็นอินสà¹à¸•นซ์)"
+msgstr "จะมี WorldEnvironment ได้เพียงอันเดียวในฉาภ(หรือà¸à¸¥à¸¸à¹ˆà¸¡à¸‚องฉาà¸à¸—ี่เป็นอินสà¹à¸•นซ์)"
#: scene/3d/world_environment.cpp
msgid ""
@@ -12897,23 +12448,20 @@ msgid "On BlendTree node '%s', animation not found: '%s'"
msgstr ""
#: scene/animation/animation_blend_tree.cpp
-#, fuzzy
msgid "Animation not found: '%s'"
-msgstr "เครื่องมือà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+msgstr "ไม่พบà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™: '%s'"
#: scene/animation/animation_tree.cpp
msgid "In node '%s', invalid animation: '%s'."
msgstr ""
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Invalid animation: '%s'."
-msgstr "ผิดพลาด: ชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹„ม่ถูà¸à¸•้อง!"
+msgstr "à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸œà¸´à¸”พลาด: '%s'."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Nothing connected to input '%s' of node '%s'."
-msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยง '%s' à¸à¸±à¸š '%s'"
+msgstr "ไม่มีà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อไปที่อินพุต '%s' ของโหนด '%s'."
#: scene/animation/animation_tree.cpp
msgid "No root AnimationNode for the graph is set."
@@ -12943,6 +12491,9 @@ msgid ""
"LMB: Set color\n"
"RMB: Remove preset"
msgstr ""
+"สี: #%s\n"
+"คลิà¸à¸‹à¹‰à¸²à¸¢: เลือà¸à¸ªà¸µ\n"
+"คลิà¸à¸‚วา: ลบสี"
#: scene/gui/color_picker.cpp
msgid "Pick a color from the editor window."
@@ -12950,11 +12501,11 @@ msgstr ""
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
msgid "Raw"
-msgstr ""
+msgstr "Raw"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -13034,6 +12585,10 @@ msgstr ""
"ให้à¹à¸à¹‰à¹„ขโหนดนี้ให้เป็นโหนดลูà¸à¸‚อง Control à¹à¸•่ถ้าไม่ ให้ปรับเป็น render target à¹à¸¥à¸°à¸™à¸³à¹„ปใช้เป็น "
"texture ของโหนดอื่น"
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -13063,7 +12618,16 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "ค่าคงที่ไม่สามารถà¹à¸à¹‰à¹„ขได้"
+
+#~ msgid "Issue Tracker"
+#~ msgstr "ติดตามปัà¸à¸«à¸²"
+
+#~ msgid "Request Docs"
+#~ msgstr "ร้องขอคู่มือ"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "ช่วยพัฒนาคู่มือโดยà¸à¸²à¸£à¹ƒà¸«à¹‰à¸‚้อเสนอà¹à¸™à¸°"
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "à¹à¸—นที่à¹à¸¥à¹‰à¸§ %d ครั้ง"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 83eb878d8c..e5e8f0ba97 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -1481,7 +1481,7 @@ msgstr "KendindenYüklenme'yi Taşı"
msgid "Remove Autoload"
msgstr "KendindenYüklenme'yi Kaldır"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Etkin"
@@ -2961,8 +2961,13 @@ msgid "Q&A"
msgstr "S&C"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Sorun İzleyici"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Yeniden İçe Aktar"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4013,7 +4018,8 @@ msgid "Reimport"
msgstr "Yeniden İçe Aktar"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Sahneleri kaydet, tekrar içe aktar ve baştan başlat"
#: editor/import_dock.cpp
@@ -6857,14 +6863,6 @@ msgid "Open Godot online documentation."
msgstr "Çevrimiçi Godot dökümanlarını aç."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Belgeleri İste"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Dönüt vererek Godot belgelerini iyileştirmeye yardımcı olun."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "BaÅŸvuru belgelerinde arama yap."
@@ -7300,6 +7298,11 @@ msgid "This operation requires a single selected node."
msgstr "Bu işlem, seçilmiş tek bir düğüm gerektirir."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Dikey"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "Dönüşü Görüntülemeyi kilitle"
@@ -7388,6 +7391,10 @@ msgid "Freelook Slow Modifier"
msgstr "Serbestbakış Hız Değiştirici"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "Dönme Kilitli Görünüm"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7396,10 +7403,6 @@ msgstr ""
"Oyun içi performansın gösteri olarak ele alınamaz."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "Dönme Kilitli Görünüm"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XForm İletişim Kutusu"
@@ -10911,6 +10914,12 @@ msgid "Script file already exists."
msgstr "Betik dosyası zaten mevcut."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Sınıf İsmi:"
@@ -12682,6 +12691,10 @@ msgstr ""
"yapın böylece bir boyut elde edebilir. Aksi takdirde, Görüntüleme için bunu "
"bir RenderTarget yap ve dahili dokusunu herhangi bir düğüme ata."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Önizleme için geçersiz kaynak."
@@ -12710,6 +12723,15 @@ msgstr "varyings yalnızca vertex işlevinde atanabilir."
msgid "Constants cannot be modified."
msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez."
+#~ msgid "Issue Tracker"
+#~ msgstr "Sorun İzleyici"
+
+#~ msgid "Request Docs"
+#~ msgstr "Belgeleri İste"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Dönüt vererek Godot belgelerini iyileştirmeye yardımcı olun."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "%d değişiklik gerçekleştirildi."
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index bfb614f493..60e61d3bf7 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -17,7 +17,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ukrainian (Godot Engine)\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-02-21 23:32+0000\n"
+"PO-Revision-Date: 2020-03-18 00:10+0000\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/"
"godot/uk/>\n"
@@ -27,7 +27,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 3.11.1\n"
+"X-Generator: Weblate 4.0-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -1458,7 +1458,7 @@ msgstr "ПереміÑтити автозавантаженнÑ"
msgid "Remove Autoload"
msgstr "Видалити автозавантаженнÑ"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Ðктивувати"
@@ -2945,8 +2945,13 @@ msgid "Q&A"
msgstr "Ð—Ð°Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ð° відповіді"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "ВідÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Переімпортувати"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4001,7 +4006,8 @@ msgid "Reimport"
msgstr "Переімпортувати"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Зберегти Ñцени, повторно імпортувати Ñ– перезапуÑтити"
#: editor/import_dock.cpp
@@ -5974,9 +5980,8 @@ msgstr ""
"Цей найточніший (але найповільніший) варіант Ð´Ð»Ñ Ð²Ð¸ÑÐ²Ð»ÐµÐ½Ð½Ñ Ð·Ñ–Ñ‚ÐºÐ½ÐµÐ½ÑŒ."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
-msgstr "Створити єдині опуклі облаÑті зіткненнÑ"
+msgstr "Створити єдину опуклу облаÑть зіткненнÑ"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6865,14 +6870,6 @@ msgid "Open Godot online documentation."
msgstr "Відкрити онлайнову документацію Godot."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "Запит щодо документації"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "Допоможіть у поліпшенні документації Godot наданнÑм відгуків."
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "Пошук довідкової документації."
@@ -7310,6 +7307,11 @@ msgid "This operation requires a single selected node."
msgstr "Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ” одного обраного вузла."
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "Ортогонально"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "ЗафікÑувати Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду"
@@ -7398,6 +7400,10 @@ msgid "Freelook Slow Modifier"
msgstr "Модифікатор швидкоÑті довільного оглÑду"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду заблоковано"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7407,10 +7413,6 @@ msgstr ""
"грі."
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду заблоковано"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "Вікно XForm"
@@ -10921,6 +10923,12 @@ msgid "Script file already exists."
msgstr "Файл Ñкрипту вже Ñ–Ñнує."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "Ðазва клаÑу:"
@@ -12415,6 +12423,8 @@ msgstr ""
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
msgstr ""
+"У ConcavePolygonShape не передбачено підтримки RigidBody у режимі, "
+"відмінному від Ñтатичного."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
@@ -12715,6 +12725,10 @@ msgstr ""
"Control, щоб у неї був розмір. Крім того, можна зробити її RenderTarget і "
"пов'Ñзати Ñ—Ñ— внутрішню текÑтуру з одним із вузлів Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ."
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Ðекоректне джерело Ð´Ð»Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду."
@@ -12743,6 +12757,15 @@ msgstr "Змінні величини можна пов'Ñзувати лише
msgid "Constants cannot be modified."
msgstr "Сталі не можна змінювати."
+#~ msgid "Issue Tracker"
+#~ msgstr "ВідÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº"
+
+#~ msgid "Request Docs"
+#~ msgstr "Запит щодо документації"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "Допоможіть у поліпшенні документації Godot наданнÑм відгуків."
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Замінено %d випадок(-ів)."
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 815f92af6a..1e2f87b352 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -1429,7 +1429,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr ""
@@ -2862,7 +2862,11 @@ msgid "Q&A"
msgstr ""
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -3907,7 +3911,7 @@ msgid "Reimport"
msgstr ""
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -6762,14 +6766,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7209,6 +7205,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7298,13 +7298,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10719,6 +10719,12 @@ msgid "Script file already exists."
msgstr ""
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr ""
@@ -12370,6 +12376,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index 31b7f3ceb7..88ca61847e 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -1455,7 +1455,7 @@ msgstr ""
msgid "Remove Autoload"
msgstr ""
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "Mở"
@@ -2927,8 +2927,13 @@ msgid "Q&A"
msgstr "Há»i và Äáp"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "Theo dõi vấn Ä‘á»"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "Nhập vào lại"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3974,7 +3979,8 @@ msgid "Reimport"
msgstr "Nhập vào lại"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "Lưu các cảnh, nhập vào lại và khởi động lại"
#: editor/import_dock.cpp
@@ -6849,14 +6855,6 @@ msgid "Open Godot online documentation."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7303,6 +7301,10 @@ msgid "This operation requires a single selected node."
msgstr "Hoạt động yêu cầu chá»n má»™t nút duy nhất."
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr ""
@@ -7392,13 +7394,13 @@ msgid "Freelook Slow Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid ""
-"Note: The FPS value displayed is the editor's framerate.\n"
-"It cannot be used as a reliable indication of in-game performance."
+msgid "View Rotation Locked"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10857,6 +10859,12 @@ msgid "Script file already exists."
msgstr "Tam giác đã tồn tại."
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Lá»›p:"
@@ -12521,6 +12529,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "nguồn vô hiệu cho xem trước"
@@ -12550,6 +12562,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Không thể chỉnh sửa hằng số."
+#~ msgid "Issue Tracker"
+#~ msgstr "Theo dõi vấn Ä‘á»"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "Äã thay thế %d biến cố."
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index e7108c6e61..df8b8e1725 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -64,8 +64,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2020-03-08 22:33+0000\n"
-"Last-Translator: Revan Ji <jiruifancr@gmail.com>\n"
+"PO-Revision-Date: 2020-04-05 12:05+0000\n"
+"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
"Language: zh_CN\n"
@@ -1481,7 +1481,7 @@ msgstr "移动Autoload"
msgid "Remove Autoload"
msgstr "移除Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "å¯ç”¨"
@@ -2919,8 +2919,13 @@ msgid "Q&A"
msgstr "问答"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
-msgstr "问题跟踪器"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "釿–°å¯¼å…¥"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3957,7 +3962,8 @@ msgid "Reimport"
msgstr "釿–°å¯¼å…¥"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "ä¿å­˜åœºæ™¯ï¼Œé‡æ–°å¯¼å…¥ï¼Œä»Žå¤´å¼€å§‹"
#: editor/import_dock.cpp
@@ -6774,14 +6780,6 @@ msgid "Open Godot online documentation."
msgstr "打开Godot在线文档。"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "请求文档"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "通过æä¾›å馈帮助改进godot文档。"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "æœç´¢æ–‡æ¡£ã€‚"
@@ -7215,6 +7213,11 @@ msgid "This operation requires a single selected node."
msgstr "æ­¤æ“作åªèƒ½åº”用于å•个选中节点。"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "正交"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "é”定视角旋转"
@@ -7303,6 +7306,10 @@ msgid "Freelook Slow Modifier"
msgstr "缓慢自由视图速度"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "é”定视角旋转"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
@@ -7311,10 +7318,6 @@ msgstr ""
"它ä¸èƒ½ç”¨äºŽè¡¨çŽ°æ¸¸æˆä¸­çš„实际性能。"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "é”定视角旋转"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XFormå¯¹è¯æ¡†"
@@ -7906,7 +7909,7 @@ msgstr "字体"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Color"
-msgstr "Color(颜色)"
+msgstr "颜色"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme File"
@@ -10740,6 +10743,12 @@ msgid "Script file already exists."
msgstr "脚本文件已存在。"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "Class Name:"
msgstr "ç±»å:"
@@ -12428,6 +12437,10 @@ msgstr ""
"幕上显示其内容,使其æˆä¸ºå­æŽ§ä»¶çš„æ‰€ä»¥å®ƒå¯ä»¥æœ‰ä¸€ä¸ªå°ºå¯¸å¤§å°å€¼ã€‚å¦åˆ™è¯·å°†å…¶è®¾ç½®ä¸º "
"RenderTarget,并将其内部纹ç†åˆ†é…给其它节点显示。"
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "预览的æºèµ„æºæ— æ•ˆã€‚"
@@ -12456,6 +12469,15 @@ msgstr "å˜é‡åªèƒ½åœ¨é¡¶ç‚¹å‡½æ•°ä¸­æŒ‡å®šã€‚"
msgid "Constants cannot be modified."
msgstr "ä¸å…许修改常é‡ã€‚"
+#~ msgid "Issue Tracker"
+#~ msgstr "问题跟踪器"
+
+#~ msgid "Request Docs"
+#~ msgstr "请求文档"
+
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "通过æä¾›å馈帮助改进godot文档。"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "替æ¢äº†%d项。"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index a228d6ee60..31306885ae 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -1533,7 +1533,7 @@ msgstr "移動Autoload"
msgid "Remove Autoload"
msgstr "移除Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
#, fuzzy
msgid "Enable"
msgstr "啟用"
@@ -3070,7 +3070,12 @@ msgid "Q&A"
msgstr "Q&A"
#: editor/editor_node.cpp
-msgid "Issue Tracker"
+#, fuzzy
+msgid "Report a Bug"
+msgstr "å°Žå…¥"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
@@ -4182,7 +4187,7 @@ msgid "Reimport"
msgstr "å°Žå…¥"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+msgid "Save Scenes, Re-Import, and Restart"
msgstr ""
#: editor/import_dock.cpp
@@ -7143,14 +7148,6 @@ msgid "Open Godot online documentation."
msgstr "開啓最近的"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr ""
@@ -7611,6 +7608,10 @@ msgid "This operation requires a single selected node."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Lock View Rotation"
msgstr "本地化"
@@ -7705,17 +7706,17 @@ msgid "Freelook Slow Modifier"
msgstr "下滾"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "View Rotation Locked"
+msgstr "本地化"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "View Rotation Locked"
-msgstr "本地化"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr ""
@@ -11249,6 +11250,12 @@ msgid "Script file already exists."
msgstr "AutoLoad '%s'已存在ï¼"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "å稱:"
@@ -12946,6 +12953,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 466e8db554..235ce0d023 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -1521,7 +1521,7 @@ msgstr "移動 Autoload"
msgid "Remove Autoload"
msgstr "刪除 Autoload"
-#: editor/editor_autoload_settings.cpp
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
msgstr "啟用"
@@ -3062,8 +3062,12 @@ msgstr "Q&A"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Issue Tracker"
-msgstr "å•題追蹤器"
+msgid "Report a Bug"
+msgstr "釿–°å°Žå…¥"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4155,7 +4159,8 @@ msgid "Reimport"
msgstr "釿–°å°Žå…¥"
#: editor/import_dock.cpp
-msgid "Save scenes, re-import and restart"
+#, fuzzy
+msgid "Save Scenes, Re-Import, and Restart"
msgstr "ä¿å­˜å ´æ™¯ï¼Œé‡æ–°å°Žå…¥ä¸¦é‡æ–°å•Ÿå‹•"
#: editor/import_dock.cpp
@@ -7125,15 +7130,6 @@ msgid "Open Godot online documentation."
msgstr "打開 Godot 線上文檔"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Request Docs"
-msgstr "請求檔案"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Help improve the Godot documentation by giving feedback."
-msgstr "é€šéŽæä¾›å›žé¥‹å¹«åŠ©æ”¹é€² Godot 文檔"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
msgstr "æœç´¢åƒè€ƒæ–‡æª”。"
@@ -7589,6 +7585,11 @@ msgid "This operation requires a single selected node."
msgstr "æ­¤æ“作需è¦å–®å€‹é¸å®šçš„節點。"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Auto Orthogonal Enabled"
+msgstr "正交"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
msgstr "鎖定視圖旋轉"
@@ -7680,16 +7681,16 @@ msgid "Freelook Slow Modifier"
msgstr "自由視圖速度調節"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr "視圖旋轉已鎖定"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr "注æ„: 顯示的FPS值是編輯器的幀率。 它ä¸èƒ½ç”¨äºŽè¡¨ç¾éŠæˆ²å…§çš„實際性能"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "View Rotation Locked"
-msgstr "視圖旋轉已鎖定"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
msgstr "XFormå°è©±æ¡†"
@@ -11230,6 +11231,12 @@ msgid "Script file already exists."
msgstr "Autoload「%sã€å·²ç¶“存在!"
#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Class Name:"
msgstr "Class:"
@@ -12956,6 +12963,10 @@ msgid ""
"texture to some node for display."
msgstr ""
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
@@ -12987,6 +12998,17 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#, fuzzy
+#~ msgid "Issue Tracker"
+#~ msgstr "å•題追蹤器"
+
+#~ msgid "Request Docs"
+#~ msgstr "請求檔案"
+
+#, fuzzy
+#~ msgid "Help improve the Godot documentation by giving feedback."
+#~ msgstr "é€šéŽæä¾›å›žé¥‹å¹«åŠ©æ”¹é€² Godot 文檔"
+
#~ msgid "Replaced %d occurrence(s)."
#~ msgstr "å–代了 %d 個。"
diff --git a/main/main.cpp b/main/main.cpp
index a53e52e485..ad8e8dadfe 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -55,13 +55,13 @@
#include "main/splash.gen.h"
#include "main/splash_editor.gen.h"
#include "main/tests/test_main.h"
+#include "modules/modules_enabled.gen.h"
#include "modules/register_module_types.h"
#include "platform/register_platform_apis.h"
#include "scene/main/scene_tree.h"
#include "scene/main/window.h"
#include "scene/register_scene_types.h"
#include "scene/resources/packed_scene.h"
-#include "servers/arvr_server.h"
#include "servers/audio_server.h"
#include "servers/camera_server.h"
#include "servers/display_server.h"
@@ -72,6 +72,7 @@
#include "servers/register_server_types.h"
#include "servers/rendering/rendering_server_raster.h"
#include "servers/rendering/rendering_server_wrap_mt.h"
+#include "servers/xr_server.h"
#ifdef TOOLS_ENABLED
#include "editor/doc_data.h"
@@ -105,7 +106,7 @@ static AudioServer *audio_server = nullptr;
static DisplayServer *display_server = nullptr;
static RenderingServer *rendering_server = nullptr;
static CameraServer *camera_server = nullptr;
-static ARVRServer *arvr_server = nullptr;
+static XRServer *xr_server = nullptr;
static PhysicsServer3D *physics_server = nullptr;
static PhysicsServer2D *physics_2d_server = nullptr;
static NavigationServer3D *navigation_server = nullptr;
@@ -478,6 +479,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
I = args.front();
while (I) {
+#ifdef OSX_ENABLED
+ // Ignore the process serial number argument passed by macOS Gatekeeper.
+ // Otherwise, Godot would try to open a non-existent project on the first start and abort.
+ if (I->get().begins_with("-psn_")) {
+ I = I->next();
+ continue;
+ }
+#endif
List<String>::Element *N = I->next();
@@ -1154,9 +1163,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps", PropertyInfo(Variant::INT, "debug/settings/fps/force_fps", PROPERTY_HINT_RANGE, "0,120,1,or_greater"));
GLOBAL_DEF("debug/settings/stdout/print_fps", false);
+ GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false);
- if (!OS::get_singleton()->_verbose_stdout) //overridden
- OS::get_singleton()->_verbose_stdout = GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false);
+ if (!OS::get_singleton()->_verbose_stdout) { // Not manually overridden.
+ OS::get_singleton()->_verbose_stdout = GLOBAL_GET("debug/settings/stdout/verbose_stdout");
+ }
if (frame_delay == 0) {
frame_delay = GLOBAL_DEF("application/run/frame_delay_msec", 0);
@@ -1297,8 +1308,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
audio_server = memnew(AudioServer);
audio_server->init();
- // also init our arvr_server from here
- arvr_server = memnew(ARVRServer);
+ // also init our xr_server from here
+ xr_server = memnew(XRServer);
register_core_singletons();
@@ -1473,6 +1484,15 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
// We could add more, and make the CLI arg require a comma-separated list of profilers.
EngineDebugger::get_singleton()->profiler_enable("scripts", true);
}
+
+ if (!project_manager) {
+ // If not running the project manager, and now that the engine is
+ // able to load resources, load the global shader variables.
+ // If running on editor, dont load the textures because the editor
+ // may want to import them first. Editor will reload those later.
+ rendering_server->global_variables_load_settings(!editor);
+ }
+
_start_success = true;
locale = String();
@@ -1580,6 +1600,19 @@ bool Main::start() {
DirAccessRef da = DirAccess::open(doc_tool);
ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a base Godot build directory.");
}
+
+#ifndef MODULE_MONO_ENABLED
+ // Hack to define Mono-specific project settings even on non-Mono builds,
+ // so that we don't lose their descriptions and default values in DocData.
+ // Default values should be synced with mono_gd/gd_mono.cpp.
+ GLOBAL_DEF("mono/debugger_agent/port", 23685);
+ GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false);
+ GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000);
+ GLOBAL_DEF("mono/profiler/args", "log:calls,alloc,sample,output=output.mlpd");
+ GLOBAL_DEF("mono/profiler/enabled", false);
+ GLOBAL_DEF("mono/unhandled_exception_policy", 0);
+#endif
+
DocData doc;
doc.generate(doc_base);
@@ -1667,7 +1700,7 @@ bool Main::start() {
return false;
}
- if (script_res->can_instance() /*&& script_res->inherits_from("SceneTreeScripted")*/) {
+ if (script_res->can_instance()) {
StringName instance_type = script_res->get_instance_base_type();
Object *obj = ClassDB::instance(instance_type);
@@ -1675,7 +1708,7 @@ bool Main::start() {
if (!script_loop) {
if (obj)
memdelete(obj);
- ERR_FAIL_V_MSG(false, "Can't load script '" + script + "', it does not inherit from a MainLoop type.");
+ ERR_FAIL_V_MSG(false, vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script));
}
script_loop->set_init_script(script_res);
@@ -2272,13 +2305,16 @@ void Main::cleanup() {
// Sync pending commands that may have been queued from a different thread during ScriptServer finalization
RenderingServer::get_singleton()->sync();
+ //clear global shader variables before scene and other graphics stuff is deinitialized.
+ rendering_server->global_variables_clear();
+
#ifdef TOOLS_ENABLED
EditorNode::unregister_editor_types();
#endif
- if (arvr_server) {
+ if (xr_server) {
// cleanup now before we pull the rug from underneath...
- memdelete(arvr_server);
+ memdelete(xr_server);
}
ImageLoader::cleanup();
diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp
index 1e85f7f1d2..dbe2da86cf 100644
--- a/main/tests/test_shader_lang.cpp
+++ b/main/tests/test_shader_lang.cpp
@@ -342,7 +342,7 @@ MainLoop *test() {
Set<String> types;
types.insert("spatial");
- Error err = sl.compile(code, dt, rm, types);
+ Error err = sl.compile(code, dt, rm, types, NULL);
if (err) {
diff --git a/misc/travis/android-tools-linux.sh b/misc/travis/android-tools-linux.sh
index d0c123ee6c..6114551861 100755
--- a/misc/travis/android-tools-linux.sh
+++ b/misc/travis/android-tools-linux.sh
@@ -24,12 +24,12 @@ ANDROID_SDK_URL=$ANDROID_BASE_URL/$ANDROID_SDK_FILENAME
ANDROID_SDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_SDK_DIR
ANDROID_SDK_SHA256=92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9
-ANDROID_NDK_RELEASE=r20
+ANDROID_NDK_RELEASE=r21
ANDROID_NDK_DIR=android-ndk
ANDROID_NDK_FILENAME=android-ndk-$ANDROID_NDK_RELEASE-linux-x86_64.zip
ANDROID_NDK_URL=$ANDROID_BASE_URL/$ANDROID_NDK_FILENAME
ANDROID_NDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_NDK_DIR
-ANDROID_NDK_SHA1=8665fc84a1b1f0d6ab3b5fdd1e30200cc7b9adff
+ANDROID_NDK_SHA1=afc9c0b9faad222898ac8168c78ad4ccac8a1b5c
echo
echo "Download and install Android development tools ..."
@@ -76,7 +76,7 @@ yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager --licenses > /dev/null
echo "Installing: Android Build and Platform Tools ..."
yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'tools' > /dev/null
yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'platform-tools' > /dev/null
-yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'build-tools;28.0.3' > /dev/null
+yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'build-tools;29.0.3' > /dev/null
echo
EXPORT_VAL="export ANDROID_HOME=$ANDROID_SDK_PATH"
diff --git a/modules/SCsub b/modules/SCsub
index 1671b398e5..fb46c5f877 100644
--- a/modules/SCsub
+++ b/modules/SCsub
@@ -11,6 +11,7 @@ Export("env_modules")
# Header with MODULE_*_ENABLED defines.
env.CommandNoCache("modules_enabled.gen.h", Value(env.module_list), modules_builders.generate_modules_enabled)
+vs_sources = []
# libmodule_<name>.a for each active module.
for module in env.module_list:
env.modules_sources = []
@@ -23,6 +24,8 @@ for module in env.module_list:
lib = env_modules.add_library("module_%s" % module, env.modules_sources)
env.Prepend(LIBS=[lib])
+ if env["vsproj"]:
+ vs_sources += env.modules_sources
# libmodules.a with only register_module_types.
# Must be last so that all libmodule_<name>.a libraries are on the right side
@@ -31,3 +34,5 @@ env.modules_sources = []
env_modules.add_source_files(env.modules_sources, "register_module_types.gen.cpp")
lib = env_modules.add_library("modules", env.modules_sources)
env.Prepend(LIBS=[lib])
+if env["vsproj"]:
+ env.modules_sources += vs_sources
diff --git a/modules/arkit/arkit_interface.h b/modules/arkit/arkit_interface.h
index 4f8f726816..1044f3cf6f 100644
--- a/modules/arkit/arkit_interface.h
+++ b/modules/arkit/arkit_interface.h
@@ -31,9 +31,9 @@
#ifndef ARKIT_INTERFACE_H
#define ARKIT_INTERFACE_H
-#include "servers/arvr/arvr_interface.h"
-#include "servers/arvr/arvr_positional_tracker.h"
#include "servers/camera/camera_feed.h"
+#include "servers/xr/xr_interface.h"
+#include "servers/xr/xr_positional_tracker.h"
/**
@author Bastiaan Olij <mux213@gmail.com>
@@ -44,8 +44,8 @@
// forward declaration for some needed objects
class ARKitShader;
-class ARKitInterface : public ARVRInterface {
- GDCLASS(ARKitInterface, ARVRInterface);
+class ARKitInterface : public XRInterface {
+ GDCLASS(ARKitInterface, XRInterface);
private:
bool initialized;
@@ -65,7 +65,7 @@ private:
Vector<uint8_t> img_data[2];
struct anchor_map {
- ARVRPositionalTracker *tracker;
+ XRPositionalTracker *tracker;
unsigned char uuid[16];
};
@@ -73,7 +73,7 @@ private:
unsigned int num_anchors;
unsigned int max_anchors;
anchor_map *anchors;
- ARVRPositionalTracker *get_anchor_for_uuid(const unsigned char *p_uuid);
+ XRPositionalTracker *get_anchor_for_uuid(const unsigned char *p_uuid);
void remove_anchor_for_uuid(const unsigned char *p_uuid);
void remove_all_anchors();
@@ -108,9 +108,9 @@ public:
virtual Size2 get_render_targetsize();
virtual bool is_stereo();
- virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
- virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
- virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
+ virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform);
+ virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+ virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
virtual void process();
diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm
index 031e1e115e..79f09e2a7e 100644
--- a/modules/arkit/arkit_interface.mm
+++ b/modules/arkit/arkit_interface.mm
@@ -158,7 +158,7 @@ StringName ARKitInterface::get_name() const {
}
int ARKitInterface::get_capabilities() const {
- return ARKitInterface::ARVR_MONO + ARKitInterface::ARVR_AR;
+ return ARKitInterface::XR_MONO + ARKitInterface::XR_AR;
}
Array ARKitInterface::raycast(Vector2 p_screen_coord) {
@@ -218,8 +218,8 @@ bool ARKitInterface::is_initialized() const {
}
bool ARKitInterface::initialize() {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, false);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, false);
if (!initialized) {
print_line("initializing ARKit");
@@ -244,7 +244,7 @@ bool ARKitInterface::initialize() {
transform = Transform();
// make this our primary interface
- arvr_server->set_primary_interface(this);
+ xr_server->set_primary_interface(this);
// make sure we have our feed setup
if (feed.is_null()) {
@@ -270,10 +270,10 @@ bool ARKitInterface::initialize() {
void ARKitInterface::uninitialize() {
if (initialized) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != NULL) {
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != NULL) {
// no longer our primary interface
- arvr_server->clear_primary_interface_if(this);
+ xr_server->clear_primary_interface_if(this);
}
if (feed.is_valid()) {
@@ -303,22 +303,22 @@ Size2 ARKitInterface::get_render_targetsize() {
return target_size;
}
-Transform ARKitInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
+Transform ARKitInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) {
_THREAD_SAFE_METHOD_
Transform transform_for_eye;
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, transform_for_eye);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, transform_for_eye);
if (initialized) {
- float world_scale = arvr_server->get_world_scale();
+ float world_scale = xr_server->get_world_scale();
// just scale our origin point of our transform, note that we really shouldn't be using world_scale in ARKit but....
transform_for_eye = transform;
transform_for_eye.origin *= world_scale;
- transform_for_eye = p_cam_transform * arvr_server->get_reference_frame() * transform_for_eye;
+ transform_for_eye = p_cam_transform * xr_server->get_reference_frame() * transform_for_eye;
} else {
// huh? well just return what we got....
transform_for_eye = p_cam_transform;
@@ -327,7 +327,7 @@ Transform ARKitInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const
return transform_for_eye;
}
-CameraMatrix ARKitInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+CameraMatrix ARKitInterface::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
// Remember our near and far, it will be used in process when we obtain our projection from our ARKit session.
z_near = p_z_near;
z_far = p_z_far;
@@ -335,7 +335,7 @@ CameraMatrix ARKitInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, r
return projection;
}
-void ARKitInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+void ARKitInterface::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
_THREAD_SAFE_METHOD_
// We must have a valid render target
@@ -356,7 +356,7 @@ void ARKitInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_targ
VSG::rasterizer->blit_render_target_to_screen(p_render_target, screen_rect, 0);
}
-ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *p_uuid) {
+XRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *p_uuid) {
if (anchors == NULL) {
num_anchors = 0;
max_anchors = 10;
@@ -377,8 +377,8 @@ ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *
ERR_FAIL_NULL_V(anchors, NULL);
}
- ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker);
- new_tracker->set_type(ARVRServer::TRACKER_ANCHOR);
+ XRPositionalTracker *new_tracker = memnew(XRPositionalTracker);
+ new_tracker->set_type(XRServer::TRACKER_ANCHOR);
char tracker_name[256];
sprintf(tracker_name, "Anchor %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p_uuid[0], p_uuid[1], p_uuid[2], p_uuid[3], p_uuid[4], p_uuid[5], p_uuid[6], p_uuid[7], p_uuid[8], p_uuid[9], p_uuid[10], p_uuid[11], p_uuid[12], p_uuid[13], p_uuid[14], p_uuid[15]);
@@ -388,7 +388,7 @@ ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *
new_tracker->set_name(name);
// add our tracker
- ARVRServer::get_singleton()->add_tracker(new_tracker);
+ XRServer::get_singleton()->add_tracker(new_tracker);
anchors[num_anchors].tracker = new_tracker;
memcpy(anchors[num_anchors].uuid, p_uuid, 16);
num_anchors++;
@@ -401,7 +401,7 @@ void ARKitInterface::remove_anchor_for_uuid(const unsigned char *p_uuid) {
for (unsigned int i = 0; i < num_anchors; i++) {
if (memcmp(anchors[i].uuid, p_uuid, 16) == 0) {
// remove our tracker
- ARVRServer::get_singleton()->remove_tracker(anchors[i].tracker);
+ XRServer::get_singleton()->remove_tracker(anchors[i].tracker);
memdelete(anchors[i].tracker);
// bring remaining forward
@@ -421,7 +421,7 @@ void ARKitInterface::remove_all_anchors() {
if (anchors != NULL) {
for (unsigned int i = 0; i < num_anchors; i++) {
// remove our tracker
- ARVRServer::get_singleton()->remove_tracker(anchors[i].tracker);
+ XRServer::get_singleton()->remove_tracker(anchors[i].tracker);
memdelete(anchors[i].tracker);
};
@@ -582,16 +582,16 @@ void ARKitInterface::process() {
// strangely enough we have to states, rolling them up into one
if (camera.trackingState == ARTrackingStateNotAvailable) {
// no tracking, would be good if we black out the screen or something...
- tracking_state = ARVRInterface::ARVR_NOT_TRACKING;
+ tracking_state = XRInterface::XR_NOT_TRACKING;
} else {
if (camera.trackingState == ARTrackingStateNormal) {
- tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
+ tracking_state = XRInterface::XR_NORMAL_TRACKING;
} else if (camera.trackingStateReason == ARTrackingStateReasonExcessiveMotion) {
- tracking_state = ARVRInterface::ARVR_EXCESSIVE_MOTION;
+ tracking_state = XRInterface::XR_EXCESSIVE_MOTION;
} else if (camera.trackingStateReason == ARTrackingStateReasonInsufficientFeatures) {
- tracking_state = ARVRInterface::ARVR_INSUFFICIENT_FEATURES;
+ tracking_state = XRInterface::XR_INSUFFICIENT_FEATURES;
} else {
- tracking_state = ARVRInterface::ARVR_UNKNOWN_TRACKING;
+ tracking_state = XRInterface::XR_UNKNOWN_TRACKING;
}
// copy our current frame transform
@@ -665,7 +665,7 @@ void ARKitInterface::_add_or_update_anchor(void *p_anchor) {
unsigned char uuid[16];
[anchor.identifier getUUIDBytes:uuid];
- ARVRPositionalTracker *tracker = get_anchor_for_uuid(uuid);
+ XRPositionalTracker *tracker = get_anchor_for_uuid(uuid);
if (tracker != NULL) {
// lets update our mesh! (using Arjens code as is for now)
// we should also probably limit how often we do this...
@@ -695,7 +695,7 @@ void ARKitInterface::_add_or_update_anchor(void *p_anchor) {
}
// Note, this also contains a scale factor which gives us an idea of the size of the anchor
- // We may extract that in our ARVRAnchor class
+ // We may extract that in our XRAnchor class
Basis b;
matrix_float4x4 m44 = anchor.transform;
b.elements[0].x = m44.columns[0][0];
diff --git a/modules/arkit/register_types.cpp b/modules/arkit/register_types.cpp
index c78b35529b..91069ab364 100644
--- a/modules/arkit/register_types.cpp
+++ b/modules/arkit/register_types.cpp
@@ -37,7 +37,7 @@ void register_arkit_types() {
Ref<ARKitInterface> arkit_interface;
arkit_interface.instance();
- ARVRServer::get_singleton()->add_interface(arkit_interface);
+ XRServer::get_singleton()->add_interface(arkit_interface);
}
void unregister_arkit_types() {
diff --git a/modules/bullet/config.py b/modules/bullet/config.py
index e8ca273f61..d22f9454ed 100644
--- a/modules/bullet/config.py
+++ b/modules/bullet/config.py
@@ -4,14 +4,3 @@ def can_build(env, platform):
def configure(env):
pass
-
-
-def get_doc_classes():
- return [
- "BulletPhysicsDirectBodyState3D",
- "BulletPhysicsServer3D",
- ]
-
-
-def get_doc_path():
- return "doc_classes"
diff --git a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml
deleted file mode 100644
index 1c0181bd9c..0000000000
--- a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="BulletPhysicsDirectBodyState3D" inherits="PhysicsDirectBodyState3D" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index fc4e1d57de..a4f9affa95 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -138,8 +138,8 @@ void BulletPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impul
body->apply_torque_impulse(p_impulse);
}
-void BulletPhysicsDirectBodyState3D::set_sleep_state(bool p_enable) {
- body->set_activation_state(p_enable);
+void BulletPhysicsDirectBodyState3D::set_sleep_state(bool p_sleep) {
+ body->set_activation_state(!p_sleep);
}
bool BulletPhysicsDirectBodyState3D::is_sleeping() const {
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 95491b1e62..420b5cc443 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -117,7 +117,7 @@ public:
virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
virtual void apply_torque_impulse(const Vector3 &p_impulse);
- virtual void set_sleep_state(bool p_enable);
+ virtual void set_sleep_state(bool p_sleep);
virtual bool is_sleeping() const;
virtual int get_contact_count() const;
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index ae21156b8b..294d594135 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -94,7 +94,7 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = {
{ "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 }
};
-RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_CANT_OPEN;
diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h
index 5b89f16277..ef08967df7 100644
--- a/modules/dds/texture_loader_dds.h
+++ b/modules/dds/texture_loader_dds.h
@@ -36,7 +36,7 @@
class ResourceFormatDDS : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp
index ad0cc91c96..bfb2098dff 100644
--- a/modules/etc/texture_loader_pkm.cpp
+++ b/modules/etc/texture_loader_pkm.cpp
@@ -42,7 +42,7 @@ struct ETC1Header {
uint16_t origHeight;
};
-RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_CANT_OPEN;
diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h
index 989e203994..6507e0bdec 100644
--- a/modules/etc/texture_loader_pkm.h
+++ b/modules/etc/texture_loader_pkm.h
@@ -36,7 +36,7 @@
class ResourceFormatPKM : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub
index a788175b07..cab05549d2 100644
--- a/modules/gdnative/SCsub
+++ b/modules/gdnative/SCsub
@@ -17,7 +17,7 @@ env_gdnative.Prepend(CPPPATH=["#modules/gdnative/include/"])
Export("env_gdnative")
SConscript("net/SCsub")
-SConscript("arvr/SCsub")
+SConscript("xr/SCsub")
SConscript("pluginscript/SCsub")
SConscript("videodecoder/SCsub")
diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py
index 37e25a46d4..4b997e4bfe 100644
--- a/modules/gdnative/config.py
+++ b/modules/gdnative/config.py
@@ -9,7 +9,7 @@ def configure(env):
def get_doc_classes():
return [
"@NativeScript",
- "ARVRInterfaceGDNative",
+ "XRInterfaceGDNative",
"GDNative",
"GDNativeLibrary",
"MultiplayerPeerGDNative",
diff --git a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
deleted file mode 100644
index e8405b64a3..0000000000
--- a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" version="4.0">
- <brief_description>
- GDNative wrapper for an ARVR interface.
- </brief_description>
- <description>
- This is a wrapper class for GDNative implementations of the ARVR interface. To use a GDNative ARVR interface, simply instantiate this object and set your GDNative library containing the ARVR interface implementation.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml
index 601e132d42..1aab864102 100644
--- a/modules/gdnative/doc_classes/GDNativeLibrary.xml
+++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml
@@ -4,7 +4,7 @@
An external library containing functions or script classes to use in Godot.
</brief_description>
<description>
- A GDNative library can implement [NativeScript]s, global functions to call with the [GDNative] class, or low-level engine extensions through interfaces such as [ARVRInterfaceGDNative]. The library must be compiled for each platform and architecture that the project will run on.
+ A GDNative library can implement [NativeScript]s, global functions to call with the [GDNative] class, or low-level engine extensions through interfaces such as [XRInterfaceGDNative]. The library must be compiled for each platform and architecture that the project will run on.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-c-example.html</link>
diff --git a/modules/gdnative/doc_classes/XRInterfaceGDNative.xml b/modules/gdnative/doc_classes/XRInterfaceGDNative.xml
new file mode 100644
index 0000000000..13de815793
--- /dev/null
+++ b/modules/gdnative/doc_classes/XRInterfaceGDNative.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="XRInterfaceGDNative" inherits="XRInterface" version="4.0">
+ <brief_description>
+ GDNative wrapper for an XR interface.
+ </brief_description>
+ <description>
+ This is a wrapper class for GDNative implementations of the XR interface. To use a GDNative XR interface, simply instantiate this object and set your GDNative library containing the XR interface implementation.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index d3426044ec..a131e3a78f 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -493,7 +493,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_
return result;
}
-RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
Ref<GDNativeLibrary> lib;
lib.instance();
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index 9ef9c706d1..6d26c2141d 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -166,7 +166,7 @@ public:
class GDNativeLibraryResourceLoader : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index e1d6c0c867..9473a3d419 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -5935,8 +5935,8 @@
]
},
{
- "name": "arvr",
- "type": "ARVR",
+ "name": "xr",
+ "type": "XR",
"version": {
"major": 1,
"minor": 1
@@ -5944,24 +5944,24 @@
"next": null,
"api": [
{
- "name": "godot_arvr_register_interface",
+ "name": "godot_xr_register_interface",
"return_type": "void",
"arguments": [
- ["const godot_arvr_interface_gdnative *", "p_interface"]
+ ["const godot_xr_interface_gdnative *", "p_interface"]
]
},
{
- "name": "godot_arvr_get_worldscale",
+ "name": "godot_xr_get_worldscale",
"return_type": "godot_real",
"arguments": []
},
{
- "name": "godot_arvr_get_reference_frame",
+ "name": "godot_xr_get_reference_frame",
"return_type": "godot_transform",
"arguments": []
},
{
- "name": "godot_arvr_blit",
+ "name": "godot_xr_blit",
"return_type": "void",
"arguments": [
["godot_int", "p_eye"],
@@ -5970,14 +5970,14 @@
]
},
{
- "name": "godot_arvr_get_texid",
+ "name": "godot_xr_get_texid",
"return_type": "godot_int",
"arguments": [
["godot_rid *", "p_render_target"]
]
},
{
- "name": "godot_arvr_add_controller",
+ "name": "godot_xr_add_controller",
"return_type": "godot_int",
"arguments": [
["char *", "p_device_name"],
@@ -5987,14 +5987,14 @@
]
},
{
- "name": "godot_arvr_remove_controller",
+ "name": "godot_xr_remove_controller",
"return_type": "void",
"arguments": [
["godot_int", "p_controller_id"]
]
},
{
- "name": "godot_arvr_set_controller_transform",
+ "name": "godot_xr_set_controller_transform",
"return_type": "void",
"arguments": [
["godot_int", "p_controller_id"],
@@ -6004,7 +6004,7 @@
]
},
{
- "name": "godot_arvr_set_controller_button",
+ "name": "godot_xr_set_controller_button",
"return_type": "void",
"arguments": [
["godot_int", "p_controller_id"],
@@ -6013,7 +6013,7 @@
]
},
{
- "name": "godot_arvr_set_controller_axis",
+ "name": "godot_xr_set_controller_axis",
"return_type": "void",
"arguments": [
["godot_int", "p_controller_id"],
@@ -6023,7 +6023,7 @@
]
},
{
- "name": "godot_arvr_get_controller_rumble",
+ "name": "godot_xr_get_controller_rumble",
"return_type": "godot_real",
"arguments": [
["godot_int", "p_controller_id"]
diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py
index 2d84f93d87..620935795f 100644
--- a/modules/gdnative/gdnative_builders.py
+++ b/modules/gdnative/gdnative_builders.py
@@ -19,7 +19,7 @@ def _build_gdnative_api_struct_header(api):
"",
"#include <gdnative/gdnative.h>",
"#include <android/godot_android.h>",
- "#include <arvr/godot_arvr.h>",
+ "#include <xr/godot_xr.h>",
"#include <nativescript/godot_nativescript.h>",
"#include <net/godot_net.h>",
"#include <pluginscript/godot_pluginscript.h>",
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index 1b131c8cf0..0fb5180103 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -54,7 +54,6 @@ typedef enum {
GODOT_PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
GODOT_PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease)
GODOT_PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
- GODOT_PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat
GODOT_PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
GODOT_PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
GODOT_PROPERTY_HINT_LAYERS_2D_RENDER,
@@ -96,8 +95,7 @@ typedef enum {
GODOT_PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
GODOT_PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
GODOT_PROPERTY_USAGE_CATEGORY = 256,
- GODOT_PROPERTY_USAGE_STORE_IF_NONZERO = 512, // FIXME: Obsolete: drop whenever we can break compat
- GODOT_PROPERTY_USAGE_STORE_IF_NONONE = 1024, // FIXME: Obsolete: drop whenever we can break compat
+ GODOT_PROPERTY_USAGE_SUBGROUP = 512,
GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
diff --git a/modules/gdnative/include/arvr/godot_arvr.h b/modules/gdnative/include/xr/godot_xr.h
index aaef31a855..22f7f021c4 100644
--- a/modules/gdnative/include/arvr/godot_arvr.h
+++ b/modules/gdnative/include/xr/godot_xr.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_arvr.h */
+/* godot_xr.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GODOT_NATIVEARVR_H
-#define GODOT_NATIVEARVR_H
+#ifndef GODOT_NATIVEXR_H
+#define GODOT_NATIVEXR_H
#include <gdnative/gdnative.h>
@@ -61,32 +61,31 @@ typedef struct {
void (*fill_projection_for_eye)(void *, godot_real *, godot_int, godot_real, godot_real, godot_real);
void (*commit_for_eye)(void *, godot_int, godot_rid *, godot_rect2 *);
void (*process)(void *);
- // only in 1.1 onwards
godot_int (*get_external_texture_for_eye)(void *, godot_int);
void (*notification)(void *, godot_int);
godot_int (*get_camera_feed_id)(void *);
-} godot_arvr_interface_gdnative;
+} godot_xr_interface_gdnative;
-void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface);
+void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_interface);
-// helper functions to access ARVRServer data
-godot_real GDAPI godot_arvr_get_worldscale();
-godot_transform GDAPI godot_arvr_get_reference_frame();
+// helper functions to access XRServer data
+godot_real GDAPI godot_xr_get_worldscale();
+godot_transform GDAPI godot_xr_get_reference_frame();
// helper functions for rendering
-void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect);
-godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target);
+void GDAPI godot_xr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect);
+godot_int GDAPI godot_xr_get_texid(godot_rid *p_render_target);
-// helper functions for updating ARVR controllers
-godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
-void GDAPI godot_arvr_remove_controller(godot_int p_controller_id);
-void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
-void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed);
-void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative);
-godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id);
+// helper functions for updating XR controllers
+godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
+void GDAPI godot_xr_remove_controller(godot_int p_controller_id);
+void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
+void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed);
+void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative);
+godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id);
#ifdef __cplusplus
}
#endif
-#endif /* !GODOT_NATIVEARVR_H */
+#endif /* !GODOT_NATIVEXR_H */
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index bf458c15ee..ed3ec44bf7 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -111,6 +111,13 @@ void NativeScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder)
#endif
+bool NativeScript::inherits_script(const Ref<Script> &p_script) const {
+#ifndef _MSC_VER
+#warning inheritance needs to be implemented in NativeScript
+#endif
+ return false;
+}
+
void NativeScript::set_class_name(String p_class_name) {
class_name = p_class_name;
}
@@ -1931,7 +1938,7 @@ void NativeReloadNode::_notification(int p_what) {
#endif
}
-RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error);
}
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index 75bbb42664..7e7598e06c 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -133,6 +133,8 @@ protected:
public:
inline NativeScriptDesc *get_script_desc() const;
+ bool inherits_script(const Ref<Script> &p_script) const;
+
void set_class_name(String p_class_name);
String get_class_name() const;
@@ -406,7 +408,7 @@ public:
class ResourceFormatLoaderNativeScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp
index 3fb22b3f8d..64582cc517 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp
@@ -39,7 +39,7 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL
_language = language;
}
-RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h
index c929be53bd..e47754490a 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.h
+++ b/modules/gdnative/pluginscript/pluginscript_loader.h
@@ -44,7 +44,7 @@ class ResourceFormatLoaderPluginScript : public ResourceFormatLoader {
public:
ResourceFormatLoaderPluginScript(PluginScriptLanguage *language);
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
index a4c84dc0ca..6b303c8716 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -140,6 +140,13 @@ bool PluginScript::can_instance() const {
return can;
}
+bool PluginScript::inherits_script(const Ref<Script> &p_script) const {
+#ifndef _MSC_VER
+#warning inheritance needs to be implemented in PluginScript
+#endif
+ return false;
+}
+
Ref<Script> PluginScript::get_base_script() const {
if (_ref_base_parent.is_valid()) {
return Ref<PluginScript>(_ref_base_parent);
diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h
index 5c93ae38f5..70b9ca980b 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.h
+++ b/modules/gdnative/pluginscript/pluginscript_script.h
@@ -72,6 +72,8 @@ private:
protected:
static void _bind_methods();
+ bool inherits_script(const Ref<Script> &p_script) const;
+
PluginScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error);
Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 397a020689..67a286ee2e 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -34,11 +34,11 @@
#include "gdnative.h"
-#include "arvr/register_types.h"
#include "nativescript/register_types.h"
#include "net/register_types.h"
#include "pluginscript/register_types.h"
#include "videodecoder/register_types.h"
+#include "xr/register_types.h"
#include "core/engine.h"
#include "core/io/resource_loader.h"
@@ -240,7 +240,7 @@ void register_gdnative_types() {
GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall);
register_net_types();
- register_arvr_types();
+ register_xr_types();
register_nativescript_types();
register_pluginscript_types();
register_videodecoder_types();
@@ -305,7 +305,7 @@ void unregister_gdnative_types() {
unregister_videodecoder_types();
unregister_pluginscript_types();
unregister_nativescript_types();
- unregister_arvr_types();
+ unregister_xr_types();
unregister_net_types();
memdelete(GDNativeCallRegistry::singleton);
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
index fa9f6be5c1..f7d87595af 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
@@ -373,7 +373,7 @@ void VideoStreamGDNative::set_audio_track(int p_track) {
/* --- NOTE ResourceFormatLoaderVideoStreamGDNative starts here. ----- */
-RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h
index fbc0d4016f..092e10a0f5 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.h
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.h
@@ -199,7 +199,7 @@ public:
class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/arvr/SCsub b/modules/gdnative/xr/SCsub
index 0b2db3b504..0b2db3b504 100644
--- a/modules/gdnative/arvr/SCsub
+++ b/modules/gdnative/xr/SCsub
diff --git a/modules/gdnative/arvr/config.py b/modules/gdnative/xr/config.py
index d22f9454ed..d22f9454ed 100644
--- a/modules/gdnative/arvr/config.py
+++ b/modules/gdnative/xr/config.py
diff --git a/modules/gdnative/arvr/register_types.cpp b/modules/gdnative/xr/register_types.cpp
index 0f6e2bca1a..da3a7dc4b8 100644
--- a/modules/gdnative/arvr/register_types.cpp
+++ b/modules/gdnative/xr/register_types.cpp
@@ -29,11 +29,12 @@
/*************************************************************************/
#include "register_types.h"
-#include "arvr_interface_gdnative.h"
+#include "xr_interface_gdnative.h"
-void register_arvr_types() {
- ClassDB::register_class<ARVRInterfaceGDNative>();
+void register_xr_types() {
+ ClassDB::register_class<XRInterfaceGDNative>();
+ ClassDB::add_compatibility_class("ARVRInterfaceGDNative", "XRInterfaceGDNative");
}
-void unregister_arvr_types() {
+void unregister_xr_types() {
}
diff --git a/modules/gdnative/arvr/register_types.h b/modules/gdnative/xr/register_types.h
index b0de6f7c14..2501d28651 100644
--- a/modules/gdnative/arvr/register_types.h
+++ b/modules/gdnative/xr/register_types.h
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARVR_REGISTER_TYPES_H
-#define ARVR_REGISTER_TYPES_H
+#ifndef XR_REGISTER_TYPES_H
+#define XR_REGISTER_TYPES_H
-void register_arvr_types();
-void unregister_arvr_types();
+void register_xr_types();
+void unregister_xr_types();
-#endif // ARVR_REGISTER_TYPES_H
+#endif // XR_REGISTER_TYPES_H
diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp
index f14691027a..0451945139 100644
--- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp
+++ b/modules/gdnative/xr/xr_interface_gdnative.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_interface_gdnative.cpp */
+/* xr_interface_gdnative.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,17 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "arvr_interface_gdnative.h"
+#include "xr_interface_gdnative.h"
#include "core/input/input_filter.h"
-#include "servers/arvr/arvr_positional_tracker.h"
#include "servers/rendering/rendering_server_globals.h"
+#include "servers/xr/xr_positional_tracker.h"
-void ARVRInterfaceGDNative::_bind_methods() {
+void XRInterfaceGDNative::_bind_methods() {
ADD_PROPERTY_DEFAULT("interface_is_initialized", false);
ADD_PROPERTY_DEFAULT("ar_is_anchor_detection_enabled", false);
}
-ARVRInterfaceGDNative::ARVRInterfaceGDNative() {
+XRInterfaceGDNative::XRInterfaceGDNative() {
print_verbose("Construct gdnative interface\n");
// we won't have our data pointer until our library gets set
@@ -47,7 +47,7 @@ ARVRInterfaceGDNative::ARVRInterfaceGDNative() {
interface = nullptr;
}
-ARVRInterfaceGDNative::~ARVRInterfaceGDNative() {
+XRInterfaceGDNative::~XRInterfaceGDNative() {
print_verbose("Destruct gdnative interface\n");
if (interface != nullptr && is_initialized()) {
@@ -58,7 +58,7 @@ ARVRInterfaceGDNative::~ARVRInterfaceGDNative() {
cleanup();
}
-void ARVRInterfaceGDNative::cleanup() {
+void XRInterfaceGDNative::cleanup() {
if (interface != nullptr) {
interface->destructor(data);
data = nullptr;
@@ -66,7 +66,7 @@ void ARVRInterfaceGDNative::cleanup() {
}
}
-void ARVRInterfaceGDNative::set_interface(const godot_arvr_interface_gdnative *p_interface) {
+void XRInterfaceGDNative::set_interface(const godot_xr_interface_gdnative *p_interface) {
// this should only be called once, just being paranoid..
if (interface) {
cleanup();
@@ -79,7 +79,7 @@ void ARVRInterfaceGDNative::set_interface(const godot_arvr_interface_gdnative *p
data = interface->constructor((godot_object *)this);
}
-StringName ARVRInterfaceGDNative::get_name() const {
+StringName XRInterfaceGDNative::get_name() const {
ERR_FAIL_COND_V(interface == nullptr, StringName());
@@ -92,7 +92,7 @@ StringName ARVRInterfaceGDNative::get_name() const {
return name;
}
-int ARVRInterfaceGDNative::get_capabilities() const {
+int XRInterfaceGDNative::get_capabilities() const {
int capabilities;
ERR_FAIL_COND_V(interface == nullptr, 0); // 0 = None
@@ -102,32 +102,28 @@ int ARVRInterfaceGDNative::get_capabilities() const {
return capabilities;
}
-bool ARVRInterfaceGDNative::get_anchor_detection_is_enabled() const {
+bool XRInterfaceGDNative::get_anchor_detection_is_enabled() const {
ERR_FAIL_COND_V(interface == nullptr, false);
return interface->get_anchor_detection_is_enabled(data);
}
-void ARVRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) {
+void XRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) {
ERR_FAIL_COND(interface == nullptr);
interface->set_anchor_detection_is_enabled(data, p_enable);
}
-int ARVRInterfaceGDNative::get_camera_feed_id() {
+int XRInterfaceGDNative::get_camera_feed_id() {
ERR_FAIL_COND_V(interface == nullptr, 0);
- if ((interface->version.major > 1) || ((interface->version.major) == 1 && (interface->version.minor >= 1))) {
- return (unsigned int)interface->get_camera_feed_id(data);
- } else {
- return 0;
- }
+ return (unsigned int)interface->get_camera_feed_id(data);
}
-bool ARVRInterfaceGDNative::is_stereo() {
+bool XRInterfaceGDNative::is_stereo() {
bool stereo;
ERR_FAIL_COND_V(interface == nullptr, false);
@@ -137,14 +133,14 @@ bool ARVRInterfaceGDNative::is_stereo() {
return stereo;
}
-bool ARVRInterfaceGDNative::is_initialized() const {
+bool XRInterfaceGDNative::is_initialized() const {
ERR_FAIL_COND_V(interface == nullptr, false);
return interface->is_initialized(data);
}
-bool ARVRInterfaceGDNative::initialize() {
+bool XRInterfaceGDNative::initialize() {
ERR_FAIL_COND_V(interface == nullptr, false);
bool initialized = interface->initialize(data);
@@ -152,28 +148,28 @@ bool ARVRInterfaceGDNative::initialize() {
if (initialized) {
// if we successfully initialize our interface and we don't have a primary interface yet, this becomes our primary interface
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if ((arvr_server != nullptr) && (arvr_server->get_primary_interface() == nullptr)) {
- arvr_server->set_primary_interface(this);
+ XRServer *xr_server = XRServer::get_singleton();
+ if ((xr_server != nullptr) && (xr_server->get_primary_interface() == nullptr)) {
+ xr_server->set_primary_interface(this);
};
};
return initialized;
}
-void ARVRInterfaceGDNative::uninitialize() {
+void XRInterfaceGDNative::uninitialize() {
ERR_FAIL_COND(interface == nullptr);
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != nullptr) {
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != nullptr) {
// Whatever happens, make sure this is no longer our primary interface
- arvr_server->clear_primary_interface_if(this);
+ xr_server->clear_primary_interface_if(this);
}
interface->uninitialize(data);
}
-Size2 ARVRInterfaceGDNative::get_render_targetsize() {
+Size2 XRInterfaceGDNative::get_render_targetsize() {
ERR_FAIL_COND_V(interface == nullptr, Size2());
@@ -183,7 +179,7 @@ Size2 ARVRInterfaceGDNative::get_render_targetsize() {
return *vec;
}
-Transform ARVRInterfaceGDNative::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
+Transform XRInterfaceGDNative::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) {
Transform *ret;
ERR_FAIL_COND_V(interface == nullptr, Transform());
@@ -195,7 +191,7 @@ Transform ARVRInterfaceGDNative::get_transform_for_eye(ARVRInterface::Eyes p_eye
return *ret;
}
-CameraMatrix ARVRInterfaceGDNative::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+CameraMatrix XRInterfaceGDNative::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
CameraMatrix cm;
ERR_FAIL_COND_V(interface == nullptr, CameraMatrix());
@@ -205,37 +201,30 @@ CameraMatrix ARVRInterfaceGDNative::get_projection_for_eye(ARVRInterface::Eyes p
return cm;
}
-unsigned int ARVRInterfaceGDNative::get_external_texture_for_eye(ARVRInterface::Eyes p_eye) {
+unsigned int XRInterfaceGDNative::get_external_texture_for_eye(XRInterface::Eyes p_eye) {
ERR_FAIL_COND_V(interface == nullptr, 0);
- if ((interface->version.major > 1) || ((interface->version.major) == 1 && (interface->version.minor >= 1))) {
- return (unsigned int)interface->get_external_texture_for_eye(data, (godot_int)p_eye);
- } else {
- return 0;
- }
+ return (unsigned int)interface->get_external_texture_for_eye(data, (godot_int)p_eye);
}
-void ARVRInterfaceGDNative::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+void XRInterfaceGDNative::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
ERR_FAIL_COND(interface == nullptr);
interface->commit_for_eye(data, (godot_int)p_eye, (godot_rid *)&p_render_target, (godot_rect2 *)&p_screen_rect);
}
-void ARVRInterfaceGDNative::process() {
+void XRInterfaceGDNative::process() {
ERR_FAIL_COND(interface == nullptr);
interface->process(data);
}
-void ARVRInterfaceGDNative::notification(int p_what) {
+void XRInterfaceGDNative::notification(int p_what) {
ERR_FAIL_COND(interface == nullptr);
- // this is only available in interfaces that implement 1.1 or later
- if ((interface->version.major > 1) || ((interface->version.major == 1) && (interface->version.minor > 0))) {
- interface->notification(data, p_what);
- }
+ interface->notification(data, p_what);
}
/////////////////////////////////////////////////////////////////////////////////////
@@ -243,30 +232,30 @@ void ARVRInterfaceGDNative::notification(int p_what) {
extern "C" {
-void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface) {
- // If our major version is 0 or bigger then 10, we're likely looking at our constructor pointer from an older plugin
- ERR_FAIL_COND_MSG((p_interface->version.major == 0) || (p_interface->version.major > 10), "GDNative ARVR interfaces build for Godot 3.0 are not supported.");
+void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_interface) {
+ // Must be on a version 4 plugin
+ ERR_FAIL_COND_MSG(p_interface->version.major < 4, "GDNative XR interfaces build for Godot 3.x are not supported.");
- Ref<ARVRInterfaceGDNative> new_interface;
+ Ref<XRInterfaceGDNative> new_interface;
new_interface.instance();
- new_interface->set_interface((const godot_arvr_interface_gdnative *)p_interface);
- ARVRServer::get_singleton()->add_interface(new_interface);
+ new_interface->set_interface((const godot_xr_interface_gdnative *)p_interface);
+ XRServer::get_singleton()->add_interface(new_interface);
}
-godot_real GDAPI godot_arvr_get_worldscale() {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 1.0);
+godot_real GDAPI godot_xr_get_worldscale() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 1.0);
- return arvr_server->get_world_scale();
+ return xr_server->get_world_scale();
}
-godot_transform GDAPI godot_arvr_get_reference_frame() {
+godot_transform GDAPI godot_xr_get_reference_frame() {
godot_transform reference_frame;
Transform *reference_frame_ptr = (Transform *)&reference_frame;
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != nullptr) {
- *reference_frame_ptr = arvr_server->get_reference_frame();
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != nullptr) {
+ *reference_frame_ptr = xr_server->get_reference_frame();
} else {
godot_transform_new_identity(&reference_frame);
}
@@ -274,17 +263,17 @@ godot_transform GDAPI godot_arvr_get_reference_frame() {
return reference_frame;
}
-void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) {
+void GDAPI godot_xr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) {
// blits out our texture as is, handy for preview display of one of the eyes that is already rendered with lens distortion on an external HMD
- ARVRInterface::Eyes eye = (ARVRInterface::Eyes)p_eye;
+ XRInterface::Eyes eye = (XRInterface::Eyes)p_eye;
#if 0
RID *render_target = (RID *)p_render_target;
#endif
Rect2 screen_rect = *(Rect2 *)p_rect;
- if (eye == ARVRInterface::EYE_LEFT) {
+ if (eye == XRInterface::EYE_LEFT) {
screen_rect.size.x /= 2.0;
- } else if (p_eye == ARVRInterface::EYE_RIGHT) {
+ } else if (p_eye == XRInterface::EYE_RIGHT) {
screen_rect.size.x /= 2.0;
screen_rect.position.x += screen_rect.size.x;
}
@@ -296,7 +285,7 @@ void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_re
#endif
}
-godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) {
+godot_int GDAPI godot_xr_get_texid(godot_rid *p_render_target) {
// In order to send off our textures to display on our hardware we need the opengl texture ID instead of the render target RID
// This is a handy function to expose that.
#if 0
@@ -313,20 +302,20 @@ godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) {
return texid;
}
-godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 0);
+godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 0);
InputFilter *input = InputFilter::get_singleton();
ERR_FAIL_NULL_V(input, 0);
- ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker);
+ XRPositionalTracker *new_tracker = memnew(XRPositionalTracker);
new_tracker->set_name(p_device_name);
- new_tracker->set_type(ARVRServer::TRACKER_CONTROLLER);
+ new_tracker->set_type(XRServer::TRACKER_CONTROLLER);
if (p_hand == 1) {
- new_tracker->set_hand(ARVRPositionalTracker::TRACKER_LEFT_HAND);
+ new_tracker->set_hand(XRPositionalTracker::TRACKER_LEFT_HAND);
} else if (p_hand == 2) {
- new_tracker->set_hand(ARVRPositionalTracker::TRACKER_RIGHT_HAND);
+ new_tracker->set_hand(XRPositionalTracker::TRACKER_RIGHT_HAND);
}
// also register as joystick...
@@ -346,20 +335,20 @@ godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand,
}
// add our tracker to our server and remember its pointer
- arvr_server->add_tracker(new_tracker);
+ xr_server->add_tracker(new_tracker);
// note, this ID is only unique within controllers!
return new_tracker->get_tracker_id();
}
-void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
InputFilter *input = InputFilter::get_singleton();
ERR_FAIL_NULL(input);
- ARVRPositionalTracker *remove_tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ XRPositionalTracker *remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (remove_tracker != nullptr) {
// unset our joystick if applicable
int joyid = remove_tracker->get_joy_id();
@@ -369,16 +358,16 @@ void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) {
}
// remove our tracker from our server
- arvr_server->remove_tracker(remove_tracker);
+ xr_server->remove_tracker(remove_tracker);
memdelete(remove_tracker);
}
}
-void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) {
Transform *transform = (Transform *)p_transform;
if (p_tracks_orientation) {
@@ -390,14 +379,14 @@ void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_
}
}
-void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
InputFilter *input = InputFilter::get_singleton();
ERR_FAIL_NULL(input);
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) {
int joyid = tracker->get_joy_id();
if (joyid != -1) {
@@ -406,14 +395,14 @@ void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int
}
}
-void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
InputFilter *input = InputFilter::get_singleton();
ERR_FAIL_NULL(input);
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) {
int joyid = tracker->get_joy_id();
if (joyid != -1) {
@@ -425,11 +414,11 @@ void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p
}
}
-godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 0.0);
+godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 0.0);
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) {
return tracker->get_rumble();
}
diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.h b/modules/gdnative/xr/xr_interface_gdnative.h
index e38eb435c6..64f1282a7e 100644
--- a/modules/gdnative/arvr/arvr_interface_gdnative.h
+++ b/modules/gdnative/xr/xr_interface_gdnative.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_interface_gdnative.h */
+/* xr_interface_gdnative.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARVR_INTERFACE_GDNATIVE_H
-#define ARVR_INTERFACE_GDNATIVE_H
+#ifndef XR_INTERFACE_GDNATIVE_H
+#define XR_INTERFACE_GDNATIVE_H
#include "modules/gdnative/gdnative.h"
-#include "servers/arvr/arvr_interface.h"
+#include "servers/xr/xr_interface.h"
/**
@authors Hinsbart & Karroffel & Mux213
@@ -40,23 +40,23 @@
This subclass of our AR/VR interface forms a bridge to GDNative.
*/
-class ARVRInterfaceGDNative : public ARVRInterface {
- GDCLASS(ARVRInterfaceGDNative, ARVRInterface);
+class XRInterfaceGDNative : public XRInterface {
+ GDCLASS(XRInterfaceGDNative, XRInterface);
void cleanup();
protected:
- const godot_arvr_interface_gdnative *interface;
+ const godot_xr_interface_gdnative *interface;
void *data;
static void _bind_methods();
public:
/** general interface information **/
- ARVRInterfaceGDNative();
- ~ARVRInterfaceGDNative();
+ XRInterfaceGDNative();
+ ~XRInterfaceGDNative();
- void set_interface(const godot_arvr_interface_gdnative *p_interface);
+ void set_interface(const godot_xr_interface_gdnative *p_interface);
virtual StringName get_name() const;
virtual int get_capabilities() const;
@@ -73,19 +73,19 @@ public:
/** rendering and internal **/
virtual Size2 get_render_targetsize();
virtual bool is_stereo();
- virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
+ virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform);
// we expose a Vector<float> version of this function to GDNative
- Vector<float> _get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+ Vector<float> _get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
- // and a CameraMatrix version to ARVRServer
- virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+ // and a CameraMatrix version to XRServer
+ virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
- virtual unsigned int get_external_texture_for_eye(ARVRInterface::Eyes p_eye);
- virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
+ virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye);
+ virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
virtual void process();
virtual void notification(int p_what);
};
-#endif // ARVR_INTERFACE_GDNATIVE_H
+#endif // XR_INTERFACE_GDNATIVE_H
diff --git a/modules/gdscript/config.py b/modules/gdscript/config.py
index 185a10bcb2..6fc227e7f5 100644
--- a/modules/gdscript/config.py
+++ b/modules/gdscript/config.py
@@ -11,7 +11,6 @@ def get_doc_classes():
"@GDScript",
"GDScript",
"GDScriptFunctionState",
- "GDScriptNativeClass",
]
diff --git a/modules/gdscript/doc_classes/GDScriptNativeClass.xml b/modules/gdscript/doc_classes/GDScriptNativeClass.xml
deleted file mode 100644
index 0a8982de8e..0000000000
--- a/modules/gdscript/doc_classes/GDScriptNativeClass.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GDScriptNativeClass" inherits="Reference" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- <method name="new">
- <return type="Variant">
- </return>
- <description>
- </description>
- </method>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 9a4fa5cc86..98366f7957 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -895,6 +895,24 @@ Ref<GDScript> GDScript::get_base() const {
return base;
}
+bool GDScript::inherits_script(const Ref<Script> &p_script) const {
+ Ref<GDScript> gd = p_script;
+ if (gd.is_null()) {
+ return false;
+ }
+
+ const GDScript *s = this;
+
+ while (s) {
+ if (s == p_script.ptr()) {
+ return true;
+ }
+ s = s->_base;
+ }
+
+ return false;
+}
+
bool GDScript::has_script_signal(const StringName &p_signal) const {
if (_signals.has(p_signal))
return true;
@@ -2257,7 +2275,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 2c5876372b..5fdc25669f 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -151,6 +151,8 @@ protected:
public:
virtual bool is_valid() const { return valid; }
+ bool inherits_script(const Ref<Script> &p_script) const;
+
const Map<StringName, Ref<GDScript>> &get_subclasses() const { return subclasses; }
const Map<StringName, Variant> &get_constants() const { return constants; }
const Set<StringName> &get_members() const { return members; }
@@ -545,7 +547,7 @@ public:
class ResourceFormatLoaderGDScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 1e3cbd661e..221cce205a 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -2057,7 +2057,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
List<PropertyInfo> pinfo;
ClassDB::get_property_list(type, &pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
- if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) {
+ if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)) {
continue;
}
if (E->get().name.find("/") != -1) {
@@ -2098,7 +2098,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
if (!p_only_functions) {
List<PropertyInfo> members;
- p_base.value.get_property_list(&members);
+ tmp.get_property_list(&members);
for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
if (String(E->get().name).find("/") == -1) {
@@ -2236,6 +2236,8 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
+#define IS_METHOD_SIGNAL(m_method) (m_method == "connect" || m_method == "disconnect" || m_method == "is_connected" || m_method == "emit_signal")
+
while (base_type.has_type) {
switch (base_type.kind) {
case GDScriptParser::DataType::CLASS: {
@@ -2252,7 +2254,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
}
}
- if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) {
+ if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
for (int i = 0; i < base_type.class_type->_signals.size(); i++) {
ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL);
option.insert_text = quote_style + option.display + quote_style;
@@ -2265,7 +2267,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
case GDScriptParser::DataType::GDSCRIPT: {
Ref<GDScript> gds = base_type.script_type;
if (gds.is_valid()) {
- if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) {
+ if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
List<MethodInfo> signals;
gds->get_script_signal_list(&signals);
for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
@@ -2327,7 +2329,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
}
}
- if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) {
+ if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
List<MethodInfo> signals;
ClassDB::get_signal_list(class_name, &signals);
for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
@@ -2336,6 +2338,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
r_result.insert(option.display, option);
}
}
+#undef IS_METHOD_SIGNAL
if (ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node") && p_argidx == 0) {
// Get autoloads
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index ca4d6f6de9..4e0891921e 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -337,15 +337,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (!argument_types[i].is_type(*p_args[i], true)) {
- if (argument_types[i].is_type(Variant(), true)) {
- memnew_placement(&stack[i], Variant);
- continue;
- } else {
- r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_err.argument = i;
- r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
- return Variant();
- }
+ r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_err.argument = i;
+ r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
+ return Variant();
}
if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err);
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index a99d4b96f7..a83416375c 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -827,6 +827,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
//check from singletons
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = GDScriptLanguage::get_singleton()->get_named_globals_map()[identifier];
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -837,6 +838,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (scr.is_valid() && scr->is_valid()) {
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = scr;
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -852,6 +854,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (parent_constants.has(identifier)) {
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = parent_constants[identifier];
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -2386,6 +2389,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// a bind always matches
ConstantNode *true_value = alloc_node<ConstantNode>();
true_value->value = Variant(true);
+ true_value->datatype = _type_from_variant(true_value->value);
p_resulting_node = true_value;
} break;
case PatternNode::PT_ARRAY: {
@@ -2432,6 +2436,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// size
ConstantNode *length = alloc_node<ConstantNode>();
length->value = Variant(open_ended ? p_pattern->array.size() - 1 : p_pattern->array.size());
+ length->datatype = _type_from_variant(length->value);
OperatorNode *call = alloc_node<OperatorNode>();
call->op = OperatorNode::OP_CALL;
@@ -2465,6 +2470,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
ConstantNode *index = alloc_node<ConstantNode>();
index->value = Variant(i);
+ index->datatype = _type_from_variant(index->value);
OperatorNode *indexed_value = alloc_node<OperatorNode>();
indexed_value->op = OperatorNode::OP_INDEX;
@@ -2525,6 +2531,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// size
ConstantNode *length = alloc_node<ConstantNode>();
length->value = Variant(open_ended ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size());
+ length->datatype = _type_from_variant(length->value);
OperatorNode *call = alloc_node<OperatorNode>();
call->op = OperatorNode::OP_CALL;
@@ -2601,6 +2608,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// simply generate a `true`
ConstantNode *true_value = alloc_node<ConstantNode>();
true_value->value = Variant(true);
+ true_value->datatype = _type_from_variant(true_value->value);
p_resulting_node = true_value;
} break;
default: {
@@ -2683,6 +2691,7 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
LocalVarNode *local_var = branch->body->variables[e->key()];
local_var->assign = e->value();
local_var->set_datatype(local_var->assign->get_datatype());
+ local_var->assignments++;
IdentifierNode *id2 = alloc_node<IdentifierNode>();
id2->name = local_var->name;
@@ -3319,6 +3328,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
} else {
ConstantNode *message_node = alloc_node<ConstantNode>();
message_node->value = String();
+ message_node->datatype = _type_from_variant(message_node->value);
an->message = message_node;
}
@@ -3673,6 +3683,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("A constant named \"" + String(name) + "\" already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ").");
return;
}
+ for (int i = 0; i < outer_class->variables.size(); i++) {
+ if (outer_class->variables[i].identifier == name) {
+ _set_error("A variable named \"" + String(name) + "\" already exists in the outer class scope (at line " + itos(outer_class->variables[i].line) + ").");
+ return;
+ }
+ }
outer_class = outer_class->owner;
}
@@ -6229,11 +6245,13 @@ GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType
ConstantNode *c = alloc_node<ConstantNode>();
Callable::CallError err;
c->value = Variant::construct(p_type.builtin_type, nullptr, 0, err);
+ c->datatype = _type_from_variant(c->value);
result = c;
}
} else {
ConstantNode *c = alloc_node<ConstantNode>();
c->value = Variant();
+ c->datatype = _type_from_variant(c->value);
result = c;
}
@@ -6562,6 +6580,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true);
#ifdef DEBUG_ENABLED
if (!node_type.has_type) {
+ _mark_line_as_unsafe(op->line);
_add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string());
}
#endif // DEBUG_ENABLED
@@ -7364,6 +7383,8 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
}
}
+#define IS_USAGE_MEMBER(m_usage) (!(m_usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)))
+
// Check other script types
while (scr.is_valid()) {
Map<StringName, Variant> constants;
@@ -7376,7 +7397,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
List<PropertyInfo> properties;
scr->get_script_property_list(&properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name == p_member) {
+ if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
r_member_type = _type_from_property(E->get());
return true;
}
@@ -7418,7 +7439,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
List<PropertyInfo> properties;
ClassDB::get_property_list(native, &properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name == p_member) {
+ if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
// Check if a getter exists
StringName getter_name = ClassDB::get_property_getter(native, p_member);
if (getter_name != StringName()) {
@@ -7458,7 +7479,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
List<PropertyInfo> properties;
ClassDB::get_property_list(native, &properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name == p_member) {
+ if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
// Check if a getter exists
StringName getter_name = ClassDB::get_property_getter(native, p_member);
if (getter_name != StringName()) {
@@ -7480,6 +7501,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
}
}
}
+#undef IS_USAGE_MEMBER
return false;
}
@@ -8107,6 +8129,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
ConstantNode *tgt_type = alloc_node<ConstantNode>();
tgt_type->line = lv->line;
tgt_type->value = (int)lv->datatype.builtin_type;
+ tgt_type->datatype = _type_from_variant(tgt_type->value);
OperatorNode *convert_call = alloc_node<OperatorNode>();
convert_call->line = lv->line;
@@ -8242,6 +8265,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
ConstantNode *tgt_type = alloc_node<ConstantNode>();
tgt_type->line = op->line;
tgt_type->value = (int)lh_type.builtin_type;
+ tgt_type->datatype = _type_from_variant(tgt_type->value);
OperatorNode *convert_call = alloc_node<OperatorNode>();
convert_call->line = op->line;
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 1b432ae8c1..180ec3c77e 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -32,6 +32,7 @@
#define GDSCRIPT_TOKENIZER_H
#include "core/pair.h"
+#include "core/set.h"
#include "core/string_name.h"
#include "core/ustring.h"
#include "core/variant.h"
diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml
index 7552abe61d..120535bd41 100644
--- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml
+++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="MobileVRInterface" inherits="ARVRInterface" version="4.0">
+<class name="MobileVRInterface" inherits="XRInterface" version="4.0">
<brief_description>
Generic mobile VR implementation.
</brief_description>
@@ -8,9 +8,9 @@
Note that even though there is no positional tracking, the camera will assume the headset is at a height of 1.85 meters. You can change this by setting [member eye_height].
You can initialise this interface as follows:
[codeblock]
- var interface = ARVRServer.find_interface("Native mobile")
+ var interface = XRServer.find_interface("Native mobile")
if interface and interface.initialize():
- get_viewport().arvr = true
+ get_viewport().xr = true
[/codeblock]
</description>
<tutorials>
@@ -25,7 +25,7 @@
The width of the display in centimeters.
</member>
<member name="eye_height" type="float" setter="set_eye_height" getter="get_eye_height" default="1.85">
- The height at which the camera is placed in relation to the ground (i.e. [ARVROrigin] node).
+ The height at which the camera is placed in relation to the ground (i.e. [XROrigin3D] node).
</member>
<member name="iod" type="float" setter="set_iod" getter="get_iod" default="6.0">
The interocular distance, also known as the interpupillary distance. The distance between the pupils of the left and right eye.
diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp
index 6b5a70435d..2f0a15f20b 100644
--- a/modules/mobile_vr/mobile_vr_interface.cpp
+++ b/modules/mobile_vr/mobile_vr_interface.cpp
@@ -39,7 +39,7 @@ StringName MobileVRInterface::get_name() const {
};
int MobileVRInterface::get_capabilities() const {
- return ARVRInterface::ARVR_STEREO;
+ return XRInterface::XR_STEREO;
};
Vector3 MobileVRInterface::scale_magneto(const Vector3 &p_magnetometer) {
@@ -165,7 +165,7 @@ void MobileVRInterface::set_position_from_sensors() {
rotate.rotate(orientation.get_axis(2), gyro.z * delta_time);
orientation = rotate * orientation;
- tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
+ tracking_state = XRInterface::XR_NORMAL_TRACKING;
};
///@TODO improve this, the magnetometer is very fidgity sometimes flipping the axis for no apparent reason (probably a bug on my part)
@@ -177,7 +177,7 @@ void MobileVRInterface::set_position_from_sensors() {
transform_quat = transform_quat.slerp(acc_mag_quat, 0.1);
orientation = Basis(transform_quat);
- tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
+ tracking_state = XRInterface::XR_NORMAL_TRACKING;
} else if (has_grav) {
// use gravity vector to make sure down is down...
// transform gravity into our world space
@@ -297,8 +297,8 @@ bool MobileVRInterface::is_initialized() const {
};
bool MobileVRInterface::initialize() {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, false);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, false);
if (!initialized) {
// reset our sensor data and orientation
@@ -314,7 +314,7 @@ bool MobileVRInterface::initialize() {
orientation = Basis();
// make this our primary interface
- arvr_server->set_primary_interface(this);
+ xr_server->set_primary_interface(this);
last_ticks = OS::get_singleton()->get_ticks_usec();
@@ -326,10 +326,10 @@ bool MobileVRInterface::initialize() {
void MobileVRInterface::uninitialize() {
if (initialized) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != nullptr) {
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != nullptr) {
// no longer our primary interface
- arvr_server->clear_primary_interface_if(this);
+ xr_server->clear_primary_interface_if(this);
}
initialized = false;
@@ -348,22 +348,22 @@ Size2 MobileVRInterface::get_render_targetsize() {
return target_size;
};
-Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
+Transform MobileVRInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) {
_THREAD_SAFE_METHOD_
Transform transform_for_eye;
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, transform_for_eye);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, transform_for_eye);
if (initialized) {
- float world_scale = arvr_server->get_world_scale();
+ float world_scale = xr_server->get_world_scale();
// we don't need to check for the existence of our HMD, doesn't effect our values...
// note * 0.01 to convert cm to m and * 0.5 as we're moving half in each direction...
- if (p_eye == ARVRInterface::EYE_LEFT) {
+ if (p_eye == XRInterface::EYE_LEFT) {
transform_for_eye.origin.x = -(intraocular_dist * 0.01 * 0.5 * world_scale);
- } else if (p_eye == ARVRInterface::EYE_RIGHT) {
+ } else if (p_eye == XRInterface::EYE_RIGHT) {
transform_for_eye.origin.x = intraocular_dist * 0.01 * 0.5 * world_scale;
} else {
// for mono we don't reposition, we want our center position.
@@ -374,7 +374,7 @@ Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, co
hmd_transform.basis = orientation;
hmd_transform.origin = Vector3(0.0, eye_height * world_scale, 0.0);
- transform_for_eye = p_cam_transform * (arvr_server->get_reference_frame()) * hmd_transform * transform_for_eye;
+ transform_for_eye = p_cam_transform * (xr_server->get_reference_frame()) * hmd_transform * transform_for_eye;
} else {
// huh? well just return what we got....
transform_for_eye = p_cam_transform;
@@ -383,12 +383,12 @@ Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, co
return transform_for_eye;
};
-CameraMatrix MobileVRInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+CameraMatrix MobileVRInterface::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
_THREAD_SAFE_METHOD_
CameraMatrix eye;
- if (p_eye == ARVRInterface::EYE_MONO) {
+ if (p_eye == XRInterface::EYE_MONO) {
///@TODO for now hardcode some of this, what is really needed here is that this needs to be in sync with the real cameras properties
// which probably means implementing a specific class for iOS and Android. For now this is purely here as an example.
// Note also that if you use a normal viewport with AR/VR turned off you can still use the tracker output of this interface
@@ -396,13 +396,13 @@ CameraMatrix MobileVRInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye
// This will make more sense when we implement ARkit on iOS (probably a separate interface).
eye.set_perspective(60.0, p_aspect, p_z_near, p_z_far, false);
} else {
- eye.set_for_hmd(p_eye == ARVRInterface::EYE_LEFT ? 1 : 2, p_aspect, intraocular_dist, display_width, display_to_lens, oversample, p_z_near, p_z_far);
+ eye.set_for_hmd(p_eye == XRInterface::EYE_LEFT ? 1 : 2, p_aspect, intraocular_dist, display_width, display_to_lens, oversample, p_z_near, p_z_far);
};
return eye;
};
-void MobileVRInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+void MobileVRInterface::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
_THREAD_SAFE_METHOD_
// We must have a valid render target
@@ -417,9 +417,9 @@ void MobileVRInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_t
// we output half a screen
dest.size.x *= 0.5;
- if (p_eye == ARVRInterface::EYE_LEFT) {
+ if (p_eye == XRInterface::EYE_LEFT) {
eye_center.x = ((-intraocular_dist / 2.0) + (display_width / 4.0)) / (display_width / 2.0);
- } else if (p_eye == ARVRInterface::EYE_RIGHT) {
+ } else if (p_eye == XRInterface::EYE_RIGHT) {
dest.position.x = dest.size.x;
eye_center.x = ((intraocular_dist / 2.0) - (display_width / 4.0)) / (display_width / 2.0);
}
diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h
index c762c9b799..3a9ed1314a 100644
--- a/modules/mobile_vr/mobile_vr_interface.h
+++ b/modules/mobile_vr/mobile_vr_interface.h
@@ -31,8 +31,8 @@
#ifndef MOBILE_VR_INTERFACE_H
#define MOBILE_VR_INTERFACE_H
-#include "servers/arvr/arvr_interface.h"
-#include "servers/arvr/arvr_positional_tracker.h"
+#include "servers/xr/xr_interface.h"
+#include "servers/xr/xr_positional_tracker.h"
/**
@author Bastiaan Olij <mux213@gmail.com>
@@ -47,8 +47,8 @@
more advanced interfaces.
*/
-class MobileVRInterface : public ARVRInterface {
- GDCLASS(MobileVRInterface, ARVRInterface);
+class MobileVRInterface : public XRInterface {
+ GDCLASS(MobileVRInterface, XRInterface);
private:
bool initialized;
@@ -137,9 +137,9 @@ public:
virtual Size2 get_render_targetsize();
virtual bool is_stereo();
- virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
- virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
- virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
+ virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform);
+ virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+ virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
virtual void process();
virtual void notification(int p_what);
diff --git a/modules/mobile_vr/register_types.cpp b/modules/mobile_vr/register_types.cpp
index faf6c3b151..75638d47c4 100644
--- a/modules/mobile_vr/register_types.cpp
+++ b/modules/mobile_vr/register_types.cpp
@@ -37,7 +37,7 @@ void register_mobile_vr_types() {
Ref<MobileVRInterface> mobile_vr;
mobile_vr.instance();
- ARVRServer::get_singleton()->add_interface(mobile_vr);
+ XRServer::get_singleton()->add_interface(mobile_vr);
}
void unregister_mobile_vr_types() {
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 0b5d3c8dbc..f5911275c9 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -3536,6 +3536,18 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
}
}
+bool CSharpScript::inherits_script(const Ref<Script> &p_script) const {
+ Ref<CSharpScript> cs = p_script;
+ if (cs.is_null()) {
+ return false;
+ }
+
+#ifndef _MSC_VER
+#warning TODO: Implement CSharpScript::inherits_script and other relevant changes after GH-38063.
+#endif
+ return false;
+}
+
Ref<Script> CSharpScript::get_base_script() const {
// TODO search in metadata file once we have it, not important any way?
@@ -3673,7 +3685,7 @@ CSharpScript::~CSharpScript() {
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 29c33b50bb..05e2857538 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -194,6 +194,8 @@ public:
virtual bool is_tool() const { return tool; }
virtual bool is_valid() const { return valid; }
+ bool inherits_script(const Ref<Script> &p_script) const;
+
virtual Ref<Script> get_base_script() const;
virtual ScriptLanguage *get_language() const;
@@ -530,7 +532,7 @@ public:
class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs
new file mode 100644
index 0000000000..85760a3705
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs
@@ -0,0 +1,27 @@
+using System.IO;
+
+namespace GodotTools.Core
+{
+ public static class FileUtils
+ {
+ public static void SaveBackupCopy(string filePath)
+ {
+ string backupPathBase = filePath + ".old";
+ string backupPath = backupPathBase;
+
+ const int maxAttempts = 5;
+ int attempt = 1;
+
+ while (File.Exists(backupPath) && attempt <= maxAttempts)
+ {
+ backupPath = backupPathBase + "." + (attempt);
+ attempt++;
+ }
+
+ if (attempt > maxAttempts + 1)
+ return;
+
+ File.Copy(filePath, backupPath, overwrite: true);
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
index 2c35ef540a..c9ea7d3a2c 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
@@ -31,6 +31,7 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="FileUtils.cs" />
<Compile Include="ProcessExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StringExtensions.cs" />
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
index 9afd9adeb1..6f318aab4a 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
@@ -153,7 +153,12 @@ EndProject";
var result = regex.Replace(input,m => dict[m.Value]);
if (result != input)
+ {
+ // Save a copy of the solution before replacing it
+ FileUtils.SaveBackupCopy(slnPath);
+
File.WriteAllText(slnPath, result);
+ }
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
index 1776b46e6a..a875e1c14f 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
@@ -9,8 +9,28 @@ using Microsoft.Build.Construction;
namespace GodotTools.ProjectEditor
{
+ public sealed class MSBuildProject
+ {
+ public ProjectRootElement Root { get; }
+
+ public bool HasUnsavedChanges => Root.HasUnsavedChanges;
+
+ public void Save() => Root.Save();
+
+ public MSBuildProject(ProjectRootElement root)
+ {
+ Root = root;
+ }
+ }
+
public static class ProjectUtils
{
+ public static MSBuildProject Open(string path)
+ {
+ var root = ProjectRootElement.Open(path);
+ return root != null ? new MSBuildProject(root) : null;
+ }
+
public static void AddItemToProjectChecked(string projectPath, string itemType, string include)
{
var dir = Directory.GetParent(projectPath).FullName;
@@ -43,7 +63,6 @@ namespace GodotTools.ProjectEditor
public static void RemoveItemFromProjectChecked(string projectPath, string itemType, string include)
{
- var dir = Directory.GetParent(projectPath).FullName;
var root = ProjectRootElement.Open(projectPath);
Debug.Assert(root != null);
@@ -59,8 +78,6 @@ namespace GodotTools.ProjectEditor
var root = ProjectRootElement.Open(projectPath);
Debug.Assert(root != null);
- bool dirty = false;
-
var oldFolderNormalized = oldFolder.NormalizePath();
var newFolderNormalized = newFolder.NormalizePath();
string absOldFolderNormalized = Path.GetFullPath(oldFolderNormalized).NormalizePath();
@@ -71,10 +88,9 @@ namespace GodotTools.ProjectEditor
string absPathNormalized = Path.GetFullPath(item.Include).NormalizePath();
string absNewIncludeNormalized = absNewFolderNormalized + absPathNormalized.Substring(absOldFolderNormalized.Length);
item.Include = absNewIncludeNormalized.RelativeToPath(dir).Replace("/", "\\");
- dirty = true;
}
- if (dirty)
+ if (root.HasUnsavedChanges)
root.Save();
}
@@ -150,12 +166,9 @@ namespace GodotTools.ProjectEditor
}
/// Simple function to make sure the Api assembly references are configured correctly
- public static void FixApiHintPath(string projectPath)
+ public static void FixApiHintPath(MSBuildProject project)
{
- var root = ProjectRootElement.Open(projectPath);
- Debug.Assert(root != null);
-
- bool dirty = false;
+ var root = project.Root;
void AddPropertyIfNotPresent(string name, string condition, string value)
{
@@ -170,7 +183,6 @@ namespace GodotTools.ProjectEditor
}
root.AddProperty(name, value).Condition = " " + condition + " ";
- dirty = true;
}
AddPropertyIfNotPresent(name: "ApiConfiguration",
@@ -212,7 +224,6 @@ namespace GodotTools.ProjectEditor
}
referenceWithHintPath.AddMetadata("HintPath", hintPath);
- dirty = true;
return;
}
@@ -221,14 +232,12 @@ namespace GodotTools.ProjectEditor
{
// Found a Reference item without a HintPath
referenceWithoutHintPath.AddMetadata("HintPath", hintPath);
- dirty = true;
return;
}
}
// Found no Reference item at all. Add it.
root.AddItem("Reference", referenceName).Condition = " " + condition + " ";
- dirty = true;
}
const string coreProjectName = "GodotSharp";
@@ -242,17 +251,11 @@ namespace GodotTools.ProjectEditor
SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath);
SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath);
-
- if (dirty)
- root.Save();
}
- public static void MigrateFromOldConfigNames(string projectPath)
+ public static void MigrateFromOldConfigNames(MSBuildProject project)
{
- var root = ProjectRootElement.Open(projectPath);
- Debug.Assert(root != null);
-
- bool dirty = false;
+ var root = project.Root;
bool hasGodotProjectGeneratorVersion = false;
bool foundOldConfiguration = false;
@@ -267,7 +270,6 @@ namespace GodotTools.ProjectEditor
{
configItem.Value = "Debug";
foundOldConfiguration = true;
- dirty = true;
}
}
@@ -275,7 +277,6 @@ namespace GodotTools.ProjectEditor
{
root.PropertyGroups.First(g => g.Condition == string.Empty)?
.AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString());
- dirty = true;
}
if (!foundOldConfiguration)
@@ -299,33 +300,21 @@ namespace GodotTools.ProjectEditor
void MigrateConditions(string oldCondition, string newCondition)
{
foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition))
- {
propertyGroup.Condition = " " + newCondition + " ";
- dirty = true;
- }
foreach (var propertyGroup in root.PropertyGroups)
{
foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition))
- {
prop.Condition = " " + newCondition + " ";
- dirty = true;
- }
}
foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition))
- {
itemGroup.Condition = " " + newCondition + " ";
- dirty = true;
- }
foreach (var itemGroup in root.ItemGroups)
{
foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition))
- {
item.Condition = " " + newCondition + " ";
- dirty = true;
- }
}
}
@@ -340,10 +329,6 @@ namespace GodotTools.ProjectEditor
MigrateConfigurationConditions("Release", "ExportRelease");
MigrateConfigurationConditions("Tools", "Debug"); // Must be last
}
-
-
- if (dirty)
- root.Save();
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index d782d4e61b..2ceb4888a2 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -168,13 +168,13 @@ namespace GodotTools.Export
// Add dependency assemblies
- var dependencies = new Godot.Collections.Dictionary<string, string>();
+ var assemblies = new Godot.Collections.Dictionary<string, string>();
string projectDllName = GodotSharpEditor.ProjectAssemblyName;
string projectDllSrcDir = Path.Combine(GodotSharpDirs.ResTempAssembliesBaseDir, buildConfig);
string projectDllSrcPath = Path.Combine(projectDllSrcDir, $"{projectDllName}.dll");
- dependencies[projectDllName] = projectDllSrcPath;
+ assemblies[projectDllName] = projectDllSrcPath;
if (platform == OS.Platforms.Android)
{
@@ -184,15 +184,15 @@ namespace GodotTools.Export
if (!File.Exists(monoAndroidAssemblyPath))
throw new FileNotFoundException("Assembly not found: 'Mono.Android'", monoAndroidAssemblyPath);
- dependencies["Mono.Android"] = monoAndroidAssemblyPath;
+ assemblies["Mono.Android"] = monoAndroidAssemblyPath;
}
string bclDir = DeterminePlatformBclDir(platform);
- var initialDependencies = dependencies.Duplicate();
- internal_GetExportedAssemblyDependencies(initialDependencies, buildConfig, bclDir, dependencies);
+ var initialAssemblies = assemblies.Duplicate();
+ internal_GetExportedAssemblyDependencies(initialAssemblies, buildConfig, bclDir, assemblies);
- AddI18NAssemblies(dependencies, bclDir);
+ AddI18NAssemblies(assemblies, bclDir);
string outputDataDir = null;
@@ -211,20 +211,32 @@ namespace GodotTools.Export
Directory.CreateDirectory(outputDataGameAssembliesDir);
}
- foreach (var dependency in dependencies)
+ foreach (var assembly in assemblies)
{
- string dependSrcPath = dependency.Value;
-
- if (assembliesInsidePck)
- {
- string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile());
- AddFile(dependSrcPath, dependDstPath);
- }
- else
+ void AddToAssembliesDir(string fileSrcPath)
{
- string dependDstPath = Path.Combine(outputDataDir, "Assemblies", dependSrcPath.GetFile());
- File.Copy(dependSrcPath, dependDstPath);
+ if (assembliesInsidePck)
+ {
+ string fileDstPath = Path.Combine(resAssembliesDir, fileSrcPath.GetFile());
+ AddFile(fileSrcPath, fileDstPath);
+ }
+ else
+ {
+ Debug.Assert(outputDataDir != null);
+ string fileDstPath = Path.Combine(outputDataDir, "Assemblies", fileSrcPath.GetFile());
+ File.Copy(fileSrcPath, fileDstPath);
+ }
}
+
+ string assemblySrcPath = assembly.Value;
+
+ string assemblyPathWithoutExtension = Path.ChangeExtension(assemblySrcPath, null);
+ string pdbSrcPath = assemblyPathWithoutExtension + ".pdb";
+
+ AddToAssembliesDir(assemblySrcPath);
+
+ if (File.Exists(pdbSrcPath))
+ AddToAssembliesDir(pdbSrcPath);
}
// AOT compilation
@@ -254,7 +266,7 @@ namespace GodotTools.Export
ToolchainPath = aotToolchainPath
};
- AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, dependencies);
+ AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, assemblies);
}
}
@@ -366,7 +378,7 @@ namespace GodotTools.Export
if (PlatformRequiresCustomBcl(platform))
throw new FileNotFoundException($"Missing BCL (Base Class Library) for platform: {platform}");
- platformBclDir = typeof(object).Assembly.Location; // Use the one we're running on
+ platformBclDir = typeof(object).Assembly.Location.GetBaseDir(); // Use the one we're running on
}
}
@@ -425,7 +437,7 @@ namespace GodotTools.Export
}
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialDependencies,
- string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencies);
+ private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialAssemblies,
+ string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencyAssemblies);
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index c9d7dd26f8..c070cb16d9 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -1,4 +1,5 @@
using Godot;
+using GodotTools.Core;
using GodotTools.Export;
using GodotTools.Utils;
using System;
@@ -442,13 +443,27 @@ namespace GodotTools
{
// Migrate solution from old configuration names to: Debug, ExportDebug and ExportRelease
DotNetSolution.MigrateFromOldConfigNames(GodotSharpDirs.ProjectSlnPath);
+
+ var msbuildProject = ProjectUtils.Open(GodotSharpDirs.ProjectCsProjPath)
+ ?? throw new Exception("Cannot open C# project");
+
+ // NOTE: The order in which changes are made to the project is important
+
// Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease
- ProjectUtils.MigrateFromOldConfigNames(GodotSharpDirs.ProjectCsProjPath);
+ ProjectUtils.MigrateFromOldConfigNames(msbuildProject);
- // Apply the other fixes after configurations are migrated
+ // Apply the other fixes only after configurations have been migrated
// Make sure the existing project has Api assembly references configured correctly
- ProjectUtils.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath);
+ ProjectUtils.FixApiHintPath(msbuildProject);
+
+ if (msbuildProject.HasUnsavedChanges)
+ {
+ // Save a copy of the project before replacing it
+ FileUtils.SaveBackupCopy(GodotSharpDirs.ProjectCsProjPath);
+
+ msbuildProject.Save();
+ }
}
catch (Exception e)
{
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 71bb8ff851..ee92a6234a 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -2383,7 +2383,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
const PropertyInfo &property = E->get();
- if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_CATEGORY)
+ if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY)
continue;
PropertyInterface iprop;
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index 283d4beb8e..c3e7e67ae9 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -231,14 +231,14 @@ int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObje
return err;
}
-uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_dependencies,
- MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_dependencies) {
- Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_dependencies);
+uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_assemblies,
+ MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_assembly_dependencies) {
+ Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_assemblies);
String build_config = GDMonoMarshal::mono_string_to_godot(p_build_config);
String custom_bcl_dir = GDMonoMarshal::mono_string_to_godot(p_custom_bcl_dir);
- Dictionary dependencies = GDMonoMarshal::mono_object_to_variant(r_dependencies);
+ Dictionary assembly_dependencies = GDMonoMarshal::mono_object_to_variant(r_assembly_dependencies);
- return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, dependencies);
+ return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, assembly_dependencies);
}
MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_config) {
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index 324013e5e2..4126da16be 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -50,13 +50,13 @@ String get_assemblyref_name(MonoImage *p_image, int index) {
return String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME]));
}
-Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) {
+Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_assembly_dependencies) {
MonoImage *image = p_assembly->get_image();
for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) {
String ref_name = get_assemblyref_name(image, i);
- if (r_dependencies.has(ref_name))
+ if (r_assembly_dependencies.has(ref_name))
continue;
GDMonoAssembly *ref_assembly = nullptr;
@@ -93,17 +93,17 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
// Use the path we got from the search. Don't try to get the path from the loaded assembly as we can't trust it will be from the selected BCL dir.
- r_dependencies[ref_name] = path;
+ r_assembly_dependencies[ref_name] = path;
- Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies);
+ Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_assembly_dependencies);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'.");
}
return OK;
}
-Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
- const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) {
+Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
+ const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_assembly_dependencies) {
MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ProjectExport");
ERR_FAIL_NULL_V(export_domain, FAILED);
_GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain);
@@ -113,16 +113,16 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencie
Vector<String> search_dirs;
GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_bcl_dir);
- for (const Variant *key = p_initial_dependencies.next(); key; key = p_initial_dependencies.next(key)) {
+ for (const Variant *key = p_initial_assemblies.next(); key; key = p_initial_assemblies.next(key)) {
String assembly_name = *key;
- String assembly_path = p_initial_dependencies[*key];
+ String assembly_path = p_initial_assemblies[*key];
GDMonoAssembly *assembly = nullptr;
bool load_success = GDMono::get_singleton()->load_assembly_from(assembly_name, assembly_path, &assembly, /* refonly: */ true);
ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'.");
- Error err = get_assembly_dependencies(assembly, search_dirs, r_dependencies);
+ Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies);
if (err != OK)
return err;
}
diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h
index 36138f81b7..9ab57755de 100644
--- a/modules/mono/editor/godotsharp_export.h
+++ b/modules/mono/editor/godotsharp_export.h
@@ -41,8 +41,8 @@ namespace GodotSharpExport {
Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies);
-Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
- const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies);
+Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
+ const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_assembly_dependencies);
} // namespace GodotSharpExport
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index aba1065498..a963810d63 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -15,10 +15,7 @@ namespace Godot.Collections
public override bool IsInvalid
{
- get
- {
- return handle == IntPtr.Zero;
- }
+ get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
@@ -43,7 +40,8 @@ namespace Godot.Collections
if (collection == null)
throw new NullReferenceException($"Parameter '{nameof(collection)} cannot be null.'");
- MarshalUtils.EnumerableToArray(collection, GetPtr());
+ foreach (object element in collection)
+ Add(element);
}
internal Array(ArraySafeHandle handle)
@@ -272,14 +270,8 @@ namespace Godot.Collections
public T this[int index]
{
- get
- {
- return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass);
- }
- set
- {
- objectArray[index] = value;
- }
+ get { return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); }
+ set { objectArray[index] = value; }
}
public int IndexOf(T item)
@@ -301,18 +293,12 @@ namespace Godot.Collections
public int Count
{
- get
- {
- return objectArray.Count;
- }
+ get { return objectArray.Count; }
}
public bool IsReadOnly
{
- get
- {
- return objectArray.IsReadOnly;
- }
+ get { return objectArray.IsReadOnly; }
}
public void Add(T item)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
index d72109de92..213fc181c1 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
@@ -15,10 +15,7 @@ namespace Godot.Collections
public override bool IsInvalid
{
- get
- {
- return handle == IntPtr.Zero;
- }
+ get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
@@ -45,7 +42,8 @@ namespace Godot.Collections
if (dictionary == null)
throw new NullReferenceException($"Parameter '{nameof(dictionary)} cannot be null.'");
- MarshalUtils.IDictionaryToDictionary(dictionary, GetPtr());
+ foreach (DictionaryEntry entry in dictionary)
+ Add(entry.Key, entry.Value);
}
internal Dictionary(DictionarySafeHandle handle)
@@ -330,14 +328,8 @@ namespace Godot.Collections
public TValue this[TKey key]
{
- get
- {
- return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass);
- }
- set
- {
- objectDict[key] = value;
- }
+ get { return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); }
+ set { objectDict[key] = value; }
}
public ICollection<TKey> Keys
@@ -385,18 +377,12 @@ namespace Godot.Collections
public int Count
{
- get
- {
- return objectDict.Count;
- }
+ get { return objectDict.Count; }
}
public bool IsReadOnly
{
- get
- {
- return objectDict.IsReadOnly;
- }
+ get { return objectDict.IsReadOnly; }
}
public void Add(KeyValuePair<TKey, TValue> item)
@@ -440,7 +426,8 @@ namespace Godot.Collections
public bool Remove(KeyValuePair<TKey, TValue> item)
{
- return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value); ;
+ return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value);
+ ;
}
// IEnumerable<KeyValuePair<TKey, TValue>>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
index a1d63a62ef..c59d083080 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
@@ -16,10 +16,8 @@ namespace Godot
/// <exception cref="System.InvalidOperationException">
/// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
/// </exception>
- static bool TypeIsGenericArray(Type type)
- {
- return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>);
- }
+ static bool TypeIsGenericArray(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>);
/// <summary>
/// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
@@ -28,10 +26,20 @@ namespace Godot
/// <exception cref="System.InvalidOperationException">
/// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
/// </exception>
- static bool TypeIsGenericDictionary(Type type)
- {
- return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>);
- }
+ static bool TypeIsGenericDictionary(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>);
+
+ static bool TypeIsSystemGenericList(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>);
+
+ static bool TypeIsSystemGenericDictionary(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.Dictionary<,>);
+
+ static bool TypeIsGenericIEnumerable(Type type) => type.GetGenericTypeDefinition() == typeof(IEnumerable<>);
+
+ static bool TypeIsGenericICollection(Type type) => type.GetGenericTypeDefinition() == typeof(ICollection<>);
+
+ static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>);
static void ArrayGetElementType(Type arrayType, out Type elementType)
{
@@ -45,105 +53,6 @@ namespace Godot
valueType = genericArgs[1];
}
- static bool GenericIEnumerableIsAssignableFromType(Type type)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- return true;
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- return true;
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- return false;
-
- return GenericIEnumerableIsAssignableFromType(baseType);
- }
-
- static bool GenericIDictionaryIsAssignableFromType(Type type)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- return true;
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- return true;
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- return false;
-
- return GenericIDictionaryIsAssignableFromType(baseType);
- }
-
- static bool GenericIEnumerableIsAssignableFromType(Type type, out Type elementType)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- {
- elementType = type.GetGenericArguments()[0];
- return true;
- }
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- {
- elementType = interfaceType.GetGenericArguments()[0];
- return true;
- }
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- {
- elementType = null;
- return false;
- }
-
- return GenericIEnumerableIsAssignableFromType(baseType, out elementType);
- }
-
- static bool GenericIDictionaryIsAssignableFromType(Type type, out Type keyType, out Type valueType)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- {
- var genericArgs = type.GetGenericArguments();
- keyType = genericArgs[0];
- valueType = genericArgs[1];
- return true;
- }
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- {
- var genericArgs = interfaceType.GetGenericArguments();
- keyType = genericArgs[0];
- valueType = genericArgs[1];
- return true;
- }
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- {
- keyType = null;
- valueType = null;
- return false;
- }
-
- return GenericIDictionaryIsAssignableFromType(baseType, out keyType, out valueType);
- }
-
static Type MakeGenericArrayType(Type elemType)
{
return typeof(Godot.Collections.Array<>).MakeGenericType(elemType);
@@ -153,60 +62,5 @@ namespace Godot
{
return typeof(Godot.Collections.Dictionary<,>).MakeGenericType(keyType, valueType);
}
-
- // TODO Add support for IEnumerable<T> and IDictionary<TKey, TValue>
- // TODO: EnumerableToArray and IDictionaryToDictionary can be optimized
-
- internal static void EnumerableToArray(IEnumerable enumerable, IntPtr godotArrayPtr)
- {
- if (enumerable is ICollection collection)
- {
- int count = collection.Count;
-
- object[] tempArray = new object[count];
- collection.CopyTo(tempArray, 0);
-
- for (int i = 0; i < count; i++)
- {
- Array.godot_icall_Array_Add(godotArrayPtr, tempArray[i]);
- }
- }
- else
- {
- foreach (object element in enumerable)
- {
- Array.godot_icall_Array_Add(godotArrayPtr, element);
- }
- }
- }
-
- internal static void IDictionaryToDictionary(IDictionary dictionary, IntPtr godotDictionaryPtr)
- {
- foreach (DictionaryEntry entry in dictionary)
- {
- Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, entry.Key, entry.Value);
- }
- }
-
- internal static void GenericIDictionaryToDictionary(object dictionary, IntPtr godotDictionaryPtr)
- {
-#if DEBUG
- if (!GenericIDictionaryIsAssignableFromType(dictionary.GetType()))
- throw new InvalidOperationException("The type does not implement IDictionary<,>");
-#endif
-
- // TODO: Can we optimize this?
-
- var keys = ((IEnumerable)dictionary.GetType().GetProperty("Keys").GetValue(dictionary)).GetEnumerator();
- var values = ((IEnumerable)dictionary.GetType().GetProperty("Values").GetValue(dictionary)).GetEnumerator();
-
- while (keys.MoveNext() && values.MoveNext())
- {
- object key = keys.Current;
- object value = values.Current;
-
- Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, key, value);
- }
- }
}
}
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index fe8b925257..d596163926 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -40,7 +40,7 @@
#endif
#ifdef ANDROID_ENABLED
-#include "mono_gd/support/mono-support.h"
+#include "mono_gd/support/android_support.h"
#endif
#include "mono_gd/gd_mono.h"
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 306a1997ab..3298c5da4c 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -129,12 +129,8 @@ void gd_mono_profiler_init() {
}
}
-#if defined(DEBUG_ENABLED)
-
void gd_mono_debug_init() {
- mono_debug_init(MONO_DEBUG_FORMAT_MONO);
-
CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8();
#ifdef TOOLS_ENABLED
@@ -159,6 +155,10 @@ void gd_mono_debug_init() {
return; // Exported games don't use the project settings to setup the debugger agent
#endif
+ // Debugging enabled
+
+ mono_debug_init(MONO_DEBUG_FORMAT_MONO);
+
// --debugger-agent=help
const char *options[] = {
"--soft-breakpoints",
@@ -167,7 +167,6 @@ void gd_mono_debug_init() {
mono_jit_parse_options(2, (char **)options);
}
-#endif // defined(DEBUG_ENABLED)
#endif // !defined(JAVASCRIPT_ENABLED)
#if defined(JAVASCRIPT_ENABLED)
@@ -175,6 +174,7 @@ MonoDomain *gd_initialize_mono_runtime() {
const char *vfs_prefix = "managed";
int enable_debugging = 0;
+ // TODO: Provide a way to enable debugging on WASM release builds.
#ifdef DEBUG_ENABLED
enable_debugging = 1;
#endif
@@ -185,9 +185,7 @@ MonoDomain *gd_initialize_mono_runtime() {
}
#else
MonoDomain *gd_initialize_mono_runtime() {
-#ifdef DEBUG_ENABLED
gd_mono_debug_init();
-#endif
#if defined(IPHONE_ENABLED) || defined(ANDROID_ENABLED)
// I don't know whether this actually matters or not
@@ -1389,7 +1387,10 @@ bool _GodotSharp::is_runtime_initialized() {
void _GodotSharp::_reload_assemblies(bool p_soft_reload) {
#ifdef GD_MONO_HOT_RELOAD
- CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
+ // This method may be called more than once with `call_deferred`, so we need to check
+ // again if reloading is needed to avoid reloading multiple times unnecessarily.
+ if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed())
+ CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
#endif
}
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp
index facc0da780..5ddf18d544 100644
--- a/modules/mono/mono_gd/gd_mono_cache.cpp
+++ b/modules/mono/mono_gd/gd_mono_cache.cpp
@@ -84,6 +84,7 @@ void CachedData::clear_corlib_cache() {
class_IntPtr = nullptr;
class_System_Collections_IEnumerable = nullptr;
+ class_System_Collections_ICollection = nullptr;
class_System_Collections_IDictionary = nullptr;
#ifdef DEBUG_ENABLED
@@ -171,22 +172,18 @@ void CachedData::clear_godot_api_cache() {
methodthunk_MarshalUtils_TypeIsGenericArray.nullify();
methodthunk_MarshalUtils_TypeIsGenericDictionary.nullify();
+ methodthunk_MarshalUtils_TypeIsSystemGenericList.nullify();
+ methodthunk_MarshalUtils_TypeIsSystemGenericDictionary.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericIEnumerable.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericICollection.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify();
methodthunk_MarshalUtils_ArrayGetElementType.nullify();
methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify();
- methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType.nullify();
- methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info.nullify();
-
methodthunk_MarshalUtils_MakeGenericArrayType.nullify();
methodthunk_MarshalUtils_MakeGenericDictionaryType.nullify();
- methodthunk_MarshalUtils_EnumerableToArray.nullify();
- methodthunk_MarshalUtils_IDictionaryToDictionary.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryToDictionary.nullify();
-
// End of MarshalUtils methods
task_scheduler_handle = Ref<MonoGCHandleRef>();
@@ -213,6 +210,7 @@ void update_corlib_cache() {
CACHE_CLASS_AND_CHECK(IntPtr, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_intptr_class()));
CACHE_CLASS_AND_CHECK(System_Collections_IEnumerable, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IEnumerable"));
+ CACHE_CLASS_AND_CHECK(System_Collections_ICollection, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "ICollection"));
CACHE_CLASS_AND_CHECK(System_Collections_IDictionary, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IDictionary"));
#ifdef DEBUG_ENABLED
@@ -297,22 +295,18 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericArray, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericArray", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericDictionary", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericList, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericList", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericDictionary", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIEnumerable, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIEnumerable", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 1));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 1));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 3));
-
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericArrayType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericArrayType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericDictionaryType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericDictionaryType", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, EnumerableToArray, GODOT_API_CLASS(MarshalUtils)->get_method("EnumerableToArray", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("IDictionaryToDictionary", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryToDictionary", 2));
-
// End of MarshalUtils methods
#ifdef DEBUG_ENABLED
diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h
index 21c8ed4efe..3cf2bd6ce5 100644
--- a/modules/mono/mono_gd/gd_mono_cache.h
+++ b/modules/mono/mono_gd/gd_mono_cache.h
@@ -58,6 +58,7 @@ struct CachedData {
GDMonoClass *class_IntPtr; // System.IntPtr
GDMonoClass *class_System_Collections_IEnumerable;
+ GDMonoClass *class_System_Collections_ICollection;
GDMonoClass *class_System_Collections_IDictionary;
#ifdef DEBUG_ENABLED
@@ -141,22 +142,18 @@ struct CachedData {
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericArray;
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericDictionary;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericList;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericDictionary;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIEnumerable;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary;
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType;
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info;
-
GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericArrayType;
GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericDictionaryType;
- GDMonoMethodThunk<MonoObject *, Array *> methodthunk_MarshalUtils_EnumerableToArray;
- GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_IDictionaryToDictionary;
- GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_GenericIDictionaryToDictionary;
-
// End of MarshalUtils methods
Ref<MonoGCHandleRef> task_scheduler_handle;
@@ -186,14 +183,6 @@ inline void clear_godot_api_cache() {
cached_data.clear_godot_api_cache();
}
-_FORCE_INLINE_ bool tools_godot_api_check() {
-#ifdef TOOLS_ENABLED
- return cached_data.godot_api_cache_updated;
-#else
- return true; // Assume it's updated if this was called, otherwise it's a bug
-#endif
-}
-
} // namespace GDMonoCache
#define CACHED_CLASS(m_class) (GDMonoCache::cached_data.class_##m_class)
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index ede4203e35..2c65f7e3a0 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -31,6 +31,7 @@
#include "gd_mono_class.h"
#include <mono/metadata/attrdefs.h>
+#include <mono/metadata/debug-helpers.h>
#include "gd_mono_assembly.h"
#include "gd_mono_cache.h"
@@ -55,7 +56,11 @@ String GDMonoClass::get_full_name() const {
return get_full_name(mono_class);
}
-MonoType *GDMonoClass::get_mono_type() {
+String GDMonoClass::get_type_desc() const {
+ return GDMonoUtils::get_type_desc(get_mono_type());
+}
+
+MonoType *GDMonoClass::get_mono_type() const {
// Careful, you cannot compare two MonoType*.
// There is mono_metadata_type_equal, how is this different from comparing two MonoClass*?
return get_mono_type(mono_class);
@@ -264,6 +269,12 @@ bool GDMonoClass::implements_interface(GDMonoClass *p_interface) {
return mono_class_implements_interface(mono_class, p_interface->get_mono_ptr());
}
+bool GDMonoClass::has_public_parameterless_ctor() {
+
+ GDMonoMethod *ctor = get_method(".ctor", 0);
+ return ctor && ctor->get_visibility() == IMonoClassMember::PUBLIC;
+}
+
GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) {
MethodKey key = MethodKey(p_name, p_params_count);
@@ -328,6 +339,9 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo
MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class);
mono_method_desc_free(desc);
+ if (!method)
+ return nullptr;
+
ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr);
return get_method(method);
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index 0c9a8cdafe..9237aae057 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -31,8 +31,6 @@
#ifndef GD_MONO_CLASS_H
#define GD_MONO_CLASS_H
-#include <mono/metadata/debug-helpers.h>
-
#include "core/map.h"
#include "core/ustring.h"
@@ -107,7 +105,8 @@ public:
static MonoType *get_mono_type(MonoClass *p_mono_class);
String get_full_name() const;
- MonoType *get_mono_type();
+ String get_type_desc() const;
+ MonoType *get_mono_type() const;
uint32_t get_flags() const;
bool is_static() const;
@@ -137,6 +136,7 @@ public:
void fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base);
bool implements_interface(GDMonoClass *p_interface);
+ bool has_public_parameterless_ctor();
GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0);
GDMonoMethod *get_method(MonoMethod *p_raw_method);
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index 3f4e5fe5ac..e76cb84d43 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -322,6 +322,13 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
+ MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class);
+ mono_field_set_value(p_object, mono_field, managed);
+ break;
+ }
+
ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
@@ -353,56 +360,22 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
- if (CACHED_CLASS(Dictionary) == type_class) {
+ // Godot.Collections.Dictionary or IDictionary
+ if (CACHED_CLASS(Dictionary) == type_class || type_class == CACHED_CLASS(System_Collections_IDictionary)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (CACHED_CLASS(Array) == type_class) {
+ // Godot.Collections.Array or ICollection or IEnumerable
+ if (CACHED_CLASS(Array) == type_class ||
+ type_class == CACHED_CLASS(System_Collections_ICollection) ||
+ type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
mono_field_set_value(p_object, mono_field, managed);
break;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- } else {
- MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
- }
-
ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'.");
} break;
@@ -535,52 +508,62 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ MonoObject *managed = GDMonoMarshal::Dictionary_to_system_generic_dict(p_value.operator Dictionary(),
+ type.type_class, key_reftype, value_reftype);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ MonoObject *managed = GDMonoMarshal::Array_to_system_generic_list(p_value.operator Array(),
+ type.type_class, elem_reftype);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ MonoReflectionType *key_reftype;
+ MonoReflectionType *value_reftype;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
+
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), godot_dict_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- } else {
- MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
+ MonoReflectionType *elem_reftype;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
+
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), godot_array_class);
+ mono_field_set_value(p_object, mono_field, managed);
+ break;
}
} break;
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 1878038f44..91ee07388b 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -154,6 +154,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return Variant::PACKED_COLOR_ARRAY;
+
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return Variant::ARRAY;
} break;
case MONO_TYPE_CLASS: {
@@ -184,23 +188,14 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
return Variant::ARRAY;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return Variant::DICTIONARY;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
+ // IDictionary
+ if (p_type.type_class == CACHED_CLASS(System_Collections_IDictionary)) {
return Variant::DICTIONARY;
}
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
- return Variant::ARRAY;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
+ // ICollection or IEnumerable
+ if (p_type.type_class == CACHED_CLASS(System_Collections_ICollection) ||
+ p_type.type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
return Variant::ARRAY;
}
} break;
@@ -214,27 +209,33 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
return Variant::DICTIONARY;
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
return Variant::ARRAY;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype))
- return Variant::DICTIONARY;
-
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
return Variant::DICTIONARY;
}
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype))
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
return Variant::ARRAY;
+ }
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ return Variant::DICTIONARY;
+ }
+
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
return Variant::ARRAY;
}
} break;
@@ -252,10 +253,20 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) {
switch (p_array_type.type_encoding) {
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY: {
+ MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type());
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ r_elem_type = ManagedType::from_class(array_type_class);
+ return true;
+ } break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *array_reftype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type());
- if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype)) {
+ if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_system_generic_list(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_icollection(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_ienumerable(array_reftype)) {
MonoReflectionType *elem_reftype;
GDMonoUtils::Marshal::array_get_element_type(array_reftype, &elem_reftype);
@@ -263,12 +274,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_
r_elem_type = ManagedType::from_reftype(elem_reftype);
return true;
}
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(array_reftype, &elem_reftype)) {
- r_elem_type = ManagedType::from_reftype(elem_reftype);
- return true;
- }
} break;
default: {
} break;
@@ -282,7 +287,9 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma
case MONO_TYPE_GENERICINST: {
MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type());
- if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype)) {
+ if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) ||
+ GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) {
MonoReflectionType *key_reftype;
MonoReflectionType *value_reftype;
@@ -292,13 +299,6 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma
r_value_type = ManagedType::from_reftype(value_reftype);
return true;
}
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(dict_reftype, &key_reftype, &value_reftype)) {
- r_key_type = ManagedType::from_reftype(key_reftype);
- r_value_type = ManagedType::from_reftype(value_reftype);
- return true;
- }
} break;
default: {
} break;
@@ -577,6 +577,10 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class);
+
ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
@@ -600,41 +604,17 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return GDMonoUtils::create_managed_from(p_var->operator RID());
}
- if (CACHED_CLASS(Dictionary) == type_class) {
+ // Godot.Collections.Dictionary or IDictionary
+ if (CACHED_CLASS(Dictionary) == type_class || CACHED_CLASS(System_Collections_IDictionary) == type_class) {
return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
}
- if (CACHED_CLASS(Array) == type_class) {
+ // Godot.Collections.Array or ICollection or IEnumerable
+ if (CACHED_CLASS(Array) == type_class ||
+ CACHED_CLASS(System_Collections_ICollection) == type_class ||
+ CACHED_CLASS(System_Collections_IEnumerable) == type_class) {
return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
}
-
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
- }
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- } else {
- return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array());
- }
- }
} break;
case MONO_TYPE_OBJECT: {
// Variant
@@ -755,38 +735,48 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class);
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
return GDMonoUtils::create_managed_from(p_var->operator Array(), p_type.type_class);
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ return Dictionary_to_system_generic_dict(p_var->operator Dictionary(), p_type.type_class, key_reftype, value_reftype);
}
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ return Array_to_system_generic_list(p_var->operator Array(), p_type.type_class, elem_reftype);
}
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ MonoReflectionType *key_reftype;
+ MonoReflectionType *value_reftype;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
+
+ return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), godot_dict_class);
}
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- } else {
- return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array());
- }
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
+ MonoReflectionType *elem_reftype;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
+
+ return GDMonoUtils::create_managed_from(p_var->operator Array(), godot_array_class);
}
} break;
} break;
@@ -922,6 +912,10 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return mono_array_to_PackedColorArray((MonoArray *)p_obj);
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return mono_array_to_Array((MonoArray *)p_obj);
+
if (p_fail_with_err) {
ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
} else {
@@ -957,44 +951,27 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return ptr ? Variant(*ptr) : Variant();
}
- if (CACHED_CLASS(Array) == type_class) {
+ // Godot.Collections.Dictionary
+ if (CACHED_CLASS(Dictionary) == type_class) {
MonoException *exc = nullptr;
- Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc);
+ Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc);
UNHANDLED_EXCEPTION(exc);
return ptr ? Variant(*ptr) : Variant();
}
- if (CACHED_CLASS(Dictionary) == type_class) {
+ // Godot.Collections.Array
+ if (CACHED_CLASS(Array) == type_class) {
MonoException *exc = nullptr;
- Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc);
+ Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc);
UNHANDLED_EXCEPTION(exc);
return ptr ? Variant(*ptr) : Variant();
}
-
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj);
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj);
- }
-
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
- }
} break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
MonoException *exc = nullptr;
MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
@@ -1002,6 +979,7 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return *unbox<Dictionary *>(ret);
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
MonoException *exc = nullptr;
MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
@@ -1009,22 +987,19 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return *unbox<Array *>(ret);
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj);
- }
-
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj);
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ return system_generic_dict_to_Dictionary(p_obj, p_type.type_class, key_reftype, value_reftype);
}
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
- }
-
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ return system_generic_list_to_Array(p_obj, p_type.type_class, elem_reftype);
}
} break;
}
@@ -1081,6 +1056,80 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
}
}
+MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) {
+ String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) +
+ ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)";
+ GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(ctor == nullptr);
+
+ MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(mono_object, nullptr);
+
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype);
+ MonoObject *godot_dict = GDMonoUtils::create_managed_from(p_dict, godot_dict_class);
+
+ void *ctor_args[1] = { godot_dict };
+
+ MonoException *exc = nullptr;
+ ctor->invoke_raw(mono_object, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_object;
+}
+
+Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) {
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype);
+ String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) +
+ ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)";
+ GDMonoMethod *godot_dict_ctor = godot_dict_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(godot_dict_ctor == nullptr);
+
+ MonoObject *godot_dict = mono_object_new(mono_domain_get(), godot_dict_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(godot_dict, Dictionary());
+
+ void *ctor_args[1] = { p_obj };
+
+ MonoException *exc = nullptr;
+ godot_dict_ctor->invoke_raw(godot_dict, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ exc = nullptr;
+ MonoObject *ret = godot_dict_class->get_method("GetPtr")->invoke(godot_dict, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return *unbox<Dictionary *>(ret);
+}
+
+MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype) {
+ GDMonoClass *elem_class = ManagedType::from_reftype(p_elem_reftype).type_class;
+
+ String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + elem_class->get_type_desc() + ">)";
+ GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(ctor == nullptr);
+
+ MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(mono_object, nullptr);
+
+ void *ctor_args[1] = { Array_to_mono_array(p_array, elem_class) };
+
+ MonoException *exc = nullptr;
+ ctor->invoke_raw(mono_object, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_object;
+}
+
+Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) {
+ GDMonoMethod *to_array = p_class->get_method("ToArray", 0);
+ CRASH_COND(to_array == nullptr);
+
+ MonoException *exc = nullptr;
+ MonoArray *mono_array = (MonoArray *)to_array->invoke_raw(p_obj, nullptr, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_array_to_Array(mono_array);
+}
+
MonoArray *Array_to_mono_array(const Array &p_array) {
int length = p_array.size();
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), length);
@@ -1093,6 +1142,18 @@ MonoArray *Array_to_mono_array(const Array &p_array) {
return ret;
}
+MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class) {
+ int length = p_array.size();
+ MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class->get_mono_ptr(), length);
+
+ for (int i = 0; i < length; i++) {
+ MonoObject *boxed = variant_to_mono_object(p_array[i]);
+ mono_array_setref(ret, i, boxed);
+ }
+
+ return ret;
+}
+
Array mono_array_to_Array(MonoArray *p_array) {
Array ret;
if (!p_array)
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 8b405291a7..f2d887e6d6 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -123,9 +123,18 @@ Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_ty
/// If the MonoObject* cannot be converted to Variant, then 'ToString()' is called instead.
String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc);
+// System.Collections.Generic
+
+MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
+Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
+
+MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
+Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
+
// Array
MonoArray *Array_to_mono_array(const Array &p_array);
+MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class);
Array mono_array_to_Array(MonoArray *p_array);
// PackedInt32Array
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index c8cc5247c6..432aa74a6f 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -30,13 +30,14 @@
#include "gd_mono_method.h"
+#include <mono/metadata/attrdefs.h>
+#include <mono/metadata/debug-helpers.h>
+
#include "gd_mono_cache.h"
#include "gd_mono_class.h"
#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"
-#include <mono/metadata/attrdefs.h>
-
void GDMonoMethod::_update_signature() {
// Apparently MonoMethodSignature needs not to be freed.
// mono_method_signature caches the result, we don't need to cache it ourselves.
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 00119ced88..f9d492dabb 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -30,6 +30,7 @@
#include "gd_mono_utils.h"
+#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/exception.h>
#include "core/debugger/engine_debugger.h"
@@ -358,6 +359,14 @@ MonoDomain *create_domain(const String &p_friendly_name) {
return domain;
}
+String get_type_desc(MonoType *p_type) {
+ return mono_type_full_name(p_type);
+}
+
+String get_type_desc(MonoReflectionType *p_reftype) {
+ return get_type_desc(mono_reflection_type_get_type(p_reftype));
+}
+
String get_exception_name_and_message(MonoException *p_exc) {
String res;
@@ -584,75 +593,56 @@ bool type_is_generic_dictionary(MonoReflectionType *p_reftype) {
return (bool)res;
}
-void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) {
- MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc);
- UNHANDLED_EXCEPTION(exc);
-}
-
-void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
- MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc);
- UNHANDLED_EXCEPTION(exc);
-}
-
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) {
+bool type_is_system_generic_list(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
MonoException *exc = nullptr;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType).invoke(p_reftype, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericList).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) {
+bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
MonoException *exc = nullptr;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType).invoke(p_reftype, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericDictionary).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) {
+bool type_is_generic_ienumerable(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
MonoException *exc = nullptr;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info).invoke(p_reftype, r_elem_reftype, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIEnumerable).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
+bool type_is_generic_icollection(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
MonoException *exc = nullptr;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info).invoke(p_reftype, r_key_reftype, r_value_reftype, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericICollection).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-Array enumerable_to_array(MonoObject *p_enumerable) {
- NO_GLUE_RET(Array());
- Array result;
+bool type_is_generic_idictionary(MonoReflectionType *p_reftype) {
+ NO_GLUE_RET(false);
MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, EnumerableToArray).invoke(p_enumerable, &result, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIDictionary).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
+ return (bool)res;
}
-Dictionary idictionary_to_dictionary(MonoObject *p_idictionary) {
- NO_GLUE_RET(Dictionary());
- Dictionary result;
+void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) {
MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, IDictionaryToDictionary).invoke(p_idictionary, &result, &exc);
+ CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
}
-Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary) {
- NO_GLUE_RET(Dictionary());
- Dictionary result;
+void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryToDictionary).invoke(p_generic_idictionary, &result, &exc);
+ CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
}
GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype) {
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index b850e1be9b..e3011ade5d 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -52,22 +52,18 @@ namespace Marshal {
bool type_is_generic_array(MonoReflectionType *p_reftype);
bool type_is_generic_dictionary(MonoReflectionType *p_reftype);
+bool type_is_system_generic_list(MonoReflectionType *p_reftype);
+bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype);
+bool type_is_generic_ienumerable(MonoReflectionType *p_reftype);
+bool type_is_generic_icollection(MonoReflectionType *p_reftype);
+bool type_is_generic_idictionary(MonoReflectionType *p_reftype);
void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype);
void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype);
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype);
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype);
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);
-
GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype);
GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
-Array enumerable_to_array(MonoObject *p_enumerable);
-Dictionary idictionary_to_dictionary(MonoObject *p_idictionary);
-Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary);
-
} // namespace Marshal
_FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) {
@@ -115,6 +111,9 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class);
MonoDomain *create_domain(const String &p_friendly_name);
+String get_type_desc(MonoType *p_type);
+String get_type_desc(MonoReflectionType *p_reftype);
+
String get_exception_name_and_message(MonoException *p_exc);
void set_exception_message(MonoException *p_exc, String message);
diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp
index ec67030a65..2018f90e9f 100644
--- a/modules/opensimplex/noise_texture.cpp
+++ b/modules/opensimplex/noise_texture.cpp
@@ -137,14 +137,19 @@ void NoiseTexture::_queue_update() {
Ref<Image> NoiseTexture::_generate_texture() {
- if (noise.is_null()) return Ref<Image>();
+ // Prevent memdelete due to unref() on other thread.
+ Ref<OpenSimplexNoise> ref_noise = noise;
+
+ if (ref_noise.is_null()) {
+ return Ref<Image>();
+ }
Ref<Image> image;
if (seamless) {
- image = noise->get_seamless_image(size.x);
+ image = ref_noise->get_seamless_image(size.x);
} else {
- image = noise->get_image(size.x, size.y);
+ image = ref_noise->get_image(size.x, size.y);
}
if (as_normalmap) {
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index 10d4d71f5e..a8e8a9a2f1 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -51,7 +51,7 @@ enum PVRFLags {
};
-RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_CANT_OPEN;
diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h
index 642323db35..07ef129689 100644
--- a/modules/pvr/texture_loader_pvr.h
+++ b/modules/pvr/texture_loader_pvr.h
@@ -36,7 +36,7 @@
class ResourceFormatPVR : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index e5fb6f996d..b9f276fb12 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -725,7 +725,7 @@ void VideoStreamTheora::_bind_methods() {
////////////
-RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h
index cd7bff7adb..f98368ed8b 100644
--- a/modules/theora/video_stream_theora.h
+++ b/modules/theora/video_stream_theora.h
@@ -187,7 +187,7 @@ public:
class ResourceFormatLoaderTheora : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp
index 856f4188aa..988bf3017d 100644
--- a/modules/upnp/upnp.cpp
+++ b/modules/upnp/upnp.cpp
@@ -44,9 +44,8 @@ bool UPNP::is_common_device(const String &dev) const {
}
int UPNP::discover(int timeout, int ttl, const String &device_filter) {
- ERR_FAIL_COND_V(timeout < 0, UPNP_RESULT_INVALID_PARAM);
- ERR_FAIL_COND_V(ttl < 0, UPNP_RESULT_INVALID_PARAM);
- ERR_FAIL_COND_V(ttl > 255, UPNP_RESULT_INVALID_PARAM);
+ ERR_FAIL_COND_V_MSG(timeout < 0, UPNP_RESULT_INVALID_PARAM, "The response's wait time can't be negative.");
+ ERR_FAIL_COND_V_MSG(ttl < 0 || ttl > 255, UPNP_RESULT_INVALID_PARAM, "The time-to-live must be set between 0 and 255 (inclusive).");
devices.clear();
@@ -264,7 +263,7 @@ void UPNP::clear_devices() {
}
Ref<UPNPDevice> UPNP::get_gateway() const {
- ERR_FAIL_COND_V(devices.size() < 1, nullptr);
+ ERR_FAIL_COND_V_MSG(devices.size() < 1, nullptr, "Couldn't find any UPNPDevices.");
for (int i = 0; i < devices.size(); i++) {
Ref<UPNPDevice> dev = get_device(i);
diff --git a/modules/upnp/upnp_device.cpp b/modules/upnp/upnp_device.cpp
index c21826d14d..40eb6106a0 100644
--- a/modules/upnp/upnp_device.cpp
+++ b/modules/upnp/upnp_device.cpp
@@ -35,7 +35,7 @@
#include <miniupnpc/upnpcommands.h>
String UPNPDevice::query_external_address() const {
- ERR_FAIL_COND_V(!is_valid_gateway(), "");
+ ERR_FAIL_COND_V_MSG(!is_valid_gateway(), "", "The Internet Gateway Device must be valid.");
char addr[16];
int i = UPNP_GetExternalIPAddress(
@@ -43,17 +43,17 @@ String UPNPDevice::query_external_address() const {
igd_service_type.utf8().get_data(),
(char *)&addr);
- ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, "");
+ ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, "", "Couldn't get external IP address.");
return String(addr);
}
int UPNPDevice::add_port_mapping(int port, int port_internal, String desc, String proto, int duration) const {
- ERR_FAIL_COND_V(!is_valid_gateway(), UPNP::UPNP_RESULT_INVALID_GATEWAY);
- ERR_FAIL_COND_V(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT);
- ERR_FAIL_COND_V(port_internal < 0 || port_internal > 65535, UPNP::UPNP_RESULT_INVALID_PORT); // Needs to allow 0 because 0 signifies "use external port as internal port"
- ERR_FAIL_COND_V(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL);
- ERR_FAIL_COND_V(duration < 0, UPNP::UPNP_RESULT_INVALID_DURATION);
+ ERR_FAIL_COND_V_MSG(!is_valid_gateway(), UPNP::UPNP_RESULT_INVALID_GATEWAY, "The Internet Gateway Device must be valid.");
+ ERR_FAIL_COND_V_MSG(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 1 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(port_internal < 0 || port_internal > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 0 and 65535 (inclusive)."); // Needs to allow 0 because 0 signifies "use external port as internal port"
+ ERR_FAIL_COND_V_MSG(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL, "The protocol must be either TCP or UDP.");
+ ERR_FAIL_COND_V_MSG(duration < 0, UPNP::UPNP_RESULT_INVALID_DURATION, "The port mapping's lease duration can't be negative.");
if (port_internal < 1) {
port_internal = port;
@@ -70,14 +70,14 @@ int UPNPDevice::add_port_mapping(int port, int port_internal, String desc, Strin
nullptr, // Remote host, always nullptr as IGDs don't support it
duration > 0 ? itos(duration).utf8().get_data() : nullptr);
- ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i));
+ ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i), "Couldn't add port mapping.");
return UPNP::UPNP_RESULT_SUCCESS;
}
int UPNPDevice::delete_port_mapping(int port, String proto) const {
- ERR_FAIL_COND_V(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT);
- ERR_FAIL_COND_V(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL);
+ ERR_FAIL_COND_V_MSG(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 1 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL, "The protocol must be either TCP or UDP.");
int i = UPNP_DeletePortMapping(
igd_control_url.utf8().get_data(),
@@ -87,7 +87,7 @@ int UPNPDevice::delete_port_mapping(int port, String proto) const {
nullptr // Remote host, always nullptr as IGDs don't support it
);
- ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i));
+ ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i), "Couldn't delete port mapping.");
return UPNP::UPNP_RESULT_SUCCESS;
}
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index b52dfe1733..fe1d82f977 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -727,6 +727,26 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p
variables[p_new_name] = variables[p_name];
variables.erase(p_name);
+
+ List<StringName> funcs;
+ get_function_list(&funcs);
+ for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions
+ List<int> ids;
+ get_node_list(F->get(), &ids);
+ for (List<int>::Element *E = ids.front(); E; E = E->next()) {
+ Ref<VisualScriptVariableGet> nodeget = get_node(F->get(), E->get());
+ if (nodeget.is_valid()) {
+ if (nodeget->get_variable() == p_name)
+ nodeget->set_variable(p_new_name);
+ } else {
+ Ref<VisualScriptVariableSet> nodeset = get_node(F->get(), E->get());
+ if (nodeset.is_valid()) {
+ if (nodeset->get_variable() == p_name)
+ nodeset->set_variable(p_new_name);
+ }
+ }
+ }
+ }
}
void VisualScript::add_custom_signal(const StringName &p_name) {
@@ -1440,6 +1460,10 @@ VisualScript::VisualScript() {
is_tool_script = false;
}
+bool VisualScript::inherits_script(const Ref<Script> &p_script) const {
+ return this == p_script.ptr(); //there is no inheritance in visual scripts, so this is enough
+}
+
StringName VisualScript::get_default_func() const {
return StringName("f_312843592");
}
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 29309aa156..c154e56703 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -272,6 +272,8 @@ protected:
static void _bind_methods();
public:
+ bool inherits_script(const Ref<Script> &p_script) const;
+
// TODO: Remove it in future when breaking changes are acceptable
StringName get_default_func() const;
void add_function(const StringName &p_name);
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index 39d8f7c082..bb291b1cb6 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -506,10 +506,12 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_CEIL: {
t = Variant::FLOAT;
} break;
- case MATH_POSMOD:
- case MATH_ROUND: {
+ case MATH_POSMOD: {
t = Variant::INT;
} break;
+ case MATH_ROUND: {
+ t = Variant::FLOAT;
+ } break;
case MATH_ABS: {
t = Variant::NIL;
} break;
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index ab528fac30..59b1bcdd96 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -350,8 +350,11 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
case Variant::STRING: color = Color(0.42, 0.65, 0.93); break;
case Variant::VECTOR2: color = Color(0.74, 0.57, 0.95); break;
+ case Variant::VECTOR2I: color = Color(0.74, 0.57, 0.95); break;
case Variant::RECT2: color = Color(0.95, 0.57, 0.65); break;
+ case Variant::RECT2I: color = Color(0.95, 0.57, 0.65); break;
case Variant::VECTOR3: color = Color(0.84, 0.49, 0.93); break;
+ case Variant::VECTOR3I: color = Color(0.84, 0.49, 0.93); break;
case Variant::TRANSFORM2D: color = Color(0.77, 0.93, 0.41); break;
case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break;
case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break;
@@ -389,8 +392,11 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
case Variant::STRING: color = Color(0.27, 0.56, 0.91); break;
case Variant::VECTOR2: color = Color(0.68, 0.46, 0.93); break;
+ case Variant::VECTOR2I: color = Color(0.68, 0.46, 0.93); break;
case Variant::RECT2: color = Color(0.93, 0.46, 0.56); break;
+ case Variant::RECT2I: color = Color(0.93, 0.46, 0.56); break;
case Variant::VECTOR3: color = Color(0.86, 0.42, 0.93); break;
+ case Variant::VECTOR3I: color = Color(0.86, 0.42, 0.93); break;
case Variant::TRANSFORM2D: color = Color(0.59, 0.81, 0.1); break;
case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break;
case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break;
@@ -510,8 +516,11 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Control::get_theme_icon("float", "EditorIcons"),
Control::get_theme_icon("String", "EditorIcons"),
Control::get_theme_icon("Vector2", "EditorIcons"),
+ Control::get_theme_icon("Vector2i", "EditorIcons"),
Control::get_theme_icon("Rect2", "EditorIcons"),
+ Control::get_theme_icon("Rect2i", "EditorIcons"),
Control::get_theme_icon("Vector3", "EditorIcons"),
+ Control::get_theme_icon("Vector3i", "EditorIcons"),
Control::get_theme_icon("Transform2D", "EditorIcons"),
Control::get_theme_icon("Plane", "EditorIcons"),
Control::get_theme_icon("Quat", "EditorIcons"),
@@ -522,6 +531,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Control::get_theme_icon("NodePath", "EditorIcons"),
Control::get_theme_icon("RID", "EditorIcons"),
Control::get_theme_icon("MiniObject", "EditorIcons"),
+ Control::get_theme_icon("Callable", "EditorIcons"),
+ Control::get_theme_icon("Signal", "EditorIcons"),
Control::get_theme_icon("Dictionary", "EditorIcons"),
Control::get_theme_icon("Array", "EditorIcons"),
Control::get_theme_icon("PackedByteArray", "EditorIcons"),
@@ -974,8 +985,11 @@ void VisualScriptEditor::_update_members() {
Control::get_theme_icon("float", "EditorIcons"),
Control::get_theme_icon("String", "EditorIcons"),
Control::get_theme_icon("Vector2", "EditorIcons"),
+ Control::get_theme_icon("Vector2i", "EditorIcons"),
Control::get_theme_icon("Rect2", "EditorIcons"),
+ Control::get_theme_icon("Rect2i", "EditorIcons"),
Control::get_theme_icon("Vector3", "EditorIcons"),
+ Control::get_theme_icon("Vector3i", "EditorIcons"),
Control::get_theme_icon("Transform2D", "EditorIcons"),
Control::get_theme_icon("Plane", "EditorIcons"),
Control::get_theme_icon("Quat", "EditorIcons"),
@@ -986,6 +1000,8 @@ void VisualScriptEditor::_update_members() {
Control::get_theme_icon("NodePath", "EditorIcons"),
Control::get_theme_icon("RID", "EditorIcons"),
Control::get_theme_icon("MiniObject", "EditorIcons"),
+ Control::get_theme_icon("Callable", "EditorIcons"),
+ Control::get_theme_icon("Signal", "EditorIcons"),
Control::get_theme_icon("Dictionary", "EditorIcons"),
Control::get_theme_icon("Array", "EditorIcons"),
Control::get_theme_icon("PackedByteArray", "EditorIcons"),
@@ -1155,6 +1171,8 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(script.ptr(), "rename_variable", new_name, name);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
+ undo_redo->add_do_method(this, "_update_graph");
+ undo_redo->add_undo_method(this, "_update_graph");
undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
@@ -3917,7 +3935,9 @@ void VisualScriptEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members));
+ variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED);
signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members));
+ signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED);
[[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
@@ -4629,6 +4649,7 @@ void VisualScriptEditor::_bind_methods() {
ClassDB::bind_method("_input", &VisualScriptEditor::_input);
ClassDB::bind_method("_update_graph_connections", &VisualScriptEditor::_update_graph_connections);
+ ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members);
ClassDB::bind_method("_generic_search", &VisualScriptEditor::_generic_search);
}
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 97c2686cd5..c860e08943 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -4184,9 +4184,12 @@ void register_visual_script_nodes() {
VisualScriptLanguage::singleton->add_register_func("operators/logic/select", create_node_generic<VisualScriptSelect>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2), create_node_deconst_typed<Variant::Type::VECTOR2>);
+ VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2I), create_node_deconst_typed<Variant::Type::VECTOR2I>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3), create_node_deconst_typed<Variant::Type::VECTOR3>);
+ VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3I), create_node_deconst_typed<Variant::Type::VECTOR3I>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::COLOR), create_node_deconst_typed<Variant::Type::COLOR>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2), create_node_deconst_typed<Variant::Type::RECT2>);
+ VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2I), create_node_deconst_typed<Variant::Type::RECT2I>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM2D), create_node_deconst_typed<Variant::Type::TRANSFORM2D>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PLANE), create_node_deconst_typed<Variant::Type::PLANE>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::QUAT), create_node_deconst_typed<Variant::Type::QUAT>);
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index ca78d664f7..a2d0f78f5f 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -474,7 +474,7 @@ void VideoStreamWebm::set_audio_track(int p_track) {
////////////
-RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h
index bc209e0057..6677fb85aa 100644
--- a/modules/webm/video_stream_webm.h
+++ b/modules/webm/video_stream_webm.h
@@ -128,7 +128,7 @@ public:
class ResourceFormatLoaderWebm : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/platform/android/SCsub b/platform/android/SCsub
index f39eb8b889..ec42bc42b5 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -17,8 +17,8 @@ android_files = [
"java_godot_io_wrapper.cpp",
"jni_utils.cpp",
"android_keys_utils.cpp",
- "vulkan/vk_renderer_jni.cpp",
- "plugin/godot_plugin_jni.cpp",
+ "display_server_android.cpp",
+ "vulkan/vulkan_context_android.cpp",
]
env_android = env.Clone()
diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp
index ef11b12971..4fe868d4f0 100644
--- a/platform/android/api/api.cpp
+++ b/platform/android/api/api.cpp
@@ -32,6 +32,7 @@
#include "core/engine.h"
#include "java_class_wrapper.h"
+#include "jni_singleton.h"
#if !defined(ANDROID_ENABLED)
static JavaClassWrapper *java_class_wrapper = nullptr;
@@ -40,7 +41,11 @@ static JavaClassWrapper *java_class_wrapper = nullptr;
void register_android_api() {
#if !defined(ANDROID_ENABLED)
+ // On Android platforms, the `java_class_wrapper` instantiation and the
+ // `JNISingleton` registration occurs in
+ // `platform/android/java_godot_lib_jni.cpp#Java_org_godotengine_godot_GodotLib_setup`
java_class_wrapper = memnew(JavaClassWrapper); // Dummy
+ ClassDB::register_class<JNISingleton>();
#endif
ClassDB::register_class<JavaClass>();
diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h
new file mode 100644
index 0000000000..917c3f5029
--- /dev/null
+++ b/platform/android/api/jni_singleton.h
@@ -0,0 +1,242 @@
+/*************************************************************************/
+/* jni_singleton.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef JNI_SINGLETON_H
+#define JNI_SINGLETON_H
+
+#include <core/engine.h>
+#include <core/variant.h>
+#ifdef ANDROID_ENABLED
+#include <platform/android/jni_utils.h>
+#endif
+
+class JNISingleton : public Object {
+
+ GDCLASS(JNISingleton, Object);
+
+#ifdef ANDROID_ENABLED
+ struct MethodData {
+
+ jmethodID method;
+ Variant::Type ret_type;
+ Vector<Variant::Type> argtypes;
+ };
+
+ jobject instance;
+ Map<StringName, MethodData> method_map;
+#endif
+
+public:
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+#ifdef ANDROID_ENABLED
+ Map<StringName, MethodData>::Element *E = method_map.find(p_method);
+
+ // Check the method we're looking for is in the JNISingleton map and that
+ // the arguments match.
+ bool call_error = !E || E->get().argtypes.size() != p_argcount;
+ if (!call_error) {
+ for (int i = 0; i < p_argcount; i++) {
+
+ if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) {
+ call_error = true;
+ break;
+ }
+ }
+ }
+
+ if (call_error) {
+ // The method is not in this map, defaulting to the regular instance calls.
+ return Object::call(p_method, p_args, p_argcount, r_error);
+ }
+
+ ERR_FAIL_COND_V(!instance, Variant());
+
+ r_error.error = Callable::CallError::CALL_OK;
+
+ jvalue *v = nullptr;
+
+ if (p_argcount) {
+
+ v = (jvalue *)alloca(sizeof(jvalue) * p_argcount);
+ }
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ int res = env->PushLocalFrame(16);
+
+ ERR_FAIL_COND_V(res != 0, Variant());
+
+ List<jobject> to_erase;
+ for (int i = 0; i < p_argcount; i++) {
+
+ jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]);
+ v[i] = vr.val;
+ if (vr.obj)
+ to_erase.push_back(vr.obj);
+ }
+
+ Variant ret;
+
+ switch (E->get().ret_type) {
+
+ case Variant::NIL: {
+
+ env->CallVoidMethodA(instance, E->get().method, v);
+ } break;
+ case Variant::BOOL: {
+
+ ret = env->CallBooleanMethodA(instance, E->get().method, v) == JNI_TRUE;
+ } break;
+ case Variant::INT: {
+
+ ret = env->CallIntMethodA(instance, E->get().method, v);
+ } break;
+ case Variant::FLOAT: {
+
+ ret = env->CallFloatMethodA(instance, E->get().method, v);
+ } break;
+ case Variant::STRING: {
+
+ jobject o = env->CallObjectMethodA(instance, E->get().method, v);
+ ret = jstring_to_string((jstring)o, env);
+ env->DeleteLocalRef(o);
+ } break;
+ case Variant::PACKED_STRING_ARRAY: {
+
+ jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v);
+
+ ret = _jobject_to_variant(env, arr);
+
+ env->DeleteLocalRef(arr);
+ } break;
+ case Variant::PACKED_INT32_ARRAY: {
+
+ jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v);
+
+ int fCount = env->GetArrayLength(arr);
+ Vector<int> sarr;
+ sarr.resize(fCount);
+
+ int *w = sarr.ptrw();
+ env->GetIntArrayRegion(arr, 0, fCount, w);
+ ret = sarr;
+ env->DeleteLocalRef(arr);
+ } break;
+ case Variant::PACKED_FLOAT32_ARRAY: {
+
+ jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v);
+
+ int fCount = env->GetArrayLength(arr);
+ Vector<float> sarr;
+ sarr.resize(fCount);
+
+ float *w = sarr.ptrw();
+ env->GetFloatArrayRegion(arr, 0, fCount, w);
+ ret = sarr;
+ env->DeleteLocalRef(arr);
+ } break;
+
+#ifndef _MSC_VER
+#warning This is missing 64 bits arrays, I have no idea how to do it in JNI
+#endif
+ case Variant::DICTIONARY: {
+
+ jobject obj = env->CallObjectMethodA(instance, E->get().method, v);
+ ret = _jobject_to_variant(env, obj);
+ env->DeleteLocalRef(obj);
+
+ } break;
+ default: {
+
+ env->PopLocalFrame(nullptr);
+ ERR_FAIL_V(Variant());
+ } break;
+ }
+
+ while (to_erase.size()) {
+ env->DeleteLocalRef(to_erase.front()->get());
+ to_erase.pop_front();
+ }
+
+ env->PopLocalFrame(nullptr);
+
+ return ret;
+#else // ANDROID_ENABLED
+
+ // Defaulting to the regular instance calls.
+ return Object::call(p_method, p_args, p_argcount, r_error);
+#endif
+ }
+
+#ifdef ANDROID_ENABLED
+ jobject get_instance() const {
+
+ return instance;
+ }
+
+ void set_instance(jobject p_instance) {
+
+ instance = p_instance;
+ }
+
+ void add_method(const StringName &p_name, jmethodID p_method, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) {
+
+ MethodData md;
+ md.method = p_method;
+ md.argtypes = p_args;
+ md.ret_type = p_ret_type;
+ method_map[p_name] = md;
+ }
+
+ void add_signal(const StringName &p_name, const Vector<Variant::Type> &p_args) {
+ if (p_args.size() == 0)
+ ADD_SIGNAL(MethodInfo(p_name));
+ else if (p_args.size() == 1)
+ ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1")));
+ else if (p_args.size() == 2)
+ ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"), PropertyInfo(p_args[1], "arg2")));
+ else if (p_args.size() == 3)
+ ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"), PropertyInfo(p_args[1], "arg2"), PropertyInfo(p_args[2], "arg3")));
+ else if (p_args.size() == 4)
+ ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"), PropertyInfo(p_args[1], "arg2"), PropertyInfo(p_args[2], "arg3"), PropertyInfo(p_args[3], "arg4")));
+ else if (p_args.size() == 5)
+ ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"), PropertyInfo(p_args[1], "arg2"), PropertyInfo(p_args[2], "arg3"), PropertyInfo(p_args[3], "arg4"), PropertyInfo(p_args[4], "arg5")));
+ }
+
+#endif
+
+ JNISingleton() {
+#ifdef ANDROID_ENABLED
+ instance = nullptr;
+#endif
+ }
+};
+
+#endif // JNI_SINGLETON_H
diff --git a/platform/android/detect.py b/platform/android/detect.py
index ed0643e3b3..6da1e5f3d6 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -25,7 +25,7 @@ def get_opts():
return [
("ANDROID_NDK_ROOT", "Path to the Android NDK", os.environ.get("ANDROID_NDK_ROOT", 0)),
- ("ndk_platform", 'Target platform (android-<api>, e.g. "android-18")', "android-18"),
+ ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")),
BoolVariable("android_neon", "Enable NEON support (armv7 only)", True),
]
@@ -102,7 +102,7 @@ def configure(env):
neon_text = ""
if env["android_arch"] == "armv7" and env["android_neon"]:
neon_text = " (with NEON)"
- print("Building for Android (" + env["android_arch"] + ")" + neon_text)
+ print("Building for Android, platform " + env["ndk_platform"] + " (" + env["android_arch"] + ")" + neon_text)
can_vectorize = True
if env["android_arch"] == "x86":
@@ -314,8 +314,8 @@ def configure(env):
)
env.Prepend(CPPPATH=["#platform/android"])
- env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED", "NO_FCNTL"])
- env.Append(LIBS=["OpenSLES", "EGL", "GLESv3", "GLESv2", "android", "log", "z", "dl"])
+ env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED", "VULKAN_ENABLED", "NO_FCNTL"])
+ env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "vulkan", "android", "log", "z", "dl"])
# Return NDK version string in source.properties (adapted from the Chromium project).
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
new file mode 100644
index 0000000000..9534387d35
--- /dev/null
+++ b/platform/android/display_server_android.cpp
@@ -0,0 +1,655 @@
+/*************************************************************************/
+/* display_server_android.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "display_server_android.h"
+
+#include "android_keys_utils.h"
+#include "core/project_settings.h"
+#include "java_godot_io_wrapper.h"
+#include "java_godot_wrapper.h"
+#include "os_android.h"
+
+#if defined(OPENGL_ENABLED)
+#include "drivers/gles2/rasterizer_gles2.h"
+#endif
+#if defined(VULKAN_ENABLED)
+#include "drivers/vulkan/rendering_device_vulkan.h"
+#include "platform/android/vulkan/vulkan_context_android.h"
+#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#endif
+
+DisplayServerAndroid *DisplayServerAndroid::get_singleton() {
+ return (DisplayServerAndroid *)DisplayServer::get_singleton();
+}
+
+bool DisplayServerAndroid::has_feature(Feature p_feature) const {
+ switch (p_feature) {
+ //case FEATURE_CONSOLE_WINDOW:
+ //case FEATURE_CURSOR_SHAPE:
+ //case FEATURE_CUSTOM_CURSOR_SHAPE:
+ //case FEATURE_GLOBAL_MENU:
+ //case FEATURE_HIDPI:
+ //case FEATURE_ICON:
+ //case FEATURE_IME:
+ //case FEATURE_MOUSE:
+ //case FEATURE_MOUSE_WARP:
+ //case FEATURE_NATIVE_DIALOG:
+ //case FEATURE_NATIVE_ICON:
+ //case FEATURE_NATIVE_VIDEO:
+ //case FEATURE_WINDOW_TRANSPARENCY:
+ case FEATURE_CLIPBOARD:
+ case FEATURE_KEEP_SCREEN_ON:
+ case FEATURE_ORIENTATION:
+ case FEATURE_TOUCHSCREEN:
+ case FEATURE_VIRTUAL_KEYBOARD:
+ return true;
+ default:
+ return false;
+ }
+}
+
+String DisplayServerAndroid::get_name() const {
+ return "Android";
+}
+
+void DisplayServerAndroid::clipboard_set(const String &p_text) {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_COND(!godot_java);
+
+ if (godot_java->has_set_clipboard()) {
+ godot_java->set_clipboard(p_text);
+ } else {
+ DisplayServer::clipboard_set(p_text);
+ }
+}
+
+String DisplayServerAndroid::clipboard_get() const {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_COND_V(!godot_java, String());
+
+ if (godot_java->has_get_clipboard()) {
+ return godot_java->get_clipboard();
+ } else {
+ return DisplayServer::clipboard_get();
+ }
+}
+
+void DisplayServerAndroid::screen_set_keep_on(bool p_enable) {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_COND(!godot_java);
+
+ godot_java->set_keep_screen_on(p_enable);
+ keep_screen_on = p_enable;
+}
+
+bool DisplayServerAndroid::screen_is_kept_on() const {
+ return keep_screen_on;
+}
+
+void DisplayServerAndroid::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND(!godot_io_java);
+
+ godot_io_java->set_screen_orientation(p_orientation);
+}
+
+DisplayServer::ScreenOrientation DisplayServerAndroid::screen_get_orientation(int p_screen) const {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND_V(!godot_io_java, SCREEN_LANDSCAPE);
+
+ return (ScreenOrientation)godot_io_java->get_screen_orientation();
+}
+
+int DisplayServerAndroid::get_screen_count() const {
+ return 1;
+}
+
+Point2i DisplayServerAndroid::screen_get_position(int p_screen) const {
+ return Point2i(0, 0);
+}
+
+Size2i DisplayServerAndroid::screen_get_size(int p_screen) const {
+ return OS_Android::get_singleton()->get_display_size();
+}
+
+Rect2i DisplayServerAndroid::screen_get_usable_rect(int p_screen) const {
+ Size2i display_size = OS_Android::get_singleton()->get_display_size();
+ return Rect2i(0, 0, display_size.width, display_size.height);
+}
+
+int DisplayServerAndroid::screen_get_dpi(int p_screen) const {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND_V(!godot_io_java, 0);
+
+ return godot_io_java->get_screen_dpi();
+}
+
+bool DisplayServerAndroid::screen_is_touchscreen(int p_screen) const {
+ return true;
+}
+
+void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length) {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND(!godot_io_java);
+
+ if (godot_io_java->has_vk()) {
+ godot_io_java->show_vk(p_existing_text, p_max_length);
+ } else {
+ ERR_PRINT("Virtual keyboard not available");
+ }
+}
+
+void DisplayServerAndroid::virtual_keyboard_hide() {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND(!godot_io_java);
+
+ if (godot_io_java->has_vk()) {
+ godot_io_java->hide_vk();
+ } else {
+ ERR_PRINT("Virtual keyboard not available");
+ }
+}
+
+int DisplayServerAndroid::virtual_keyboard_get_height() const {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND_V(!godot_io_java, 0);
+
+ return godot_io_java->get_vk_height();
+}
+
+void DisplayServerAndroid::window_set_window_event_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ window_event_callback = p_callable;
+}
+
+void DisplayServerAndroid::window_set_input_event_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ input_event_callback = p_callable;
+}
+
+void DisplayServerAndroid::window_set_input_text_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ input_text_callback = p_callable;
+}
+
+void DisplayServerAndroid::window_set_rect_changed_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::window_set_drop_files_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
+ if (!p_callable.is_null()) {
+ const Variant *argp = &p_arg;
+ Variant ret;
+ Callable::CallError ce;
+ p_callable.call((const Variant **)&argp, 1, ret, ce);
+ }
+}
+
+void DisplayServerAndroid::send_window_event(DisplayServer::WindowEvent p_event) const {
+ _window_callback(window_event_callback, int(p_event));
+}
+
+void DisplayServerAndroid::send_input_event(const Ref<InputEvent> &p_event) const {
+ _window_callback(input_event_callback, p_event);
+}
+
+void DisplayServerAndroid::send_input_text(const String &p_text) const {
+ _window_callback(input_text_callback, p_text);
+}
+
+void DisplayServerAndroid::_dispatch_input_events(const Ref<InputEvent> &p_event) {
+ DisplayServerAndroid::get_singleton()->send_input_event(p_event);
+}
+
+Vector<DisplayServer::WindowID> DisplayServerAndroid::get_window_list() const {
+ Vector<WindowID> ret;
+ ret.push_back(MAIN_WINDOW_ID);
+ return ret;
+}
+
+DisplayServer::WindowID DisplayServerAndroid::get_window_at_screen_position(const Point2i &p_position) const {
+ return MAIN_WINDOW_ID;
+}
+
+void DisplayServerAndroid::window_attach_instance_id(ObjectID p_instance, DisplayServer::WindowID p_window) {
+ window_attached_instance_id = p_instance;
+}
+
+ObjectID DisplayServerAndroid::window_get_attached_instance_id(DisplayServer::WindowID p_window) const {
+ return window_attached_instance_id;
+}
+
+void DisplayServerAndroid::window_set_title(const String &p_title, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+int DisplayServerAndroid::window_get_current_screen(DisplayServer::WindowID p_window) const {
+ return SCREEN_OF_MAIN_WINDOW;
+}
+
+void DisplayServerAndroid::window_set_current_screen(int p_screen, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+Point2i DisplayServerAndroid::window_get_position(DisplayServer::WindowID p_window) const {
+ return Point2i();
+}
+
+void DisplayServerAndroid::window_set_position(const Point2i &p_position, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::window_set_transient(DisplayServer::WindowID p_window, DisplayServer::WindowID p_parent) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::window_set_max_size(const Size2i p_size, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+Size2i DisplayServerAndroid::window_get_max_size(DisplayServer::WindowID p_window) const {
+ return Size2i();
+}
+
+void DisplayServerAndroid::window_set_min_size(const Size2i p_size, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+Size2i DisplayServerAndroid::window_get_min_size(DisplayServer::WindowID p_window) const {
+ return Size2i();
+}
+
+void DisplayServerAndroid::window_set_size(const Size2i p_size, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+Size2i DisplayServerAndroid::window_get_size(DisplayServer::WindowID p_window) const {
+ return OS_Android::get_singleton()->get_display_size();
+}
+
+Size2i DisplayServerAndroid::window_get_real_size(DisplayServer::WindowID p_window) const {
+ return OS_Android::get_singleton()->get_display_size();
+}
+
+void DisplayServerAndroid::window_set_mode(DisplayServer::WindowMode p_mode, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+DisplayServer::WindowMode DisplayServerAndroid::window_get_mode(DisplayServer::WindowID p_window) const {
+ return WINDOW_MODE_FULLSCREEN;
+}
+
+bool DisplayServerAndroid::window_is_maximize_allowed(DisplayServer::WindowID p_window) const {
+ return false;
+}
+
+void DisplayServerAndroid::window_set_flag(DisplayServer::WindowFlags p_flag, bool p_enabled, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+bool DisplayServerAndroid::window_get_flag(DisplayServer::WindowFlags p_flag, DisplayServer::WindowID p_window) const {
+ return false;
+}
+
+void DisplayServerAndroid::window_request_attention(DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::window_move_to_foreground(DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+bool DisplayServerAndroid::window_can_draw(DisplayServer::WindowID p_window) const {
+ return true;
+}
+
+bool DisplayServerAndroid::can_any_window_draw() const {
+ return true;
+}
+
+void DisplayServerAndroid::alert(const String &p_alert, const String &p_title) {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_COND(!godot_java);
+
+ godot_java->alert(p_alert, p_title);
+}
+
+void DisplayServerAndroid::process_events() {
+ // Nothing to do
+}
+
+Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
+ Vector<String> drivers;
+
+#ifdef OPENGL_ENABLED
+ drivers.push_back("opengl");
+#endif
+#ifdef VULKAN_ENABLED
+ drivers.push_back("vulkan");
+#endif
+
+ return drivers;
+}
+
+DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ return memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+}
+
+void DisplayServerAndroid::register_android_driver() {
+ register_create_function("android", create_func, get_rendering_drivers_func);
+}
+
+DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ rendering_driver = p_rendering_driver;
+
+ // TODO: rendering_driver is broken, change when different drivers are supported again
+ rendering_driver = "vulkan";
+
+ keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
+
+#if defined(OPENGL_ENABLED)
+ if (rendering_driver == "opengl") {
+ bool gl_initialization_error = false;
+
+ if (RasterizerGLES2::is_viable() == OK) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ } else {
+ gl_initialization_error = true;
+ }
+
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n"
+ "Please try updating your Android version.",
+ "Unable to initialize video driver");
+ return;
+ }
+ }
+#endif
+
+#if defined(VULKAN_ENABLED)
+ context_vulkan = nullptr;
+ rendering_device_vulkan = nullptr;
+
+ if (rendering_driver == "vulkan") {
+ ANativeWindow *native_window = OS_Android::get_singleton()->get_native_window();
+ ERR_FAIL_COND(!native_window);
+
+ context_vulkan = memnew(VulkanContextAndroid);
+ if (context_vulkan->initialize() != OK) {
+ memdelete(context_vulkan);
+ context_vulkan = nullptr;
+ ERR_FAIL_MSG("Failed to initialize Vulkan context");
+ }
+
+ Size2i display_size = OS_Android::get_singleton()->get_display_size();
+ if (context_vulkan->window_create(native_window, display_size.width, display_size.height) == -1) {
+ memdelete(context_vulkan);
+ context_vulkan = nullptr;
+ ERR_FAIL_MSG("Failed to create Vulkan window.");
+ }
+
+ rendering_device_vulkan = memnew(RenderingDeviceVulkan);
+ rendering_device_vulkan->initialize(context_vulkan);
+
+ RasterizerRD::make_current();
+ }
+#endif
+
+ InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
+}
+
+DisplayServerAndroid::~DisplayServerAndroid() {
+#if defined(VULKAN_ENABLED)
+ if (rendering_driver == "vulkan") {
+ if (rendering_device_vulkan) {
+ rendering_device_vulkan->finalize();
+ memdelete(rendering_device_vulkan);
+ }
+
+ if (context_vulkan) {
+ memdelete(context_vulkan);
+ }
+ }
+#endif
+}
+
+void DisplayServerAndroid::process_joy_event(DisplayServerAndroid::JoypadEvent p_event) {
+ switch (p_event.type) {
+ case JOY_EVENT_BUTTON:
+ InputFilter::get_singleton()->joy_button(p_event.device, p_event.index, p_event.pressed);
+ break;
+ case JOY_EVENT_AXIS:
+ InputFilter::JoyAxis value;
+ value.min = -1;
+ value.value = p_event.value;
+ InputFilter::get_singleton()->joy_axis(p_event.device, p_event.index, value);
+ break;
+ case JOY_EVENT_HAT:
+ InputFilter::get_singleton()->joy_hat(p_event.device, p_event.hat);
+ break;
+ default:
+ return;
+ }
+}
+
+void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) {
+ Ref<InputEventKey> ev;
+ ev.instance();
+ int val = p_unicode_char;
+ int keycode = android_get_keysym(p_keycode);
+ int phy_keycode = android_get_keysym(p_scancode);
+ ev->set_keycode(keycode);
+ ev->set_physical_keycode(phy_keycode);
+ ev->set_unicode(val);
+ ev->set_pressed(p_pressed);
+
+ if (val == '\n') {
+ ev->set_keycode(KEY_ENTER);
+ } else if (val == 61448) {
+ ev->set_keycode(KEY_BACKSPACE);
+ ev->set_unicode(KEY_BACKSPACE);
+ } else if (val == 61453) {
+ ev->set_keycode(KEY_ENTER);
+ ev->set_unicode(KEY_ENTER);
+ } else if (p_keycode == 4) {
+ OS_Android::get_singleton()->main_loop_request_go_back();
+ }
+
+ InputFilter::get_singleton()->parse_input_event(ev);
+}
+
+void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector<DisplayServerAndroid::TouchPos> &p_points) {
+ switch (p_what) {
+ case 0: { //gesture begin
+ if (touch.size()) {
+ //end all if exist
+ for (int i = 0; i < touch.size(); i++) {
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ }
+ }
+
+ touch.resize(p_points.size());
+ for (int i = 0; i < p_points.size(); i++) {
+ touch.write[i].id = p_points[i].id;
+ touch.write[i].pos = p_points[i].pos;
+ }
+
+ //send touch
+ for (int i = 0; i < touch.size(); i++) {
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(true);
+ ev->set_position(touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ }
+
+ } break;
+ case 1: { //motion
+ ERR_FAIL_COND(touch.size() != p_points.size());
+
+ for (int i = 0; i < touch.size(); i++) {
+
+ int idx = -1;
+ for (int j = 0; j < p_points.size(); j++) {
+
+ if (touch[i].id == p_points[j].id) {
+ idx = j;
+ break;
+ }
+ }
+
+ ERR_CONTINUE(idx == -1);
+
+ if (touch[i].pos == p_points[idx].pos)
+ continue; //no move unncesearily
+
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_position(p_points[idx].pos);
+ ev->set_relative(p_points[idx].pos - touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ touch.write[i].pos = p_points[idx].pos;
+ }
+
+ } break;
+ case 2: { //release
+ if (touch.size()) {
+ //end all if exist
+ for (int i = 0; i < touch.size(); i++) {
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ }
+ touch.clear();
+ }
+ } break;
+ case 3: { // add touch
+ for (int i = 0; i < p_points.size(); i++) {
+ if (p_points[i].id == p_pointer) {
+ TouchPos tp = p_points[i];
+ touch.push_back(tp);
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+
+ ev->set_index(tp.id);
+ ev->set_pressed(true);
+ ev->set_position(tp.pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+
+ break;
+ }
+ }
+ } break;
+ case 4: { // remove touch
+ for (int i = 0; i < touch.size(); i++) {
+ if (touch[i].id == p_pointer) {
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ touch.remove(i);
+
+ break;
+ }
+ }
+ } break;
+ }
+}
+
+void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) {
+ // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER
+ switch (p_type) {
+ case 7: // hover move
+ case 9: // hover enter
+ case 10: { // hover exit
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
+ ev->set_position(p_pos);
+ ev->set_global_position(p_pos);
+ ev->set_relative(p_pos - hover_prev_pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ hover_prev_pos = p_pos;
+ } break;
+ }
+}
+
+void DisplayServerAndroid::process_double_tap(Point2 p_pos) {
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_position(p_pos);
+ ev->set_global_position(p_pos);
+ ev->set_pressed(false);
+ ev->set_doubleclick(true);
+ InputFilter::get_singleton()->parse_input_event(ev);
+}
+
+void DisplayServerAndroid::process_scroll(Point2 p_pos) {
+ Ref<InputEventPanGesture> ev;
+ ev.instance();
+ ev->set_position(p_pos);
+ ev->set_delta(p_pos - scroll_prev_pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ scroll_prev_pos = p_pos;
+}
+
+void DisplayServerAndroid::process_accelerometer(const Vector3 &p_accelerometer) {
+ InputFilter::get_singleton()->set_accelerometer(p_accelerometer);
+}
+
+void DisplayServerAndroid::process_gravity(const Vector3 &p_gravity) {
+ InputFilter::get_singleton()->set_gravity(p_gravity);
+}
+
+void DisplayServerAndroid::process_magnetometer(const Vector3 &p_magnetometer) {
+ InputFilter::get_singleton()->set_magnetometer(p_magnetometer);
+}
+
+void DisplayServerAndroid::process_gyroscope(const Vector3 &p_gyroscope) {
+ InputFilter::get_singleton()->set_gyroscope(p_gyroscope);
+}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
new file mode 100644
index 0000000000..2096ba68f1
--- /dev/null
+++ b/platform/android/display_server_android.h
@@ -0,0 +1,174 @@
+/*************************************************************************/
+/* display_server_android.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef DISPLAY_SERVER_ANDROID_H
+#define DISPLAY_SERVER_ANDROID_H
+
+#include "servers/display_server.h"
+
+#if defined(VULKAN_ENABLED)
+class VulkanContextAndroid;
+class RenderingDeviceVulkan;
+#endif
+
+class DisplayServerAndroid : public DisplayServer {
+public:
+ struct TouchPos {
+ int id;
+ Point2 pos;
+ };
+
+ enum {
+ JOY_EVENT_BUTTON = 0,
+ JOY_EVENT_AXIS = 1,
+ JOY_EVENT_HAT = 2
+ };
+
+ struct JoypadEvent {
+
+ int device;
+ int type;
+ int index;
+ bool pressed;
+ float value;
+ int hat;
+ };
+
+private:
+ String rendering_driver;
+
+ bool keep_screen_on;
+
+ Vector<TouchPos> touch;
+ Point2 hover_prev_pos; // needed to calculate the relative position on hover events
+ Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events
+
+#if defined(VULKAN_ENABLED)
+ VulkanContextAndroid *context_vulkan;
+ RenderingDeviceVulkan *rendering_device_vulkan;
+#endif
+
+ ObjectID window_attached_instance_id;
+
+ Callable window_event_callback;
+ Callable input_event_callback;
+ Callable input_text_callback;
+
+ void _window_callback(const Callable &p_callable, const Variant &p_arg) const;
+
+ static void _dispatch_input_events(const Ref<InputEvent> &p_event);
+
+public:
+ static DisplayServerAndroid *get_singleton();
+
+ virtual bool has_feature(Feature p_feature) const;
+ virtual String get_name() const;
+
+ virtual void clipboard_set(const String &p_text);
+ virtual String clipboard_get() const;
+
+ virtual void screen_set_keep_on(bool p_enable);
+ virtual bool screen_is_kept_on() const;
+
+ virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW);
+ virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+
+ virtual int get_screen_count() const;
+ virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+
+ virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1);
+ virtual void virtual_keyboard_hide();
+ virtual int virtual_keyboard_get_height() const;
+
+ virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+
+ void send_window_event(WindowEvent p_event) const;
+ void send_input_event(const Ref<InputEvent> &p_event) const;
+ void send_input_text(const String &p_text) const;
+
+ virtual Vector<WindowID> get_window_list() const;
+ virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
+ virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID);
+ virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
+ virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_transient(WindowID p_window, WindowID p_parent);
+ virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID);
+ virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID);
+ virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID);
+ virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual bool can_any_window_draw() const;
+
+ virtual void alert(const String &p_alert, const String &p_title);
+
+ virtual void process_events();
+
+ void process_accelerometer(const Vector3 &p_accelerometer);
+ void process_gravity(const Vector3 &p_gravity);
+ void process_magnetometer(const Vector3 &p_magnetometer);
+ void process_gyroscope(const Vector3 &p_gyroscope);
+ void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
+ void process_hover(int p_type, Point2 p_pos);
+ void process_double_tap(Point2 p_pos);
+ void process_scroll(Point2 p_pos);
+ void process_joy_event(JoypadEvent p_event);
+ void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed);
+
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static Vector<String> get_rendering_drivers_func();
+ static void register_android_driver();
+
+ DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ ~DisplayServerAndroid();
+};
+
+#endif // DISPLAY_SERVER_ANDROID_H
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index b6c30d120c..1eb1ee0d29 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1932,6 +1932,7 @@ public:
ImageLoader::load_image(path, launcher_adaptive_icon_background_image);
}
+ Vector<String> invalid_abis(enabled_abis);
while (ret == UNZ_OK) {
//get filename
@@ -1977,6 +1978,7 @@ public:
bool enabled = false;
for (int i = 0; i < enabled_abis.size(); ++i) {
if (file.begins_with("lib/" + enabled_abis[i] + "/")) {
+ invalid_abis.erase(enabled_abis[i]);
enabled = true;
break;
}
@@ -2016,6 +2018,13 @@ public:
ret = unzGoToNextFile(pkg);
}
+ if (!invalid_abis.empty()) {
+ String unsupported_arch = String(", ").join(invalid_abis);
+ EditorNode::add_io_error("Missing libraries in the export template for the selected architectures: " + unsupported_arch + ".\n" +
+ "Please build a template with all required libraries, or uncheck the missing architectures in the export preset.");
+ CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
+ }
+
if (ep.step("Adding files...", 1)) {
CLEANUP_AND_RETURN(ERR_SKIP);
}
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index 1a3bb77670..9ae47d6174 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -56,6 +56,11 @@ android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
+ compileOptions {
+ sourceCompatibility 1.8
+ targetCompatibility 1.8
+ }
+
defaultConfig {
// Feel free to modify the application id to your own.
applicationId getExportPackageName()
@@ -71,7 +76,9 @@ android {
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
- doNotStrip '**/*.so'
+
+ // Should be uncommented for development purpose within Android Studio
+ // doNotStrip '**/*.so'
}
// Both signing and zip-aligning will be done at export time
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 96cfd272f2..aa98194a10 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -3,7 +3,7 @@ ext.versions = [
compileSdk : 29,
minSdk : 18,
targetSdk : 29,
- buildTools : '29.0.1',
+ buildTools : '29.0.3',
supportCoreUtils : '28.0.0',
kotlinVersion : '1.3.61',
v4Support : '28.0.0'
diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle
new file mode 100644
index 0000000000..33b863c7bf
--- /dev/null
+++ b/platform/android/java/app/settings.gradle
@@ -0,0 +1,2 @@
+// Empty settings.gradle file to denote this directory as being the root project
+// of the Godot custom build.
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index b133585f99..fa39bc0f1d 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -13,7 +13,7 @@
<instrumentation
android:icon="@mipmap/icon"
android:label="@string/godot_project_name_string"
- android:name=".GodotInstrumentation"
+ android:name="org.godotengine.godot.GodotInstrumentation"
android:targetPackage="org.godotengine.godot" />
</manifest>
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index 062f91e08e..19eee5a315 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -1,4 +1,5 @@
apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
dependencies {
implementation libraries.supportCoreUtils
@@ -11,7 +12,6 @@ def pathToRootDir = "../../../../"
android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
- useLibrary 'org.apache.http.legacy'
defaultConfig {
minSdkVersion versions.minSdk
@@ -26,7 +26,9 @@ android {
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
- doNotStrip '**/*.so'
+
+ // Should be uncommented for development purpose within Android Studio
+ // doNotStrip '**/*.so'
}
sourceSets {
diff --git a/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index f849d8e90d..0000000000
--- a/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index 1dfb28b33a..0000000000
--- a/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index 372b763ec5..0000000000
--- a/platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index 302a972049..0000000000
--- a/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index 1798a1df3a..bf0d1c6273 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -153,7 +153,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
private String[] command_line;
private boolean use_apk_expansion;
- public GodotView mView;
+ public GodotRenderView mRenderView;
private boolean godot_initialized = false;
private SensorManager mSensorManager;
@@ -213,34 +213,41 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
setContentView(layout);
// GodotEditText layout
- GodotEditText edittext = new GodotEditText(this);
- edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+ GodotEditText editText = new GodotEditText(this);
+ editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
// ...add to FrameLayout
- layout.addView(edittext);
+ layout.addView(editText);
- mView = new GodotView(this, xrMode, use_32_bits, use_debug_opengl);
- layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- edittext.setView(mView);
- io.setEdit(edittext);
+ GodotLib.setup(command_line);
- mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ final String videoDriver = GodotLib.getGlobal("rendering/quality/driver/driver_name");
+ if (videoDriver.equals("Vulkan")) {
+ mRenderView = new GodotVulkanRenderView(this);
+ } else {
+ mRenderView = new GodotGLRenderView(this, xrMode, use_32_bits, use_debug_opengl);
+ }
+
+ View view = mRenderView.getView();
+ layout.addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ editText.setView(mRenderView);
+ io.setEdit(editText);
+
+ view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Point fullSize = new Point();
getWindowManager().getDefaultDisplay().getSize(fullSize);
Rect gameSize = new Rect();
- mView.getWindowVisibleDisplayFrame(gameSize);
+ mRenderView.getView().getWindowVisibleDisplayFrame(gameSize);
final int keyboardHeight = fullSize.y - gameSize.bottom;
GodotLib.setVirtualKeyboardHeight(keyboardHeight);
}
});
- final String[] current_command_line = command_line;
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
- GodotLib.setup(current_command_line);
// Must occur after GodotLib.setup has completed.
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
@@ -384,7 +391,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
*/
@Keep
private Surface getSurface() {
- return mView.getHolder().getSurface();
+ return mRenderView.getView().getHolder().getSurface();
}
/**
@@ -617,7 +624,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
return;
}
- mView.onPause();
+ mRenderView.onActivityPaused();
mSensorManager.unregisterListener(this);
@@ -655,7 +662,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
return;
}
- mView.onResume();
+ mRenderView.onActivityResumed();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mGravity, SensorManager.SENSOR_DELAY_GAME);
@@ -721,8 +728,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
final float z = adjustedValues[2];
final int typeOfSensor = event.sensor.getType();
- if (mView != null) {
- mView.queueEvent(new Runnable() {
+ if (mRenderView != null) {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) {
@@ -773,8 +780,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
}
- if (shouldQuit && mView != null) {
- mView.queueEvent(new Runnable() {
+ if (shouldQuit && mRenderView != null) {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
GodotLib.back();
@@ -789,8 +796,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
* This must be called after the render thread has started.
*/
public final void runOnRenderThread(@NonNull Runnable action) {
- if (mView != null) {
- mView.queueEvent(action);
+ if (mRenderView != null) {
+ mRenderView.queueOnRenderThread(action);
}
}
@@ -847,7 +854,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
if (evcount == 0)
return true;
- if (mView != null) {
+ if (mRenderView != null) {
final int[] arr = new int[event.getPointerCount() * 3];
for (int i = 0; i < event.getPointerCount(); i++) {
@@ -860,7 +867,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
//System.out.printf("gaction: %d\n",event.getAction());
final int action = event.getAction() & MotionEvent.ACTION_MASK;
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
switch (action) {
@@ -911,7 +918,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0)
;
if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
// This method will be called on the rendering thread:
public void run() {
for (int i = 0, n = cc.length; i < n; i++) {
@@ -1033,6 +1040,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
progress.mOverallTotal));
}
public void initInputDevices() {
- mView.initInputDevices();
+ mRenderView.initInputDevices();
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index 8d3c2ae319..9be93243b8 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotView.java */
+/* GodotGLRenderView.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -35,6 +35,7 @@ import android.opengl.GLSurfaceView;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.SurfaceView;
import org.godotengine.godot.input.GodotGestureHandler;
import org.godotengine.godot.input.GodotInputHandler;
import org.godotengine.godot.utils.GLUtils;
@@ -64,16 +65,14 @@ import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser;
* that matches it exactly (with regards to red/green/blue/alpha channels
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
*/
-public class GodotView extends GLSurfaceView {
-
- private static String TAG = GodotView.class.getSimpleName();
+public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView {
private final Godot activity;
private final GodotInputHandler inputHandler;
private final GestureDetector detector;
private final GodotRenderer godotRenderer;
- public GodotView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) {
+ public GodotGLRenderView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) {
super(activity);
GLUtils.use_32 = p_use_32_bits;
GLUtils.use_debug_opengl = p_use_debug_opengl;
@@ -85,10 +84,36 @@ public class GodotView extends GLSurfaceView {
init(xrMode, false, 16, 0);
}
+ @Override
+ public SurfaceView getView() {
+ return this;
+ }
+
+ @Override
public void initInputDevices() {
this.inputHandler.initInputDevices();
}
+ @Override
+ public void queueOnRenderThread(Runnable event) {
+ queueEvent(event);
+ }
+
+ @Override
+ public void onActivityPaused() {
+ onPause();
+ }
+
+ @Override
+ public void onActivityResumed() {
+ onResume();
+ }
+
+ @Override
+ public void onBackPressed() {
+ activity.onBackPressed();
+ }
+
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
@@ -170,10 +195,6 @@ public class GodotView extends GLSurfaceView {
setRenderer(godotRenderer);
}
- public void onBackPressed() {
- activity.onBackPressed();
- }
-
@Override
public void onResume() {
super.onResume();
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index 68ce40ba10..016a3a8d18 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -53,8 +53,6 @@ public class GodotIO {
Godot activity;
GodotEditText edit;
- MediaPlayer mediaPlayer;
-
final int SCREEN_LANDSCAPE = 0;
final int SCREEN_PORTRAIT = 1;
final int SCREEN_REVERSE_LANDSCAPE = 2;
@@ -530,44 +528,14 @@ public class GodotIO {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
} break;
}
- };
-
- public void setEdit(GodotEditText _edit) {
- edit = _edit;
- }
-
- public void playVideo(String p_path) {
- Uri filePath = Uri.parse(p_path);
- mediaPlayer = new MediaPlayer();
-
- try {
- mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
- mediaPlayer.setDataSource(activity.getApplicationContext(), filePath);
- mediaPlayer.prepare();
- mediaPlayer.start();
- } catch (IOException e) {
- System.out.println("IOError while playing video");
- }
}
- public boolean isVideoPlaying() {
- if (mediaPlayer != null) {
- return mediaPlayer.isPlaying();
- }
- return false;
+ public int getScreenOrientation() {
+ return activity.getRequestedOrientation();
}
- public void pauseVideo() {
- if (mediaPlayer != null) {
- mediaPlayer.pause();
- }
- }
-
- public void stopVideo() {
- if (mediaPlayer != null) {
- mediaPlayer.release();
- mediaPlayer = null;
- }
+ public void setEdit(GodotEditText _edit) {
+ edit = _edit;
}
public static final int SYSTEM_DIR_DESKTOP = 0;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 89a65aea24..71fe822233 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -32,6 +32,7 @@ package org.godotengine.godot;
import android.app.Activity;
import android.hardware.SensorEvent;
+import android.view.Surface;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
@@ -72,11 +73,11 @@ public class GodotLib {
public static native void resize(int width, int height);
/**
- * Invoked on the GL thread when the underlying Android surface is created or recreated.
+ * Invoked on the render thread when the underlying Android surface is created or recreated.
+ * @param p_surface
* @param p_32_bits
- * @see android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)
*/
- public static native void newcontext(boolean p_32_bits);
+ public static native void newcontext(Surface p_surface, boolean p_32_bits);
/**
* Forward {@link Activity#onBackPressed()} event from the main thread to the GL thread.
diff --git a/platform/android/vulkan/vk_renderer_jni.h b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
index 017766fea2..170c433c9c 100644
--- a/platform/android/vulkan/vk_renderer_jni.h
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vk_renderer_jni.h */
+/* GodotRenderView.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,19 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VK_RENDERER_JNI_H
-#define VK_RENDERER_JNI_H
+package org.godotengine.godot;
-#include <android/log.h>
-#include <jni.h>
+import android.view.SurfaceView;
-extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceCreated(JNIEnv *env, jobject obj, jobject j_surface);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceChanged(JNIEnv *env, jobject object, jobject j_surface, jint width, jint height);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkResume(JNIEnv *env, jobject obj);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDrawFrame(JNIEnv *env, jobject obj);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkPause(JNIEnv *env, jobject obj);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDestroy(JNIEnv *env, jobject obj);
-}
+public interface GodotRenderView {
+
+ abstract public SurfaceView getView();
+
+ abstract public void initInputDevices();
-#endif // VK_RENDERER_JNI_H
+ abstract public void queueOnRenderThread(Runnable event);
+
+ abstract public void onActivityPaused();
+ abstract public void onActivityResumed();
+
+ abstract public void onBackPressed();
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
index ee9a2aee4f..3e5bb4a4c9 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
@@ -70,7 +70,7 @@ class GodotRenderer implements GLSurfaceView.Renderer {
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- GodotLib.newcontext(GLUtils.use_32);
+ GodotLib.newcontext(null, GLUtils.use_32);
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
plugin.onGLSurfaceCreated(gl, config);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
new file mode 100644
index 0000000000..30197d5729
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -0,0 +1,142 @@
+/*************************************************************************/
+/* GodotVulkanRenderView.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot;
+
+import android.annotation.SuppressLint;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.SurfaceView;
+import org.godotengine.godot.input.GodotGestureHandler;
+import org.godotengine.godot.input.GodotInputHandler;
+import org.godotengine.godot.vulkan.VkRenderer;
+import org.godotengine.godot.vulkan.VkSurfaceView;
+
+public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView {
+
+ private final Godot mActivity;
+ private final GodotInputHandler mInputHandler;
+ private final GestureDetector mGestureDetector;
+ private final VkRenderer mRenderer;
+
+ public GodotVulkanRenderView(Godot activity) {
+ super(activity);
+
+ mActivity = activity;
+ mInputHandler = new GodotInputHandler(this);
+ mGestureDetector = new GestureDetector(mActivity, new GodotGestureHandler(this));
+ mRenderer = new VkRenderer();
+
+ setFocusableInTouchMode(true);
+ startRenderer(mRenderer);
+ }
+
+ @Override
+ public SurfaceView getView() {
+ return this;
+ }
+
+ @Override
+ public void initInputDevices() {
+ mInputHandler.initInputDevices();
+ }
+
+ @Override
+ public void queueOnRenderThread(Runnable event) {
+ queueOnVkThread(event);
+ }
+
+ @Override
+ public void onActivityPaused() {
+ onPause();
+ }
+
+ @Override
+ public void onActivityResumed() {
+ onResume();
+ }
+
+ @Override
+ public void onBackPressed() {
+ mActivity.onBackPressed();
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ super.onTouchEvent(event);
+ mGestureDetector.onTouchEvent(event);
+ return mActivity.gotTouchEvent(event);
+ }
+
+ @Override
+ public boolean onKeyUp(final int keyCode, KeyEvent event) {
+ return mInputHandler.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyDown(final int keyCode, KeyEvent event) {
+ return mInputHandler.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ return mInputHandler.onGenericMotionEvent(event) || super.onGenericMotionEvent(event);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ queueOnVkThread(new Runnable() {
+ @Override
+ public void run() {
+ // Resume the renderer
+ mRenderer.onVkResume();
+ GodotLib.focusin();
+ }
+ });
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ queueOnVkThread(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.focusout();
+ // Pause the renderer
+ mRenderer.onVkPause();
+ }
+ });
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
index e901b4b36d..92bb118e44 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
@@ -51,7 +51,7 @@ public class GodotEditText extends EditText {
// ===========================================================
// Fields
// ===========================================================
- private GodotView mView;
+ private GodotRenderView mRenderView;
private GodotTextInputWrapper mInputWrapper;
private EditHandler sHandler = new EditHandler(this);
private String mOriginText;
@@ -76,22 +76,22 @@ public class GodotEditText extends EditText {
// ===========================================================
public GodotEditText(final Context context) {
super(context);
- this.initView();
+ initView();
}
public GodotEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
- this.initView();
+ initView();
}
public GodotEditText(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
- this.initView();
+ initView();
}
protected void initView() {
- this.setPadding(0, 0, 0, 0);
- this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
+ setPadding(0, 0, 0, 0);
+ setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
}
private void handleMessage(final Message msg) {
@@ -106,7 +106,7 @@ public class GodotEditText extends EditText {
edit.mInputWrapper.setOriginText(text);
edit.addTextChangedListener(edit.mInputWrapper);
setMaxInputLength(edit, msg.arg1);
- final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edit, 0);
}
} break;
@@ -115,9 +115,9 @@ public class GodotEditText extends EditText {
GodotEditText edit = (GodotEditText)msg.obj;
edit.removeTextChangedListener(mInputWrapper);
- final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
- edit.mView.requestFocus();
+ edit.mRenderView.getView().requestFocus();
} break;
}
}
@@ -135,12 +135,12 @@ public class GodotEditText extends EditText {
// ===========================================================
// Getter & Setter
// ===========================================================
- public void setView(final GodotView view) {
- this.mView = view;
+ public void setView(final GodotRenderView view) {
+ mRenderView = view;
if (mInputWrapper == null)
- mInputWrapper = new GodotTextInputWrapper(mView, this);
- this.setOnEditorActionListener(mInputWrapper);
- view.requestFocus();
+ mInputWrapper = new GodotTextInputWrapper(mRenderView, this);
+ setOnEditorActionListener(mInputWrapper);
+ view.getView().requestFocus();
}
// ===========================================================
@@ -152,7 +152,7 @@ public class GodotEditText extends EditText {
/* Let GlSurfaceView get focus if back key is input. */
if (keyCode == KeyEvent.KEYCODE_BACK) {
- this.mView.requestFocus();
+ mRenderView.getView().requestFocus();
}
return true;
@@ -162,7 +162,7 @@ public class GodotEditText extends EditText {
// Methods
// ===========================================================
public void showKeyboard(String p_existing_text, int p_max_input_length) {
- this.mOriginText = p_existing_text;
+ mOriginText = p_existing_text;
final Message msg = new Message();
msg.what = HANDLER_OPEN_IME_KEYBOARD;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
index 1a38a9c3d2..b1e0f66373 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -34,22 +34,22 @@ import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.GodotView;
+import org.godotengine.godot.GodotRenderView;
/**
- * Handles gesture input related events for the {@link GodotView} view.
+ * Handles gesture input related events for the {@link GodotRenderView} view.
* https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener
*/
public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener {
- private final GodotView godotView;
+ private final GodotRenderView mRenderView;
- public GodotGestureHandler(GodotView godotView) {
- this.godotView = godotView;
+ public GodotGestureHandler(GodotRenderView godotView) {
+ mRenderView = godotView;
}
private void queueEvent(Runnable task) {
- godotView.queueEvent(task);
+ mRenderView.queueOnRenderThread(task);
}
@Override
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index e00ca86c41..0e4fc65119 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -42,27 +42,27 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.GodotView;
+import org.godotengine.godot.GodotRenderView;
import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
/**
- * Handles input related events for the {@link GodotView} view.
+ * Handles input related events for the {@link GodotRenderView} view.
*/
public class GodotInputHandler implements InputDeviceListener {
- private final ArrayList<Joystick> joysticksDevices = new ArrayList<Joystick>();
+ private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>();
- private final GodotView godotView;
- private final InputManagerCompat inputManager;
+ private final GodotRenderView mRenderView;
+ private final InputManagerCompat mInputManager;
- public GodotInputHandler(GodotView godotView) {
- this.godotView = godotView;
- this.inputManager = InputManagerCompat.Factory.getInputManager(godotView.getContext());
- this.inputManager.registerInputDeviceListener(this, null);
+ public GodotInputHandler(GodotRenderView godotView) {
+ mRenderView = godotView;
+ mInputManager = InputManagerCompat.Factory.getInputManager(mRenderView.getView().getContext());
+ mInputManager.registerInputDeviceListener(this, null);
}
private void queueEvent(Runnable task) {
- godotView.queueEvent(task);
+ mRenderView.queueOnRenderThread(task);
}
private boolean isKeyEvent_GameDevice(int source) {
@@ -113,7 +113,7 @@ public class GodotInputHandler implements InputDeviceListener {
public boolean onKeyDown(final int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
- godotView.onBackPressed();
+ mRenderView.onBackPressed();
// press 'back' button should not terminate program
//normal handle 'back' event in game logic
return true;
@@ -164,7 +164,7 @@ public class GodotInputHandler implements InputDeviceListener {
// Check if the device exists
if (device_id > -1) {
- Joystick joy = joysticksDevices.get(device_id);
+ Joystick joy = mJoysticksDevices.get(device_id);
for (int i = 0; i < joy.axes.size(); i++) {
InputDevice.MotionRange range = joy.axes.get(i);
@@ -208,11 +208,11 @@ public class GodotInputHandler implements InputDeviceListener {
public void initInputDevices() {
/* initially add input devices*/
- int[] deviceIds = inputManager.getInputDeviceIds();
+ int[] deviceIds = mInputManager.getInputDeviceIds();
for (int deviceId : deviceIds) {
- InputDevice device = inputManager.getInputDevice(deviceId);
+ InputDevice device = mInputManager.getInputDevice(deviceId);
if (DEBUG) {
- Log.v("GodotView", String.format("init() deviceId:%d, Name:%s\n", deviceId, device.getName()));
+ Log.v("GodotInputHandler", String.format("init() deviceId:%d, Name:%s\n", deviceId, device.getName()));
}
onInputDeviceAdded(deviceId);
}
@@ -224,13 +224,13 @@ public class GodotInputHandler implements InputDeviceListener {
// Check if the device has not been already added
if (id < 0) {
- InputDevice device = inputManager.getInputDevice(deviceId);
+ InputDevice device = mInputManager.getInputDevice(deviceId);
//device can be null if deviceId is not found
if (device != null) {
int sources = device.getSources();
if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ||
((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) {
- id = joysticksDevices.size();
+ id = mJoysticksDevices.size();
Joystick joy = new Joystick();
joy.device_id = deviceId;
@@ -249,7 +249,7 @@ public class GodotInputHandler implements InputDeviceListener {
}
}
- joysticksDevices.add(joy);
+ mJoysticksDevices.add(joy);
final int device_id = id;
final String name = joy.name;
@@ -270,7 +270,7 @@ public class GodotInputHandler implements InputDeviceListener {
// Check if the evice has not been already removed
if (device_id > -1) {
- joysticksDevices.remove(device_id);
+ mJoysticksDevices.remove(device_id);
queueEvent(new Runnable() {
@Override
@@ -360,8 +360,8 @@ public class GodotInputHandler implements InputDeviceListener {
}
private int findJoystickDevice(int device_id) {
- for (int i = 0; i < joysticksDevices.size(); i++) {
- if (joysticksDevices.get(i).device_id == device_id) {
+ for (int i = 0; i < mJoysticksDevices.size(); i++) {
+ if (mJoysticksDevices.get(i).device_id == device_id) {
return i;
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index 18f2d57661..e12ff266bf 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -48,7 +48,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
// ===========================================================
// Fields
// ===========================================================
- private final GodotView mView;
+ private final GodotRenderView mRenderView;
private final GodotEditText mEdit;
private String mOriginText;
@@ -56,9 +56,9 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
// Constructors
// ===========================================================
- public GodotTextInputWrapper(final GodotView view, final GodotEditText edit) {
- this.mView = view;
- this.mEdit = edit;
+ public GodotTextInputWrapper(final GodotRenderView view, final GodotEditText edit) {
+ mRenderView = view;
+ mEdit = edit;
}
// ===========================================================
@@ -66,13 +66,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
// ===========================================================
private boolean isFullScreenEdit() {
- final TextView textField = this.mEdit;
+ final TextView textField = mEdit;
final InputMethodManager imm = (InputMethodManager)textField.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return imm.isFullscreenMode();
}
public void setOriginText(final String originText) {
- this.mOriginText = originText;
+ mOriginText = originText;
}
// ===========================================================
@@ -87,7 +87,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) {
//Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after);
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < count; ++i) {
@@ -106,7 +106,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
for (int i = start; i < start + count; ++i) {
newChars[i - start] = pCharSequence.charAt(i);
}
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < count; ++i) {
@@ -124,10 +124,10 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
@Override
public boolean onEditorAction(final TextView pTextView, final int pActionID, final KeyEvent pKeyEvent) {
- if (this.mEdit == pTextView && this.isFullScreenEdit()) {
+ if (mEdit == pTextView && isFullScreenEdit()) {
final String characters = pKeyEvent.getCharacters();
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < characters.length(); i++) {
@@ -144,7 +144,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true);
GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false);
- this.mView.requestFocus();
+ mRenderView.getView().requestFocus();
return true;
}
return false;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
index e3683704e1..a051164d15 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
@@ -34,6 +34,8 @@ import android.app.Activity;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
import android.view.Surface;
import android.view.View;
import java.lang.reflect.Method;
@@ -41,8 +43,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
+import org.godotengine.godot.BuildConfig;
import org.godotengine.godot.Godot;
/**
@@ -70,7 +74,10 @@ import org.godotengine.godot.Godot;
*/
public abstract class GodotPlugin {
+ private static final String TAG = GodotPlugin.class.getSimpleName();
+
private final Godot godot;
+ private final ConcurrentHashMap<String, SignalInfo> registeredSignals = new ConcurrentHashMap<>();
public GodotPlugin(Godot godot) {
this.godot = godot;
@@ -118,6 +125,13 @@ public abstract class GodotPlugin {
nativeRegisterMethod(getPluginName(), method.getName(), method.getReturnType().getName(), pt);
}
+ // Register the signals for this plugin.
+ for (SignalInfo signalInfo : getPluginSignals()) {
+ String signalName = signalInfo.getName();
+ nativeRegisterSignal(getPluginName(), signalName, signalInfo.getParamTypesNames());
+ registeredSignals.put(signalName, signalInfo);
+ }
+
// Get the list of gdnative libraries to register.
Set<String> gdnativeLibrariesPaths = getPluginGDNativeLibrariesPaths();
if (!gdnativeLibrariesPaths.isEmpty()) {
@@ -220,7 +234,17 @@ public abstract class GodotPlugin {
* Returns the list of methods to be exposed to Godot.
*/
@NonNull
- public abstract List<String> getPluginMethods();
+ public List<String> getPluginMethods() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Returns the list of signals to be exposed to Godot.
+ */
+ @NonNull
+ public Set<SignalInfo> getPluginSignals() {
+ return Collections.emptySet();
+ }
/**
* Returns the paths for the plugin's gdnative libraries.
@@ -253,6 +277,49 @@ public abstract class GodotPlugin {
}
/**
+ * Emit a registered Godot signal.
+ * @param signalName
+ * @param signalArgs
+ */
+ protected void emitSignal(final String signalName, final Object... signalArgs) {
+ try {
+ // Check that the given signal is among the registered set.
+ SignalInfo signalInfo = registeredSignals.get(signalName);
+ if (signalInfo == null) {
+ throw new IllegalArgumentException(
+ "Signal " + signalName + " is not registered for this plugin.");
+ }
+
+ // Validate the arguments count.
+ Class<?>[] signalParamTypes = signalInfo.getParamTypes();
+ if (signalArgs.length != signalParamTypes.length) {
+ throw new IllegalArgumentException(
+ "Invalid arguments count. Should be " + signalParamTypes.length + " but is " + signalArgs.length);
+ }
+
+ // Validate the argument's types.
+ for (int i = 0; i < signalParamTypes.length; i++) {
+ if (!signalParamTypes[i].isInstance(signalArgs[i])) {
+ throw new IllegalArgumentException(
+ "Invalid type for argument #" + i + ". Should be of type " + signalParamTypes[i].getName());
+ }
+ }
+
+ runOnRenderThread(new Runnable() {
+ @Override
+ public void run() {
+ nativeEmitSignal(getPluginName(), signalName, signalArgs);
+ }
+ });
+ } catch (IllegalArgumentException exception) {
+ Log.w(TAG, exception.getMessage());
+ if (BuildConfig.DEBUG) {
+ throw exception;
+ }
+ }
+ }
+
+ /**
* Used to setup a {@link GodotPlugin} instance.
* @param p_name Name of the instance.
*/
@@ -272,4 +339,20 @@ public abstract class GodotPlugin {
* @param gdnlibPaths Paths to the libraries relative to the 'assets' directory.
*/
private native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths);
+
+ /**
+ * Used to complete registration of the {@link GodotPlugin} instance's methods.
+ * @param pluginName Name of the plugin
+ * @param signalName Name of the signal to register
+ * @param signalParamTypes Signal parameters types
+ */
+ private native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes);
+
+ /**
+ * Used to emit signal by {@link GodotPlugin} instance.
+ * @param pluginName Name of the plugin
+ * @param signalName Name of the signal to emit
+ * @param signalParams Signal parameters
+ */
+ private native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
new file mode 100644
index 0000000000..f907706889
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
@@ -0,0 +1,98 @@
+/*************************************************************************/
+/* SignalInfo.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.plugin;
+
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import java.util.Arrays;
+
+/**
+ * Store information about a {@link GodotPlugin}'s signal.
+ */
+public final class SignalInfo {
+
+ private final String name;
+ private final Class<?>[] paramTypes;
+ private final String[] paramTypesNames;
+
+ public SignalInfo(@NonNull String signalName, Class<?>... paramTypes) {
+ if (TextUtils.isEmpty(signalName)) {
+ throw new IllegalArgumentException("Invalid signal name: " + signalName);
+ }
+
+ this.name = signalName;
+ this.paramTypes = paramTypes == null ? new Class<?>[ 0 ] : paramTypes;
+ this.paramTypesNames = new String[this.paramTypes.length];
+ for (int i = 0; i < this.paramTypes.length; i++) {
+ this.paramTypesNames[i] = this.paramTypes[i].getName();
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ Class<?>[] getParamTypes() {
+ return paramTypes;
+ }
+
+ String[] getParamTypesNames() {
+ return paramTypesNames;
+ }
+
+ @Override
+ public String toString() {
+ return "SignalInfo{"
+ +
+ "name='" + name + '\'' +
+ ", paramsTypes=" + Arrays.toString(paramTypes) +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SignalInfo)) {
+ return false;
+ }
+
+ SignalInfo that = (SignalInfo)o;
+
+ return name.equals(that.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
index 67faad8ddd..608ad48df9 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
@@ -33,6 +33,11 @@ package org.godotengine.godot.vulkan
import android.view.Surface
+import org.godotengine.godot.Godot
+import org.godotengine.godot.GodotLib
+import org.godotengine.godot.plugin.GodotPlugin
+import org.godotengine.godot.plugin.GodotPluginRegistry
+
/**
* Responsible to setting up and driving the Vulkan rendering logic.
*
@@ -48,52 +53,64 @@ import android.view.Surface
*/
internal class VkRenderer {
+ private val pluginRegistry: GodotPluginRegistry = GodotPluginRegistry.getPluginRegistry()
+
/**
* Called when the surface is created and signals the beginning of rendering.
*/
fun onVkSurfaceCreated(surface: Surface) {
- nativeOnVkSurfaceCreated(surface)
+ // TODO: properly implement surface re-creation:
+ // GodotLib.newcontext should be called here once it's done.
+ //GodotLib.newcontext(surface, false)
+
+ for (plugin in pluginRegistry.getAllPlugins()) {
+ plugin.onVkSurfaceCreated(surface)
+ }
}
/**
* Called after the surface is created and whenever its size changes.
*/
fun onVkSurfaceChanged(surface: Surface, width: Int, height: Int) {
- nativeOnVkSurfaceChanged(surface, width, height)
+ GodotLib.resize(width, height)
+
+ // TODO: properly implement surface re-creation:
+ // Update the native renderer instead of restarting the app.
+ // GodotLib.newcontext should not be called here once it's done.
+ GodotLib.newcontext(surface, false)
+
+ for (plugin in pluginRegistry.getAllPlugins()) {
+ plugin.onVkSurfaceChanged(surface, width, height)
+ }
}
/**
* Called to draw the current frame.
*/
fun onVkDrawFrame() {
- nativeOnVkDrawFrame()
+ GodotLib.step()
+ for (plugin in pluginRegistry.getAllPlugins()) {
+ plugin.onVkDrawFrame()
+ }
}
/**
* Called when the rendering thread is resumed.
*/
fun onVkResume() {
- nativeOnVkResume()
+ GodotLib.onRendererResumed()
}
/**
* Called when the rendering thread is paused.
*/
fun onVkPause() {
- nativeOnVkPause()
+ GodotLib.onRendererPaused()
}
/**
* Called when the rendering thread is destroyed and used as signal to tear down the Vulkan logic.
*/
fun onVkDestroy() {
- nativeOnVkDestroy()
}
-
- private external fun nativeOnVkSurfaceCreated(surface: Surface)
- private external fun nativeOnVkSurfaceChanged(surface: Surface, width: Int, height: Int)
- private external fun nativeOnVkResume()
- private external fun nativeOnVkDrawFrame()
- private external fun nativeOnVkPause()
- private external fun nativeOnVkDestroy()
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
index 1c594f3201..6b0e12b21a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
@@ -49,7 +49,7 @@ import android.view.SurfaceView
* UI thread.
* </ul>
*/
-internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHolder.Callback {
+open internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHolder.Callback {
companion object {
fun checkState(expression: Boolean, errorMessage: Any) {
@@ -100,7 +100,7 @@ internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHo
*
* Must not be called before a [VkRenderer] has been set.
*/
- fun onResume() {
+ open fun onResume() {
vkThread.onResume()
}
@@ -109,7 +109,7 @@ internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHo
*
* Must not be called before a [VkRenderer] has been set.
*/
- fun onPause() {
+ open fun onPause() {
vkThread.onPause()
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
index 2e332840bf..7557c8aa22 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
@@ -219,9 +219,9 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk
vkRenderer.onVkDrawFrame()
}
} catch (ex: InterruptedException) {
- Log.i(TAG, ex.message)
+ Log.i(TAG, "InterruptedException", ex)
} catch (ex: IllegalStateException) {
- Log.i(TAG, ex.message)
+ Log.i(TAG, "IllegalStateException", ex)
} finally {
threadExiting()
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
index f2b4c95a2c..31cf696195 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
@@ -51,7 +51,6 @@ public class RegularContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
- String driver_name = GodotLib.getGlobal("rendering/quality/driver/driver_name");
// FIXME: Add support for Vulkan.
Log.w(TAG, "creating OpenGL ES 2.0 context :");
diff --git a/platform/android/java/plugins/godotpayment/build.gradle b/platform/android/java/plugins/godotpayment/build.gradle
index 4f376c4587..ffab86e26e 100644
--- a/platform/android/java/plugins/godotpayment/build.gradle
+++ b/platform/android/java/plugins/godotpayment/build.gradle
@@ -3,6 +3,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
+ useLibrary 'org.apache.http.legacy'
defaultConfig {
minSdkVersion versions.minSdk
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java
index 179cc08ed1..d42ded0c9b 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java
@@ -34,8 +34,8 @@ import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import java.lang.ref.WeakReference;
-import org.godotengine.godot.utils.HttpRequester;
-import org.godotengine.godot.utils.RequestParams;
+import org.godotengine.godot.plugin.payment.utils.HttpRequester;
+import org.godotengine.godot.plugin.payment.utils.RequestParams;
import org.json.JSONException;
import org.json.JSONObject;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java
index c78e8c1c66..9571769cd3 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java
@@ -28,7 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.godot.utils;
+package org.godotengine.godot.plugin.payment.utils;
+
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java
index 68f9a83597..dcb983201e 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.godot.utils;
+package org.godotengine.godot.plugin.payment.utils;
import android.content.Context;
import android.content.SharedPreferences;
@@ -61,6 +61,7 @@ import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
+import org.godotengine.godot.utils.Crypt;
/**
*
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java
index 25fa10647d..4be8b37473 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java
@@ -28,10 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.godot.utils;
+package org.godotengine.godot.plugin.payment.utils;
import java.util.ArrayList;
-import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp
index 8d075f8e97..0da0bd6387 100644
--- a/platform/android/java_godot_io_wrapper.cpp
+++ b/platform/android/java_godot_io_wrapper.cpp
@@ -56,11 +56,8 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;I)V");
_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
+ _get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I");
_get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;");
- _play_video = p_env->GetMethodID(cls, "playVideo", "(Ljava/lang/String;)V");
- _is_video_playing = p_env->GetMethodID(cls, "isVideoPlaying", "()Z");
- _pause_video = p_env->GetMethodID(cls, "pauseVideo", "()V");
- _stop_video = p_env->GetMethodID(cls, "stopVideo", "()V");
}
}
@@ -157,40 +154,22 @@ void GodotIOJavaWrapper::set_screen_orientation(int p_orient) {
}
}
-String GodotIOJavaWrapper::get_system_dir(int p_dir) {
- if (_get_system_dir) {
+int GodotIOJavaWrapper::get_screen_orientation() {
+ if (_get_screen_orientation) {
JNIEnv *env = ThreadAndroid::get_env();
- jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir);
- return jstring_to_string(s, env);
+ return env->CallIntMethod(godot_io_instance, _get_screen_orientation);
} else {
- return String(".");
+ return 0;
}
}
-void GodotIOJavaWrapper::play_video(const String &p_path) {
- // Why is this not here?!?!
-}
-
-bool GodotIOJavaWrapper::is_video_playing() {
- if (_is_video_playing) {
+String GodotIOJavaWrapper::get_system_dir(int p_dir) {
+ if (_get_system_dir) {
JNIEnv *env = ThreadAndroid::get_env();
- return env->CallBooleanMethod(godot_io_instance, _is_video_playing);
+ jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir);
+ return jstring_to_string(s, env);
} else {
- return false;
- }
-}
-
-void GodotIOJavaWrapper::pause_video() {
- if (_pause_video) {
- JNIEnv *env = ThreadAndroid::get_env();
- env->CallVoidMethod(godot_io_instance, _pause_video);
- }
-}
-
-void GodotIOJavaWrapper::stop_video() {
- if (_stop_video) {
- JNIEnv *env = ThreadAndroid::get_env();
- env->CallVoidMethod(godot_io_instance, _stop_video);
+ return String(".");
}
}
diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h
index 7dfed52187..dbb3b564f6 100644
--- a/platform/android/java_godot_io_wrapper.h
+++ b/platform/android/java_godot_io_wrapper.h
@@ -54,11 +54,8 @@ private:
jmethodID _show_keyboard = 0;
jmethodID _hide_keyboard = 0;
jmethodID _set_screen_orientation = 0;
+ jmethodID _get_screen_orientation = 0;
jmethodID _get_system_dir = 0;
- jmethodID _play_video = 0;
- jmethodID _is_video_playing = 0;
- jmethodID _pause_video = 0;
- jmethodID _stop_video = 0;
public:
GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instance);
@@ -78,11 +75,8 @@ public:
int get_vk_height();
void set_vk_height(int p_height);
void set_screen_orientation(int p_orient);
+ int get_screen_orientation();
String get_system_dir(int p_dir);
- void play_video(const String &p_path);
- bool is_video_playing();
- void pause_video();
- void stop_video();
};
#endif /* !JAVA_GODOT_IO_WRAPPER_H */
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 9d44ab4619..8b38113e09 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -34,13 +34,14 @@
#include "java_godot_wrapper.h"
#include "android/asset_manager_jni.h"
-#include "android_keys_utils.h"
#include "api/java_class_wrapper.h"
+#include "api/jni_singleton.h"
#include "audio_driver_jandroid.h"
#include "core/engine.h"
#include "core/input/input_filter.h"
#include "core/project_settings.h"
#include "dir_access_jandroid.h"
+#include "display_server_android.h"
#include "file_access_android.h"
#include "file_access_jandroid.h"
#include "jni_utils.h"
@@ -52,6 +53,8 @@
#include <unistd.h>
+#include <android/native_window_jni.h>
+
static JavaClassWrapper *java_class_wrapper = nullptr;
static OS_Android *os_android = nullptr;
static GodotJavaWrapper *godot_java = nullptr;
@@ -160,22 +163,26 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc
}
java_class_wrapper = memnew(JavaClassWrapper(godot_java->get_activity()));
+ ClassDB::register_class<JNISingleton>();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height) {
if (os_android)
- os_android->set_display_size(Size2(width, height));
+ os_android->set_display_size(Size2i(width, height));
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits) {
-
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits) {
if (os_android) {
if (step == 0) {
// During startup
os_android->set_context_is_16_bits(!p_32_bits);
+ if (p_surface) {
+ ANativeWindow *native_window = ANativeWindow_fromSurface(env, p_surface);
+ os_android->set_native_window(native_window);
+ }
} else {
- // GL context recreated because it was lost; restart app to let it reload everything
+ // Rendering context recreated because it was lost; restart app to let it reload everything
os_android->main_loop_end();
godot_java->restart(env);
step = -1; // Ensure no further steps are attempted
@@ -195,7 +202,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
return;
if (step == 0) {
-
// Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id,
// but for Godot purposes, the main thread is the one running the game loop
Main::setup2(Thread::get_caller_id());
@@ -213,10 +219,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
++step;
}
- os_android->process_accelerometer(accelerometer);
- os_android->process_gravity(gravity);
- os_android->process_magnetometer(magnetometer);
- os_android->process_gyroscope(gyroscope);
+ DisplayServerAndroid::get_singleton()->process_accelerometer(accelerometer);
+ DisplayServerAndroid::get_singleton()->process_gravity(gravity);
+ DisplayServerAndroid::get_singleton()->process_magnetometer(magnetometer);
+ DisplayServerAndroid::get_singleton()->process_gyroscope(gyroscope);
if (os_android->main_loop_iterate()) {
@@ -229,18 +235,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jc
if (step == 0)
return;
- Vector<OS_Android::TouchPos> points;
+ Vector<DisplayServerAndroid::TouchPos> points;
for (int i = 0; i < count; i++) {
jint p[3];
env->GetIntArrayRegion(positions, i * 3, 3, p);
- OS_Android::TouchPos tp;
+ DisplayServerAndroid::TouchPos tp;
tp.pos = Point2(p[1], p[2]);
tp.id = p[0];
points.push_back(tp);
}
- os_android->process_touch(ev, pointer, points);
+ DisplayServerAndroid::get_singleton()->process_touch(ev, pointer, points);
/*
if (os_android)
@@ -252,78 +258,78 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jc
if (step == 0)
return;
- os_android->process_hover(p_type, Point2(p_x, p_y));
+ DisplayServerAndroid::get_singleton()->process_hover(p_type, Point2(p_x, p_y));
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
if (step == 0)
return;
- os_android->process_double_tap(Point2(p_x, p_y));
+ DisplayServerAndroid::get_singleton()->process_double_tap(Point2(p_x, p_y));
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
if (step == 0)
return;
- os_android->process_scroll(Point2(p_x, p_y));
+ DisplayServerAndroid::get_singleton()->process_scroll(Point2(p_x, p_y));
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed) {
if (step == 0)
return;
- OS_Android::JoypadEvent jevent;
+ DisplayServerAndroid::JoypadEvent jevent;
jevent.device = p_device;
- jevent.type = OS_Android::JOY_EVENT_BUTTON;
+ jevent.type = DisplayServerAndroid::JOY_EVENT_BUTTON;
jevent.index = p_button;
jevent.pressed = p_pressed;
- os_android->process_joy_event(jevent);
+ DisplayServerAndroid::get_singleton()->process_joy_event(jevent);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value) {
if (step == 0)
return;
- OS_Android::JoypadEvent jevent;
+ DisplayServerAndroid::JoypadEvent jevent;
jevent.device = p_device;
- jevent.type = OS_Android::JOY_EVENT_AXIS;
+ jevent.type = DisplayServerAndroid::JOY_EVENT_AXIS;
jevent.index = p_axis;
jevent.value = p_value;
- os_android->process_joy_event(jevent);
+ DisplayServerAndroid::get_singleton()->process_joy_event(jevent);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y) {
if (step == 0)
return;
- OS_Android::JoypadEvent jevent;
+ DisplayServerAndroid::JoypadEvent jevent;
jevent.device = p_device;
- jevent.type = OS_Android::JOY_EVENT_HAT;
+ jevent.type = DisplayServerAndroid::JOY_EVENT_HAT;
int hat = 0;
if (p_hat_x != 0) {
if (p_hat_x < 0)
- hat |= InputDefault::HAT_MASK_LEFT;
+ hat |= InputFilter::HAT_MASK_LEFT;
else
- hat |= InputDefault::HAT_MASK_RIGHT;
+ hat |= InputFilter::HAT_MASK_RIGHT;
}
if (p_hat_y != 0) {
if (p_hat_y < 0)
- hat |= InputDefault::HAT_MASK_UP;
+ hat |= InputFilter::HAT_MASK_UP;
else
- hat |= InputDefault::HAT_MASK_DOWN;
+ hat |= InputFilter::HAT_MASK_DOWN;
}
jevent.hat = hat;
- os_android->process_joy_event(jevent);
+ DisplayServerAndroid::get_singleton()->process_joy_event(jevent);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jclass clazz, jint p_device, jboolean p_connected, jstring p_name) {
if (os_android) {
String name = jstring_to_string(p_name, env);
- os_android->joy_connection_changed(p_device, p_connected, name);
+ InputFilter::get_singleton()->joy_connection_changed(p_device, p_connected, name);
}
}
@@ -331,29 +337,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jcla
if (step == 0)
return;
- Ref<InputEventKey> ievent;
- ievent.instance();
- int val = p_unicode_char;
- int keycode = android_get_keysym(p_keycode);
- int phy_keycode = android_get_keysym(p_scancode);
- ievent->set_keycode(keycode);
- ievent->set_physical_keycode(phy_keycode);
- ievent->set_unicode(val);
- ievent->set_pressed(p_pressed);
-
- if (val == '\n') {
- ievent->set_keycode(KEY_ENTER);
- } else if (val == 61448) {
- ievent->set_keycode(KEY_BACKSPACE);
- ievent->set_unicode(KEY_BACKSPACE);
- } else if (val == 61453) {
- ievent->set_keycode(KEY_ENTER);
- ievent->set_unicode(KEY_ENTER);
- } else if (p_keycode == 4) {
- os_android->main_loop_request_go_back();
- }
-
- os_android->process_event(ievent);
+ DisplayServerAndroid::get_singleton()->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) {
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index a7a5970440..221d701e2b 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -41,7 +41,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint count, jintArray positions);
diff --git a/platform/android/jni_utils.h b/platform/android/jni_utils.h
index b9ee243308..c2baa51b4a 100644
--- a/platform/android/jni_utils.h
+++ b/platform/android/jni_utils.h
@@ -53,190 +53,4 @@ Variant::Type get_jni_type(const String &p_type);
const char *get_jni_sig(const String &p_type);
-class JNISingleton : public Object {
-
- GDCLASS(JNISingleton, Object);
-
- struct MethodData {
-
- jmethodID method;
- Variant::Type ret_type;
- Vector<Variant::Type> argtypes;
- };
-
- jobject instance;
- Map<StringName, MethodData> method_map;
-
-public:
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
- ERR_FAIL_COND_V(!instance, Variant());
-
- r_error.error = Callable::CallError::CALL_OK;
-
- Map<StringName, MethodData>::Element *E = method_map.find(p_method);
- if (!E) {
-
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
- return Variant();
- }
-
- int ac = E->get().argtypes.size();
- if (ac < p_argcount) {
-
- r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
- r_error.argument = ac;
- return Variant();
- }
-
- if (ac > p_argcount) {
-
- r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
- r_error.argument = ac;
- return Variant();
- }
-
- for (int i = 0; i < p_argcount; i++) {
-
- if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) {
-
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = i;
- r_error.expected = E->get().argtypes[i];
- }
- }
-
- jvalue *v = nullptr;
-
- if (p_argcount) {
-
- v = (jvalue *)alloca(sizeof(jvalue) * p_argcount);
- }
-
- JNIEnv *env = ThreadAndroid::get_env();
-
- int res = env->PushLocalFrame(16);
-
- ERR_FAIL_COND_V(res != 0, Variant());
-
- List<jobject> to_erase;
- for (int i = 0; i < p_argcount; i++) {
-
- jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]);
- v[i] = vr.val;
- if (vr.obj)
- to_erase.push_back(vr.obj);
- }
-
- Variant ret;
-
- switch (E->get().ret_type) {
-
- case Variant::NIL: {
-
- env->CallVoidMethodA(instance, E->get().method, v);
- } break;
- case Variant::BOOL: {
-
- ret = env->CallBooleanMethodA(instance, E->get().method, v) == JNI_TRUE;
- } break;
- case Variant::INT: {
-
- ret = env->CallIntMethodA(instance, E->get().method, v);
- } break;
- case Variant::FLOAT: {
-
- ret = env->CallFloatMethodA(instance, E->get().method, v);
- } break;
- case Variant::STRING: {
-
- jobject o = env->CallObjectMethodA(instance, E->get().method, v);
- ret = jstring_to_string((jstring)o, env);
- env->DeleteLocalRef(o);
- } break;
- case Variant::PACKED_STRING_ARRAY: {
-
- jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v);
-
- ret = _jobject_to_variant(env, arr);
-
- env->DeleteLocalRef(arr);
- } break;
- case Variant::PACKED_INT32_ARRAY: {
-
- jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v);
-
- int fCount = env->GetArrayLength(arr);
- Vector<int> sarr;
- sarr.resize(fCount);
-
- int *w = sarr.ptrw();
- env->GetIntArrayRegion(arr, 0, fCount, w);
- ret = sarr;
- env->DeleteLocalRef(arr);
- } break;
- case Variant::PACKED_FLOAT32_ARRAY: {
-
- jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v);
-
- int fCount = env->GetArrayLength(arr);
- Vector<float> sarr;
- sarr.resize(fCount);
-
- float *w = sarr.ptrw();
- env->GetFloatArrayRegion(arr, 0, fCount, w);
- ret = sarr;
- env->DeleteLocalRef(arr);
- } break;
-
-#ifndef _MSC_VER
-#warning This is missing 64 bits arrays, I have no idea how to do it in JNI
-#endif
- case Variant::DICTIONARY: {
-
- jobject obj = env->CallObjectMethodA(instance, E->get().method, v);
- ret = _jobject_to_variant(env, obj);
- env->DeleteLocalRef(obj);
-
- } break;
- default: {
-
- env->PopLocalFrame(nullptr);
- ERR_FAIL_V(Variant());
- } break;
- }
-
- while (to_erase.size()) {
- env->DeleteLocalRef(to_erase.front()->get());
- to_erase.pop_front();
- }
-
- env->PopLocalFrame(nullptr);
-
- return ret;
- }
-
- jobject get_instance() const {
-
- return instance;
- }
- void set_instance(jobject p_instance) {
-
- instance = p_instance;
- }
-
- void add_method(const StringName &p_name, jmethodID p_method, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) {
-
- MethodData md;
- md.method = p_method;
- md.argtypes = p_args;
- md.ret_type = p_ret_type;
- method_map[p_name] = md;
- }
-
- JNISingleton() {
- instance = nullptr;
- }
-};
-
#endif // JNI_UTILS_H
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 344377d673..760157595c 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -32,15 +32,11 @@
#include "core/io/file_access_buffered_fa.h"
#include "core/project_settings.h"
-#if defined(OPENGL_ENABLED)
-#include "drivers/gles2/rasterizer_gles2.h"
-#endif
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "file_access_android.h"
#include "main/main.h"
-#include "servers/rendering/rendering_server_raster.h"
-#include "servers/rendering/rendering_server_wrap_mt.h"
+#include "platform/android/display_server_android.h"
#include "dir_access_jandroid.h"
#include "file_access_jandroid.h"
@@ -60,29 +56,6 @@ public:
virtual ~AndroidLogger() {}
};
-int OS_Android::get_video_driver_count() const {
-
- return 2;
-}
-
-const char *OS_Android::get_video_driver_name(int p_driver) const {
-
- switch (p_driver) {
- case VIDEO_DRIVER_GLES2:
- return "GLES2";
- }
- ERR_FAIL_V_MSG(nullptr, "Invalid video driver index: " + itos(p_driver) + ".");
-}
-int OS_Android::get_audio_driver_count() const {
-
- return 1;
-}
-
-const char *OS_Android::get_audio_driver_name(int p_driver) const {
-
- return "Android";
-}
-
void OS_Android::initialize_core() {
OS_Unix::initialize_core();
@@ -110,71 +83,33 @@ void OS_Android::initialize_core() {
NetSocketAndroid::make_default();
}
-void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
-
- ERR_FAIL_COND(!p_gl_extensions);
- gl_extensions = p_gl_extensions;
-}
-
-int OS_Android::get_current_video_driver() const {
- return video_driver_index;
+void OS_Android::initialize() {
+ initialize_core();
}
-Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
+void OS_Android::initialize_joypads() {
+ InputFilter::get_singleton()->set_fallback_mapping(godot_java->get_input_fallback_mapping());
- // FIXME: Add Vulkan support. Readd fallback code from Vulkan to GLES2?
-
-#if defined(OPENGL_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_GLES2) {
- bool gl_initialization_error = false;
-
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- gl_initialization_error = true;
- }
-
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n"
- "Please try updating your Android version.",
- "Unable to initialize video driver");
- return ERR_UNAVAILABLE;
- }
- }
-#endif
-
- video_driver_index = p_video_driver;
-
- rendering_server = memnew(RenderingServerRaster);
- if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
- rendering_server = memnew(RenderingServerWrapMT(rendering_server, false));
- }
-
- rendering_server->init();
-
- AudioDriverManager::initialize(p_audio_driver);
-
- input = memnew(InputDefault);
- input->set_fallback_mapping(godot_java->get_input_fallback_mapping());
-
- return OK;
+ // This queries/updates the currently connected devices/joypads.
+ godot_java->init_input_devices();
}
void OS_Android::set_main_loop(MainLoop *p_main_loop) {
-
main_loop = p_main_loop;
- input->set_main_loop(p_main_loop);
}
void OS_Android::delete_main_loop() {
-
- memdelete(main_loop);
+ if (main_loop) {
+ memdelete(main_loop);
+ main_loop = nullptr;
+ }
}
void OS_Android::finalize() {
+}
- memdelete(input);
+OS_Android *OS_Android::get_singleton() {
+ return (OS_Android *)OS::get_singleton();
}
GodotJavaWrapper *OS_Android::get_godot_java() {
@@ -185,12 +120,6 @@ GodotIOJavaWrapper *OS_Android::get_godot_io_java() {
return godot_io_java;
}
-void OS_Android::alert(const String &p_alert, const String &p_title) {
-
- //print("ALERT: %s\n", p_alert.utf8().get_data());
- godot_java->alert(p_alert, p_title);
-}
-
bool OS_Android::request_permission(const String &p_name) {
return godot_java->request_permission(p_name);
@@ -212,63 +141,6 @@ Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_han
return OK;
}
-void OS_Android::set_mouse_show(bool p_show) {
-
- //android has no mouse...
-}
-
-void OS_Android::set_mouse_grab(bool p_grab) {
-
- //it really has no mouse...!
-}
-
-bool OS_Android::is_mouse_grab_enabled() const {
-
- //*sigh* technology has evolved so much since i was a kid..
- return false;
-}
-
-Point2 OS_Android::get_mouse_position() const {
-
- return Point2();
-}
-
-int OS_Android::get_mouse_button_state() const {
-
- return 0;
-}
-
-void OS_Android::set_window_title(const String &p_title) {
- //This queries/updates the currently connected devices/joypads
- //Set_window_title is called when initializing the main loop (main.cpp)
- //therefore this place is found to be suitable (I found no better).
- godot_java->init_input_devices();
-}
-
-void OS_Android::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-}
-
-OS::VideoMode OS_Android::get_video_mode(int p_screen) const {
-
- return default_videomode;
-}
-
-void OS_Android::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-
- p_list->push_back(default_videomode);
-}
-
-void OS_Android::set_keep_screen_on(bool p_enabled) {
- OS::set_keep_screen_on(p_enabled);
-
- godot_java->set_keep_screen_on(p_enabled);
-}
-
-Size2 OS_Android::get_window_size() const {
-
- return Vector2(default_videomode.width, default_videomode.height);
-}
-
String OS_Android::get_name() const {
return "Android";
@@ -279,11 +151,6 @@ MainLoop *OS_Android::get_main_loop() const {
return main_loop;
}
-bool OS_Android::can_draw() const {
-
- return true; //always?
-}
-
void OS_Android::main_loop_begin() {
if (main_loop)
@@ -304,277 +171,17 @@ void OS_Android::main_loop_end() {
}
void OS_Android::main_loop_focusout() {
-
- if (main_loop)
- main_loop->notification(NOTIFICATION_WM_FOCUS_OUT);
+ DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
audio_driver_android.set_pause(true);
}
void OS_Android::main_loop_focusin() {
-
- if (main_loop)
- main_loop->notification(NOTIFICATION_WM_FOCUS_IN);
+ DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
audio_driver_android.set_pause(false);
}
-void OS_Android::process_joy_event(OS_Android::JoypadEvent p_event) {
-
- switch (p_event.type) {
- case JOY_EVENT_BUTTON:
- input->joy_button(p_event.device, p_event.index, p_event.pressed);
- break;
- case JOY_EVENT_AXIS:
- InputDefault::JoyAxis value;
- value.min = -1;
- value.value = p_event.value;
- input->joy_axis(p_event.device, p_event.index, value);
- break;
- case JOY_EVENT_HAT:
- input->joy_hat(p_event.device, p_event.hat);
- break;
- default:
- return;
- }
-}
-
-void OS_Android::process_event(Ref<InputEvent> p_event) {
-
- input->parse_input_event(p_event);
-}
-
-void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) {
-
- switch (p_what) {
- case 0: { //gesture begin
-
- if (touch.size()) {
- //end all if exist
- for (int i = 0; i < touch.size(); i++) {
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_pressed(false);
- ev->set_position(touch[i].pos);
- input->parse_input_event(ev);
- }
- }
-
- touch.resize(p_points.size());
- for (int i = 0; i < p_points.size(); i++) {
- touch.write[i].id = p_points[i].id;
- touch.write[i].pos = p_points[i].pos;
- }
-
- //send touch
- for (int i = 0; i < touch.size(); i++) {
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_pressed(true);
- ev->set_position(touch[i].pos);
- input->parse_input_event(ev);
- }
-
- } break;
- case 1: { //motion
-
- ERR_FAIL_COND(touch.size() != p_points.size());
-
- for (int i = 0; i < touch.size(); i++) {
-
- int idx = -1;
- for (int j = 0; j < p_points.size(); j++) {
-
- if (touch[i].id == p_points[j].id) {
- idx = j;
- break;
- }
- }
-
- ERR_CONTINUE(idx == -1);
-
- if (touch[i].pos == p_points[idx].pos)
- continue; //no move unncesearily
-
- Ref<InputEventScreenDrag> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_position(p_points[idx].pos);
- ev->set_relative(p_points[idx].pos - touch[i].pos);
- input->parse_input_event(ev);
- touch.write[i].pos = p_points[idx].pos;
- }
-
- } break;
- case 2: { //release
-
- if (touch.size()) {
- //end all if exist
- for (int i = 0; i < touch.size(); i++) {
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_pressed(false);
- ev->set_position(touch[i].pos);
- input->parse_input_event(ev);
- }
- touch.clear();
- }
- } break;
- case 3: { // add touch
-
- for (int i = 0; i < p_points.size(); i++) {
- if (p_points[i].id == p_pointer) {
- TouchPos tp = p_points[i];
- touch.push_back(tp);
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
-
- ev->set_index(tp.id);
- ev->set_pressed(true);
- ev->set_position(tp.pos);
- input->parse_input_event(ev);
-
- break;
- }
- }
- } break;
- case 4: { // remove touch
-
- for (int i = 0; i < touch.size(); i++) {
- if (touch[i].id == p_pointer) {
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_pressed(false);
- ev->set_position(touch[i].pos);
- input->parse_input_event(ev);
- touch.remove(i);
-
- break;
- }
- }
- } break;
- }
-}
-
-void OS_Android::process_hover(int p_type, Point2 p_pos) {
- // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER
- switch (p_type) {
- case 7: // hover move
- case 9: // hover enter
- case 10: { // hover exit
- Ref<InputEventMouseMotion> ev;
- ev.instance();
- ev->set_position(p_pos);
- ev->set_global_position(p_pos);
- ev->set_relative(p_pos - hover_prev_pos);
- input->parse_input_event(ev);
- hover_prev_pos = p_pos;
- } break;
- }
-}
-
-void OS_Android::process_double_tap(Point2 p_pos) {
- Ref<InputEventMouseButton> ev;
- ev.instance();
- ev->set_position(p_pos);
- ev->set_global_position(p_pos);
- ev->set_pressed(false);
- ev->set_doubleclick(true);
- input->parse_input_event(ev);
-}
-
-void OS_Android::process_scroll(Point2 p_pos) {
- Ref<InputEventPanGesture> ev;
- ev.instance();
- ev->set_position(p_pos);
- ev->set_delta(p_pos - scroll_prev_pos);
- input->parse_input_event(ev);
- scroll_prev_pos = p_pos;
-}
-
-void OS_Android::process_accelerometer(const Vector3 &p_accelerometer) {
-
- input->set_accelerometer(p_accelerometer);
-}
-
-void OS_Android::process_gravity(const Vector3 &p_gravity) {
-
- input->set_gravity(p_gravity);
-}
-
-void OS_Android::process_magnetometer(const Vector3 &p_magnetometer) {
-
- input->set_magnetometer(p_magnetometer);
-}
-
-void OS_Android::process_gyroscope(const Vector3 &p_gyroscope) {
-
- input->set_gyroscope(p_gyroscope);
-}
-
-bool OS_Android::has_touchscreen_ui_hint() const {
-
- return true;
-}
-
-bool OS_Android::has_virtual_keyboard() const {
-
- return true;
-}
-
-int OS_Android::get_virtual_keyboard_height() const {
- return godot_io_java->get_vk_height();
-
- // ERR_PRINT("Cannot obtain virtual keyboard height.");
- // return 0;
-}
-
-void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
-
- if (godot_io_java->has_vk()) {
- godot_io_java->show_vk(p_existing_text, p_max_input_length);
- } else {
-
- ERR_PRINT("Virtual keyboard not available");
- };
-}
-
-void OS_Android::hide_virtual_keyboard() {
-
- if (godot_io_java->has_vk()) {
-
- godot_io_java->hide_vk();
- } else {
-
- ERR_PRINT("Virtual keyboard not available");
- };
-}
-
-void OS_Android::init_video_mode(int p_video_width, int p_video_height) {
-
- default_videomode.width = p_video_width;
- default_videomode.height = p_video_height;
- default_videomode.fullscreen = true;
- default_videomode.resizable = false;
-}
-
void OS_Android::main_loop_request_go_back() {
-
- if (main_loop)
- main_loop->notification(NOTIFICATION_WM_GO_BACK_REQUEST);
-}
-
-void OS_Android::set_display_size(Size2 p_size) {
-
- default_videomode.width = p_size.x;
- default_videomode.height = p_size.y;
+ DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST);
}
Error OS_Android::shell_open(String p_uri) {
@@ -597,26 +204,6 @@ String OS_Android::get_locale() const {
return OS_Unix::get_locale();
}
-void OS_Android::set_clipboard(const String &p_text) {
-
- // DO we really need the fallback to OS_Unix here?!
- if (godot_java->has_set_clipboard()) {
- godot_java->set_clipboard(p_text);
- } else {
- OS_Unix::set_clipboard(p_text);
- }
-}
-
-String OS_Android::get_clipboard() const {
-
- // DO we really need the fallback to OS_Unix here?!
- if (godot_java->has_get_clipboard()) {
- return godot_java->get_clipboard();
- }
-
- return OS_Unix::get_clipboard();
-}
-
String OS_Android::get_model_name() const {
String model = godot_io_java->get_model();
@@ -626,11 +213,6 @@ String OS_Android::get_model_name() const {
return OS_Unix::get_model_name();
}
-int OS_Android::get_screen_dpi(int p_screen) const {
-
- return godot_io_java->get_screen_dpi();
-}
-
String OS_Android::get_user_data_dir() const {
if (data_dir_cache != String())
@@ -662,11 +244,6 @@ String OS_Android::get_user_data_dir() const {
return ".";
}
-void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) {
-
- godot_io_java->set_screen_orientation(p_orientation);
-}
-
String OS_Android::get_unique_id() const {
String unique_id = godot_io_java->get_unique_id();
@@ -676,50 +253,46 @@ String OS_Android::get_unique_id() const {
return OS::get_unique_id();
}
-Error OS_Android::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
- // FIXME: Add support for volume, audio and subtitle tracks
-
- godot_io_java->play_video(p_path);
- return OK;
-}
-
-bool OS_Android::native_video_is_playing() const {
-
- return godot_io_java->is_video_playing();
-}
-
-void OS_Android::native_video_pause() {
-
- godot_io_java->pause_video();
-}
-
String OS_Android::get_system_dir(SystemDir p_dir) const {
return godot_io_java->get_system_dir(p_dir);
}
-void OS_Android::native_video_stop() {
+void OS_Android::set_display_size(const Size2i &p_size) {
+ display_size = p_size;
+}
- godot_io_java->stop_video();
+Size2i OS_Android::get_display_size() const {
+ return display_size;
}
void OS_Android::set_context_is_16_bits(bool p_is_16) {
-
+#if defined(OPENGL_ENABLED)
//use_16bits_fbo = p_is_16;
//if (rasterizer)
// rasterizer->set_force_16_bits_fbo(p_is_16);
+#endif
}
-void OS_Android::joy_connection_changed(int p_device, bool p_connected, String p_name) {
- return input->joy_connection_changed(p_device, p_connected, p_name, "");
+void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
+#if defined(OPENGL_ENABLED)
+ ERR_FAIL_COND(!p_gl_extensions);
+ gl_extensions = p_gl_extensions;
+#endif
}
-bool OS_Android::is_joy_known(int p_device) {
- return input->is_joy_mapped(p_device);
+void OS_Android::set_native_window(ANativeWindow *p_native_window) {
+#if defined(VULKAN_ENABLED)
+ native_window = p_native_window;
+#endif
}
-String OS_Android::get_joy_guid(int p_device) const {
- return input->get_joy_guid_remapped(p_device);
+ANativeWindow *OS_Android::get_native_window() const {
+#if defined(VULKAN_ENABLED)
+ return native_window;
+#else
+ return nullptr;
+#endif
}
void OS_Android::vibrate_handheld(int p_duration_ms) {
@@ -747,19 +320,21 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) {
}
OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion) {
+ display_size.width = 800;
+ display_size.height = 600;
use_apk_expansion = p_use_apk_expansion;
- default_videomode.width = 800;
- default_videomode.height = 600;
- default_videomode.fullscreen = true;
- default_videomode.resizable = false;
main_loop = nullptr;
+
+#if defined(OPENGL_ENABLED)
gl_extensions = nullptr;
- //rasterizer = nullptr;
use_gl2 = false;
+#endif
- rendering_server = nullptr;
+#if defined(VULKAN_ENABLED)
+ native_window = nullptr;
+#endif
godot_java = p_godot_java;
godot_io_java = p_godot_io_java;
@@ -769,6 +344,8 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god
_set_logger(memnew(CompositeLogger(loggers)));
AudioDriverManager::add_driver(&audio_driver_android);
+
+ DisplayServerAndroid::register_android_driver();
}
OS_Android::~OS_Android() {
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 8a91412ef6..cac7efaa88 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -33,78 +33,45 @@
#include "audio_driver_jandroid.h"
#include "audio_driver_opensl.h"
-#include "core/input/input_filter.h"
#include "core/os/main_loop.h"
#include "drivers/unix/os_unix.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
class GodotJavaWrapper;
class GodotIOJavaWrapper;
-class OS_Android : public OS_Unix {
-public:
- struct TouchPos {
- int id;
- Point2 pos;
- };
-
- enum {
- JOY_EVENT_BUTTON = 0,
- JOY_EVENT_AXIS = 1,
- JOY_EVENT_HAT = 2
- };
-
- struct JoypadEvent {
-
- int device;
- int type;
- int index;
- bool pressed;
- float value;
- int hat;
- };
+struct ANativeWindow;
+class OS_Android : public OS_Unix {
private:
- Vector<TouchPos> touch;
- Point2 hover_prev_pos; // needed to calculate the relative position on hover events
- Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events
+ Size2i display_size;
- bool use_gl2;
bool use_apk_expansion;
+#if defined(OPENGL_ENABLED)
bool use_16bits_fbo;
+ const char *gl_extensions;
+#endif
- RenderingServer *rendering_server;
+#if defined(VULKAN_ENABLED)
+ ANativeWindow *native_window;
+#endif
mutable String data_dir_cache;
//AudioDriverAndroid audio_driver_android;
AudioDriverOpenSL audio_driver_android;
- const char *gl_extensions;
-
- InputDefault *input;
- VideoMode default_videomode;
MainLoop *main_loop;
GodotJavaWrapper *godot_java;
GodotIOJavaWrapper *godot_io_java;
- int video_driver_index;
-
public:
- // functions used by main to initialize/deinitialize the OS
- virtual int get_video_driver_count() const;
- virtual const char *get_video_driver_name(int p_driver) const;
-
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
-
- virtual int get_current_video_driver() const;
-
virtual void initialize_core();
- virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
+ virtual void initialize();
+
+ virtual void initialize_joypads();
virtual void set_main_loop(MainLoop *p_main_loop);
virtual void delete_main_loop();
@@ -113,37 +80,19 @@ public:
typedef int64_t ProcessID;
- static OS *get_singleton();
+ static OS_Android *get_singleton();
GodotJavaWrapper *get_godot_java();
GodotIOJavaWrapper *get_godot_io_java();
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual bool request_permission(const String &p_name);
virtual bool request_permissions();
virtual Vector<String> get_granted_permissions() const;
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
- virtual void set_mouse_show(bool p_show);
- virtual void set_mouse_grab(bool p_grab);
- virtual bool is_mouse_grab_enabled() const;
- virtual Point2 get_mouse_position() const;
- virtual int get_mouse_button_state() const;
- virtual void set_window_title(const String &p_title);
-
- virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
- virtual VideoMode get_video_mode(int p_screen = 0) const;
- virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
-
- virtual void set_keep_screen_on(bool p_enabled);
-
- virtual Size2 get_window_size() const;
-
virtual String get_name() const;
virtual MainLoop *get_main_loop() const;
- virtual bool can_draw() const;
-
void main_loop_begin();
bool main_loop_iterate();
void main_loop_request_go_back();
@@ -151,53 +100,25 @@ public:
void main_loop_focusout();
void main_loop_focusin();
- virtual bool has_touchscreen_ui_hint() const;
-
- virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1);
- virtual void hide_virtual_keyboard();
- virtual int get_virtual_keyboard_height() const;
-
- void set_opengl_extensions(const char *p_gl_extensions);
- void set_display_size(Size2 p_size);
+ void set_display_size(const Size2i &p_size);
+ Size2i get_display_size() const;
void set_context_is_16_bits(bool p_is_16);
+ void set_opengl_extensions(const char *p_gl_extensions);
- virtual void set_screen_orientation(ScreenOrientation p_orientation);
+ void set_native_window(ANativeWindow *p_native_window);
+ ANativeWindow *get_native_window() const;
virtual Error shell_open(String p_uri);
virtual String get_user_data_dir() const;
virtual String get_resource_dir() const;
virtual String get_locale() const;
- virtual void set_clipboard(const String &p_text);
- virtual String get_clipboard() const;
virtual String get_model_name() const;
- virtual int get_screen_dpi(int p_screen = 0) const;
virtual String get_unique_id() const;
virtual String get_system_dir(SystemDir p_dir) const;
- void process_accelerometer(const Vector3 &p_accelerometer);
- void process_gravity(const Vector3 &p_gravity);
- void process_magnetometer(const Vector3 &p_magnetometer);
- void process_gyroscope(const Vector3 &p_gyroscope);
- void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
- void process_hover(int p_type, Point2 p_pos);
- void process_double_tap(Point2 p_pos);
- void process_scroll(Point2 p_pos);
- void process_joy_event(JoypadEvent p_event);
- void process_event(Ref<InputEvent> p_event);
- void init_video_mode(int p_video_width, int p_video_height);
-
- virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
- virtual bool native_video_is_playing() const;
- virtual void native_video_pause();
- virtual void native_video_stop();
-
- virtual bool is_joy_known(int p_device);
- virtual String get_joy_guid(int p_device) const;
- void joy_connection_changed(int p_device, bool p_connected, String p_name);
void vibrate_handheld(int p_duration_ms);
virtual bool _check_internal_feature_support(const String &p_feature);
diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp
index 7413236e5d..c3bfb2f2ed 100644
--- a/platform/android/plugin/godot_plugin_jni.cpp
+++ b/platform/android/plugin/godot_plugin_jni.cpp
@@ -33,6 +33,7 @@
#include <core/engine.h>
#include <core/error_macros.h>
#include <core/project_settings.h>
+#include <platform/android/api/jni_singleton.h>
#include <platform/android/jni_utils.h>
#include <platform/android/string_android.h>
@@ -43,7 +44,7 @@ extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name) {
String singname = jstring_to_string(name, env);
- JNISingleton *s = memnew(JNISingleton);
+ JNISingleton *s = (JNISingleton *)ClassDB::instance("JNISingleton");
s->set_instance(env->NewGlobalRef(obj));
jni_singletons[singname] = s;
@@ -86,6 +87,51 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
s->add_method(mname, mid, types, get_jni_type(retval));
}
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types) {
+ String singleton_name = jstring_to_string(j_plugin_name, env);
+
+ ERR_FAIL_COND(!jni_singletons.has(singleton_name));
+
+ JNISingleton *singleton = jni_singletons.get(singleton_name);
+
+ String signal_name = jstring_to_string(j_signal_name, env);
+ Vector<Variant::Type> types;
+
+ int stringCount = env->GetArrayLength(j_signal_param_types);
+
+ for (int i = 0; i < stringCount; i++) {
+
+ jstring j_signal_param_type = (jstring)env->GetObjectArrayElement(j_signal_param_types, i);
+ const String signal_param_type = jstring_to_string(j_signal_param_type, env);
+ types.push_back(get_jni_type(signal_param_type));
+ }
+
+ singleton->add_signal(signal_name, types);
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params) {
+ String singleton_name = jstring_to_string(j_plugin_name, env);
+
+ ERR_FAIL_COND(!jni_singletons.has(singleton_name));
+
+ JNISingleton *singleton = jni_singletons.get(singleton_name);
+
+ String signal_name = jstring_to_string(j_signal_name, env);
+
+ int count = env->GetArrayLength(j_signal_params);
+ const Variant *args[count];
+
+ for (int i = 0; i < count; i++) {
+
+ jobject j_param = env->GetObjectArrayElement(j_signal_params, i);
+ Variant variant = _jobject_to_variant(env, j_param);
+ args[i] = &variant;
+ env->DeleteLocalRef(j_param);
+ };
+
+ singleton->emit_signal(signal_name, args, count);
+}
+
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths) {
int gdnlib_count = env->GetArrayLength(gdnlib_paths);
if (gdnlib_count == 0) {
diff --git a/platform/android/plugin/godot_plugin_jni.h b/platform/android/plugin/godot_plugin_jni.h
index 0d613d3bfe..80ce332e7c 100644
--- a/platform/android/plugin/godot_plugin_jni.h
+++ b/platform/android/plugin/godot_plugin_jni.h
@@ -37,6 +37,8 @@
extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name);
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths);
}
diff --git a/platform/android/vulkan/vulkan_context_android.cpp b/platform/android/vulkan/vulkan_context_android.cpp
new file mode 100644
index 0000000000..5fb7a83da4
--- /dev/null
+++ b/platform/android/vulkan/vulkan_context_android.cpp
@@ -0,0 +1,60 @@
+/*************************************************************************/
+/* vulkan_context_android.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "vulkan_context_android.h"
+#include <vulkan/vulkan_android.h>
+
+const char *VulkanContextAndroid::_get_platform_surface_extension() const {
+ return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
+}
+
+int VulkanContextAndroid::window_create(ANativeWindow *p_window, int p_width, int p_height) {
+ VkAndroidSurfaceCreateInfoKHR createInfo;
+ createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+ createInfo.pNext = nullptr;
+ createInfo.flags = 0;
+ createInfo.window = p_window;
+
+ VkSurfaceKHR surface;
+ VkResult err = vkCreateAndroidSurfaceKHR(_get_instance(), &createInfo, nullptr, &surface);
+ if (err != VK_SUCCESS) {
+ ERR_FAIL_V_MSG(-1, "vkCreateAndroidSurfaceKHR failed with error " + itos(err));
+ }
+
+ return _window_create(DisplayServer::MAIN_WINDOW_ID, surface, p_width, p_height);
+}
+
+VulkanContextAndroid::VulkanContextAndroid() {
+ // TODO: fix validation layers
+ use_validation_layers = false;
+}
+
+VulkanContextAndroid::~VulkanContextAndroid() {
+}
diff --git a/platform/android/vulkan/vk_renderer_jni.cpp b/platform/android/vulkan/vulkan_context_android.h
index 3026e7daad..7e698ada4f 100644
--- a/platform/android/vulkan/vk_renderer_jni.cpp
+++ b/platform/android/vulkan/vulkan_context_android.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vk_renderer_jni.cpp */
+/* vulkan_context_android.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,31 +28,22 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "vk_renderer_jni.h"
+#ifndef VULKAN_CONTEXT_ANDROID_H
+#define VULKAN_CONTEXT_ANDROID_H
-extern "C" {
+#include "drivers/vulkan/vulkan_context.h"
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceCreated(JNIEnv *env, jobject obj, jobject j_surface) {
- // TODO: complete
-}
+struct ANativeWindow;
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceChanged(JNIEnv *env, jobject object, jobject j_surface, jint width, jint height) {
- // TODO: complete
-}
+class VulkanContextAndroid : public VulkanContext {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkResume(JNIEnv *env, jobject obj) {
- // TODO: complete
-}
+ virtual const char *_get_platform_surface_extension() const;
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDrawFrame(JNIEnv *env, jobject obj) {
- // TODO: complete
-}
+public:
+ int window_create(ANativeWindow *p_window, int p_width, int p_height);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkPause(JNIEnv *env, jobject obj) {
- // TODO: complete
-}
+ VulkanContextAndroid();
+ ~VulkanContextAndroid();
+};
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDestroy(JNIEnv *env, jobject obj) {
- // TODO: complete
-}
-}
+#endif // VULKAN_CONTEXT_ANDROID_H
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 47497eb95f..78ddef5ff6 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -254,10 +254,10 @@ bool DisplayServerX11::_refresh_device_info() {
bool absolute_mode = false;
int resolution_x = 0;
int resolution_y = 0;
- int range_min_x = 0;
- int range_min_y = 0;
- int range_max_x = 0;
- int range_max_y = 0;
+ double range_min_x = 0;
+ double range_min_y = 0;
+ double range_max_x = 0;
+ double range_max_y = 0;
int pressure_resolution = 0;
int tilt_resolution_x = 0;
int tilt_resolution_y = 0;
@@ -1471,8 +1471,11 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c
if (result == Success && data) {
long *state = (long *)data;
- if (state[0] == WM_IconicState)
+ if (state[0] == WM_IconicState) {
+ XFree(data);
return WINDOW_MODE_MINIMIZED;
+ }
+ XFree(data);
}
}
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index c46b6eeb5c..8ba334bc67 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -435,10 +435,10 @@ bool Area2D::is_monitorable() const {
return monitorable;
}
-Array Area2D::get_overlapping_bodies() const {
+TypedArray<Node2D> Area2D::get_overlapping_bodies() const {
ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off.");
- Array ret;
+ TypedArray<Node2D> ret;
ret.resize(body_map.size());
int idx = 0;
for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) {
@@ -453,10 +453,10 @@ Array Area2D::get_overlapping_bodies() const {
return ret;
}
-Array Area2D::get_overlapping_areas() const {
+TypedArray<Area2D> Area2D::get_overlapping_areas() const {
ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off.");
- Array ret;
+ TypedArray<Area2D> ret;
ret.resize(area_map.size());
int idx = 0;
for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) {
diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h
index c5e6635412..0e2c0ac672 100644
--- a/scene/2d/area_2d.h
+++ b/scene/2d/area_2d.h
@@ -178,8 +178,8 @@ public:
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;
- Array get_overlapping_bodies() const; //function for script
- Array get_overlapping_areas() const; //function for script
+ TypedArray<Node2D> get_overlapping_bodies() const; //function for script
+ TypedArray<Area2D> get_overlapping_areas() const; //function for script
bool overlaps_area(Node *p_area) const;
bool overlaps_body(Node *p_body) const;
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index d77fd5b097..19484442b1 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -95,7 +95,7 @@ Vector<Vector2> NavigationPolygon::get_vertices() const {
return vertices;
}
-void NavigationPolygon::_set_polygons(const Array &p_array) {
+void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) {
{
MutexLock lock(navmesh_generation);
@@ -118,7 +118,7 @@ Array NavigationPolygon::_get_polygons() const {
return ret;
}
-void NavigationPolygon::_set_outlines(const Array &p_array) {
+void NavigationPolygon::_set_outlines(const TypedArray<Vector<int32_t>> &p_array) {
outlines.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 73e056a353..cbfe4299fb 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -55,10 +55,10 @@ class NavigationPolygon : public Resource {
protected:
static void _bind_methods();
- void _set_polygons(const Array &p_array);
+ void _set_polygons(const TypedArray<Vector<int32_t>> &p_array);
Array _get_polygons() const;
- void _set_outlines(const Array &p_array);
+ void _set_outlines(const TypedArray<Vector<int32_t>> &p_array);
Array _get_outlines() const;
public:
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index d55b21bc24..ed8481db4a 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -321,16 +321,14 @@ void PathFollow2D::set_offset(float p_offset) {
offset = p_offset;
if (path) {
- if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
+ if (path->get_curve().is_valid()) {
float path_length = path->get_curve()->get_baked_length();
if (loop) {
- while (offset > path_length)
- offset -= path_length;
-
- while (offset < 0)
- offset += path_length;
-
+ offset = Math::fposmod(offset, path_length);
+ if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) {
+ offset = path_length;
+ }
} else {
offset = CLAMP(offset, 0, path_length);
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 21dc9537ec..de15f0efc2 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -139,7 +139,7 @@ PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) :
set_pickable(false);
}
-Array PhysicsBody2D::get_collision_exceptions() {
+TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
List<RID> exceptions;
PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
Array ret;
@@ -739,11 +739,11 @@ RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() cons
return ccd_mode;
}
-Array RigidBody2D::get_colliding_bodies() const {
+TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const {
ERR_FAIL_COND_V(!contact_monitor, Array());
- Array ret;
+ TypedArray<Node2D> ret;
ret.resize(contact_monitor->body_map.size());
int idx = 0;
for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 0d92a820e3..75f4f778bf 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -67,7 +67,7 @@ public:
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;
- Array get_collision_exceptions();
+ TypedArray<PhysicsBody2D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
void remove_collision_exception_with(Node *p_node);
@@ -256,7 +256,7 @@ public:
void add_force(const Vector2 &p_offset, const Vector2 &p_force);
void add_torque(float p_torque);
- Array get_colliding_bodies() const; //function for script
+ TypedArray<Node2D> get_colliding_bodies() const; //function for script
virtual String get_configuration_warning() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 1cf12e4421..9628c01718 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1691,27 +1691,27 @@ bool TileMap::is_centered_textures_enabled() const {
return centered_textures;
}
-Array TileMap::get_used_cells() const {
+TypedArray<Vector2i> TileMap::get_used_cells() const {
- Array a;
+ TypedArray<Vector2i> a;
a.resize(tile_map.size());
int i = 0;
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
- Vector2 p(E->key().x, E->key().y);
+ Vector2i p(E->key().x, E->key().y);
a[i++] = p;
}
return a;
}
-Array TileMap::get_used_cells_by_id(int p_id) const {
+TypedArray<Vector2i> TileMap::get_used_cells_by_id(int p_id) const {
- Array a;
+ TypedArray<Vector2i> a;
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
if (E->value().id == p_id) {
- Vector2 p(E->key().x, E->key().y);
+ Vector2i p(E->key().x, E->key().y);
a.push_back(p);
}
}
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index d9490aae13..cc1537f583 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -328,8 +328,8 @@ public:
void set_centered_textures(bool p_enable);
bool is_centered_textures_enabled() const;
- Array get_used_cells() const;
- Array get_used_cells_by_id(int p_id) const;
+ TypedArray<Vector2i> get_used_cells() const;
+ TypedArray<Vector2i> get_used_cells_by_id(int p_id) const;
Rect2 get_used_rect(); // Not const because of cache
void set_occluder_light_mask(int p_mask);
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 17ae553e5e..b72483d71b 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const {
return monitoring;
}
-Array Area3D::get_overlapping_bodies() const {
+TypedArray<Node3D> Area3D::get_overlapping_bodies() const {
ERR_FAIL_COND_V(!monitoring, Array());
Array ret;
@@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const {
return monitorable;
}
-Array Area3D::get_overlapping_areas() const {
+TypedArray<Area3D> Area3D::get_overlapping_areas() const {
ERR_FAIL_COND_V(!monitoring, Array());
Array ret;
diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h
index ff6c0b6b08..f6503c6d2d 100644
--- a/scene/3d/area_3d.h
+++ b/scene/3d/area_3d.h
@@ -184,8 +184,8 @@ public:
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;
- Array get_overlapping_bodies() const;
- Array get_overlapping_areas() const; //function for script
+ TypedArray<Node3D> get_overlapping_bodies() const;
+ TypedArray<Area3D> get_overlapping_areas() const; //function for script
bool overlaps_area(Node *p_area) const;
bool overlaps_body(Node *p_body) const;
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
new file mode 100644
index 0000000000..4c824aedc4
--- /dev/null
+++ b/scene/3d/decal.cpp
@@ -0,0 +1,235 @@
+/*************************************************************************/
+/* decal.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "decal.h"
+
+void Decal::set_extents(const Vector3 &p_extents) {
+ extents = p_extents;
+ RS::get_singleton()->decal_set_extents(decal, p_extents);
+ update_gizmo();
+ _change_notify("extents");
+}
+
+Vector3 Decal::get_extents() const {
+ return extents;
+}
+
+void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) {
+ ERR_FAIL_INDEX(p_type, TEXTURE_MAX);
+ textures[p_type] = p_texture;
+ RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
+ RS::get_singleton()->decal_set_texture(decal, RS::DecalTexture(p_type), texture_rid);
+}
+Ref<Texture2D> Decal::get_texture(DecalTexture p_type) const {
+ ERR_FAIL_INDEX_V(p_type, TEXTURE_MAX, Ref<Texture2D>());
+ return textures[p_type];
+}
+
+void Decal::set_emission_energy(float p_energy) {
+ emission_energy = p_energy;
+ RS::get_singleton()->decal_set_emission_energy(decal, emission_energy);
+}
+float Decal::get_emission_energy() const {
+ return emission_energy;
+}
+
+void Decal::set_albedo_mix(float p_mix) {
+ albedo_mix = p_mix;
+ RS::get_singleton()->decal_set_albedo_mix(decal, albedo_mix);
+}
+float Decal::get_albedo_mix() const {
+ return albedo_mix;
+}
+
+void Decal::set_upper_fade(float p_fade) {
+ upper_fade = p_fade;
+ RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade);
+}
+float Decal::get_upper_fade() const {
+ return upper_fade;
+}
+
+void Decal::set_lower_fade(float p_fade) {
+ lower_fade = p_fade;
+ RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade);
+}
+float Decal::get_lower_fade() const {
+ return lower_fade;
+}
+
+void Decal::set_normal_fade(float p_fade) {
+ normal_fade = p_fade;
+ RS::get_singleton()->decal_set_normal_fade(decal, normal_fade);
+}
+float Decal::get_normal_fade() const {
+ return normal_fade;
+}
+
+void Decal::set_modulate(Color p_modulate) {
+ modulate = p_modulate;
+ RS::get_singleton()->decal_set_modulate(decal, p_modulate);
+}
+
+Color Decal::get_modulate() const {
+ return modulate;
+}
+
+void Decal::set_enable_distance_fade(bool p_enable) {
+ distance_fade_enabled = p_enable;
+ RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length);
+}
+bool Decal::is_distance_fade_enabled() const {
+ return distance_fade_enabled;
+}
+
+void Decal::set_distance_fade_begin(float p_distance) {
+ distance_fade_begin = p_distance;
+ RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length);
+}
+float Decal::get_distance_fade_begin() const {
+ return distance_fade_begin;
+}
+
+void Decal::set_distance_fade_length(float p_length) {
+ distance_fade_length = p_length;
+ RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length);
+}
+float Decal::get_distance_fade_length() const {
+ return distance_fade_length;
+}
+
+void Decal::set_cull_mask(uint32_t p_layers) {
+ cull_mask = p_layers;
+ RS::get_singleton()->decal_set_cull_mask(decal, cull_mask);
+}
+uint32_t Decal::get_cull_mask() const {
+ return cull_mask;
+}
+
+AABB Decal::get_aabb() const {
+
+ AABB aabb;
+ aabb.position = -extents;
+ aabb.size = extents * 2.0;
+ return aabb;
+}
+Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const {
+
+ return Vector<Face3>();
+}
+
+void Decal::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents);
+
+ ClassDB::bind_method(D_METHOD("set_texture", "type", "texture"), &Decal::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture", "type"), &Decal::get_texture);
+
+ ClassDB::bind_method(D_METHOD("set_emission_energy", "energy"), &Decal::set_emission_energy);
+ ClassDB::bind_method(D_METHOD("get_emission_energy"), &Decal::get_emission_energy);
+
+ ClassDB::bind_method(D_METHOD("set_albedo_mix", "energy"), &Decal::set_albedo_mix);
+ ClassDB::bind_method(D_METHOD("get_albedo_mix"), &Decal::get_albedo_mix);
+
+ ClassDB::bind_method(D_METHOD("set_modulate", "color"), &Decal::set_modulate);
+ ClassDB::bind_method(D_METHOD("get_modulate"), &Decal::get_modulate);
+
+ ClassDB::bind_method(D_METHOD("set_upper_fade", "fade"), &Decal::set_upper_fade);
+ ClassDB::bind_method(D_METHOD("get_upper_fade"), &Decal::get_upper_fade);
+
+ ClassDB::bind_method(D_METHOD("set_lower_fade", "fade"), &Decal::set_lower_fade);
+ ClassDB::bind_method(D_METHOD("get_lower_fade"), &Decal::get_lower_fade);
+
+ ClassDB::bind_method(D_METHOD("set_normal_fade", "fade"), &Decal::set_normal_fade);
+ ClassDB::bind_method(D_METHOD("get_normal_fade"), &Decal::get_normal_fade);
+
+ ClassDB::bind_method(D_METHOD("set_enable_distance_fade", "enable"), &Decal::set_enable_distance_fade);
+ ClassDB::bind_method(D_METHOD("is_distance_fade_enabled"), &Decal::is_distance_fade_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_distance_fade_begin", "distance"), &Decal::set_distance_fade_begin);
+ ClassDB::bind_method(D_METHOD("get_distance_fade_begin"), &Decal::get_distance_fade_begin);
+
+ ClassDB::bind_method(D_METHOD("set_distance_fade_length", "distance"), &Decal::set_distance_fade_length);
+ ClassDB::bind_method(D_METHOD("get_distance_fade_length"), &Decal::get_distance_fade_length);
+
+ ClassDB::bind_method(D_METHOD("set_cull_mask", "mask"), &Decal::set_cull_mask);
+ ClassDB::bind_method(D_METHOD("get_cull_mask"), &Decal::get_cull_mask);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater"), "set_extents", "get_extents");
+ ADD_GROUP("Textures", "texture_");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION);
+ ADD_GROUP("Parameters", "");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "albedo_mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_albedo_mix", "get_albedo_mix");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_normal_fade", "get_normal_fade");
+ ADD_GROUP("Vertical Fade", "");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "upper_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_upper_fade", "get_upper_fade");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lower_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_lower_fade", "get_lower_fade");
+ ADD_GROUP("Distance Fade", "distance_fade_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin"), "set_distance_fade_begin", "get_distance_fade_begin");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length"), "set_distance_fade_length", "get_distance_fade_length");
+ ADD_GROUP("Cull Mask", "");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
+
+ BIND_ENUM_CONSTANT(TEXTURE_ALBEDO);
+ BIND_ENUM_CONSTANT(TEXTURE_NORMAL);
+ BIND_ENUM_CONSTANT(TEXTURE_ORM);
+ BIND_ENUM_CONSTANT(TEXTURE_EMISSION);
+ BIND_ENUM_CONSTANT(TEXTURE_MAX);
+}
+
+Decal::Decal() {
+
+ extents = Vector3(1, 1, 1);
+ emission_energy = 1.0;
+ modulate = Color(1, 1, 1, 1);
+ albedo_mix = 1.0;
+ cull_mask = (1 << 20) - 1;
+ upper_fade = 0.3;
+ lower_fade = 0.3;
+ normal_fade = 0;
+ distance_fade_enabled = false;
+ distance_fade_begin = 10;
+ distance_fade_length = 1;
+
+ decal = RenderingServer::get_singleton()->decal_create();
+ RS::get_singleton()->instance_set_base(get_instance(), decal);
+}
+
+Decal::~Decal() {
+
+ RS::get_singleton()->free(decal);
+}
diff --git a/scene/3d/decal.h b/scene/3d/decal.h
new file mode 100644
index 0000000000..665444829d
--- /dev/null
+++ b/scene/3d/decal.h
@@ -0,0 +1,114 @@
+/*************************************************************************/
+/* decal.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef DECAL_H
+#define DECAL_H
+
+#include "scene/3d/visual_instance_3d.h"
+#include "scene/resources/texture.h"
+#include "servers/rendering_server.h"
+
+class Decal : public VisualInstance3D {
+ GDCLASS(Decal, VisualInstance3D);
+
+public:
+ enum DecalTexture {
+ TEXTURE_ALBEDO,
+ TEXTURE_NORMAL,
+ TEXTURE_ORM,
+ TEXTURE_EMISSION,
+ TEXTURE_MAX
+ };
+
+private:
+ RID decal;
+ Vector3 extents;
+ Ref<Texture2D> textures[TEXTURE_MAX];
+ float emission_energy;
+ float albedo_mix;
+ Color modulate;
+ uint32_t cull_mask;
+ float normal_fade;
+ float upper_fade;
+ float lower_fade;
+ bool distance_fade_enabled;
+ float distance_fade_begin;
+ float distance_fade_length;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_extents(const Vector3 &p_extents);
+ Vector3 get_extents() const;
+
+ void set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture(DecalTexture p_type) const;
+
+ void set_emission_energy(float p_energy);
+ float get_emission_energy() const;
+
+ void set_albedo_mix(float p_mix);
+ float get_albedo_mix() const;
+
+ void set_modulate(Color p_modulate);
+ Color get_modulate() const;
+
+ void set_upper_fade(float p_energy);
+ float get_upper_fade() const;
+
+ void set_lower_fade(float p_fade);
+ float get_lower_fade() const;
+
+ void set_normal_fade(float p_fade);
+ float get_normal_fade() const;
+
+ void set_enable_distance_fade(bool p_enable);
+ bool is_distance_fade_enabled() const;
+
+ void set_distance_fade_begin(float p_distance);
+ float get_distance_fade_begin() const;
+
+ void set_distance_fade_length(float p_length);
+ float get_distance_fade_length() const;
+
+ void set_cull_mask(uint32_t p_layers);
+ uint32_t get_cull_mask() const;
+
+ virtual AABB get_aabb() const;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+
+ Decal();
+ ~Decal();
+};
+
+VARIANT_ENUM_CAST(Decal::DecalTexture);
+
+#endif // DECAL_H
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index be3b369724..c048f60ebd 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -70,7 +70,7 @@ void Light3D::set_shadow(bool p_enable) {
shadow = p_enable;
RS::get_singleton()->light_set_shadow(light, p_enable);
- if (type == RenderingServer::LIGHT_SPOT) {
+ if (type == RenderingServer::LIGHT_SPOT || type == RenderingServer::LIGHT_OMNI) {
update_configuration_warning();
}
}
@@ -166,6 +166,18 @@ Light3D::BakeMode Light3D::get_bake_mode() const {
return bake_mode;
}
+void Light3D::set_projector(const Ref<Texture2D> &p_texture) {
+
+ projector = p_texture;
+ RID tex_id = projector.is_valid() ? projector->get_rid() : RID();
+ RS::get_singleton()->light_set_projector(light, tex_id);
+ update_configuration_warning();
+}
+
+Ref<Texture2D> Light3D::get_projector() const {
+ return projector;
+}
+
void Light3D::_update_visibility() {
if (!is_inside_tree())
@@ -217,8 +229,16 @@ bool Light3D::is_editor_only() const {
void Light3D::_validate_property(PropertyInfo &property) const {
- if (RenderingServer::get_singleton()->is_low_end() && property.name == "shadow_contact") {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_size") {
+ property.usage = 0;
+ }
+
+ if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") {
+ property.usage = 0;
+ }
+
+ if (get_light_type() != RS::LIGHT_DIRECTIONAL && property.name == "light_angular_distance") {
+ property.usage = 0;
}
}
@@ -251,10 +271,16 @@ void Light3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode);
ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode);
+ ClassDB::bind_method(D_METHOD("set_projector", "projector"), &Light3D::set_projector);
+ ClassDB::bind_method(D_METHOD("get_projector"), &Light3D::get_projector);
+
ADD_GROUP("Light", "light_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY);
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector");
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,64,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01"), "set_param", "get_param", PARAM_SIZE);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR);
ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disable,Indirect,All"), "set_bake_mode", "get_bake_mode");
@@ -262,9 +288,11 @@ void Light3D::_bind_methods() {
ADD_GROUP("Shadow", "shadow_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_contact", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BIAS);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face");
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0.1,8,0.01"), "set_param", "get_param", PARAM_SHADOW_BLUR);
ADD_GROUP("Editor", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only");
ADD_GROUP("", "");
@@ -273,10 +301,10 @@ void Light3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY);
BIND_ENUM_CONSTANT(PARAM_SPECULAR);
BIND_ENUM_CONSTANT(PARAM_RANGE);
+ BIND_ENUM_CONSTANT(PARAM_SIZE);
BIND_ENUM_CONSTANT(PARAM_ATTENUATION);
BIND_ENUM_CONSTANT(PARAM_SPOT_ANGLE);
BIND_ENUM_CONSTANT(PARAM_SPOT_ATTENUATION);
- BIND_ENUM_CONSTANT(PARAM_CONTACT_SHADOW_SIZE);
BIND_ENUM_CONSTANT(PARAM_SHADOW_MAX_DISTANCE);
BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_1_OFFSET);
BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_2_OFFSET);
@@ -284,7 +312,9 @@ void Light3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_SHADOW_FADE_START);
BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS);
BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS);
- BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS_SPLIT_SCALE);
+ BIND_ENUM_CONSTANT(PARAM_SHADOW_PANCAKE_SIZE);
+ BIND_ENUM_CONSTANT(PARAM_SHADOW_BLUR);
+ BIND_ENUM_CONSTANT(PARAM_TRANSMITTANCE_BIAS);
BIND_ENUM_CONSTANT(PARAM_MAX);
BIND_ENUM_CONSTANT(BAKE_DISABLED);
@@ -318,17 +348,20 @@ Light3D::Light3D(RenderingServer::LightType p_type) {
set_param(PARAM_INDIRECT_ENERGY, 1);
set_param(PARAM_SPECULAR, 0.5);
set_param(PARAM_RANGE, 5);
+ set_param(PARAM_SIZE, 0);
set_param(PARAM_ATTENUATION, 1);
set_param(PARAM_SPOT_ANGLE, 45);
set_param(PARAM_SPOT_ATTENUATION, 1);
- set_param(PARAM_CONTACT_SHADOW_SIZE, 0);
set_param(PARAM_SHADOW_MAX_DISTANCE, 0);
set_param(PARAM_SHADOW_SPLIT_1_OFFSET, 0.1);
set_param(PARAM_SHADOW_SPLIT_2_OFFSET, 0.2);
set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5);
set_param(PARAM_SHADOW_FADE_START, 0.8);
- set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0);
- set_param(PARAM_SHADOW_BIAS, 0.15);
+ set_param(PARAM_SHADOW_PANCAKE_SIZE, 20.0);
+ set_param(PARAM_SHADOW_BLUR, 1.0);
+ set_param(PARAM_SHADOW_BIAS, 0.02);
+ set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0);
+ set_param(PARAM_TRANSMITTANCE_BIAS, 0.05);
set_param(PARAM_SHADOW_FADE_START, 1);
set_disable_scale(true);
}
@@ -398,10 +431,9 @@ void DirectionalLight3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_fade_start", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_FADE_START);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE);
ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_EXP_RANGE, "0,8192,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_pancake_size", PROPERTY_HINT_EXP_RANGE, "0,1024,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_PANCAKE_SIZE);
BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL);
BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS);
@@ -414,11 +446,8 @@ void DirectionalLight3D::_bind_methods() {
DirectionalLight3D::DirectionalLight3D() :
Light3D(RenderingServer::LIGHT_DIRECTIONAL) {
- set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8);
- set_param(PARAM_SHADOW_BIAS, 0.1);
set_param(PARAM_SHADOW_MAX_DISTANCE, 100);
set_param(PARAM_SHADOW_FADE_START, 0.8);
- set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25);
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE);
@@ -436,6 +465,19 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const {
return shadow_mode;
}
+String OmniLight3D::get_configuration_warning() const {
+ String warning = Light3D::get_configuration_warning();
+
+ if (!has_shadow() && get_projector().is_valid()) {
+ if (warning != String()) {
+ warning += "\n\n";
+ }
+ warning += TTR("Projector texture only works with shadows active.");
+ }
+
+ return warning;
+}
+
void OmniLight3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight3D::set_shadow_mode);
@@ -467,6 +509,13 @@ String SpotLight3D::get_configuration_warning() const {
warning += TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows.");
}
+ if (!has_shadow() && get_projector().is_valid()) {
+ if (warning != String()) {
+ warning += "\n\n";
+ }
+ warning += TTR("Projector texture only works with shadows active.");
+ }
+
return warning;
}
diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h
index 197e5854ec..6e78217342 100644
--- a/scene/3d/light_3d.h
+++ b/scene/3d/light_3d.h
@@ -46,10 +46,10 @@ public:
PARAM_INDIRECT_ENERGY = RS::LIGHT_PARAM_INDIRECT_ENERGY,
PARAM_SPECULAR = RS::LIGHT_PARAM_SPECULAR,
PARAM_RANGE = RS::LIGHT_PARAM_RANGE,
+ PARAM_SIZE = RS::LIGHT_PARAM_SIZE,
PARAM_ATTENUATION = RS::LIGHT_PARAM_ATTENUATION,
PARAM_SPOT_ANGLE = RS::LIGHT_PARAM_SPOT_ANGLE,
PARAM_SPOT_ATTENUATION = RS::LIGHT_PARAM_SPOT_ATTENUATION,
- PARAM_CONTACT_SHADOW_SIZE = RS::LIGHT_PARAM_CONTACT_SHADOW_SIZE,
PARAM_SHADOW_MAX_DISTANCE = RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE,
PARAM_SHADOW_SPLIT_1_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
PARAM_SHADOW_SPLIT_2_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET,
@@ -57,7 +57,9 @@ public:
PARAM_SHADOW_FADE_START = RS::LIGHT_PARAM_SHADOW_FADE_START,
PARAM_SHADOW_NORMAL_BIAS = RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS,
PARAM_SHADOW_BIAS = RS::LIGHT_PARAM_SHADOW_BIAS,
- PARAM_SHADOW_BIAS_SPLIT_SCALE = RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
+ PARAM_SHADOW_PANCAKE_SIZE = RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE,
+ PARAM_SHADOW_BLUR = RS::LIGHT_PARAM_SHADOW_BLUR,
+ PARAM_TRANSMITTANCE_BIAS = RS::LIGHT_PARAM_TRANSMITTANCE_BIAS,
PARAM_MAX = RS::LIGHT_PARAM_MAX
};
@@ -79,6 +81,7 @@ private:
bool editor_only;
void _update_visibility();
BakeMode bake_mode;
+ Ref<Texture2D> projector;
// bind helpers
@@ -123,6 +126,9 @@ public:
void set_bake_mode(BakeMode p_mode);
BakeMode get_bake_mode() const;
+ void set_projector(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_projector() const;
+
virtual AABB get_aabb() const;
virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
@@ -194,6 +200,8 @@ public:
void set_shadow_mode(ShadowMode p_mode);
ShadowMode get_shadow_mode() const;
+ virtual String get_configuration_warning() const;
+
OmniLight3D();
};
diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp
index f06135f53d..4a425d1e0e 100644
--- a/scene/3d/path_3d.cpp
+++ b/scene/3d/path_3d.cpp
@@ -316,16 +316,14 @@ void PathFollow3D::set_offset(float p_offset) {
offset = p_offset;
if (path) {
- if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
+ if (path->get_curve().is_valid()) {
float path_length = path->get_curve()->get_baked_length();
if (loop) {
- while (offset > path_length)
- offset -= path_length;
-
- while (offset < 0)
- offset += path_length;
-
+ offset = Math::fposmod(offset, path_length);
+ if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) {
+ offset = path_length;
+ }
} else {
offset = CLAMP(offset, 0, path_length);
}
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 2b6eb8ac8a..3991efc7c0 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const {
return get_collision_layer() & (1 << p_bit);
}
-Array PhysicsBody3D::get_collision_exceptions() {
+TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() {
List<RID> exceptions;
PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
Array ret;
@@ -2134,6 +2134,10 @@ void PhysicalBone3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_joint_offset", "offset"), &PhysicalBone3D::set_joint_offset);
ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone3D::get_joint_offset);
+ ClassDB::bind_method(D_METHOD("set_joint_rotation", "euler"), &PhysicalBone3D::set_joint_rotation);
+ ClassDB::bind_method(D_METHOD("get_joint_rotation"), &PhysicalBone3D::get_joint_rotation);
+ ClassDB::bind_method(D_METHOD("set_joint_rotation_degrees", "euler_degrees"), &PhysicalBone3D::set_joint_rotation_degrees);
+ ClassDB::bind_method(D_METHOD("get_joint_rotation_degrees"), &PhysicalBone3D::get_joint_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone3D::set_body_offset);
ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone3D::get_body_offset);
@@ -2159,9 +2163,23 @@ void PhysicalBone3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &PhysicalBone3D::set_gravity_scale);
ClassDB::bind_method(D_METHOD("get_gravity_scale"), &PhysicalBone3D::get_gravity_scale);
+ ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &PhysicalBone3D::set_linear_damp);
+ ClassDB::bind_method(D_METHOD("get_linear_damp"), &PhysicalBone3D::get_linear_damp);
+
+ ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &PhysicalBone3D::set_angular_damp);
+ ClassDB::bind_method(D_METHOD("get_angular_damp"), &PhysicalBone3D::get_angular_damp);
+
+ ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep);
+ ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep);
+
+ ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock);
+ ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock);
+
ADD_GROUP("Joint", "joint_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", 0), "set_joint_rotation", "get_joint_rotation");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset");
@@ -2170,6 +2188,17 @@ void PhysicalBone3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep");
+
+ ADD_GROUP("Axis Lock", "axis_lock_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z);
BIND_ENUM_CONSTANT(JOINT_TYPE_NONE);
BIND_ENUM_CONSTANT(JOINT_TYPE_PIN);
@@ -2187,6 +2216,19 @@ Skeleton3D *PhysicalBone3D::find_skeleton_parent(Node *p_parent) {
return s ? s : find_skeleton_parent(p_parent->get_parent());
}
+void PhysicalBone3D::_update_joint_offset() {
+ _fix_joint_offset();
+
+ set_ignore_transform_notification(true);
+ reset_to_rest_position();
+ set_ignore_transform_notification(false);
+
+#ifdef TOOLS_ENABLED
+ if (get_gizmo().is_valid())
+ get_gizmo()->redraw();
+#endif
+}
+
void PhysicalBone3D::_fix_joint_offset() {
// Clamp joint origin to bone origin
if (parent_skeleton) {
@@ -2370,16 +2412,31 @@ PhysicalBone3D::JointType PhysicalBone3D::get_joint_type() const {
void PhysicalBone3D::set_joint_offset(const Transform &p_offset) {
joint_offset = p_offset;
- _fix_joint_offset();
+ _update_joint_offset();
+ _change_notify("joint_rotation_degrees");
+}
- set_ignore_transform_notification(true);
- reset_to_rest_position();
- set_ignore_transform_notification(false);
+const Transform &PhysicalBone3D::get_joint_offset() const {
+ return joint_offset;
+}
-#ifdef TOOLS_ENABLED
- if (get_gizmo().is_valid())
- get_gizmo()->redraw();
-#endif
+void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) {
+ joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale());
+
+ _update_joint_offset();
+ _change_notify("joint_offset");
+}
+
+Vector3 PhysicalBone3D::get_joint_rotation() const {
+ return joint_offset.basis.get_rotation();
+}
+
+void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) {
+ set_joint_rotation(p_euler_deg * Math_PI / 180.0);
+}
+
+Vector3 PhysicalBone3D::get_joint_rotation_degrees() const {
+ return get_joint_rotation() * 180.0 / Math_PI;
}
const Transform &PhysicalBone3D::get_body_offset() const {
@@ -2390,20 +2447,7 @@ void PhysicalBone3D::set_body_offset(const Transform &p_offset) {
body_offset = p_offset;
body_offset_inverse = body_offset.affine_inverse();
- _fix_joint_offset();
-
- set_ignore_transform_notification(true);
- reset_to_rest_position();
- set_ignore_transform_notification(false);
-
-#ifdef TOOLS_ENABLED
- if (get_gizmo().is_valid())
- get_gizmo()->redraw();
-#endif
-}
-
-const Transform &PhysicalBone3D::get_joint_offset() const {
- return joint_offset;
+ _update_joint_offset();
}
void PhysicalBone3D::set_simulate_physics(bool p_simulate) {
@@ -2496,6 +2540,43 @@ real_t PhysicalBone3D::get_gravity_scale() const {
return gravity_scale;
}
+void PhysicalBone3D::set_linear_damp(real_t p_linear_damp) {
+ ERR_FAIL_COND(p_linear_damp < -1);
+ linear_damp = p_linear_damp;
+ PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp);
+}
+
+real_t PhysicalBone3D::get_linear_damp() const {
+ return linear_damp;
+}
+
+void PhysicalBone3D::set_angular_damp(real_t p_angular_damp) {
+ ERR_FAIL_COND(p_angular_damp < -1);
+ angular_damp = p_angular_damp;
+ PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp);
+}
+
+real_t PhysicalBone3D::get_angular_damp() const {
+ return angular_damp;
+}
+
+void PhysicalBone3D::set_can_sleep(bool p_active) {
+ can_sleep = p_active;
+ PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active);
+}
+
+bool PhysicalBone3D::is_able_to_sleep() const {
+ return can_sleep;
+}
+
+void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) {
+ PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock);
+}
+
+bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const {
+ return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis);
+}
+
PhysicalBone3D::PhysicalBone3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC),
#ifdef TOOLS_ENABLED
@@ -2510,7 +2591,10 @@ PhysicalBone3D::PhysicalBone3D() :
bounce(0),
mass(1),
friction(1),
- gravity_scale(1) {
+ gravity_scale(1),
+ linear_damp(-1),
+ angular_damp(-1),
+ can_sleep(true) {
reset_physics_simulation_state();
}
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index bf7854b68d..0e719f5108 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -68,7 +68,7 @@ public:
void set_collision_mask_bit(int p_bit, bool p_value);
bool get_collision_mask_bit(int p_bit) const;
- Array get_collision_exceptions();
+ TypedArray<PhysicsBody3D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
void remove_collision_exception_with(Node *p_node);
@@ -562,6 +562,9 @@ private:
real_t mass;
real_t friction;
real_t gravity_scale;
+ real_t linear_damp;
+ real_t angular_damp;
+ bool can_sleep;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
@@ -575,6 +578,7 @@ protected:
private:
static Skeleton3D *find_skeleton_parent(Node *p_parent);
+ void _update_joint_offset();
void _fix_joint_offset();
void _reload_joint();
@@ -599,6 +603,12 @@ public:
void set_joint_offset(const Transform &p_offset);
const Transform &get_joint_offset() const;
+ void set_joint_rotation(const Vector3 &p_euler_rad);
+ Vector3 get_joint_rotation() const;
+
+ void set_joint_rotation_degrees(const Vector3 &p_euler_deg);
+ Vector3 get_joint_rotation_degrees() const;
+
void set_body_offset(const Transform &p_offset);
const Transform &get_body_offset() const;
@@ -624,6 +634,18 @@ public:
void set_gravity_scale(real_t p_gravity_scale);
real_t get_gravity_scale() const;
+ void set_linear_damp(real_t p_linear_damp);
+ real_t get_linear_damp() const;
+
+ void set_angular_damp(real_t p_angular_damp);
+ real_t get_angular_damp() const;
+
+ void set_can_sleep(bool p_active);
+ bool is_able_to_sleep() const;
+
+ void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
+ bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
+
void apply_central_impulse(const Vector3 &p_impulse);
void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 59a6e23005..973822653a 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -33,6 +33,7 @@
#include "core/engine.h"
#include "core/message_queue.h"
#include "core/project_settings.h"
+#include "core/type_info.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/resources/surface_tool.h"
@@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect
}
}
-void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
+void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) {
set_physics_process_internal(false);
Vector<int> sim_bones;
@@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
sim_bones.resize(p_bones.size());
int c = 0;
for (int i = sim_bones.size() - 1; 0 <= i; --i) {
- Variant::Type type = p_bones.get(i).get_type();
- if (Variant::STRING == type || Variant::STRING_NAME == type) {
- int bone_id = find_bone(p_bones.get(i));
- if (bone_id != -1)
- sim_bones.write[c++] = bone_id;
- }
+ int bone_id = find_bone(p_bones[i]);
+ if (bone_id != -1)
+ sim_bones.write[c++] = bone_id;
}
sim_bones.resize(c);
}
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index 08b8691658..0bccd3f8fc 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -222,7 +222,7 @@ private:
public:
void physical_bones_stop_simulation();
- void physical_bones_start_simulation_on(const Array &p_bones);
+ void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones);
void physical_bones_add_collision_exception(RID p_exception);
void physical_bones_remove_collision_exception(RID p_exception);
#endif // _3D_DISABLED
diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp
index 281be3f7d3..0ffde7aa8f 100644
--- a/scene/3d/spring_arm_3d.cpp
+++ b/scene/3d/spring_arm_3d.cpp
@@ -45,15 +45,15 @@ void SpringArm3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
if (!Engine::get_singleton()->is_editor_hint()) {
- set_process_internal(true);
+ set_physics_process_internal(true);
}
break;
case NOTIFICATION_EXIT_TREE:
if (!Engine::get_singleton()->is_editor_hint()) {
- set_process_internal(false);
+ set_physics_process_internal(false);
}
break;
- case NOTIFICATION_INTERNAL_PROCESS:
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS:
process_spring();
break;
}
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index 775a9b76e2..604bc53422 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -217,6 +217,62 @@ float GeometryInstance3D::get_lod_max_hysteresis() const {
void GeometryInstance3D::_notification(int p_what) {
}
+const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const {
+ StringName *r = instance_uniform_property_remap.getptr(p_name);
+ if (!r) {
+ String s = p_name;
+ if (s.begins_with("shader_params/")) {
+ StringName name = s.replace("shader_params/", "");
+ instance_uniform_property_remap[p_name] = name;
+ return instance_uniform_property_remap.getptr(p_name);
+ }
+
+ return nullptr;
+ }
+
+ return r;
+}
+
+bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) {
+ const StringName *r = _instance_uniform_get_remap(p_name);
+ if (r) {
+ set_shader_instance_uniform(*r, p_value);
+ return true;
+ }
+
+ return false;
+}
+
+bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const {
+ const StringName *r = _instance_uniform_get_remap(p_name);
+ if (r) {
+ r_ret = get_shader_instance_uniform(*r);
+ return true;
+ }
+
+ return false;
+}
+void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
+ List<PropertyInfo> pinfo;
+ RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo);
+ for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
+ PropertyInfo pi = E->get();
+ bool has_def_value = false;
+ Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name);
+ if (def_value.get_type() != Variant::NIL) {
+ has_def_value = true;
+ }
+ if (instance_uniforms.has(pi.name)) {
+ pi.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE | (has_def_value ? (PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED) : 0);
+ } else {
+ pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : 0); //do not save if not changed
+ }
+
+ pi.name = "shader_params/" + pi.name;
+ p_list->push_back(pi);
+ }
+}
+
void GeometryInstance3D::set_flag(Flags p_flag, bool p_value) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
@@ -258,6 +314,22 @@ float GeometryInstance3D::get_extra_cull_margin() const {
return extra_cull_margin;
}
+void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value) {
+
+ if (p_value.get_type() == Variant::NIL) {
+ Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_uniform);
+ RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, def_value);
+ instance_uniforms.erase(p_value);
+ } else {
+ instance_uniforms[p_uniform] = p_value;
+ RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, p_value);
+ }
+}
+
+Variant GeometryInstance3D::get_shader_instance_uniform(const StringName &p_uniform) const {
+
+ return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_uniform);
+}
void GeometryInstance3D::set_custom_aabb(AABB aabb) {
RS::get_singleton()->instance_set_custom_aabb(get_instance(), aabb);
@@ -280,6 +352,9 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_lod_max_distance", "mode"), &GeometryInstance3D::set_lod_max_distance);
ClassDB::bind_method(D_METHOD("get_lod_max_distance"), &GeometryInstance3D::get_lod_max_distance);
+ ClassDB::bind_method(D_METHOD("set_shader_instance_uniform", "uniform", "value"), &GeometryInstance3D::set_shader_instance_uniform);
+ ClassDB::bind_method(D_METHOD("get_shader_instance_uniform", "uniform"), &GeometryInstance3D::get_shader_instance_uniform);
+
ClassDB::bind_method(D_METHOD("set_lod_min_hysteresis", "mode"), &GeometryInstance3D::set_lod_min_hysteresis);
ClassDB::bind_method(D_METHOD("get_lod_min_hysteresis"), &GeometryInstance3D::get_lod_min_hysteresis);
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index 9476c28848..cc5f92066f 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -108,9 +108,18 @@ private:
float lod_min_hysteresis;
float lod_max_hysteresis;
+ mutable HashMap<StringName, Variant> instance_uniforms;
+ mutable HashMap<StringName, StringName> instance_uniform_property_remap;
+
float extra_cull_margin;
+ const StringName *_instance_uniform_get_remap(const StringName p_name) const;
+
protected:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
void _notification(int p_what);
static void _bind_methods();
@@ -139,6 +148,9 @@ public:
void set_extra_cull_margin(float p_margin);
float get_extra_cull_margin() const;
+ void set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value);
+ Variant get_shader_instance_uniform(const StringName &p_uniform) const;
+
void set_custom_aabb(AABB aabb);
GeometryInstance3D();
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
index 203c3cd812..f30c58be55 100644
--- a/scene/3d/voxelizer.cpp
+++ b/scene/3d/voxelizer.cpp
@@ -592,22 +592,16 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
const Vector3 *vr = vertices.ptr();
Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV];
- const Vector2 *uvr;
+ const Vector2 *uvr = nullptr;
Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL];
- const Vector3 *nr;
+ const Vector3 *nr = nullptr;
Vector<int> index = a[Mesh::ARRAY_INDEX];
- bool read_uv = false;
- bool read_normals = false;
-
if (uv.size()) {
-
uvr = uv.ptr();
- read_uv = true;
}
if (normals.size()) {
- read_normals = true;
nr = normals.ptr();
}
@@ -626,13 +620,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]);
}
- if (read_uv) {
+ if (uvr) {
for (int k = 0; k < 3; k++) {
uvs[k] = uvr[ir[j * 3 + k]];
}
}
- if (read_normals) {
+ if (nr) {
for (int k = 0; k < 3; k++) {
normal[k] = nr[ir[j * 3 + k]];
}
@@ -659,13 +653,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
vtxs[k] = p_xform.xform(vr[j * 3 + k]);
}
- if (read_uv) {
+ if (uvr) {
for (int k = 0; k < 3; k++) {
uvs[k] = uvr[j * 3 + k];
}
}
- if (read_normals) {
+ if (nr) {
for (int k = 0; k < 3; k++) {
normal[k] = nr[j * 3 + k];
}
diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/xr_nodes.cpp
index 537c094ceb..0373114e7d 100644
--- a/scene/3d/arvr_nodes.cpp
+++ b/scene/3d/xr_nodes.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_nodes.cpp */
+/* xr_nodes.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,25 +28,25 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "arvr_nodes.h"
+#include "xr_nodes.h"
#include "core/input/input_filter.h"
-#include "servers/arvr/arvr_interface.h"
-#include "servers/arvr_server.h"
+#include "servers/xr/xr_interface.h"
+#include "servers/xr_server.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
-void ARVRCamera::_notification(int p_what) {
+void XRCamera3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- // need to find our ARVROrigin parent and let it know we're its camera!
- ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent());
+ // need to find our XROrigin3D parent and let it know we're its camera!
+ XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin != nullptr) {
origin->set_tracked_camera(this);
}
}; break;
case NOTIFICATION_EXIT_TREE: {
- // need to find our ARVROrigin parent and let it know we're no longer its camera!
- ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent());
+ // need to find our XROrigin3D parent and let it know we're no longer its camera!
+ XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin != nullptr) {
origin->clear_tracked_camera_if(this);
}
@@ -54,26 +54,26 @@ void ARVRCamera::_notification(int p_what) {
};
};
-String ARVRCamera::get_configuration_warning() const {
+String XRCamera3D::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree())
return String();
- // must be child node of ARVROrigin!
- ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent());
+ // must be child node of XROrigin3D!
+ XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- return TTR("ARVRCamera must have an ARVROrigin node as its parent.");
+ return TTR("XRCamera3D must have an XROrigin3D node as its parent.");
};
return String();
};
-Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, Vector3());
+Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, Vector3());
- Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface();
- if (arvr_interface.is_null()) {
+ Ref<XRInterface> xr_interface = xr_server->get_primary_interface();
+ if (xr_interface.is_null()) {
// we might be in the editor or have VR turned off, just call superclass
return Camera3D::project_local_ray_normal(p_pos);
}
@@ -84,20 +84,20 @@ Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const {
Vector2 cpos = get_viewport()->get_camera_coords(p_pos);
Vector3 ray;
- CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
Vector2 screen_he = cm.get_viewport_half_extents();
ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_znear()).normalized();
return ray;
};
-Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, Vector2());
+Point2 XRCamera3D::unproject_position(const Vector3 &p_pos) const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, Vector2());
- Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface();
- if (arvr_interface.is_null()) {
+ Ref<XRInterface> xr_interface = xr_server->get_primary_interface();
+ if (xr_interface.is_null()) {
// we might be in the editor or have VR turned off, just call superclass
return Camera3D::unproject_position(p_pos);
}
@@ -106,7 +106,7 @@ Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const {
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
Plane p(get_camera_transform().xform_inv(p_pos), 1.0);
@@ -120,13 +120,13 @@ Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const {
return res;
};
-Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, Vector3());
+Vector3 XRCamera3D::project_position(const Point2 &p_point, float p_z_depth) const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, Vector3());
- Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface();
- if (arvr_interface.is_null()) {
+ Ref<XRInterface> xr_interface = xr_server->get_primary_interface();
+ if (xr_interface.is_null()) {
// we might be in the editor or have VR turned off, just call superclass
return Camera3D::project_position(p_point, p_z_depth);
}
@@ -135,7 +135,7 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
Vector2 vp_he = cm.get_viewport_half_extents();
@@ -149,13 +149,13 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con
return get_camera_transform().xform(p);
};
-Vector<Plane> ARVRCamera::get_frustum() const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, Vector<Plane>());
+Vector<Plane> XRCamera3D::get_frustum() const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, Vector<Plane>());
- Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface();
- if (arvr_interface.is_null()) {
+ Ref<XRInterface> xr_interface = xr_server->get_primary_interface();
+ if (xr_interface.is_null()) {
// we might be in the editor or have VR turned off, just call superclass
return Camera3D::get_frustum();
}
@@ -163,21 +163,21 @@ Vector<Plane> ARVRCamera::get_frustum() const {
ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>());
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
return cm.get_projection_planes(get_camera_transform());
};
-ARVRCamera::ARVRCamera(){
+XRCamera3D::XRCamera3D(){
// nothing to do here yet for now..
};
-ARVRCamera::~ARVRCamera(){
+XRCamera3D::~XRCamera3D(){
// nothing to do here yet for now..
};
////////////////////////////////////////////////////////////////////////////////////////////////////
-void ARVRController::_notification(int p_what) {
+void XRController3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
set_process_internal(true);
@@ -186,12 +186,12 @@ void ARVRController::_notification(int p_what) {
set_process_internal(false);
}; break;
case NOTIFICATION_INTERNAL_PROCESS: {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
// find the tracker for our controller
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) {
// this controller is currently turned off
is_active = false;
@@ -236,49 +236,49 @@ void ARVRController::_notification(int p_what) {
};
};
-void ARVRController::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &ARVRController::set_controller_id);
- ClassDB::bind_method(D_METHOD("get_controller_id"), &ARVRController::get_controller_id);
+void XRController3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &XRController3D::set_controller_id);
+ ClassDB::bind_method(D_METHOD("get_controller_id"), &XRController3D::get_controller_id);
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_controller_id", "get_controller_id");
- ClassDB::bind_method(D_METHOD("get_controller_name"), &ARVRController::get_controller_name);
+ ClassDB::bind_method(D_METHOD("get_controller_name"), &XRController3D::get_controller_name);
// passthroughs to information about our related joystick
- ClassDB::bind_method(D_METHOD("get_joystick_id"), &ARVRController::get_joystick_id);
- ClassDB::bind_method(D_METHOD("is_button_pressed", "button"), &ARVRController::is_button_pressed);
- ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &ARVRController::get_joystick_axis);
+ ClassDB::bind_method(D_METHOD("get_joystick_id"), &XRController3D::get_joystick_id);
+ ClassDB::bind_method(D_METHOD("is_button_pressed", "button"), &XRController3D::is_button_pressed);
+ ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &XRController3D::get_joystick_axis);
- ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRController::get_is_active);
- ClassDB::bind_method(D_METHOD("get_hand"), &ARVRController::get_hand);
+ ClassDB::bind_method(D_METHOD("get_is_active"), &XRController3D::get_is_active);
+ ClassDB::bind_method(D_METHOD("get_hand"), &XRController3D::get_hand);
- ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRController::get_rumble);
- ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRController::set_rumble);
+ ClassDB::bind_method(D_METHOD("get_rumble"), &XRController3D::get_rumble);
+ ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRController3D::set_rumble);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble");
ADD_PROPERTY_DEFAULT("rumble", 0.0);
- ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRController::get_mesh);
+ ClassDB::bind_method(D_METHOD("get_mesh"), &XRController3D::get_mesh);
ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button")));
ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button")));
ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh")));
};
-void ARVRController::set_controller_id(int p_controller_id) {
+void XRController3D::set_controller_id(int p_controller_id) {
// We don't check any bounds here, this controller may not yet be active and just be a place holder until it is.
// Note that setting this to 0 means this node is not bound to a controller yet.
controller_id = p_controller_id;
update_configuration_warning();
};
-int ARVRController::get_controller_id(void) const {
+int XRController3D::get_controller_id(void) const {
return controller_id;
};
-String ARVRController::get_controller_name(void) const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, String());
+String XRController3D::get_controller_name(void) const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, String());
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) {
return String("Not connected");
};
@@ -286,12 +286,12 @@ String ARVRController::get_controller_name(void) const {
return tracker->get_name();
};
-int ARVRController::get_joystick_id() const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 0);
+int XRController3D::get_joystick_id() const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 0);
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) {
// No tracker? no joystick id... (0 is our first joystick)
return -1;
@@ -300,7 +300,7 @@ int ARVRController::get_joystick_id() const {
return tracker->get_joy_id();
};
-bool ARVRController::is_button_pressed(int p_button) const {
+bool XRController3D::is_button_pressed(int p_button) const {
int joy_id = get_joystick_id();
if (joy_id == -1) {
return false;
@@ -309,7 +309,7 @@ bool ARVRController::is_button_pressed(int p_button) const {
return InputFilter::get_singleton()->is_joy_button_pressed(joy_id, p_button);
};
-float ARVRController::get_joystick_axis(int p_axis) const {
+float XRController3D::get_joystick_axis(int p_axis) const {
int joy_id = get_joystick_id();
if (joy_id == -1) {
return 0.0;
@@ -318,12 +318,12 @@ float ARVRController::get_joystick_axis(int p_axis) const {
return InputFilter::get_singleton()->get_joy_axis(joy_id, p_axis);
};
-real_t ARVRController::get_rumble() const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 0.0);
+real_t XRController3D::get_rumble() const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 0.0);
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) {
return 0.0;
};
@@ -331,46 +331,46 @@ real_t ARVRController::get_rumble() const {
return tracker->get_rumble();
};
-void ARVRController::set_rumble(real_t p_rumble) {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void XRController3D::set_rumble(real_t p_rumble) {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker != nullptr) {
tracker->set_rumble(p_rumble);
};
};
-Ref<Mesh> ARVRController::get_mesh() const {
+Ref<Mesh> XRController3D::get_mesh() const {
return mesh;
}
-bool ARVRController::get_is_active() const {
+bool XRController3D::get_is_active() const {
return is_active;
};
-ARVRPositionalTracker::TrackerHand ARVRController::get_hand() const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, ARVRPositionalTracker::TRACKER_HAND_UNKNOWN);
+XRPositionalTracker::TrackerHand XRController3D::get_hand() const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN);
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) {
- return ARVRPositionalTracker::TRACKER_HAND_UNKNOWN;
+ return XRPositionalTracker::TRACKER_HAND_UNKNOWN;
};
return tracker->get_hand();
};
-String ARVRController::get_configuration_warning() const {
+String XRController3D::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree())
return String();
- // must be child node of ARVROrigin!
- ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent());
+ // must be child node of XROrigin!
+ XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- return TTR("ARVRController must have an ARVROrigin node as its parent.");
+ return TTR("XRController3D must have an XROrigin3D node as its parent.");
};
if (controller_id == 0) {
@@ -380,19 +380,19 @@ String ARVRController::get_configuration_warning() const {
return String();
};
-ARVRController::ARVRController() {
+XRController3D::XRController3D() {
controller_id = 1;
is_active = true;
button_states = 0;
};
-ARVRController::~ARVRController(){
+XRController3D::~XRController3D(){
// nothing to do here yet for now..
};
////////////////////////////////////////////////////////////////////////////////////////////////////
-void ARVRAnchor::_notification(int p_what) {
+void XRAnchor3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
set_process_internal(true);
@@ -401,12 +401,12 @@ void ARVRAnchor::_notification(int p_what) {
set_process_internal(false);
}; break;
case NOTIFICATION_INTERNAL_PROCESS: {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
// find the tracker for our anchor
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_ANCHOR, anchor_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id);
if (tracker == nullptr) {
// this anchor is currently not available
is_active = false;
@@ -415,7 +415,7 @@ void ARVRAnchor::_notification(int p_what) {
Transform transform;
// we'll need our world_scale
- real_t world_scale = arvr_server->get_world_scale();
+ real_t world_scale = xr_server->get_world_scale();
// get our info from our tracker
transform.basis = tracker->get_orientation();
@@ -427,7 +427,7 @@ void ARVRAnchor::_notification(int p_what) {
transform.basis.orthonormalize();
// apply our reference frame and set our transform
- set_transform(arvr_server->get_reference_frame() * transform);
+ set_transform(xr_server->get_reference_frame() * transform);
// check for an updated mesh
Ref<Mesh> trackerMesh = tracker->get_mesh();
@@ -442,43 +442,43 @@ void ARVRAnchor::_notification(int p_what) {
};
};
-void ARVRAnchor::_bind_methods() {
+void XRAnchor3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &ARVRAnchor::set_anchor_id);
- ClassDB::bind_method(D_METHOD("get_anchor_id"), &ARVRAnchor::get_anchor_id);
+ ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &XRAnchor3D::set_anchor_id);
+ ClassDB::bind_method(D_METHOD("get_anchor_id"), &XRAnchor3D::get_anchor_id);
ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_anchor_id", "get_anchor_id");
- ClassDB::bind_method(D_METHOD("get_anchor_name"), &ARVRAnchor::get_anchor_name);
+ ClassDB::bind_method(D_METHOD("get_anchor_name"), &XRAnchor3D::get_anchor_name);
- ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRAnchor::get_is_active);
- ClassDB::bind_method(D_METHOD("get_size"), &ARVRAnchor::get_size);
+ ClassDB::bind_method(D_METHOD("get_is_active"), &XRAnchor3D::get_is_active);
+ ClassDB::bind_method(D_METHOD("get_size"), &XRAnchor3D::get_size);
- ClassDB::bind_method(D_METHOD("get_plane"), &ARVRAnchor::get_plane);
+ ClassDB::bind_method(D_METHOD("get_plane"), &XRAnchor3D::get_plane);
- ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRAnchor::get_mesh);
+ ClassDB::bind_method(D_METHOD("get_mesh"), &XRAnchor3D::get_mesh);
ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh")));
};
-void ARVRAnchor::set_anchor_id(int p_anchor_id) {
+void XRAnchor3D::set_anchor_id(int p_anchor_id) {
// We don't check any bounds here, this anchor may not yet be active and just be a place holder until it is.
// Note that setting this to 0 means this node is not bound to an anchor yet.
anchor_id = p_anchor_id;
update_configuration_warning();
};
-int ARVRAnchor::get_anchor_id(void) const {
+int XRAnchor3D::get_anchor_id(void) const {
return anchor_id;
};
-Vector3 ARVRAnchor::get_size() const {
+Vector3 XRAnchor3D::get_size() const {
return size;
};
-String ARVRAnchor::get_anchor_name(void) const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, String());
+String XRAnchor3D::get_anchor_name(void) const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, String());
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_ANCHOR, anchor_id);
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id);
if (tracker == nullptr) {
return String("Not connected");
};
@@ -486,18 +486,18 @@ String ARVRAnchor::get_anchor_name(void) const {
return tracker->get_name();
};
-bool ARVRAnchor::get_is_active() const {
+bool XRAnchor3D::get_is_active() const {
return is_active;
};
-String ARVRAnchor::get_configuration_warning() const {
+String XRAnchor3D::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree())
return String();
- // must be child node of ARVROrigin!
- ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent());
+ // must be child node of XROrigin3D!
+ XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- return TTR("ARVRAnchor must have an ARVROrigin node as its parent.");
+ return TTR("XRAnchor3D must have an XROrigin3D node as its parent.");
};
if (anchor_id == 0) {
@@ -507,7 +507,7 @@ String ARVRAnchor::get_configuration_warning() const {
return String();
};
-Plane ARVRAnchor::get_plane() const {
+Plane XRAnchor3D::get_plane() const {
Vector3 location = get_translation();
Basis orientation = get_transform().basis;
@@ -516,67 +516,67 @@ Plane ARVRAnchor::get_plane() const {
return plane;
};
-Ref<Mesh> ARVRAnchor::get_mesh() const {
+Ref<Mesh> XRAnchor3D::get_mesh() const {
return mesh;
}
-ARVRAnchor::ARVRAnchor() {
+XRAnchor3D::XRAnchor3D() {
anchor_id = 1;
is_active = true;
};
-ARVRAnchor::~ARVRAnchor(){
+XRAnchor3D::~XRAnchor3D(){
// nothing to do here yet for now..
};
////////////////////////////////////////////////////////////////////////////////////////////////////
-String ARVROrigin::get_configuration_warning() const {
+String XROrigin3D::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree())
return String();
if (tracked_camera == nullptr)
- return TTR("ARVROrigin requires an ARVRCamera child node.");
+ return TTR("XROrigin3D requires an XRCamera3D child node.");
return String();
};
-void ARVROrigin::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &ARVROrigin::set_world_scale);
- ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVROrigin::get_world_scale);
+void XROrigin3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &XROrigin3D::set_world_scale);
+ ClassDB::bind_method(D_METHOD("get_world_scale"), &XROrigin3D::get_world_scale);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale");
};
-void ARVROrigin::set_tracked_camera(ARVRCamera *p_tracked_camera) {
+void XROrigin3D::set_tracked_camera(XRCamera3D *p_tracked_camera) {
tracked_camera = p_tracked_camera;
};
-void ARVROrigin::clear_tracked_camera_if(ARVRCamera *p_tracked_camera) {
+void XROrigin3D::clear_tracked_camera_if(XRCamera3D *p_tracked_camera) {
if (tracked_camera == p_tracked_camera) {
tracked_camera = nullptr;
};
};
-float ARVROrigin::get_world_scale() const {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 1.0);
+float XROrigin3D::get_world_scale() const {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 1.0);
- return arvr_server->get_world_scale();
+ return xr_server->get_world_scale();
};
-void ARVROrigin::set_world_scale(float p_world_scale) {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void XROrigin3D::set_world_scale(float p_world_scale) {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
- arvr_server->set_world_scale(p_world_scale);
+ xr_server->set_world_scale(p_world_scale);
};
-void ARVROrigin::_notification(int p_what) {
- // get our ARVRServer
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void XROrigin3D::_notification(int p_what) {
+ // get our XRServer
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
@@ -587,13 +587,13 @@ void ARVROrigin::_notification(int p_what) {
}; break;
case NOTIFICATION_INTERNAL_PROCESS: {
// set our world origin to our node transform
- arvr_server->set_world_origin(get_global_transform());
+ xr_server->set_world_origin(get_global_transform());
// check if we have a primary interface
- Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface();
- if (arvr_interface.is_valid() && tracked_camera != nullptr) {
+ Ref<XRInterface> xr_interface = xr_server->get_primary_interface();
+ if (xr_interface.is_valid() && tracked_camera != nullptr) {
// get our positioning transform for our headset
- Transform t = arvr_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform());
+ Transform t = xr_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform());
// now apply this to our camera
tracked_camera->set_transform(t);
@@ -603,19 +603,19 @@ void ARVROrigin::_notification(int p_what) {
break;
};
- // send our notification to all active ARVR interfaces, they may need to react to it also
- for (int i = 0; i < arvr_server->get_interface_count(); i++) {
- Ref<ARVRInterface> interface = arvr_server->get_interface(i);
+ // send our notification to all active XE interfaces, they may need to react to it also
+ for (int i = 0; i < xr_server->get_interface_count(); i++) {
+ Ref<XRInterface> interface = xr_server->get_interface(i);
if (interface.is_valid() && interface->is_initialized()) {
interface->notification(p_what);
}
}
};
-ARVROrigin::ARVROrigin() {
+XROrigin3D::XROrigin3D() {
tracked_camera = nullptr;
};
-ARVROrigin::~ARVROrigin(){
+XROrigin3D::~XROrigin3D(){
// nothing to do here yet for now..
};
diff --git a/scene/3d/arvr_nodes.h b/scene/3d/xr_nodes.h
index bc5df2e174..a2f16545d1 100644
--- a/scene/3d/arvr_nodes.h
+++ b/scene/3d/xr_nodes.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_nodes.h */
+/* xr_nodes.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,24 +28,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARVR_NODES_H
-#define ARVR_NODES_H
+#ifndef XR_NODES_H
+#define XR_NODES_H
#include "scene/3d/camera_3d.h"
#include "scene/3d/node_3d.h"
#include "scene/resources/mesh.h"
-#include "servers/arvr/arvr_positional_tracker.h"
+#include "servers/xr/xr_positional_tracker.h"
/**
@author Bastiaan Olij <mux213@gmail.com>
**/
/*
- ARVRCamera is a subclass of camera which will register itself with its parent ARVROrigin and as a result is automatically positioned
+ XRCamera is a subclass of camera which will register itself with its parent XROrigin and as a result is automatically positioned
*/
-class ARVRCamera : public Camera3D {
+class XRCamera3D : public Camera3D {
- GDCLASS(ARVRCamera, Camera3D);
+ GDCLASS(XRCamera3D, Camera3D);
protected:
void _notification(int p_what);
@@ -58,19 +58,19 @@ public:
virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const;
virtual Vector<Plane> get_frustum() const;
- ARVRCamera();
- ~ARVRCamera();
+ XRCamera3D();
+ ~XRCamera3D();
};
/*
- ARVRController is a helper node that automatically updates its position based on tracker data.
+ XRController3D is a helper node that automatically updates its position based on tracker data.
- It must be a child node of our ARVROrigin node
+ It must be a child node of our XROrigin node
*/
-class ARVRController : public Node3D {
+class XRController3D : public Node3D {
- GDCLASS(ARVRController, Node3D);
+ GDCLASS(XRController3D, Node3D);
private:
int controller_id;
@@ -95,23 +95,23 @@ public:
void set_rumble(real_t p_rumble);
bool get_is_active() const;
- ARVRPositionalTracker::TrackerHand get_hand() const;
+ XRPositionalTracker::TrackerHand get_hand() const;
Ref<Mesh> get_mesh(void) const;
String get_configuration_warning() const;
- ARVRController();
- ~ARVRController();
+ XRController3D();
+ ~XRController3D();
};
/*
- ARVRAnchor is a helper node that automatically updates its position based on anchor data, it represents a real world location.
- It must be a child node of our ARVROrigin node
+ XRAnchor3D is a helper node that automatically updates its position based on anchor data, it represents a real world location.
+ It must be a child node of our XROrigin3D node
*/
-class ARVRAnchor : public Node3D {
- GDCLASS(ARVRAnchor, Node3D);
+class XRAnchor3D : public Node3D {
+ GDCLASS(XRAnchor3D, Node3D);
private:
int anchor_id;
@@ -137,24 +137,24 @@ public:
String get_configuration_warning() const;
- ARVRAnchor();
- ~ARVRAnchor();
+ XRAnchor3D();
+ ~XRAnchor3D();
};
/*
- ARVROrigin is special spatial node that acts as our origin point mapping our real world center of our tracking volume into our virtual world.
+ XROrigin3D is special spatial node that acts as our origin point mapping our real world center of our tracking volume into our virtual world.
It is this point that you will move around the world as the player 'moves while standing still', i.e. the player moves through teleporting or controller inputs as opposed to physically moving.
Our camera and controllers will always be child nodes and thus place relative to this origin point.
- This node will automatically locate any camera child nodes and update its position while our ARVRController node will handle tracked controllers.
+ This node will automatically locate any camera child nodes and update its position while our XRController3D node will handle tracked controllers.
*/
-class ARVROrigin : public Node3D {
+class XROrigin3D : public Node3D {
- GDCLASS(ARVROrigin, Node3D);
+ GDCLASS(XROrigin3D, Node3D);
private:
- ARVRCamera *tracked_camera;
+ XRCamera3D *tracked_camera;
protected:
void _notification(int p_what);
@@ -163,14 +163,14 @@ protected:
public:
String get_configuration_warning() const;
- void set_tracked_camera(ARVRCamera *p_tracked_camera);
- void clear_tracked_camera_if(ARVRCamera *p_tracked_camera);
+ void set_tracked_camera(XRCamera3D *p_tracked_camera);
+ void clear_tracked_camera_if(XRCamera3D *p_tracked_camera);
float get_world_scale() const;
void set_world_scale(float p_world_scale);
- ARVROrigin();
- ~ARVROrigin();
+ XROrigin3D();
+ ~XROrigin3D();
};
-#endif /* ARVR_NODES_H */
+#endif /* XR_NODES_H */
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index b657833a3b..946f759610 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -950,13 +950,13 @@ void AnimationPlayer::_animation_process(float p_delta) {
play(queued.front()->get());
String new_name = playback.assigned;
queued.pop_front();
- if (end_notify)
+ if (end_notify || playback.seeked)
emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
} else {
//stop();
playing = false;
_set_process(false);
- if (end_notify)
+ if (end_notify || playback.seeked)
emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
}
end_reached = false;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index e37e93e2a9..0fe65462e4 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -852,7 +852,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
bool in_box = r.intersects(box_selecting_rect);
if (in_box)
- gn->set_selected(box_selection_mode_aditive);
+ gn->set_selected(box_selection_mode_additive);
else
gn->set_selected(previus_selected.find(gn) != nullptr);
}
@@ -951,8 +951,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
if (!gn->is_selected() && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
for (int i = 0; i < get_child_count(); i++) {
GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i));
- if (o_gn)
- o_gn->set_selected(o_gn == gn);
+ if (o_gn) {
+ if (o_gn == gn) {
+ o_gn->set_selected(true);
+ } else {
+ if (o_gn->is_selected()) {
+ emit_signal("node_unselected", o_gn);
+ }
+ o_gn->set_selected(false);
+ }
+ }
}
}
@@ -974,7 +982,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
box_selecting = true;
box_selecting_from = get_local_mouse_position();
if (b->get_control()) {
- box_selection_mode_aditive = true;
+ box_selection_mode_additive = true;
previus_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -985,7 +993,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
previus_selected.push_back(gn2);
}
} else if (b->get_shift()) {
- box_selection_mode_aditive = false;
+ box_selection_mode_additive = false;
previus_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -996,14 +1004,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
previus_selected.push_back(gn2);
}
} else {
- box_selection_mode_aditive = true;
+ box_selection_mode_additive = true;
previus_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
if (!gn2)
continue;
-
+ if (gn2->is_selected()) {
+ emit_signal("node_unselected", gn2);
+ }
gn2->set_selected(false);
}
}
@@ -1311,6 +1321,7 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("copy_nodes_request"));
ADD_SIGNAL(MethodInfo("paste_nodes_request"));
ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
+ ADD_SIGNAL(MethodInfo("node_unselected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
ADD_SIGNAL(MethodInfo("delete_nodes_request"));
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 7f1d2699ba..f675f8c7f3 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -104,7 +104,7 @@ private:
float zoom;
bool box_selecting;
- bool box_selection_mode_aditive;
+ bool box_selection_mode_additive;
Point2 box_selecting_from;
Point2 box_selecting_to;
Rect2 box_selecting_rect;
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 30ecd651b1..a03d6d0cdc 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -340,8 +340,8 @@ void OptionButton::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items");
// "selected" property must come after "items", otherwise GH-10213 occurs.
ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected");
- ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "id")));
- ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "id")));
+ ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "index")));
+ ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "index")));
}
OptionButton::OptionButton() {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 0b314d57c5..9fab9005f9 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -407,7 +407,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
cw = tab_size * font->get_char_size(' ').width;
}
- if (end > 0 && w + cw + begin > p_width) {
+ if (end > 0 && fw + cw + begin > p_width) {
break; //don't allow lines longer than assigned width
}
@@ -416,7 +416,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
end++;
}
CHECK_HEIGHT(fh);
- ENSURE_WIDTH(w);
+ ENSURE_WIDTH(fw);
line_ascent = MAX(line_ascent, ascent);
line_descent = MAX(line_descent, descent);
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index e47e2b869d..1f135163d4 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -166,8 +166,9 @@ void Slider::_notification(int p_what) {
RID ci = get_canvas_item();
Size2i size = get_size();
Ref<StyleBox> style = get_theme_stylebox("slider");
- Ref<StyleBox> grabber_area = get_theme_stylebox("grabber_area");
- Ref<Texture2D> grabber = get_theme_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled");
+ bool highlighted = mouse_inside || has_focus();
+ Ref<StyleBox> grabber_area = get_theme_stylebox(highlighted ? "grabber_area_highlight" : "grabber_area");
+ Ref<Texture2D> grabber = get_theme_icon(editable ? (highlighted ? "grabber_highlight" : "grabber") : "grabber_disabled");
Ref<Texture2D> tick = get_theme_icon("tick");
double ratio = Math::is_nan(get_as_ratio()) ? 0 : get_as_ratio();
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index de80049862..3a128cf8e6 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -990,7 +990,7 @@ void TabContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_current_tab"), &TabContainer::get_current_tab);
ClassDB::bind_method(D_METHOD("get_previous_tab"), &TabContainer::get_previous_tab);
ClassDB::bind_method(D_METHOD("get_current_tab_control"), &TabContainer::get_current_tab_control);
- ClassDB::bind_method(D_METHOD("get_tab_control", "idx"), &TabContainer::get_tab_control);
+ ClassDB::bind_method(D_METHOD("get_tab_control", "tab_idx"), &TabContainer::get_tab_control);
ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabContainer::set_tab_align);
ClassDB::bind_method(D_METHOD("get_tab_align"), &TabContainer::get_tab_align);
ClassDB::bind_method(D_METHOD("set_tabs_visible", "visible"), &TabContainer::set_tabs_visible);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index a7acaae8df..509a52d36a 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -3045,13 +3045,6 @@ void Tree::_notification(int p_what) {
draw_item(Point2(), draw_ofs, draw_size, root);
}
- int ofs = 0;
-
- for (int i = 0; i < (columns.size() - 1 - 1); i++) {
-
- ofs += get_column_width(i);
- }
-
if (show_column_titles) {
//title buttons
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 50f3bf834f..4c02a15531 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2693,9 +2693,9 @@ void Node::queue_delete() {
}
}
-Array Node::_get_children() const {
+TypedArray<Node> Node::_get_children() const {
- Array arr;
+ TypedArray<Node> arr;
int cc = get_child_count();
arr.resize(cc);
for (int i = 0; i < cc; i++)
diff --git a/scene/main/node.h b/scene/main/node.h
index 5de07d506e..1c1b7bbd7a 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -37,6 +37,7 @@
#include "core/object.h"
#include "core/project_settings.h"
#include "core/script_language.h"
+#include "core/typed_array.h"
#include "scene/main/scene_tree.h"
class Viewport;
@@ -182,7 +183,7 @@ private:
void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const;
Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = nullptr) const;
- Array _get_children() const;
+ TypedArray<Node> _get_children() const;
Array _get_groups() const;
Variant _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 41f31617d2..f30a899d69 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -1421,10 +1421,14 @@ SceneTree::SceneTree() {
root->set_as_audio_listener_2d(true);
current_scene = nullptr;
- int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"));
+ int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"));
root->set_msaa(Viewport::MSAA(msaa_mode));
+ int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"));
+ root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));
+
{ //load default fallback environment
//get possible extensions
List<String> exts;
diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp
new file mode 100644
index 0000000000..13582cf655
--- /dev/null
+++ b/scene/main/shader_globals_override.cpp
@@ -0,0 +1,257 @@
+#include "shader_globals_override.h"
+
+#include "core/core_string_names.h"
+#include "scene/main/window.h"
+#include "scene/scene_string_names.h"
+
+StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const {
+
+ StringName *r = param_remaps.getptr(p_name);
+ if (!r) {
+ //not cached, do caching
+ String p = p_name;
+ if (p.begins_with("params/")) {
+ String q = p.replace_first("params/", "");
+ param_remaps[p] = q;
+ r = param_remaps.getptr(q);
+ }
+ }
+
+ return r;
+}
+bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_value) {
+
+ StringName *r = _remap(p_name);
+
+ if (r) {
+ Override *o = overrides.getptr(*r);
+ if (!o) {
+ Override ov;
+ ov.in_use = false;
+ overrides[*r] = ov;
+ o = overrides.getptr(*r);
+ }
+ if (o) {
+ o->override = p_value;
+ if (active) {
+ RS::get_singleton()->global_variable_set_override(*r, p_value);
+ }
+ o->in_use = p_value.get_type() != Variant::NIL;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const {
+
+ StringName *r = _remap(p_name);
+
+ if (r) {
+ const Override *o = overrides.getptr(*r);
+ if (o) {
+ r_ret = o->override;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const {
+
+ Vector<StringName> variables;
+ variables = RS::get_singleton()->global_variable_get_list();
+ for (int i = 0; i < variables.size(); i++) {
+ PropertyInfo pinfo;
+ pinfo.name = "params/" + variables[i];
+ pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
+
+ switch (RS::get_singleton()->global_variable_get_type(variables[i])) {
+ case RS::GLOBAL_VAR_TYPE_BOOL: {
+ pinfo.type = Variant::BOOL;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC2: {
+ pinfo.type = Variant::INT;
+ pinfo.hint = PROPERTY_HINT_FLAGS;
+ pinfo.hint_string = "x,y";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC3: {
+ pinfo.type = Variant::INT;
+ pinfo.hint = PROPERTY_HINT_FLAGS;
+ pinfo.hint_string = "x,y,z";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC4: {
+ pinfo.type = Variant::INT;
+ pinfo.hint = PROPERTY_HINT_FLAGS;
+ pinfo.hint_string = "x,y,z,w";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_INT: {
+ pinfo.type = Variant::INT;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC2: {
+ pinfo.type = Variant::VECTOR2I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC3: {
+ pinfo.type = Variant::VECTOR3I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC4: {
+ pinfo.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_RECT2I: {
+ pinfo.type = Variant::RECT2I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UINT: {
+ pinfo.type = Variant::INT;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC2: {
+ pinfo.type = Variant::VECTOR2I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC3: {
+ pinfo.type = Variant::VECTOR3I;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC4: {
+ pinfo.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_FLOAT: {
+ pinfo.type = Variant::FLOAT;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC2: {
+ pinfo.type = Variant::VECTOR2;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC3: {
+ pinfo.type = Variant::VECTOR3;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC4: {
+ pinfo.type = Variant::PLANE;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_RECT2: {
+ pinfo.type = Variant::RECT2;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_COLOR: {
+ pinfo.type = Variant::COLOR;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT2: {
+ pinfo.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT3: {
+ pinfo.type = Variant::BASIS;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {
+ pinfo.type = Variant::TRANSFORM2D;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
+ pinfo.type = Variant::TRANSFORM;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT4: {
+ pinfo.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2D: {
+ pinfo.type = Variant::OBJECT;
+ pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pinfo.hint_string = "Texture2D";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: {
+ pinfo.type = Variant::OBJECT;
+ pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pinfo.hint_string = "Texture2DArray";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER3D: {
+ pinfo.type = Variant::OBJECT;
+ pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pinfo.hint_string = "Texture3D";
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: {
+ pinfo.type = Variant::OBJECT;
+ pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pinfo.hint_string = "Cubemap";
+ } break;
+ default: {
+
+ } break;
+ }
+
+ if (!overrides.has(variables[i])) {
+ Override o;
+ o.in_use = false;
+ Callable::CallError ce;
+ o.override = Variant::construct(pinfo.type, NULL, 0, ce);
+ overrides[variables[i]] = o;
+ }
+
+ Override *o = overrides.getptr(variables[i]);
+ if (o->in_use && o->override.get_type() != Variant::NIL) {
+ pinfo.usage |= PROPERTY_USAGE_CHECKED;
+ pinfo.usage |= PROPERTY_USAGE_STORAGE;
+ }
+
+ p_list->push_back(pinfo);
+ }
+}
+
+void ShaderGlobalsOverride::_activate() {
+
+ List<Node *> nodes;
+ get_tree()->get_nodes_in_group(SceneStringNames::get_singleton()->shader_overrides_group_active, &nodes);
+ if (nodes.size() == 0) {
+ //good we are the only override, enable all
+ active = true;
+ add_to_group(SceneStringNames::get_singleton()->shader_overrides_group_active);
+
+ const StringName *K = nullptr;
+ while ((K = overrides.next(K))) {
+ Override *o = overrides.getptr(*K);
+ if (o->in_use && o->override.get_type() != Variant::NIL) {
+ RS::get_singleton()->global_variable_set_override(*K, o->override);
+ }
+ }
+
+ update_configuration_warning(); //may have activated
+ }
+}
+
+void ShaderGlobalsOverride::_notification(int p_what) {
+
+ if (p_what == Node3D::NOTIFICATION_ENTER_TREE) {
+
+ add_to_group(SceneStringNames::get_singleton()->shader_overrides_group);
+ _activate();
+
+ } else if (p_what == Node3D::NOTIFICATION_EXIT_TREE) {
+
+ if (active) {
+ //remove overrides
+ const StringName *K = nullptr;
+ while ((K = overrides.next(K))) {
+ Override *o = overrides.getptr(*K);
+ if (o->in_use) {
+ RS::get_singleton()->global_variable_set_override(*K, Variant());
+ }
+ }
+ }
+
+ remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group_active);
+ remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group);
+ get_tree()->call_group(SceneStringNames::get_singleton()->shader_overrides_group, "_activate"); //another may want to activate when this is removed
+ active = false;
+ }
+}
+
+String ShaderGlobalsOverride::get_configuration_warning() const {
+
+ if (!active) {
+ return TTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene.");
+ }
+
+ return String();
+}
+
+void ShaderGlobalsOverride::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_activate"), &ShaderGlobalsOverride::_activate);
+}
+
+ShaderGlobalsOverride::ShaderGlobalsOverride() {
+ active = false;
+}
diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h
new file mode 100644
index 0000000000..33d0dc948f
--- /dev/null
+++ b/scene/main/shader_globals_override.h
@@ -0,0 +1,37 @@
+#ifndef SHADER_GLOBALS_OVERRIDE_H
+#define SHADER_GLOBALS_OVERRIDE_H
+
+#include "scene/3d/node_3d.h"
+
+class ShaderGlobalsOverride : public Node {
+
+ GDCLASS(ShaderGlobalsOverride, Node);
+
+ struct Override {
+ bool in_use = false;
+ Variant override;
+ };
+
+ StringName *_remap(const StringName &p_name) const;
+
+ bool active;
+ mutable HashMap<StringName, Override> overrides;
+ mutable HashMap<StringName, StringName> param_remaps;
+
+ void _activate();
+
+protected:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ String get_configuration_warning() const;
+
+ ShaderGlobalsOverride();
+};
+
+#endif // SHADER_GLOBALS_OVERRIDE_H
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 06d6e81786..51dd22db81 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -3173,7 +3173,7 @@ int Viewport::gui_get_canvas_sort_index() {
void Viewport::set_msaa(MSAA p_msaa) {
- ERR_FAIL_INDEX(p_msaa, 7);
+ ERR_FAIL_INDEX(p_msaa, MSAA_MAX);
if (msaa == p_msaa)
return;
msaa = p_msaa;
@@ -3185,6 +3185,19 @@ Viewport::MSAA Viewport::get_msaa() const {
return msaa;
}
+void Viewport::set_screen_space_aa(ScreenSpaceAA p_screen_space_aa) {
+
+ ERR_FAIL_INDEX(p_screen_space_aa, SCREEN_SPACE_AA_MAX);
+ if (screen_space_aa == p_screen_space_aa)
+ return;
+ screen_space_aa = p_screen_space_aa;
+ RS::get_singleton()->viewport_set_screen_space_aa(viewport, RS::ViewportScreenSpaceAA(p_screen_space_aa));
+}
+
+Viewport::ScreenSpaceAA Viewport::get_screen_space_aa() const {
+
+ return screen_space_aa;
+}
void Viewport::set_debug_draw(DebugDraw p_debug_draw) {
debug_draw = p_debug_draw;
@@ -3371,6 +3384,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa);
ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa);
+ ClassDB::bind_method(D_METHOD("set_screen_space_aa", "screen_space_aa"), &Viewport::set_screen_space_aa);
+ ClassDB::bind_method(D_METHOD("get_screen_space_aa"), &Viewport::get_screen_space_aa);
+
ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw);
ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw);
@@ -3444,6 +3460,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
ADD_GROUP("Rendering", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"), "set_screen_space_aa", "get_screen_space_aa");
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw");
ADD_GROUP("Canvas Items", "canvas_item_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter");
@@ -3478,6 +3495,17 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024);
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
+ BIND_ENUM_CONSTANT(MSAA_DISABLED);
+ BIND_ENUM_CONSTANT(MSAA_2X);
+ BIND_ENUM_CONSTANT(MSAA_4X);
+ BIND_ENUM_CONSTANT(MSAA_8X);
+ BIND_ENUM_CONSTANT(MSAA_16X);
+ BIND_ENUM_CONSTANT(MSAA_MAX);
+
+ BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_DISABLED);
+ BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_FXAA);
+ BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_MAX);
+
BIND_ENUM_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME);
BIND_ENUM_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME);
BIND_ENUM_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME);
@@ -3488,9 +3516,10 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED);
BIND_ENUM_CONSTANT(DEBUG_DRAW_UNSHADED);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_LIGHTING);
BIND_ENUM_CONSTANT(DEBUG_DRAW_OVERDRAW);
BIND_ENUM_CONSTANT(DEBUG_DRAW_WIREFRAME);
-
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_NORMAL_BUFFER);
BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_ALBEDO);
BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_LIGHTING);
BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_EMISSION);
@@ -3498,19 +3527,16 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS);
BIND_ENUM_CONSTANT(DEBUG_DRAW_SCENE_LUMINANCE);
BIND_ENUM_CONSTANT(DEBUG_DRAW_SSAO);
-
- BIND_ENUM_CONSTANT(MSAA_DISABLED);
- BIND_ENUM_CONSTANT(MSAA_2X);
- BIND_ENUM_CONSTANT(MSAA_4X);
- BIND_ENUM_CONSTANT(MSAA_8X);
- BIND_ENUM_CONSTANT(MSAA_16X);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_ROUGHNESS_LIMITER);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_PSSM_SPLITS);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_DECAL_ATLAS);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
-
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX);
+
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
@@ -3584,7 +3610,7 @@ Viewport::Viewport() {
gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
msaa = MSAA_DISABLED;
-
+ screen_space_aa = SCREEN_SPACE_AA_DISABLED;
debug_draw = DEBUG_DRAW_DISABLED;
snap_controls_to_pixels = true;
@@ -3613,13 +3639,14 @@ Viewport::~Viewport() {
/////////////////////////////////
-void SubViewport::set_use_arvr(bool p_use_arvr) {
- arvr = p_use_arvr;
+void SubViewport::set_use_xr(bool p_use_xr) {
+ xr = p_use_xr;
- RS::get_singleton()->viewport_set_use_arvr(get_viewport_rid(), arvr);
+ RS::get_singleton()->viewport_set_use_xr(get_viewport_rid(), xr);
}
-bool SubViewport::is_using_arvr() {
- return arvr;
+
+bool SubViewport::is_using_xr() {
+ return xr;
}
void SubViewport::set_size(const Size2i &p_size) {
@@ -3699,8 +3726,8 @@ void SubViewport::_notification(int p_what) {
}
void SubViewport::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &SubViewport::set_use_arvr);
- ClassDB::bind_method(D_METHOD("is_using_arvr"), &SubViewport::is_using_arvr);
+ ClassDB::bind_method(D_METHOD("set_use_xr", "use"), &SubViewport::set_use_xr);
+ ClassDB::bind_method(D_METHOD("is_using_xr"), &SubViewport::is_using_xr);
ClassDB::bind_method(D_METHOD("set_size", "size"), &SubViewport::set_size);
ClassDB::bind_method(D_METHOD("get_size"), &SubViewport::get_size);
@@ -3717,7 +3744,7 @@ void SubViewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &SubViewport::set_clear_mode);
ClassDB::bind_method(D_METHOD("get_clear_mode"), &SubViewport::get_clear_mode);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "is_using_arvr");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "xr"), "set_use_xr", "is_using_xr");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size_2d_override"), "set_size_2d_override", "get_size_2d_override");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_2d_override_stretch"), "set_size_2d_override_stretch", "is_size_2d_override_stretch_enabled");
@@ -3725,19 +3752,19 @@ void SubViewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode");
+ BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS);
+ BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER);
+ BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME);
+
BIND_ENUM_CONSTANT(UPDATE_DISABLED);
BIND_ENUM_CONSTANT(UPDATE_ONCE);
BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE);
BIND_ENUM_CONSTANT(UPDATE_WHEN_PARENT_VISIBLE);
BIND_ENUM_CONSTANT(UPDATE_ALWAYS);
-
- BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS);
- BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER);
- BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME);
}
SubViewport::SubViewport() {
- arvr = false;
+ xr = false;
size_2d_override_stretch = false;
update_mode = UPDATE_WHEN_VISIBLE;
clear_mode = CLEAR_MODE_ALWAYS;
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index d603294ed5..7e2df9fe42 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -106,10 +106,16 @@ public:
MSAA_4X,
MSAA_8X,
MSAA_16X,
+ MSAA_MAX
};
- enum RenderInfo {
+ enum ScreenSpaceAA {
+ SCREEN_SPACE_AA_DISABLED,
+ SCREEN_SPACE_AA_FXAA,
+ SCREEN_SPACE_AA_MAX
+ };
+ enum RenderInfo {
RENDER_INFO_OBJECTS_IN_FRAME,
RENDER_INFO_VERTICES_IN_FRAME,
RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
@@ -133,7 +139,9 @@ public:
DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS,
DEBUG_DRAW_SCENE_LUMINANCE,
DEBUG_DRAW_SSAO,
- DEBUG_DRAW_ROUGHNESS_LIMITER
+ DEBUG_DRAW_ROUGHNESS_LIMITER,
+ DEBUG_DRAW_PSSM_SPLITS,
+ DEBUG_DRAW_DECAL_ATLAS
};
enum DefaultCanvasItemTextureFilter {
@@ -271,6 +279,7 @@ private:
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
MSAA msaa;
+ ScreenSpaceAA screen_space_aa;
Ref<ViewportTexture> default_texture;
Set<ViewportTexture *> viewport_textures;
@@ -504,6 +513,9 @@ public:
void set_msaa(MSAA p_msaa);
MSAA get_msaa() const;
+ void set_screen_space_aa(ScreenSpaceAA p_screen_space_aa);
+ ScreenSpaceAA get_screen_space_aa() const;
+
Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const;
Vector2 get_camera_rect_size() const;
@@ -589,7 +601,7 @@ public:
private:
UpdateMode update_mode;
ClearMode clear_mode;
- bool arvr;
+ bool xr;
bool size_2d_override_stretch;
protected:
@@ -605,8 +617,8 @@ public:
void set_size_2d_override(const Size2i &p_size);
Size2i get_size_2d_override() const;
- void set_use_arvr(bool p_use_arvr);
- bool is_using_arvr();
+ void set_use_xr(bool p_use_xr);
+ bool is_using_xr();
void set_size_2d_override_stretch(bool p_enable);
bool is_size_2d_override_stretch_enabled() const;
@@ -623,6 +635,7 @@ public:
VARIANT_ENUM_CAST(SubViewport::UpdateMode);
VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
VARIANT_ENUM_CAST(Viewport::MSAA);
+VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA);
VARIANT_ENUM_CAST(Viewport::DebugDraw);
VARIANT_ENUM_CAST(SubViewport::ClearMode);
VARIANT_ENUM_CAST(Viewport::RenderInfo);
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 94162cbe4e..dc3ef5b508 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -177,9 +177,10 @@
#include "scene/3d/node_3d.h"
#include "scene/3d/skeleton_3d.h"
+#include "scene/main/shader_globals_override.h"
+
#ifndef _3D_DISABLED
#include "scene/3d/area_3d.h"
-#include "scene/3d/arvr_nodes.h"
#include "scene/3d/audio_stream_player_3d.h"
#include "scene/3d/baked_lightmap.h"
#include "scene/3d/bone_attachment_3d.h"
@@ -187,6 +188,7 @@
#include "scene/3d/collision_polygon_3d.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/3d/cpu_particles_3d.h"
+#include "scene/3d/decal.h"
#include "scene/3d/gi_probe.h"
#include "scene/3d/gpu_particles_3d.h"
#include "scene/3d/immediate_geometry_3d.h"
@@ -213,6 +215,7 @@
#include "scene/3d/vehicle_body_3d.h"
#include "scene/3d/visibility_notifier_3d.h"
#include "scene/3d/world_environment.h"
+#include "scene/3d/xr_nodes.h"
#include "scene/resources/environment.h"
#include "scene/resources/mesh_library.h"
#endif
@@ -402,6 +405,8 @@ void register_scene_types() {
ClassDB::register_class<AnimationNodeTimeSeek>();
ClassDB::register_class<AnimationNodeTransition>();
+ ClassDB::register_class<ShaderGlobalsOverride>(); //can be used in any shader
+
OS::get_singleton()->yield(); //may take time to init
#ifndef _3D_DISABLED
@@ -410,10 +415,10 @@ void register_scene_types() {
ClassDB::register_class<Camera3D>();
ClassDB::register_class<ClippedCamera3D>();
ClassDB::register_class<Listener3D>();
- ClassDB::register_class<ARVRCamera>();
- ClassDB::register_class<ARVRController>();
- ClassDB::register_class<ARVRAnchor>();
- ClassDB::register_class<ARVROrigin>();
+ ClassDB::register_class<XRCamera3D>();
+ ClassDB::register_class<XRController3D>();
+ ClassDB::register_class<XRAnchor3D>();
+ ClassDB::register_class<XROrigin3D>();
ClassDB::register_class<MeshInstance3D>();
ClassDB::register_class<ImmediateGeometry3D>();
ClassDB::register_virtual_class<SpriteBase3D>();
@@ -424,6 +429,7 @@ void register_scene_types() {
ClassDB::register_class<OmniLight3D>();
ClassDB::register_class<SpotLight3D>();
ClassDB::register_class<ReflectionProbe>();
+ ClassDB::register_class<Decal>();
ClassDB::register_class<GIProbe>();
ClassDB::register_class<GIProbeData>();
//ClassDB::register_class<BakedLightmap>();
@@ -751,8 +757,16 @@ void register_scene_types() {
ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree");
// Renamed in 4.0.
+ // Keep alphabetical ordering to easily locate classes and avoid duplicates.
ClassDB::add_compatibility_class("AnimatedSprite", "AnimatedSprite2D");
ClassDB::add_compatibility_class("Area", "Area3D");
+ ClassDB::add_compatibility_class("ARVRCamera", "XRCamera3D");
+ ClassDB::add_compatibility_class("ARVRController", "XRController3D");
+ ClassDB::add_compatibility_class("ARVRAnchor", "XRAnchor3D");
+ ClassDB::add_compatibility_class("ARVRInterface", "XRInterface");
+ ClassDB::add_compatibility_class("ARVROrigin", "XROrigin3D");
+ ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker");
+ ClassDB::add_compatibility_class("ARVRServer", "XRServer");
ClassDB::add_compatibility_class("BoneAttachment", "BoneAttachment3D");
ClassDB::add_compatibility_class("BoxShape", "BoxShape3D");
ClassDB::add_compatibility_class("BulletPhysicsDirectBodyState", "BulletPhysicsDirectBodyState3D");
@@ -800,6 +814,7 @@ void register_scene_types() {
ClassDB::add_compatibility_class("Navigation2DServer", "NavigationServer2D");
ClassDB::add_compatibility_class("NavigationServer", "NavigationServer3D");
ClassDB::add_compatibility_class("OmniLight", "OmniLight3D");
+ ClassDB::add_compatibility_class("PanoramaSky", "Sky");
ClassDB::add_compatibility_class("Particles", "GPUParticles3D");
ClassDB::add_compatibility_class("Particles2D", "GPUParticles2D");
ClassDB::add_compatibility_class("Path", "Path3D");
@@ -821,6 +836,7 @@ void register_scene_types() {
ClassDB::add_compatibility_class("PhysicsShapeQueryResult", "PhysicsShapeQueryResult3D");
ClassDB::add_compatibility_class("PinJoint", "PinJoint3D");
ClassDB::add_compatibility_class("PlaneShape", "WorldMarginShape3D");
+ ClassDB::add_compatibility_class("ProceduralSky", "Sky");
ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D");
ClassDB::add_compatibility_class("RayCast", "RayCast3D");
ClassDB::add_compatibility_class("RayShape", "RayShape3D");
@@ -851,8 +867,6 @@ void register_scene_types() {
ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp");
ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform");
ClassDB::add_compatibility_class("World", "World3D");
- ClassDB::add_compatibility_class("ProceduralSky", "Sky");
- ClassDB::add_compatibility_class("PanoramaSky", "Sky");
#endif
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index e6f09eb034..a1e8bf51bd 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -497,6 +497,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("slider", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
theme->set_stylebox("grabber_area", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
+ theme->set_stylebox("grabber_area_highlight", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
theme->set_icon("grabber", "HSlider", make_icon(hslider_grabber_png));
theme->set_icon("grabber_highlight", "HSlider", make_icon(hslider_grabber_hl_png));
@@ -507,6 +508,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
theme->set_stylebox("grabber_area", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
+ theme->set_stylebox("grabber_area_highlight", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
theme->set_icon("grabber", "VSlider", make_icon(vslider_grabber_png));
theme->set_icon("grabber_highlight", "VSlider", make_icon(vslider_grabber_hl_png));
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index a613b01376..eea4d12d0e 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -1064,7 +1064,7 @@ void DynamicFont::update_oversampling() {
/////////////////////////
-RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h
index 9e628fc35a..ef4b9dd9d0 100644
--- a/scene/resources/dynamic_font.h
+++ b/scene/resources/dynamic_font.h
@@ -302,7 +302,7 @@ VARIANT_ENUM_CAST(DynamicFont::SpacingType);
class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 192eefbf6a..267816f267 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -646,7 +646,7 @@ BitmapFont::~BitmapFont() {
////////////
-RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
diff --git a/scene/resources/font.h b/scene/resources/font.h
index ce75f27e2a..c233344529 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -200,7 +200,7 @@ public:
class ResourceFormatLoaderBMFont : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 85adc8c5f1..fd8cff7cd0 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -314,7 +314,7 @@ void BaseMaterial3D::init_shaders() {
shader_names->anisotropy = "anisotropy_ratio";
shader_names->heightmap_scale = "heightmap_scale";
shader_names->subsurface_scattering_strength = "subsurface_scattering_strength";
- shader_names->transmission = "transmission";
+ shader_names->backlight = "backlight";
shader_names->refraction = "refraction";
shader_names->point_size = "point_size";
shader_names->uv1_scale = "uv1_scale";
@@ -347,6 +347,11 @@ void BaseMaterial3D::init_shaders() {
shader_names->refraction_texture_channel = "refraction_texture_channel";
shader_names->alpha_scissor_threshold = "alpha_scissor_threshold";
+ shader_names->transmittance_color = "transmittance_color";
+ shader_names->transmittance_curve = "transmittance_curve";
+ shader_names->transmittance_depth = "transmittance_depth";
+ shader_names->transmittance_boost = "transmittance_boost";
+
shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo";
shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic";
shader_names->texture_names[TEXTURE_ROUGHNESS] = "texture_roughness";
@@ -358,7 +363,8 @@ void BaseMaterial3D::init_shaders() {
shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion";
shader_names->texture_names[TEXTURE_HEIGHTMAP] = "texture_heightmap";
shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering";
- shader_names->texture_names[TEXTURE_TRANSMISSION] = "texture_transmission";
+ shader_names->texture_names[TEXTURE_SUBSURFACE_TRANSMITTANCE] = "texture_subsurface_transmittance";
+ shader_names->texture_names[TEXTURE_BACKLIGHT] = "texture_backlight";
shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction";
shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask";
shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo";
@@ -385,7 +391,7 @@ void BaseMaterial3D::_update_shader() {
dirty_materials->remove(&element);
MaterialKey mk = _compute_key();
- if (mk.key == current_key.key)
+ if (mk == current_key)
return; //no update required in the end
if (shader_map.has(current_key)) {
@@ -444,9 +450,6 @@ void BaseMaterial3D::_update_shader() {
case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break;
}
- if (features[FEATURE_SUBSURACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) {
- code += ",sss_mode_skin";
- }
if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) {
code += ",depth_prepass_alpha";
}
@@ -470,6 +473,9 @@ void BaseMaterial3D::_update_shader() {
case SPECULAR_TOON: code += ",specular_toon"; break;
case SPECULAR_DISABLED: code += ",specular_disabled"; break;
}
+ if (features[FEATURE_SUBSURFACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) {
+ code += ",sss_mode_skin";
+ }
if (shading_mode == SHADING_MODE_UNSHADED) {
code += ",unshaded";
@@ -589,16 +595,25 @@ void BaseMaterial3D::_update_shader() {
code += "uniform sampler2D texture_detail_mask : hint_white," + texfilter_str + ";\n";
}
- if (features[FEATURE_SUBSURACE_SCATTERING]) {
+ if (features[FEATURE_SUBSURFACE_SCATTERING]) {
code += "uniform float subsurface_scattering_strength : hint_range(0,1);\n";
code += "uniform sampler2D texture_subsurface_scattering : hint_white," + texfilter_str + ";\n";
}
- if (features[FEATURE_TRANSMISSION]) {
+ if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
- code += "uniform vec4 transmission : hint_color;\n";
- code += "uniform sampler2D texture_transmission : hint_black," + texfilter_str + ";\n";
+ code += "uniform vec4 transmittance_color : hint_color;\n";
+ code += "uniform float transmittance_depth;\n";
+ code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n";
+ code += "uniform float transmittance_curve;\n";
+ code += "uniform float transmittance_boost;\n";
+ }
+
+ if (features[FEATURE_BACKLIGHT]) {
+
+ code += "uniform vec4 backlight : hint_color;\n";
+ code += "uniform sampler2D texture_backlight : hint_black," + texfilter_str + ";\n";
}
if (features[FEATURE_HEIGHT_MAPPING]) {
@@ -1051,7 +1066,7 @@ void BaseMaterial3D::_update_shader() {
code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n";
}
- if (features[FEATURE_SUBSURACE_SCATTERING]) {
+ if (features[FEATURE_SUBSURFACE_SCATTERING]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n";
@@ -1061,13 +1076,27 @@ void BaseMaterial3D::_update_shader() {
code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
}
- if (features[FEATURE_TRANSMISSION]) {
+ if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
+
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec4 trans_color_tex = triplanar_texture(texture_subsurface_transmittance,uv1_power_normal,uv1_triplanar_pos);\n";
+ } else {
+ code += "\tvec4 trans_color_tex = texture(texture_subsurface_transmittance,base_uv);\n";
+ }
+ code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n";
+
+ code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n";
+ code += "\tSSS_TRANSMITTANCE_CURVE=transmittance_curve;\n";
+ code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n";
+ }
+
+ if (features[FEATURE_BACKLIGHT]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec3 transmission_tex = triplanar_texture(texture_transmission,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
+ code += "\tvec3 backlight_tex = triplanar_texture(texture_backlight,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
} else {
- code += "\tvec3 transmission_tex = texture(texture_transmission,base_uv).rgb;\n";
+ code += "\tvec3 backlight_tex = texture(texture_backlight,base_uv).rgb;\n";
}
- code += "\tTRANSMISSION = (transmission.rgb+transmission_tex);\n";
+ code += "\tBACKLIGHT = (backlight.rgb+backlight_tex);\n";
}
if (features[FEATURE_DETAIL]) {
@@ -1309,15 +1338,48 @@ float BaseMaterial3D::get_subsurface_scattering_strength() const {
return subsurface_scattering_strength;
}
-void BaseMaterial3D::set_transmission(const Color &p_transmission) {
+void BaseMaterial3D::set_transmittance_color(const Color &p_color) {
+ transmittance_color = p_color;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_color, p_color);
+}
- transmission = p_transmission;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->transmission, transmission);
+Color BaseMaterial3D::get_transmittance_color() const {
+ return transmittance_color;
}
-Color BaseMaterial3D::get_transmission() const {
+void BaseMaterial3D::set_transmittance_depth(float p_depth) {
+ transmittance_depth = p_depth;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_depth, p_depth);
+}
+float BaseMaterial3D::get_transmittance_depth() const {
+ return transmittance_depth;
+}
- return transmission;
+void BaseMaterial3D::set_transmittance_curve(float p_curve) {
+ transmittance_curve = p_curve;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_curve, p_curve);
+}
+float BaseMaterial3D::get_transmittance_curve() const {
+ return transmittance_curve;
+}
+
+void BaseMaterial3D::set_transmittance_boost(float p_boost) {
+ transmittance_boost = p_boost;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost);
+}
+float BaseMaterial3D::get_transmittance_boost() const {
+ return transmittance_boost;
+}
+
+void BaseMaterial3D::set_backlight(const Color &p_backlight) {
+
+ backlight = p_backlight;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->backlight, backlight);
+}
+
+Color BaseMaterial3D::get_backlight() const {
+
+ return backlight;
}
void BaseMaterial3D::set_refraction(float p_refraction) {
@@ -1457,7 +1519,7 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
return;
flags[p_flag] = p_enabled;
- if ((p_flag == FLAG_USE_SHADOW_TO_OPACITY) || (p_flag == FLAG_USE_TEXTURE_REPEAT)) {
+ if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN) {
_change_notify();
}
_queue_shader_change();
@@ -1540,8 +1602,8 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
_validate_feature("anisotropy", FEATURE_ANISOTROPY, property);
_validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property);
_validate_feature("heightmap", FEATURE_HEIGHT_MAPPING, property);
- _validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property);
- _validate_feature("transmission", FEATURE_TRANSMISSION, property);
+ _validate_feature("subsurf_scatter", FEATURE_SUBSURFACE_SCATTERING, property);
+ _validate_feature("backlight", FEATURE_BACKLIGHT, property);
_validate_feature("refraction", FEATURE_REFRACTION, property);
_validate_feature("detail", FEATURE_DETAIL, property);
@@ -1575,6 +1637,10 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
+ if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture" || property.name == "subsurf_scatter_transmittance_curve")) {
+ property.usage = 0;
+ }
+
if (orm) {
if (property.name == "shading_mode") {
@@ -1631,7 +1697,11 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- if (property.name.begins_with("transmission")) {
+ if (property.name.begins_with("backlight")) {
+ property.usage = 0;
+ }
+
+ if (property.name.begins_with("transmittance")) {
property.usage = 0;
}
}
@@ -2070,8 +2140,20 @@ void BaseMaterial3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &BaseMaterial3D::set_subsurface_scattering_strength);
ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &BaseMaterial3D::get_subsurface_scattering_strength);
- ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &BaseMaterial3D::set_transmission);
- ClassDB::bind_method(D_METHOD("get_transmission"), &BaseMaterial3D::get_transmission);
+ ClassDB::bind_method(D_METHOD("set_transmittance_color", "color"), &BaseMaterial3D::set_transmittance_color);
+ ClassDB::bind_method(D_METHOD("get_transmittance_color"), &BaseMaterial3D::get_transmittance_color);
+
+ ClassDB::bind_method(D_METHOD("set_transmittance_depth", "depth"), &BaseMaterial3D::set_transmittance_depth);
+ ClassDB::bind_method(D_METHOD("get_transmittance_depth"), &BaseMaterial3D::get_transmittance_depth);
+
+ ClassDB::bind_method(D_METHOD("set_transmittance_curve", "curve"), &BaseMaterial3D::set_transmittance_curve);
+ ClassDB::bind_method(D_METHOD("get_transmittance_curve"), &BaseMaterial3D::get_transmittance_curve);
+
+ ClassDB::bind_method(D_METHOD("set_transmittance_boost", "boost"), &BaseMaterial3D::set_transmittance_boost);
+ ClassDB::bind_method(D_METHOD("get_transmittance_boost"), &BaseMaterial3D::get_transmittance_boost);
+
+ ClassDB::bind_method(D_METHOD("set_backlight", "backlight"), &BaseMaterial3D::set_backlight);
+ ClassDB::bind_method(D_METHOD("get_backlight"), &BaseMaterial3D::get_backlight);
ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &BaseMaterial3D::set_refraction);
ClassDB::bind_method(D_METHOD("get_refraction"), &BaseMaterial3D::get_refraction);
@@ -2285,15 +2367,23 @@ void BaseMaterial3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_flip_texture"), "set_flag", "get_flag", FLAG_INVERT_HEIGHTMAP);
ADD_GROUP("Subsurf Scatter", "subsurf_scatter_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURACE_SCATTERING);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURFACE_SCATTERING);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_skin_mode"), "set_flag", "get_flag", FLAG_SUBSURFACE_MODE_SKIN);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING);
- ADD_GROUP("Transmission", "transmission_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transmission_enabled"), "set_feature", "get_feature", FEATURE_TRANSMISSION);
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "transmission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_transmission", "get_transmission");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_TRANSMISSION);
+ ADD_SUBGROUP("Transmittance", "subsurf_scatter_transmittance_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_transmittance_enabled"), "set_feature", "get_feature", FEATURE_SUBSURFACE_TRANSMITTANCE);
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color"), "set_transmittance_color", "get_transmittance_color");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_TRANSMITTANCE);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth", PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater"), "set_transmittance_depth", "get_transmittance_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_curve", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_transmittance_curve", "get_transmittance_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_transmittance_boost", "get_transmittance_boost");
+
+ ADD_GROUP("Back Lighting", "backlight_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "backlight_enabled"), "set_feature", "get_feature", FEATURE_BACKLIGHT);
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "backlight", PROPERTY_HINT_COLOR_NO_ALPHA), "set_backlight", "get_backlight");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "backlight_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_BACKLIGHT);
ADD_GROUP("Refraction", "refraction_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION);
@@ -2366,7 +2456,8 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(TEXTURE_AMBIENT_OCCLUSION);
BIND_ENUM_CONSTANT(TEXTURE_HEIGHTMAP);
BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING);
- BIND_ENUM_CONSTANT(TEXTURE_TRANSMISSION);
+ BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_TRANSMITTANCE);
+ BIND_ENUM_CONSTANT(TEXTURE_BACKLIGHT);
BIND_ENUM_CONSTANT(TEXTURE_REFRACTION);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_MASK);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_ALBEDO);
@@ -2403,8 +2494,9 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(FEATURE_ANISOTROPY);
BIND_ENUM_CONSTANT(FEATURE_AMBIENT_OCCLUSION);
BIND_ENUM_CONSTANT(FEATURE_HEIGHT_MAPPING);
- BIND_ENUM_CONSTANT(FEATURE_SUBSURACE_SCATTERING);
- BIND_ENUM_CONSTANT(FEATURE_TRANSMISSION);
+ BIND_ENUM_CONSTANT(FEATURE_SUBSURFACE_SCATTERING);
+ BIND_ENUM_CONSTANT(FEATURE_SUBSURFACE_TRANSMITTANCE);
+ BIND_ENUM_CONSTANT(FEATURE_BACKLIGHT);
BIND_ENUM_CONSTANT(FEATURE_REFRACTION);
BIND_ENUM_CONSTANT(FEATURE_DETAIL);
BIND_ENUM_CONSTANT(FEATURE_MAX);
@@ -2496,7 +2588,11 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
set_anisotropy(0);
set_heightmap_scale(0.05);
set_subsurface_scattering_strength(0);
- set_transmission(Color(0, 0, 0));
+ set_backlight(Color(0, 0, 0));
+ set_transmittance_color(Color(1, 1, 1, 1));
+ set_transmittance_depth(0.1);
+ set_transmittance_curve(1.0);
+ set_transmittance_boost(0.0);
set_refraction(0.05);
set_point_size(1);
set_uv1_offset(Vector3(0, 0, 0));
@@ -2552,7 +2648,8 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
features[i] = false;
}
- current_key.key = 0;
+ current_key.key0 = 0;
+ current_key.key1 = 0;
current_key.invalid_key = 1;
texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
_queue_shader_change();
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 57f9038bf5..241357ba9b 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -125,7 +125,8 @@ public:
TEXTURE_AMBIENT_OCCLUSION,
TEXTURE_HEIGHTMAP,
TEXTURE_SUBSURFACE_SCATTERING,
- TEXTURE_TRANSMISSION,
+ TEXTURE_SUBSURFACE_TRANSMITTANCE,
+ TEXTURE_BACKLIGHT,
TEXTURE_REFRACTION,
TEXTURE_DETAIL_MASK,
TEXTURE_DETAIL_ALBEDO,
@@ -173,8 +174,9 @@ public:
FEATURE_ANISOTROPY,
FEATURE_AMBIENT_OCCLUSION,
FEATURE_HEIGHT_MAPPING,
- FEATURE_SUBSURACE_SCATTERING,
- FEATURE_TRANSMISSION,
+ FEATURE_SUBSURFACE_SCATTERING,
+ FEATURE_SUBSURFACE_TRANSMITTANCE,
+ FEATURE_BACKLIGHT,
FEATURE_REFRACTION,
FEATURE_DETAIL,
FEATURE_MAX
@@ -291,10 +293,16 @@ private:
uint64_t roughness_channel : 3;
};
- uint64_t key;
+ struct {
+ uint64_t key0;
+ uint64_t key1;
+ };
+ bool operator==(const MaterialKey &p_key) const {
+ return (key0 == p_key.key0) && (key1 == p_key.key1);
+ }
bool operator<(const MaterialKey &p_key) const {
- return key < p_key.key;
+ return (key0 == p_key.key0) ? (key1 < p_key.key1) : (key0 < p_key.key0);
}
};
@@ -310,7 +318,8 @@ private:
_FORCE_INLINE_ MaterialKey _compute_key() const {
MaterialKey mk;
- mk.key = 0;
+ mk.key0 = 0;
+ mk.key1 = 0;
for (int i = 0; i < FEATURE_MAX; i++) {
if (features[i]) {
mk.feature_mask |= ((uint64_t)1 << i);
@@ -357,7 +366,11 @@ private:
StringName anisotropy;
StringName heightmap_scale;
StringName subsurface_scattering_strength;
- StringName transmission;
+ StringName transmittance_color;
+ StringName transmittance_curve;
+ StringName transmittance_depth;
+ StringName transmittance_boost;
+ StringName backlight;
StringName refraction;
StringName point_size;
StringName uv1_scale;
@@ -415,7 +428,13 @@ private:
float anisotropy;
float heightmap_scale;
float subsurface_scattering_strength;
- Color transmission;
+ float transmittance_amount;
+ Color transmittance_color;
+ float transmittance_depth;
+ float transmittance_curve;
+ float transmittance_boost;
+
+ Color backlight;
float refraction;
float point_size;
float alpha_scissor_threshold;
@@ -546,8 +565,20 @@ public:
void set_subsurface_scattering_strength(float p_subsurface_scattering_strength);
float get_subsurface_scattering_strength() const;
- void set_transmission(const Color &p_transmission);
- Color get_transmission() const;
+ void set_transmittance_color(const Color &p_color);
+ Color get_transmittance_color() const;
+
+ void set_transmittance_depth(float p_depth);
+ float get_transmittance_depth() const;
+
+ void set_transmittance_curve(float p_curve);
+ float get_transmittance_curve() const;
+
+ void set_transmittance_boost(float p_boost);
+ float get_transmittance_boost() const;
+
+ void set_backlight(const Color &p_backlight);
+ Color get_backlight() const;
void set_refraction(float p_refraction);
float get_refraction() const;
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 5068bb548f..41146036f6 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -120,18 +120,23 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R
int index = token.value;
- String path = local_path + "::" + itos(index);
+ if (use_nocache) {
+ r_res = int_resources[index];
+ } else {
- if (!ignore_resource_parsing) {
+ String path = local_path + "::" + itos(index);
- if (!ResourceCache::has(path)) {
- r_err_str = "Can't load cached sub-resource: " + path;
- return ERR_PARSE_ERROR;
- }
+ if (!ignore_resource_parsing) {
- r_res = RES(ResourceCache::get(path));
- } else {
- r_res = RES();
+ if (!ResourceCache::has(path)) {
+ r_err_str = "Can't load cached sub-resource: " + path;
+ return ERR_PARSE_ERROR;
+ }
+
+ r_res = RES(ResourceCache::get(path));
+ } else {
+ r_res = RES();
+ }
}
VariantParser::get_token(p_stream, token, line, r_err_str);
@@ -535,7 +540,7 @@ Error ResourceLoaderText::load() {
Ref<Resource> res;
- if (!ResourceCache::has(path)) { //only if it doesn't exist
+ if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist
Object *obj = ClassDB::instance(type);
if (!obj) {
@@ -556,8 +561,10 @@ Error ResourceLoaderText::load() {
}
res = Ref<Resource>(r);
- resource_cache.push_back(res);
- res->set_path(path);
+ int_resources[id] = res;
+ if (!use_nocache) {
+ res->set_path(path);
+ }
}
resource_current++;
@@ -643,10 +650,12 @@ Error ResourceLoaderText::load() {
_printerr();
} else {
error = OK;
- if (!ResourceCache::has(res_path)) {
- resource->set_path(res_path);
+ if (!use_nocache) {
+ if (!ResourceCache::has(res_path)) {
+ resource->set_path(res_path);
+ }
+ resource->set_as_translation_remapped(translation_remapped);
}
- resource->set_as_translation_remapped(translation_remapped);
}
return error;
}
@@ -691,7 +700,7 @@ Error ResourceLoaderText::load() {
error = OK;
//get it here
resource = packed_scene;
- if (!ResourceCache::has(res_path)) {
+ if (!use_nocache && !ResourceCache::has(res_path)) {
packed_scene->set_path(res_path);
}
@@ -725,6 +734,9 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) {
}
ResourceLoaderText::ResourceLoaderText() {
+
+ use_nocache = false;
+
resources_total = 0;
resource_current = 0;
use_sub_threads = false;
@@ -1285,7 +1297,7 @@ String ResourceLoaderText::recognize(FileAccess *p_f) {
/////////////////////
-RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_CANT_OPEN;
@@ -1298,6 +1310,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina
ResourceLoaderText loader;
String path = p_original_path != "" ? p_original_path : p_path;
+ loader.use_nocache = p_no_cache;
loader.use_sub_threads = p_use_sub_threads;
loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
loader.progress = r_progress;
diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h
index fbbd2e3346..b9a6db5f36 100644
--- a/scene/resources/resource_format_text.h
+++ b/scene/resources/resource_format_text.h
@@ -62,6 +62,7 @@ class ResourceLoaderText {
//Map<String,String> remaps;
Map<int, ExtResource> ext_resources;
+ Map<int, RES> int_resources;
int resources_total;
int resource_current;
@@ -69,6 +70,8 @@ class ResourceLoaderText {
VariantParser::Tag next_tag;
+ bool use_nocache;
+
bool use_sub_threads;
float *progress;
@@ -106,7 +109,6 @@ class ResourceLoaderText {
friend class ResourceFormatLoaderText;
- List<RES> resource_cache;
Error error;
RES resource;
@@ -134,7 +136,7 @@ public:
class ResourceFormatLoaderText : public ResourceFormatLoader {
public:
static ResourceFormatLoaderText *singleton;
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index a62e7ded16..1ac2f7c3c9 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -176,7 +176,7 @@ Shader::~Shader() {
}
////////////
-RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index cf0cec362c..75c38bd561 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -102,7 +102,7 @@ VARIANT_ENUM_CAST(Shader::Mode);
class ResourceFormatLoaderShader : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 37b88cccea..a0b6ab1e30 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -111,16 +111,6 @@ float ProceduralSkyMaterial::get_ground_energy() const {
return ground_energy;
}
-void ProceduralSkyMaterial::set_sun_angle_min(float p_angle) {
-
- sun_angle_min = p_angle;
- RS::get_singleton()->material_set_param(_get_material(), "sun_angle_min", Math::deg2rad(sun_angle_min));
-}
-float ProceduralSkyMaterial::get_sun_angle_min() const {
-
- return sun_angle_min;
-}
-
void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) {
sun_angle_max = p_angle;
@@ -181,9 +171,6 @@ void ProceduralSkyMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSkyMaterial::set_ground_energy);
ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSkyMaterial::get_ground_energy);
- ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSkyMaterial::set_sun_angle_min);
- ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSkyMaterial::get_sun_angle_min);
-
ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSkyMaterial::set_sun_angle_max);
ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSkyMaterial::get_sun_angle_max);
@@ -203,7 +190,6 @@ void ProceduralSkyMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
ADD_GROUP("Sun", "sun_");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
}
@@ -220,8 +206,7 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
code += "uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);\n";
code += "uniform float ground_curve : hint_range(0, 1) = 0.02;\n";
code += "uniform float ground_energy = 1.0;\n\n";
- code += "uniform float sun_angle_min = 0.01;\n";
- code += "uniform float sun_angle_max = 1.0;\n";
+ code += "uniform float sun_angle_max = 1.74;\n";
code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n";
code += "const float PI = 3.1415926535897932384626433833;\n\n";
code += "void fragment() {\n";
@@ -231,37 +216,37 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
code += "\tsky *= sky_energy;\n";
code += "\tif (LIGHT0_ENABLED) {\n";
code += "\t\tfloat sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));\n";
- code += "\t\tif (sun_angle < sun_angle_min) {\n";
+ code += "\t\tif (sun_angle < LIGHT0_SIZE) {\n";
code += "\t\t\tsky = LIGHT0_COLOR * LIGHT0_ENERGY;\n";
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
- code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+ code += "\t\t\tfloat c2 = (sun_angle - LIGHT0_SIZE) / (sun_angle_max - LIGHT0_SIZE);\n";
code += "\t\t\tsky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
code += "\t\t}\n";
code += "\t}\n";
code += "\tif (LIGHT1_ENABLED) {\n";
code += "\t\tfloat sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));\n";
- code += "\t\tif (sun_angle < sun_angle_min) {\n";
+ code += "\t\tif (sun_angle < LIGHT1_SIZE) {\n";
code += "\t\t\tsky = LIGHT1_COLOR * LIGHT1_ENERGY;\n";
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
- code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+ code += "\t\t\tfloat c2 = (sun_angle - LIGHT1_SIZE) / (sun_angle_max - LIGHT1_SIZE);\n";
code += "\t\t\tsky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
code += "\t\t}\n";
code += "\t}\n";
code += "\tif (LIGHT2_ENABLED) {\n";
code += "\t\tfloat sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));\n";
- code += "\t\tif (sun_angle < sun_angle_min) {\n";
+ code += "\t\tif (sun_angle < LIGHT2_SIZE) {\n";
code += "\t\t\tsky = LIGHT2_COLOR * LIGHT2_ENERGY;\n";
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
- code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+ code += "\t\t\tfloat c2 = (sun_angle - LIGHT2_SIZE) / (sun_angle_max - LIGHT2_SIZE);\n";
code += "\t\t\tsky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
code += "\t\t}\n";
code += "\t}\n";
code += "\tif (LIGHT3_ENABLED) {\n";
code += "\t\tfloat sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));\n";
- code += "\t\tif (sun_angle < sun_angle_min) {\n";
+ code += "\t\tif (sun_angle < LIGHT3_SIZE) {\n";
code += "\t\t\tsky = LIGHT3_COLOR * LIGHT3_ENERGY;\n";
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
- code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+ code += "\t\t\tfloat c2 = (sun_angle - LIGHT3_SIZE) / (sun_angle_max - LIGHT3_SIZE);\n";
code += "\t\t\tsky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
code += "\t\t}\n";
code += "\t}\n";
@@ -287,7 +272,6 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
set_ground_curve(0.02);
set_ground_energy(1.0);
- set_sun_angle_min(1.0);
set_sun_angle_max(100.0);
set_sun_curve(0.05);
}
@@ -535,7 +519,6 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n";
code += "// Sun constants\n";
- code += "const float SOL_SIZE = 0.00872663806;\n";
code += "const float SUN_ENERGY = 1000.0;\n\n";
code += "// optical length at zenith for molecules\n";
@@ -591,8 +574,8 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
code += "\t// Solar disk and out-scattering\n";
- code += "\tfloat sunAngularDiameterCos = cos(SOL_SIZE * sun_disk_scale);\n";
- code += "\tfloat sunAngularDiameterCos2 = cos(SOL_SIZE * sun_disk_scale*0.5);\n";
+ code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n";
+ code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
code += "\t// Note: Add nightime here: L0 += night_sky * extinction\n\n";
diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h
index 515706b0c5..9bd9d7ec8b 100644
--- a/scene/resources/sky_material.h
+++ b/scene/resources/sky_material.h
@@ -49,7 +49,6 @@ private:
float ground_curve;
float ground_energy;
- float sun_angle_min;
float sun_angle_max;
float sun_curve;
@@ -84,9 +83,6 @@ public:
void set_ground_energy(float p_energy);
float get_ground_energy() const;
- void set_sun_angle_min(float p_angle);
- float get_sun_angle_min() const;
-
void set_sun_angle_max(float p_angle);
float get_sun_angle_max() const;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 749dff24f2..f431a2ad48 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -796,7 +796,7 @@ StreamTexture::~StreamTexture() {
}
}
-RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
Ref<StreamTexture> st;
st.instance();
@@ -2024,7 +2024,7 @@ TextureLayered::~TextureLayered() {
}
}
-RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 18f70baa07..f4f00c2ca0 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -213,7 +213,7 @@ public:
class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
@@ -421,7 +421,7 @@ public:
COMPRESSION_UNCOMPRESSED
};
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index ad996e7d50..5e3f8b803b 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -202,4 +202,7 @@ SceneStringNames::SceneStringNames() {
parameters_base_path = "parameters/";
tracks_changed = "tracks_changed";
+
+ shader_overrides_group = StaticCString::create("_shader_overrides_group_");
+ shader_overrides_group_active = StaticCString::create("_shader_overrides_group_active_");
}
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index 58e8c28454..c5de10a6f6 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -207,6 +207,8 @@ public:
StringName window_input;
StringName theme_changed;
+ StringName shader_overrides_group;
+ StringName shader_overrides_group_active;
enum {
MAX_MATERIALS = 32
diff --git a/servers/SCsub b/servers/SCsub
index 7080a110da..121990f2e1 100644
--- a/servers/SCsub
+++ b/servers/SCsub
@@ -5,7 +5,7 @@ Import("env")
env.servers_sources = []
env.add_source_files(env.servers_sources, "*.cpp")
-SConscript("arvr/SCsub")
+SConscript("xr/SCsub")
SConscript("camera/SCsub")
SConscript("physics_3d/SCsub")
SConscript("physics_2d/SCsub")
diff --git a/servers/display_server.h b/servers/display_server.h
index 1956bcafca..93db7ef844 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -180,7 +180,7 @@ public:
};
virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW);
- ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
virtual void screen_set_keep_on(bool p_enable); //disable screensaver
virtual bool screen_is_kept_on() const;
diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h
index 48f3bea1e1..ca001e6dd9 100644
--- a/servers/physics_2d/shape_2d_sw.h
+++ b/servers/physics_2d/shape_2d_sw.h
@@ -465,7 +465,11 @@ public:
virtual Variant get_data() const;
_FORCE_INLINE_ void project_range(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const {
- // no matter the angle, the box is mirrored anyway
+
+ if (!points || point_count <= 0) {
+ r_min = r_max = 0;
+ return;
+ }
r_min = r_max = p_normal.dot(p_transform.xform(points[0].pos));
for (int i = 1; i < point_count; i++) {
diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h
index b553cf0670..2bd335e6c0 100644
--- a/servers/physics_3d/body_3d_sw.h
+++ b/servers/physics_3d/body_3d_sw.h
@@ -257,7 +257,7 @@ public:
_FORCE_INLINE_ void add_force(const Vector3 &p_force, const Vector3 &p_pos) {
applied_force += p_force;
- applied_torque += p_pos.cross(p_force);
+ applied_torque += (p_pos - center_of_mass).cross(p_force);
}
_FORCE_INLINE_ void add_torque(const Vector3 &p_torque) {
@@ -421,7 +421,7 @@ public:
virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) { body->apply_impulse(p_pos, p_j); }
virtual void apply_torque_impulse(const Vector3 &p_j) { body->apply_torque_impulse(p_j); }
- virtual void set_sleep_state(bool p_enable) { body->set_active(!p_enable); }
+ virtual void set_sleep_state(bool p_sleep) { body->set_active(!p_sleep); }
virtual bool is_sleeping() const { return !body->is_active(); }
virtual int get_contact_count() const { return body->contact_count; }
diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
index 1f433ec6a5..e15aeca842 100644
--- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
@@ -497,28 +497,28 @@ void Generic6DOFJoint3DSW::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DO
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning
}
@@ -597,28 +597,28 @@ real_t Generic6DOFJoint3DSW::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning
}
@@ -643,13 +643,13 @@ void Generic6DOFJoint3DSW::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF
m_angularLimits[p_axis].m_enableMotor = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
}
@@ -671,13 +671,13 @@ bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF
return m_angularLimits[p_axis].m_enableMotor;
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: {
- // Not implemented in GodotPhysics backend
+ // Not implemented in GodotPhysics3D backend
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
}
diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp
index bc42c2fd9e..b454dc54af 100644
--- a/servers/physics_3d/physics_server_3d_sw.cpp
+++ b/servers/physics_3d/physics_server_3d_sw.cpp
@@ -70,7 +70,7 @@ RID PhysicsServer3DSW::shape_create(ShapeType p_shape) {
} break;
case SHAPE_CYLINDER: {
- ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics. Please switch to Bullet in the Project Settings.");
+ ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics3D. Please switch to Bullet in the Project Settings.");
} break;
case SHAPE_CONVEX_POLYGON: {
@@ -1499,7 +1499,7 @@ void PhysicsServer3DSW::flush_queries() {
values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg));
values.push_front("physics");
- EngineDebugger::profiler_add_frame_data("server", values);
+ EngineDebugger::profiler_add_frame_data("servers", values);
}
#endif
};
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index a2f08b3ed8..8ea8b22455 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -70,7 +70,7 @@ public:
virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) = 0;
virtual void apply_torque_impulse(const Vector3 &p_j) = 0;
- virtual void set_sleep_state(bool p_enable) = 0;
+ virtual void set_sleep_state(bool p_sleep) = 0;
virtual bool is_sleeping() const = 0;
virtual int get_contact_count() const = 0;
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 64b48bea50..60217002fb 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -33,9 +33,6 @@
#include "core/engine.h"
#include "core/project_settings.h"
-#include "arvr/arvr_interface.h"
-#include "arvr/arvr_positional_tracker.h"
-#include "arvr_server.h"
#include "audio/audio_effect.h"
#include "audio/audio_stream.h"
#include "audio/effects/audio_effect_amplify.h"
@@ -65,8 +62,15 @@
#include "physics_3d/physics_server_3d_sw.h"
#include "physics_server_2d.h"
#include "physics_server_3d.h"
+#include "rendering/rasterizer.h"
+#include "rendering/rendering_device.h"
+#include "rendering/rendering_device_binds.h"
+
#include "rendering_server.h"
#include "servers/rendering/shader_types.h"
+#include "xr/xr_interface.h"
+#include "xr/xr_positional_tracker.h"
+#include "xr_server.h"
ShaderTypes *shader_types = nullptr;
@@ -100,13 +104,17 @@ void register_server_types() {
ClassDB::register_virtual_class<DisplayServer>();
ClassDB::register_virtual_class<RenderingServer>();
ClassDB::register_class<AudioServer>();
- ClassDB::register_virtual_class<PhysicsServer3D>();
ClassDB::register_virtual_class<PhysicsServer2D>();
- ClassDB::register_class<ARVRServer>();
+ ClassDB::register_virtual_class<PhysicsServer3D>();
+ ClassDB::register_virtual_class<NavigationServer2D>();
+ ClassDB::register_virtual_class<NavigationServer3D>();
+ ClassDB::register_class<XRServer>();
ClassDB::register_class<CameraServer>();
- ClassDB::register_virtual_class<ARVRInterface>();
- ClassDB::register_class<ARVRPositionalTracker>();
+ ClassDB::register_virtual_class<RenderingDevice>();
+
+ ClassDB::register_virtual_class<XRInterface>();
+ ClassDB::register_class<XRPositionalTracker>();
ClassDB::register_virtual_class<AudioStream>();
ClassDB::register_virtual_class<AudioStreamPlayback>();
@@ -157,6 +165,22 @@ void register_server_types() {
ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>();
}
+ ClassDB::register_virtual_class<RenderingDevice>();
+ ClassDB::register_class<RDTextureFormat>();
+ ClassDB::register_class<RDTextureView>();
+ ClassDB::register_class<RDAttachmentFormat>();
+ ClassDB::register_class<RDSamplerState>();
+ ClassDB::register_class<RDVertexAttribute>();
+ ClassDB::register_class<RDUniform>();
+ ClassDB::register_class<RDPipelineRasterizationState>();
+ ClassDB::register_class<RDPipelineMultisampleState>();
+ ClassDB::register_class<RDPipelineDepthStencilState>();
+ ClassDB::register_class<RDPipelineColorBlendStateAttachment>();
+ ClassDB::register_class<RDPipelineColorBlendState>();
+ ClassDB::register_class<RDShaderSource>();
+ ClassDB::register_class<RDShaderBytecode>();
+ ClassDB::register_class<RDShaderFile>();
+
ClassDB::register_class<CameraFeed>();
ClassDB::register_virtual_class<PhysicsDirectBodyState2D>();
@@ -174,15 +198,15 @@ void register_server_types() {
GLOBAL_DEF(PhysicsServer2DManager::setting_property_name, "DEFAULT");
ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServer2DManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServer2DManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"));
- PhysicsServer2DManager::register_server("GodotPhysics", &_createGodotPhysics2DCallback);
- PhysicsServer2DManager::set_default_server("GodotPhysics");
+ PhysicsServer2DManager::register_server("GodotPhysics2D", &_createGodotPhysics2DCallback);
+ PhysicsServer2DManager::set_default_server("GodotPhysics2D");
// Physics 3D
GLOBAL_DEF(PhysicsServer3DManager::setting_property_name, "DEFAULT");
ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServer3DManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServer3DManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"));
- PhysicsServer3DManager::register_server("GodotPhysics", &_createGodotPhysics3DCallback);
- PhysicsServer3DManager::set_default_server("GodotPhysics");
+ PhysicsServer3DManager::register_server("GodotPhysics3D", &_createGodotPhysics3DCallback);
+ PhysicsServer3DManager::set_default_server("GodotPhysics3D");
}
void unregister_server_types() {
@@ -192,12 +216,13 @@ void unregister_server_types() {
void register_server_singletons() {
+ Engine::get_singleton()->add_singleton(Engine::Singleton("DisplayServer", DisplayServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("AudioServer", AudioServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer2D", PhysicsServer2D::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3D", PhysicsServer3D::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton_mut()));
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton_mut()));
- Engine::get_singleton()->add_singleton(Engine::Singleton("ARVRServer", ARVRServer::get_singleton()));
+ Engine::get_singleton()->add_singleton(Engine::Singleton("XRServer", XRServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("CameraServer", CameraServer::get_singleton()));
}
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
index d77963b3dd..955241e79c 100644
--- a/servers/rendering/rasterizer.h
+++ b/servers/rendering/rasterizer.h
@@ -106,6 +106,9 @@ public:
virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0;
virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0;
+ virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
+ virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
+
struct InstanceBase;
struct InstanceDependency {
@@ -164,6 +167,17 @@ public:
AABB aabb;
AABB transformed_aabb;
+ struct InstanceShaderParameter {
+ int32_t index = -1;
+ Variant value;
+ Variant default_value;
+ PropertyInfo info;
+ };
+
+ Map<StringName, InstanceShaderParameter> instance_shader_parameters;
+ bool instance_allocated_shader_parameters = false;
+ int32_t instance_allocated_shader_parameters_offset = -1;
+
virtual void dependency_deleted(RID p_dependency) = 0;
virtual void dependency_changed(bool p_aabb, bool p_dependencies) = 0;
@@ -229,7 +243,7 @@ public:
virtual RID light_instance_create(RID p_light) = 0;
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
- virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0;
+ virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0;
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
virtual bool light_instances_can_render_shadow_cube() const {
return true;
@@ -246,12 +260,15 @@ public:
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0;
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0;
+ virtual RID decal_instance_create(RID p_decal) = 0;
+ virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0;
+
virtual RID gi_probe_instance_create(RID p_gi_probe) = 0;
virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
virtual bool gi_probe_needs_update(RID p_probe) const = 0;
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0;
- virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0;
+ virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0;
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0;
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
@@ -261,7 +278,7 @@ public:
virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;
virtual RID render_buffers_create() = 0;
- virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa) = 0;
+ virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) = 0;
virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) = 0;
virtual bool screen_space_roughness_limiter_is_active() const = 0;
@@ -321,6 +338,9 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) = 0;
+ virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
+ virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
+
/* SHADER API */
virtual RID shader_create() = 0;
@@ -348,6 +368,14 @@ public:
virtual bool material_is_animated(RID p_material) = 0;
virtual bool material_casts_shadows(RID p_material) = 0;
+ struct InstanceShaderParam {
+ PropertyInfo info;
+ int index;
+ Variant default_value;
+ };
+
+ virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
+
virtual void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) = 0;
/* MESH API */
@@ -501,6 +529,21 @@ public:
virtual void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) = 0;
virtual void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) = 0;
+ /* DECAL API */
+
+ virtual RID decal_create() = 0;
+ virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
+ virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
+ virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
+ virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
+ virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
+ virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
+ virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
+ virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
+ virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
+
+ virtual AABB decal_get_aabb(RID p_decal) const = 0;
+
/* GI PROBE API */
virtual RID gi_probe_create() = 0;
@@ -611,6 +654,24 @@ public:
virtual int particles_get_draw_passes(RID p_particles) const = 0;
virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0;
+ /* GLOBAL VARIABLES */
+
+ virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;
+ virtual void global_variable_remove(const StringName &p_name) = 0;
+ virtual Vector<StringName> global_variable_get_list() const = 0;
+
+ virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0;
+ virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0;
+ virtual Variant global_variable_get(const StringName &p_name) const = 0;
+ virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0;
+
+ virtual void global_variables_load_settings(bool p_load_textures = true) = 0;
+ virtual void global_variables_clear() = 0;
+
+ virtual int32_t global_variables_instance_allocate(RID p_instance) = 0;
+ virtual void global_variables_instance_free(RID p_instance) = 0;
+ virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0;
+
/* RENDER TARGET */
enum RenderTargetFlags {
diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp
index 943ef1c7fa..f75308a975 100644
--- a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp
+++ b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp
@@ -39,6 +39,7 @@ void LightClusterBuilder::begin(const Transform &p_view_transform, const CameraM
//reset counts
light_count = 0;
refprobe_count = 0;
+ decal_count = 0;
item_count = 0;
sort_id_count = 0;
}
diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.h b/servers/rendering/rasterizer_rd/light_cluster_builder.h
index 3411ed07a0..78288dc620 100644
--- a/servers/rendering/rasterizer_rd/light_cluster_builder.h
+++ b/servers/rendering/rasterizer_rd/light_cluster_builder.h
@@ -170,17 +170,15 @@ public:
_add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count);
} break;
case LIGHT_TYPE_SPOT: {
- Vector3 v(0, 0, -1);
- v.rotated(Vector3(0, 1, 0), Math::deg2rad(ld.spot_aperture)); //rotate in x-z
- v.normalize();
- v *= ld.radius;
- v.y = v.x;
+
+ float r = ld.radius;
+ real_t len = Math::tan(Math::deg2rad(ld.spot_aperture)) * r;
aabb.position = xform.origin;
- aabb.expand_to(xform.xform(v));
- aabb.expand_to(xform.xform(Vector3(-v.x, v.y, v.z)));
- aabb.expand_to(xform.xform(Vector3(-v.x, -v.y, v.z)));
- aabb.expand_to(xform.xform(Vector3(v.x, -v.y, v.z)));
+ aabb.expand_to(xform.xform(Vector3(len, len, -r)));
+ aabb.expand_to(xform.xform(Vector3(-len, len, -r)));
+ aabb.expand_to(xform.xform(Vector3(-len, -len, -r)));
+ aabb.expand_to(xform.xform(Vector3(len, -len, -r)));
_add_item(aabb, ITEM_TYPE_SPOT_LIGHT, light_count);
} break;
}
@@ -195,23 +193,25 @@ public:
refprobes = (OrientedBoxData *)memrealloc(refprobes, sizeof(OrientedBoxData) * refprobe_max);
}
+ Transform xform = view_xform * p_transform;
+
OrientedBoxData &rp = refprobes[refprobe_count];
- Vector3 origin = p_transform.origin;
+ Vector3 origin = xform.origin;
rp.position[0] = origin.x;
rp.position[1] = origin.y;
rp.position[2] = origin.z;
- Vector3 x_axis = p_transform.basis.get_axis(0) * p_half_extents.x;
+ Vector3 x_axis = xform.basis.get_axis(0) * p_half_extents.x;
rp.x_axis[0] = x_axis.x;
rp.x_axis[1] = x_axis.y;
rp.x_axis[2] = x_axis.z;
- Vector3 y_axis = p_transform.basis.get_axis(1) * p_half_extents.y;
+ Vector3 y_axis = xform.basis.get_axis(1) * p_half_extents.y;
rp.y_axis[0] = y_axis.x;
rp.y_axis[1] = y_axis.y;
rp.y_axis[2] = y_axis.z;
- Vector3 z_axis = p_transform.basis.get_axis(2) * p_half_extents.z;
+ Vector3 z_axis = xform.basis.get_axis(2) * p_half_extents.z;
rp.z_axis[0] = z_axis.x;
rp.z_axis[1] = z_axis.y;
rp.z_axis[2] = z_axis.z;
@@ -232,35 +232,37 @@ public:
refprobe_count++;
}
- _FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector2 &p_half_extents, float p_depth) {
+ _FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector3 &p_half_extents) {
if (unlikely(decal_count == decal_max)) {
decal_max = nearest_power_of_2_templated(decal_max + 1);
decals = (OrientedBoxData *)memrealloc(decals, sizeof(OrientedBoxData) * decal_max);
}
- OrientedBoxData &dc = decals[decal_count];
+ Transform xform = view_xform * p_transform;
- Vector3 z_axis = -p_transform.basis.get_axis(2) * p_depth * 0.5;
- dc.z_axis[0] = z_axis.x;
- dc.z_axis[1] = z_axis.y;
- dc.z_axis[2] = z_axis.z;
+ OrientedBoxData &dc = decals[decal_count];
- Vector3 origin = p_transform.origin - z_axis;
+ Vector3 origin = xform.origin;
dc.position[0] = origin.x;
dc.position[1] = origin.y;
dc.position[2] = origin.z;
- Vector3 x_axis = p_transform.basis.get_axis(0) * p_half_extents.x;
+ Vector3 x_axis = xform.basis.get_axis(0) * p_half_extents.x;
dc.x_axis[0] = x_axis.x;
dc.x_axis[1] = x_axis.y;
dc.x_axis[2] = x_axis.z;
- Vector3 y_axis = p_transform.basis.get_axis(1) * p_half_extents.y;
+ Vector3 y_axis = xform.basis.get_axis(1) * p_half_extents.y;
dc.y_axis[0] = y_axis.x;
dc.y_axis[1] = y_axis.y;
dc.y_axis[2] = y_axis.z;
+ Vector3 z_axis = xform.basis.get_axis(2) * p_half_extents.z;
+ dc.z_axis[0] = z_axis.x;
+ dc.z_axis[1] = z_axis.y;
+ dc.z_axis[2] = z_axis.z;
+
AABB aabb;
aabb.position = origin + x_axis + y_axis + z_axis;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
index ba4f4c4acb..956bf54d01 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
@@ -273,7 +273,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
Vector<uint8_t> polygon_buffer;
polygon_buffer.resize(buffer_size * sizeof(float));
- Vector<RD::VertexDescription> descriptions;
+ Vector<RD::VertexAttribute> descriptions;
descriptions.resize(4);
Vector<RID> buffers;
buffers.resize(4);
@@ -284,7 +284,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
uint32_t *uptr = (uint32_t *)r;
uint32_t base_offset = 0;
{ //vertices
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_VERTEX;
@@ -304,7 +304,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
//colors
if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_COLOR;
@@ -332,7 +332,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
}
base_offset += 4;
} else {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
vd.offset = 0;
vd.location = RS::ARRAY_COLOR;
@@ -344,7 +344,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
//uvs
if ((uint32_t)p_uvs.size() == vertex_count) {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_TEX_UV;
@@ -360,7 +360,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
}
base_offset += 2;
} else {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
vd.offset = 0;
vd.location = RS::ARRAY_TEX_UV;
@@ -372,7 +372,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
//bones
if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_BONES;
@@ -401,7 +401,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
base_offset += 4;
} else {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
vd.offset = 0;
vd.location = RS::ARRAY_BONES;
@@ -618,6 +618,14 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
}
}
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 7;
+ u.ids.push_back(storage->global_variables_get_storage_buffer());
+ uniforms.push_back(u);
+ }
+
//validate and update lighs if they are being used
if (light_count > 0) {
@@ -2012,6 +2020,9 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
+ continue;
+ }
if (E->get().texture_order >= 0) {
order[E->get().texture_order + 100000] = E->key();
} else {
@@ -2027,6 +2038,23 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_
}
}
+void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ RasterizerStorage::InstanceShaderParam p;
+ p.info = ShaderLanguage::uniform_to_property_info(E->get());
+ p.info.name = E->key(); //supply name
+ p.index = E->get().instance_index;
+ p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint);
+ p_param_list->push_back(p);
+ }
+}
+
bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
@@ -2366,6 +2394,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
actions.default_repeat = ShaderLanguage::REPEAT_DISABLE;
actions.base_varying_index = 4;
+ actions.global_buffer_array_variable = "global_variables.data";
+
shader.compiler.initialize(actions);
}
@@ -2393,8 +2423,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
}
//pipelines
- Vector<RD::VertexDescription> vf;
- RD::VertexDescription vd;
+ Vector<RD::VertexAttribute> vf;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
vd.location = 0;
vd.offset = 0;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
index 83b431eaf6..4d47b3e13b 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
@@ -185,6 +185,8 @@ class RasterizerCanvasRD : public RasterizerCanvas {
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const;
+
virtual bool is_param_texture(const StringName &p_param) const;
virtual bool is_animated() const;
virtual bool casts_shadows() const;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
index 2d881dbd37..d469dd97ca 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
@@ -99,7 +99,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use
u.ids.push_back(p_texture);
uniforms.push_back(u);
//any thing with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, blur.shader.version_get_shader(blur.shader_version, 0), 0);
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, 0), 0);
texture_to_uniform_set_cache[p_texture] = uniform_set;
@@ -204,135 +204,224 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1
return uniform_set;
}
-void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, bool p_force_luminance) {
+void RasterizerEffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) {
+
+ zeromem(&copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
+
+ copy_to_fb.push_constant.use_section = true;
+ copy_to_fb.push_constant.section[0] = p_uv_rect.position.x;
+ copy_to_fb.push_constant.section[1] = p_uv_rect.position.y;
+ copy_to_fb.push_constant.section[2] = p_uv_rect.size.x;
+ copy_to_fb.push_constant.section[3] = p_uv_rect.size.y;
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
if (p_flip_y) {
- blur.push_constant.flags |= BLUR_FLAG_FLIP_Y;
+ copy_to_fb.push_constant.flip_y = true;
+ }
+
+ RD::DrawListID draw_list = p_draw_list;
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[p_panorama ? COPY_TO_FB_COPY_PANORAMA_TO_DP : COPY_TO_FB_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+}
+
+void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero) {
+ zeromem(&copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
+
+ if (p_flip_y) {
+ copy_to_fb.push_constant.flip_y = true;
}
if (p_force_luminance) {
- blur.push_constant.flags |= BLUR_COPY_FORCE_LUMINANCE;
+ copy_to_fb.push_constant.force_luminance = true;
+ }
+ if (p_alpha_to_zero) {
+ copy_to_fb.push_constant.alpha_to_zero = true;
}
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_SIMPLY_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[COPY_TO_FB_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
RD::get_singleton()->draw_list_draw(draw_list, true);
RD::get_singleton()->draw_list_end();
}
-void RasterizerEffectsRD::region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region) {
+void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst) {
+
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+ if (p_flip_y) {
+ copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
+ }
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ if (p_force_luminance) {
+ copy.push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE;
+ }
- if (p_region != Rect2()) {
- blur.push_constant.flags = BLUR_FLAG_USE_BLUR_SECTION;
- blur.push_constant.section[0] = p_region.position.x;
- blur.push_constant.section[1] = p_region.position.y;
- blur.push_constant.section[2] = p_region.size.width;
- blur.push_constant.section[3] = p_region.size.height;
+ if (p_all_source) {
+ copy.push_constant.flags |= COPY_FLAG_ALL_SOURCE;
}
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_SIMPLY_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_rect.size.width;
+ copy.push_constant.section[3] = p_rect.size.height;
+ copy.push_constant.target[0] = p_rect.position.x;
+ copy.push_constant.target[1] = p_rect.position.y;
+
+ int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region) {
+void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) {
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+ if (p_flip_y) {
+ copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
+ }
- uint32_t base_flags = 0;
- if (p_region != Rect2()) {
- base_flags = BLUR_FLAG_USE_BLUR_SECTION;
- blur.push_constant.section[0] = p_region.position.x;
- blur.push_constant.section[1] = p_region.position.y;
- blur.push_constant.section[2] = p_region.size.width;
- blur.push_constant.section[3] = p_region.size.height;
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_rect.size.width;
+ copy.push_constant.section[3] = p_rect.size.height;
+ copy.push_constant.target[0] = p_rect.position.x;
+ copy.push_constant.target[1] = p_rect.position.y;
+ copy.push_constant.camera_z_far = p_z_far;
+ copy.push_constant.camera_z_near = p_z_near;
+
+ int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_LINEARIZE_DEPTH]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
+}
+
+void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) {
+
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+ if (p_flip_y) {
+ copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
}
- blur.push_constant.pixel_size[0] = p_pixel_size.x;
- blur.push_constant.pixel_size[1] = p_pixel_size.y;
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_rect.size.width;
+ copy.push_constant.section[3] = p_rect.size.height;
+ copy.push_constant.target[0] = p_rect.position.x;
+ copy.push_constant.target[1] = p_rect.position.y;
+ int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_SIMPLY_COPY_DEPTH]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
+}
+
+void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) {
+
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+
+ uint32_t base_flags = 0;
+ copy.push_constant.section[0] = p_region.position.x;
+ copy.push_constant.section[1] = p_region.position.y;
+ copy.push_constant.section[2] = p_region.size.width;
+ copy.push_constant.section[3] = p_region.size.height;
+
+ int32_t x_groups = (p_region.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_region.size.height - 1) / 8 + 1;
//HORIZONTAL
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_GAUSSIAN_BLUR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 0);
- blur.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL;
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL;
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
//VERTICAL
- draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_GAUSSIAN_BLUR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_rd_texture_half), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 0);
- blur.push_constant.flags = base_flags;
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ copy.push_constant.flags = base_flags;
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
+void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
- BlurMode blur_mode = p_first_pass && p_auto_exposure.is_valid() ? BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : BLUR_MODE_GAUSSIAN_GLOW;
+ CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;
uint32_t base_flags = 0;
- blur.push_constant.pixel_size[0] = p_pixel_size.x;
- blur.push_constant.pixel_size[1] = p_pixel_size.y;
+ int32_t x_groups = (p_size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_size.height - 1) / 8 + 1;
+
+ copy.push_constant.section[2] = p_size.x;
+ copy.push_constant.section[3] = p_size.y;
- blur.push_constant.glow_strength = p_strength;
- blur.push_constant.glow_bloom = p_bloom;
- blur.push_constant.glow_hdr_threshold = p_hdr_bleed_treshold;
- blur.push_constant.glow_hdr_scale = p_hdr_bleed_scale;
- blur.push_constant.glow_exposure = p_exposure;
- blur.push_constant.glow_white = 0; //actually unused
- blur.push_constant.glow_luminance_cap = p_luminance_cap;
+ copy.push_constant.glow_strength = p_strength;
+ copy.push_constant.glow_bloom = p_bloom;
+ copy.push_constant.glow_hdr_threshold = p_hdr_bleed_treshold;
+ copy.push_constant.glow_hdr_scale = p_hdr_bleed_scale;
+ copy.push_constant.glow_exposure = p_exposure;
+ copy.push_constant.glow_white = 0; //actually unused
+ copy.push_constant.glow_luminance_cap = p_luminance_cap;
- blur.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also
+ copy.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also
//HORIZONTAL
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3);
if (p_auto_exposure.is_valid() && p_first_pass) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_auto_exposure), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_auto_exposure), 1);
}
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- blur.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
- blur_mode = BLUR_MODE_GAUSSIAN_GLOW;
+ copy_mode = COPY_MODE_GAUSSIAN_GLOW;
//VERTICAL
- draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_rd_texture_half), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3);
- blur.push_constant.flags = base_flags;
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ copy.push_constant.flags = base_flags;
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
@@ -541,37 +630,49 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular,
RD::get_singleton()->draw_list_end();
}
-void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_framebuffer, const Vector2 &p_pixel_size) {
+void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
- blur.push_constant.pixel_size[0] = p_pixel_size.x;
- blur.push_constant.pixel_size[1] = p_pixel_size.y;
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_size.width;
+ copy.push_constant.section[3] = p_size.height;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_MIPMAP].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ int32_t x_groups = (p_size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_MIPMAP]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
+void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
CopyToDPPushConstant push_constant;
+ push_constant.screen_size[0] = p_rect.size.x;
+ push_constant.screen_size[1] = p_rect.size.y;
+ push_constant.dest_offset[0] = p_rect.position.x;
+ push_constant.dest_offset[1] = p_rect.position.y;
push_constant.bias = p_bias;
push_constant.z_far = p_z_far;
push_constant.z_near = p_z_near;
push_constant.z_flip = p_dp_flip;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy.pipelines[COPY_MODE_CUBE_TO_DP].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cube_to_dp.pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(CopyToDPPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
@@ -600,7 +701,11 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer,
tonemap.push_constant.use_color_correction = p_settings.use_color_correction;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ tonemap.push_constant.use_fxaa = p_settings.use_fxaa;
+ tonemap.push_constant.pixel_size[0] = 1.0 / p_settings.texture_size.x;
+ tonemap.push_constant.pixel_size[1] = 1.0 / p_settings.texture_size.y;
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_color), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_settings.exposure_texture), 1);
@@ -1110,30 +1215,39 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_
RasterizerEffectsRD::RasterizerEffectsRD() {
- { // Initialize blur
- Vector<String> blur_modes;
- blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
- blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
- blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_LOW\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_HIGH\n");
- blur_modes.push_back("\n#define MODE_SSAO_MERGE\n");
- blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
- blur_modes.push_back("\n#define MODE_MIPMAP\n");
-
- blur.shader.initialize(blur_modes);
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
- blur.shader_version = blur.shader.version_create();
-
- for (int i = 0; i < BLUR_MODE_MAX; i++) {
- blur.pipelines[i].setup(blur.shader.version_get_shader(blur.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ { // Initialize copy
+ Vector<String> copy_modes;
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n");
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
+ copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
+ copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n");
+ copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n");
+ copy_modes.push_back("\n#define MODE_MIPMAP\n");
+ copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n");
+
+ copy.shader.initialize(copy_modes);
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+ copy.shader_version = copy.shader.version_create();
+
+ for (int i = 0; i < COPY_MODE_MAX; i++) {
+ copy.pipelines[i] = RD::get_singleton()->compute_pipeline_create(copy.shader.version_get_shader(copy.shader_version, i));
+ }
+ }
+ {
+ Vector<String> copy_modes;
+ copy_modes.push_back("\n");
+ copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n");
+
+ copy_to_fb.shader.initialize(copy_modes);
+
+ copy_to_fb.shader_version = copy_to_fb.shader.version_create();
+
+ //use additive
+
+ for (int i = 0; i < COPY_TO_FB_MAX; i++) {
+ copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
}
}
@@ -1182,15 +1296,13 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
{
// Initialize copier
Vector<String> copy_modes;
- copy_modes.push_back("\n#define MODE_CUBE_TO_DP\n");
+ copy_modes.push_back("\n");
- copy.shader.initialize(copy_modes);
+ cube_to_dp.shader.initialize(copy_modes);
- copy.shader_version = copy.shader.version_create();
+ cube_to_dp.shader_version = cube_to_dp.shader.version_create();
- for (int i = 0; i < COPY_MODE_MAX; i++) {
- copy.pipelines[i].setup(copy.shader.version_get_shader(copy.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
- }
+ cube_to_dp.pipeline = RD::get_singleton()->compute_pipeline_create(cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0));
}
{
@@ -1462,9 +1574,10 @@ RasterizerEffectsRD::~RasterizerEffectsRD() {
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
RD::get_singleton()->free(filter.coefficient_buffer);
- blur.shader.version_free(blur.shader_version);
bokeh.shader.version_free(bokeh.shader_version);
copy.shader.version_free(copy.shader_version);
+ copy_to_fb.shader.version_free(copy_to_fb.shader_version);
+ cube_to_dp.shader.version_free(cube_to_dp.shader_version);
cubemap_downsampler.shader.version_free(cubemap_downsampler.shader_version);
filter.shader.version_free(filter.shader_version);
luminance_reduce.shader.version_free(luminance_reduce.shader_version);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
index 27f051d194..531591442b 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
@@ -33,9 +33,10 @@
#include "core/math/camera_matrix.h"
#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
-#include "servers/rendering/rasterizer_rd/shaders/blur.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/copy.glsl.gen.h"
+#include "servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl.gen.h"
+#include "servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
@@ -55,70 +56,87 @@
class RasterizerEffectsRD {
- enum BlurMode {
- BLUR_MODE_GAUSSIAN_BLUR,
- BLUR_MODE_GAUSSIAN_GLOW,
- BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE,
- BLUR_MODE_DOF_NEAR_LOW,
- BLUR_MODE_DOF_NEAR_MEDIUM,
- BLUR_MODE_DOF_NEAR_HIGH,
- BLUR_MODE_DOF_NEAR_MERGE_LOW,
- BLUR_MODE_DOF_NEAR_MERGE_MEDIUM,
- BLUR_MODE_DOF_NEAR_MERGE_HIGH,
- BLUR_MODE_DOF_FAR_LOW,
- BLUR_MODE_DOF_FAR_MEDIUM,
- BLUR_MODE_DOF_FAR_HIGH,
- BLUR_MODE_SSAO_MERGE,
- BLUR_MODE_SIMPLY_COPY,
- BLUR_MODE_MIPMAP,
- BLUR_MODE_MAX,
+ enum CopyMode {
+ COPY_MODE_GAUSSIAN_COPY,
+ COPY_MODE_GAUSSIAN_COPY_8BIT,
+ COPY_MODE_GAUSSIAN_GLOW,
+ COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE,
+ COPY_MODE_SIMPLY_COPY,
+ COPY_MODE_SIMPLY_COPY_8BIT,
+ COPY_MODE_SIMPLY_COPY_DEPTH,
+ COPY_MODE_MIPMAP,
+ COPY_MODE_LINEARIZE_DEPTH,
+ COPY_MODE_MAX,
};
enum {
- BLUR_FLAG_HORIZONTAL = (1 << 0),
- BLUR_FLAG_USE_BLUR_SECTION = (1 << 1),
- BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2),
- BLUR_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3),
- BLUR_FLAG_GLOW_FIRST_PASS = (1 << 4),
- BLUR_FLAG_FLIP_Y = (1 << 5),
- BLUR_COPY_FORCE_LUMINANCE = (1 << 6)
+ COPY_FLAG_HORIZONTAL = (1 << 0),
+ COPY_FLAG_USE_COPY_SECTION = (1 << 1),
+ COPY_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2),
+ COPY_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3),
+ COPY_FLAG_GLOW_FIRST_PASS = (1 << 4),
+ COPY_FLAG_FLIP_Y = (1 << 5),
+ COPY_FLAG_FORCE_LUMINANCE = (1 << 6),
+ COPY_FLAG_ALL_SOURCE = (1 << 7)
};
- struct BlurPushConstant {
- float section[4];
- float pixel_size[2];
+ struct CopyPushConstant {
+
+ int32_t section[4];
+ int32_t target[2];
uint32_t flags;
uint32_t pad;
- //glow
+ // Glow.
float glow_strength;
float glow_bloom;
float glow_hdr_threshold;
float glow_hdr_scale;
+
float glow_exposure;
float glow_white;
float glow_luminance_cap;
float glow_auto_exposure_grey;
- //dof
- float dof_begin;
- float dof_end;
- float dof_radius;
- float dof_pad;
-
- float dof_dir[2];
+ // DOF.
float camera_z_far;
float camera_z_near;
+ uint32_t pad2[2];
+ };
+
+ struct Copy {
+ CopyPushConstant push_constant;
+ CopyShaderRD shader;
+ RID shader_version;
+ RID pipelines[COPY_MODE_MAX];
+
+ } copy;
+
+ enum CopyToFBMode {
+ COPY_TO_FB_COPY,
+ COPY_TO_FB_COPY_PANORAMA_TO_DP,
+ COPY_TO_FB_MAX,
+
+ };
+
+ struct CopyToFbPushConstant {
+
+ float section[4];
+ float pixel_size[2];
+ uint32_t flip_y;
+ uint32_t use_section;
- float ssao_color[4];
+ uint32_t force_luminance;
+ uint32_t alpha_to_zero;
+ uint32_t pad[2];
};
- struct Blur {
- BlurPushConstant push_constant;
- BlurShaderRD shader;
+ struct CopyToFb {
+ CopyToFbPushConstant push_constant;
+ CopyToFbShaderRD shader;
RID shader_version;
- RenderPipelineVertexFormatCacheRD pipelines[BLUR_MODE_MAX];
+ RenderPipelineVertexFormatCacheRD pipelines[COPY_TO_FB_MAX];
- } blur;
+ } copy_to_fb;
struct CubemapRoughnessPushConstant {
uint32_t face_id;
@@ -161,10 +179,17 @@ class RasterizerEffectsRD {
float exposure;
float white;
float auto_exposure_grey;
+
+ float pixel_size[2];
+ uint32_t use_fxaa;
+ uint32_t pad;
};
+ /* tonemap actually writes to a framebuffer, which is
+ * better to do using the raster pipeline rather than
+ * comptute, as that framebuffer might be in different formats
+ */
struct Tonemap {
-
TonemapPushConstant push_constant;
TonemapShaderRD shader;
RID shader_version;
@@ -195,23 +220,20 @@ class RasterizerEffectsRD {
} luminance_reduce;
struct CopyToDPPushConstant {
+ int32_t screen_size[2];
+ int32_t dest_offset[2];
float bias;
float z_far;
float z_near;
uint32_t z_flip;
};
- enum CopyMode {
- COPY_MODE_CUBE_TO_DP,
- COPY_MODE_MAX
- };
-
- struct Copy {
+ struct CoptToDP {
- CopyShaderRD shader;
+ CubeToDpShaderRD shader;
RID shader_version;
- RenderPipelineVertexFormatCacheRD pipelines[COPY_MODE_MAX];
- } copy;
+ RID pipeline;
+ } cube_to_dp;
struct BokehPushConstant {
uint32_t size[2];
@@ -391,6 +413,10 @@ class RasterizerEffectsRD {
SPECULAR_MERGE_MAX
};
+ /* Specular merge must be done using raster, rather than compute
+ * because it must continue the existing color buffer
+ */
+
struct SpecularMerge {
SpecularMergeShaderRD shader;
@@ -536,16 +562,17 @@ class RasterizerEffectsRD {
RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2);
public:
- //TODO must re-do most of the shaders in compute
-
- void region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region);
- void copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y = false, bool p_force_luminance = false);
- void gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region);
- void gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
+ void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false);
+ void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false);
+ void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
+ void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
+ void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false);
+ void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false);
+ void gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
- void make_mipmap(RID p_source_rd_texture, RID p_framebuffer_half, const Vector2 &p_pixel_size);
- void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
+ void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
+ void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal);
@@ -582,6 +609,9 @@ public:
bool use_color_correction = false;
RID color_correction_texture;
+
+ bool use_fxaa = false;
+ Vector2i texture_size;
};
void tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
index 685c30b5b8..b3cf40f166 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
@@ -52,6 +52,21 @@ static _FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_arra
p_array[15] = 1;
}
+static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.elements[0][0];
+ p_array[1] = p_mtx.elements[1][0];
+ p_array[2] = p_mtx.elements[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.elements[0][1];
+ p_array[5] = p_mtx.elements[1][1];
+ p_array[6] = p_mtx.elements[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.elements[0][2];
+ p_array[9] = p_mtx.elements[1][2];
+ p_array[10] = p_mtx.elements[2][2];
+ p_array[11] = 0;
+}
+
static _FORCE_INLINE_ void store_transform_3x3(const Transform &p_mtx, float *p_array) {
p_array[0] = p_mtx.basis.elements[0][0];
p_array[1] = p_mtx.basis.elements[1][0];
@@ -77,6 +92,13 @@ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_arra
}
}
+static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) {
+
+ for (int i = 0; i < 128; i++) {
+ p_array[i] = p_kernel[i];
+ }
+}
+
/* SCENE SHADER */
void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
//compile
@@ -109,6 +131,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
unshaded = false;
uses_vertex = false;
uses_sss = false;
+ uses_transmittance = false;
uses_screen_texture = false;
uses_depth_texture = false;
uses_normal_texture = false;
@@ -142,6 +165,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass;
actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
+ actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture;
@@ -354,6 +378,10 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
+ continue;
+ }
+
if (E->get().texture_order >= 0) {
order[E->get().texture_order + 100000] = E->key();
} else {
@@ -369,6 +397,23 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_
}
}
+void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ RasterizerStorage::InstanceShaderParam p;
+ p.info = ShaderLanguage::uniform_to_property_info(E->get());
+ p.info.name = E->key(); //supply name
+ p.index = E->get().instance_index;
+ p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint);
+ p_param_list->push_back(p);
+ }
+}
+
bool RasterizerSceneHighEndRD::ShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
@@ -533,46 +578,100 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = width;
tf.height = height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ if (msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ } else {
+ tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ }
specular = RD::get_singleton()->texture_create(tf, RD::TextureView());
- {
- Vector<RID> fb;
- fb.push_back(color);
- fb.push_back(specular);
- fb.push_back(depth);
+ if (msaa == RS::VIEWPORT_MSAA_DISABLED) {
- color_specular_fb = RD::get_singleton()->framebuffer_create(fb);
- }
- {
- Vector<RID> fb;
- fb.push_back(specular);
+ {
+ Vector<RID> fb;
+ fb.push_back(color);
+ fb.push_back(specular);
+ fb.push_back(depth);
+
+ color_specular_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
+ {
+ Vector<RID> fb;
+ fb.push_back(specular);
+
+ specular_only_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
- specular_only_fb = RD::get_singleton()->framebuffer_create(fb);
+ } else {
+
+ tf.samples = texture_samples;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ specular_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ {
+ Vector<RID> fb;
+ fb.push_back(color_msaa);
+ fb.push_back(specular_msaa);
+ fb.push_back(depth_msaa);
+
+ color_specular_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
+ {
+ Vector<RID> fb;
+ fb.push_back(specular_msaa);
+
+ specular_only_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
}
}
}
void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() {
+ if (color_msaa.is_valid()) {
+ RD::get_singleton()->free(color_msaa);
+ color_msaa = RID();
+ }
+
+ if (depth_msaa.is_valid()) {
+ RD::get_singleton()->free(depth_msaa);
+ depth_msaa = RID();
+ }
+
if (specular.is_valid()) {
+ if (specular_msaa.is_valid()) {
+ RD::get_singleton()->free(specular_msaa);
+ specular_msaa = RID();
+ }
RD::get_singleton()->free(specular);
specular = RID();
}
+ color = RID();
+ depth = RID();
color_specular_fb = RID();
specular_only_fb = RID();
color_fb = RID();
+ depth_fb = RID();
if (normal_buffer.is_valid()) {
RD::get_singleton()->free(normal_buffer);
+ if (normal_buffer_msaa.is_valid()) {
+ RD::get_singleton()->free(normal_buffer_msaa);
+ normal_buffer_msaa = RID();
+ }
normal_buffer = RID();
depth_normal_fb = RID();
}
if (roughness_buffer.is_valid()) {
RD::get_singleton()->free(roughness_buffer);
+ if (roughness_buffer_msaa.is_valid()) {
+ RD::get_singleton()->free(roughness_buffer_msaa);
+ roughness_buffer_msaa = RID();
+ }
roughness_buffer = RID();
depth_normal_roughness_fb = RID();
}
@@ -581,24 +680,69 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() {
void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
clear();
+ msaa = p_msaa;
+
width = p_width;
height = p_height;
color = p_color_buffer;
depth = p_depth_buffer;
- {
- Vector<RID> fb;
- fb.push_back(p_color_buffer);
- fb.push_back(depth);
+ if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) {
- color_fb = RD::get_singleton()->framebuffer_create(fb);
- }
- {
- Vector<RID> fb;
- fb.push_back(depth);
+ {
+ Vector<RID> fb;
+ fb.push_back(p_color_buffer);
+ fb.push_back(depth);
+
+ color_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
+ {
+ Vector<RID> fb;
+ fb.push_back(depth);
+
+ depth_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
+ } else {
- depth_fb = RD::get_singleton()->framebuffer_create(fb);
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.width = p_width;
+ tf.height = p_height;
+ tf.type = RD::TEXTURE_TYPE_2D;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+
+ RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = {
+ RD::TEXTURE_SAMPLES_1,
+ RD::TEXTURE_SAMPLES_2,
+ RD::TEXTURE_SAMPLES_4,
+ RD::TEXTURE_SAMPLES_8,
+ RD::TEXTURE_SAMPLES_16
+ };
+
+ texture_samples = ts[p_msaa];
+ tf.samples = texture_samples;
+
+ color_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
+ tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+
+ depth_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ {
+ Vector<RID> fb;
+ fb.push_back(color_msaa);
+ fb.push_back(depth_msaa);
+
+ color_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
+ {
+ Vector<RID> fb;
+ fb.push_back(depth_msaa);
+
+ depth_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
}
}
@@ -611,13 +755,31 @@ void RasterizerSceneHighEndRD::_allocate_normal_texture(RenderBufferDataHighEnd
tf.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
tf.width = rb->width;
tf.height = rb->height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
+
+ if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ } else {
+ tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ }
rb->normal_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
- Vector<RID> fb;
- fb.push_back(rb->depth);
- fb.push_back(rb->normal_buffer);
- rb->depth_normal_fb = RD::get_singleton()->framebuffer_create(fb);
+
+ if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) {
+ Vector<RID> fb;
+ fb.push_back(rb->depth);
+ fb.push_back(rb->normal_buffer);
+ rb->depth_normal_fb = RD::get_singleton()->framebuffer_create(fb);
+ } else {
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ tf.samples = rb->texture_samples;
+ rb->normal_buffer_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ Vector<RID> fb;
+ fb.push_back(rb->depth_msaa);
+ fb.push_back(rb->normal_buffer_msaa);
+ rb->depth_normal_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
_render_buffers_clear_uniform_set(rb);
}
@@ -636,12 +798,32 @@ void RasterizerSceneHighEndRD::_allocate_roughness_texture(RenderBufferDataHighE
tf.height = rb->height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ } else {
+ tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ }
+
rb->roughness_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
- Vector<RID> fb;
- fb.push_back(rb->depth);
- fb.push_back(rb->normal_buffer);
- fb.push_back(rb->roughness_buffer);
- rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb);
+
+ if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) {
+
+ Vector<RID> fb;
+ fb.push_back(rb->depth);
+ fb.push_back(rb->normal_buffer);
+ fb.push_back(rb->roughness_buffer);
+ rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb);
+ } else {
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ tf.samples = rb->texture_samples;
+ rb->roughness_buffer_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ Vector<RID> fb;
+ fb.push_back(rb->depth_msaa);
+ fb.push_back(rb->normal_buffer_msaa);
+ fb.push_back(rb->roughness_buffer_msaa);
+ rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb);
+ }
_render_buffers_clear_uniform_set(rb);
}
@@ -667,6 +849,7 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements,
store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform);
id.flags = 0;
id.mask = e->instance->layer_mask;
+ id.instance_uniforms_ofs = e->instance->instance_allocated_shader_parameters_offset >= 0 ? e->instance->instance_allocated_shader_parameters_offset : 0;
if (e->instance->base_type == RS::INSTANCE_MULTIMESH) {
id.flags |= INSTANCE_DATA_FLAG_MULTIMESH;
@@ -944,7 +1127,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
}
}
-void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers) {
+void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) {
//CameraMatrix projection = p_cam_projection;
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
@@ -961,6 +1144,18 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
scene_state.ubo.z_far = p_zfar;
scene_state.ubo.z_near = p_znear;
+ scene_state.ubo.pancake_shadows = p_pancake_shadows;
+
+ store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
+ store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
+ store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
+ store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
+
+ scene_state.ubo.directional_penumbra_shadow_samples = directional_penumbra_shadow_samples_get();
+ scene_state.ubo.directional_soft_shadow_samples = directional_soft_shadow_samples_get();
+ scene_state.ubo.penumbra_shadow_samples = penumbra_shadow_samples_get();
+ scene_state.ubo.soft_shadow_samples = soft_shadow_samples_get();
+
scene_state.ubo.screen_pixel_size[0] = p_screen_pixel_size.x;
scene_state.ubo.screen_pixel_size[1] = p_screen_pixel_size.y;
@@ -991,7 +1186,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
} else if (is_environment(p_environment)) {
RS::EnvironmentBG env_bg = environment_get_background(p_environment);
- RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_light_ambient_source(p_environment);
+ RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment);
float bg_energy = environment_get_bg_energy(p_environment);
scene_state.ubo.ambient_light_color_energy[3] = bg_energy;
@@ -1011,7 +1206,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
scene_state.ubo.use_ambient_cubemap = false;
} else {
- float energy = environment_get_ambient_light_ambient_energy(p_environment);
+ float energy = environment_get_ambient_light_energy(p_environment);
Color color = environment_get_ambient_light_color(p_environment);
color = color.to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
@@ -1353,7 +1548,7 @@ void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_r
Color ambient_linear = storage->reflection_probe_get_interior_ambient(base_probe).to_linear();
if (is_environment(p_environment)) {
Color env_ambient_color = environment_get_ambient_light_color(p_environment).to_linear();
- float env_ambient_energy = environment_get_ambient_light_ambient_energy(p_environment);
+ float env_ambient_energy = environment_get_ambient_light_energy(p_environment);
ambient_linear = env_ambient_color;
ambient_linear.r *= env_ambient_energy;
ambient_linear.g *= env_ambient_energy;
@@ -1479,11 +1674,49 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
light_data.specular = storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR);
light_data.mask = storage->light_get_cull_mask(base);
+ float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+
+ light_data.size = 1.0 - Math::cos(Math::deg2rad(size)); //angle to cosine offset
+
Color shadow_col = storage->light_get_shadow_color(base).to_linear();
- light_data.shadow_color[0] = shadow_col.r;
- light_data.shadow_color[1] = shadow_col.g;
- light_data.shadow_color[2] = shadow_col.b;
+ if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS) {
+ light_data.shadow_color1[0] = 1.0;
+ light_data.shadow_color1[1] = 0.0;
+ light_data.shadow_color1[2] = 0.0;
+ light_data.shadow_color1[3] = 1.0;
+ light_data.shadow_color2[0] = 0.0;
+ light_data.shadow_color2[1] = 1.0;
+ light_data.shadow_color2[2] = 0.0;
+ light_data.shadow_color2[3] = 1.0;
+ light_data.shadow_color3[0] = 0.0;
+ light_data.shadow_color3[1] = 0.0;
+ light_data.shadow_color3[2] = 1.0;
+ light_data.shadow_color3[3] = 1.0;
+ light_data.shadow_color4[0] = 1.0;
+ light_data.shadow_color4[1] = 1.0;
+ light_data.shadow_color4[2] = 0.0;
+ light_data.shadow_color4[3] = 1.0;
+
+ } else {
+
+ light_data.shadow_color1[0] = shadow_col.r;
+ light_data.shadow_color1[1] = shadow_col.g;
+ light_data.shadow_color1[2] = shadow_col.b;
+ light_data.shadow_color1[3] = 1.0;
+ light_data.shadow_color2[0] = shadow_col.r;
+ light_data.shadow_color2[1] = shadow_col.g;
+ light_data.shadow_color2[2] = shadow_col.b;
+ light_data.shadow_color2[3] = 1.0;
+ light_data.shadow_color3[0] = shadow_col.r;
+ light_data.shadow_color3[1] = shadow_col.g;
+ light_data.shadow_color3[2] = shadow_col.b;
+ light_data.shadow_color3[3] = 1.0;
+ light_data.shadow_color4[0] = shadow_col.r;
+ light_data.shadow_color4[1] = shadow_col.g;
+ light_data.shadow_color4[2] = shadow_col.b;
+ light_data.shadow_color4[3] = 1.0;
+ }
light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base);
@@ -1507,12 +1740,52 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
CameraMatrix shadow_mtx = rectm * bias * matrix * modelview;
light_data.shadow_split_offsets[j] = split;
+ float bias_scale = light_instance_get_shadow_bias_scale(li, j);
+ light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_scale;
+ light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * light_instance_get_directional_shadow_texel_size(li, j);
+ light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale;
+ light_data.shadow_transmittance_z_scale[j] = light_instance_get_shadow_range(li, j);
+ light_data.shadow_range_begin[j] = light_instance_get_shadow_range_begin(li, j);
store_camera(shadow_mtx, light_data.shadow_matrices[j]);
+
+ Vector2 uv_scale = light_instance_get_shadow_uv_scale(li, j);
+ uv_scale *= atlas_rect.size; //adapt to atlas size
+ switch (j) {
+ case 0: {
+ light_data.uv_scale1[0] = uv_scale.x;
+ light_data.uv_scale1[1] = uv_scale.y;
+ } break;
+ case 1: {
+ light_data.uv_scale2[0] = uv_scale.x;
+ light_data.uv_scale2[1] = uv_scale.y;
+ } break;
+ case 2: {
+ light_data.uv_scale3[0] = uv_scale.x;
+ light_data.uv_scale3[1] = uv_scale.y;
+ } break;
+ case 3: {
+ light_data.uv_scale4[0] = uv_scale.x;
+ light_data.uv_scale4[1] = uv_scale.y;
+ } break;
+ }
}
float fade_start = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START);
light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep
light_data.fade_to = -light_data.shadow_split_offsets[3];
+
+ light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
+
+ float softshadow_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+ if (softshadow_angle > 0.0) {
+ // I know tan(0) is 0, but let's not risk it with numerical precision.
+ // technically this will keep expanding until reaching the sun, but all we care
+ // is expand until we reach the radius of the near plane (there can't be more occluders than that)
+ light_data.softshadow_angle = Math::tan(Math::deg2rad(softshadow_angle));
+ } else {
+ light_data.softshadow_angle = 0;
+ light_data.soft_shadow_scale *= directional_shadow_quality_radius_get(); // Only use quality radius for PCF
+ }
}
// Copy to SkyDirectionalLightData
@@ -1533,6 +1806,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
sky_light_data.color[2] = light_data.color[2];
sky_light_data.enabled = true;
+ sky_light_data.size = light_data.softshadow_angle;
sky_scene_state.directional_light_count++;
}
@@ -1575,51 +1849,114 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
light_data.direction[1] = direction.y;
light_data.direction[2] = direction.z;
+ float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+
+ light_data.size = size;
+
light_data.cone_attenuation_angle[0] = Math::make_half_float(storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION));
float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE);
light_data.cone_attenuation_angle[1] = Math::make_half_float(Math::cos(Math::deg2rad(spot_angle)));
light_data.mask = storage->light_get_cull_mask(base);
- Color shadow_color = storage->light_get_shadow_color(base);
-
- bool has_shadow = p_using_shadows && storage->light_has_shadow(base);
- light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255);
- light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255);
- light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255);
- light_data.shadow_color_enabled[3] = has_shadow ? 255 : 0;
-
light_data.atlas_rect[0] = 0;
light_data.atlas_rect[1] = 0;
light_data.atlas_rect[2] = 0;
light_data.atlas_rect[3] = 0;
+ RID projector = storage->light_get_projector(base);
+
+ if (projector.is_valid()) {
+ Rect2 rect = storage->decal_atlas_get_texture_rect(projector);
+
+ if (type == RS::LIGHT_SPOT) {
+
+ light_data.projector_rect[0] = rect.position.x;
+ light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped
+ light_data.projector_rect[2] = rect.size.width;
+ light_data.projector_rect[3] = -rect.size.height;
+ } else {
+ light_data.projector_rect[0] = rect.position.x;
+ light_data.projector_rect[1] = rect.position.y;
+ light_data.projector_rect[2] = rect.size.width;
+ light_data.projector_rect[3] = rect.size.height * 0.5; //used by dp, so needs to be half
+ }
+ } else {
+ light_data.projector_rect[0] = 0;
+ light_data.projector_rect[1] = 0;
+ light_data.projector_rect[2] = 0;
+ light_data.projector_rect[3] = 0;
+ }
+
if (p_using_shadows && p_shadow_atlas.is_valid() && shadow_atlas_owns_light_instance(p_shadow_atlas, li)) {
// fill in the shadow information
+ Color shadow_color = storage->light_get_shadow_color(base);
+
+ light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255);
+ light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255);
+ light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255);
+ light_data.shadow_color_enabled[3] = 255;
+
+ if (type == RS::LIGHT_SPOT) {
+ light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0);
+ float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0;
+ shadow_texel_size *= light_instance_get_shadow_texel_size(li, p_shadow_atlas);
+
+ light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size;
+
+ } else { //omni
+ light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0;
+ float shadow_texel_size = light_instance_get_shadow_texel_size(li, p_shadow_atlas);
+ light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space
+ }
+
+ light_data.transmittance_bias = storage->light_get_transmittance_bias(base);
+
Rect2 rect = light_instance_get_shadow_atlas_rect(li, p_shadow_atlas);
- if (type == RS::LIGHT_OMNI) {
+ light_data.atlas_rect[0] = rect.position.x;
+ light_data.atlas_rect[1] = rect.position.y;
+ light_data.atlas_rect[2] = rect.size.width;
+ light_data.atlas_rect[3] = rect.size.height;
+
+ light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
- light_data.atlas_rect[0] = rect.position.x;
- light_data.atlas_rect[1] = rect.position.y;
- light_data.atlas_rect[2] = rect.size.width;
- light_data.atlas_rect[3] = rect.size.height * 0.5;
+ if (type == RS::LIGHT_OMNI) {
+ light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another
Transform proj = (p_camera_inverse_transform * light_transform).inverse();
store_transform(proj, light_data.shadow_matrix);
+
+ if (size > 0.0) {
+
+ light_data.soft_shadow_size = size;
+ } else {
+ light_data.soft_shadow_size = 0.0;
+ light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF
+ }
+
} else if (type == RS::LIGHT_SPOT) {
Transform modelview = (p_camera_inverse_transform * light_transform).inverse();
CameraMatrix bias;
bias.set_light_bias();
- CameraMatrix rectm;
- rectm.set_light_atlas_rect(rect);
- CameraMatrix shadow_mtx = rectm * bias * light_instance_get_shadow_camera(li, 0) * modelview;
+ CameraMatrix shadow_mtx = bias * light_instance_get_shadow_camera(li, 0) * modelview;
store_camera(shadow_mtx, light_data.shadow_matrix);
+
+ if (size > 0.0) {
+ CameraMatrix cm = light_instance_get_shadow_camera(li, 0);
+ float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle));
+ light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width;
+ } else {
+ light_data.soft_shadow_size = 0.0;
+ light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF
+ }
}
+ } else {
+ light_data.shadow_color_enabled[3] = 0;
}
light_instance_set_index(li, light_count);
@@ -1644,7 +1981,140 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
}
}
-void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) {
+void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) {
+
+ Transform uv_xform;
+ uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
+ uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
+
+ p_decal_count = MIN((uint32_t)p_decal_count, scene_state.max_decals);
+ int idx = 0;
+ for (int i = 0; i < p_decal_count; i++) {
+
+ RID di = p_decal_instances[i];
+ RID decal = decal_instance_get_base(di);
+
+ Transform xform = decal_instance_get_transform(di);
+
+ float fade = 1.0;
+
+ if (storage->decal_is_distance_fade_enabled(decal)) {
+ real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
+ float fade_begin = storage->decal_get_distance_fade_begin(decal);
+ float fade_length = storage->decal_get_distance_fade_length(decal);
+
+ if (distance > fade_begin) {
+ if (distance > fade_begin + fade_length) {
+ continue; // do not use this decal, its invisible
+ }
+
+ fade = 1.0 - (distance - fade_begin) / fade_length;
+ }
+ }
+
+ DecalData &dd = scene_state.decals[idx];
+
+ Vector3 decal_extents = storage->decal_get_extents(decal);
+
+ Transform scale_xform;
+ scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z));
+ Transform to_decal_xform = (p_camera_inverse_xform * decal_instance_get_transform(di) * scale_xform * uv_xform).affine_inverse();
+ store_transform(to_decal_xform, dd.xform);
+
+ Vector3 normal = xform.basis.get_axis(Vector3::AXIS_Y).normalized();
+ normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine
+
+ dd.normal[0] = normal.x;
+ dd.normal[1] = normal.y;
+ dd.normal[2] = normal.z;
+ dd.normal_fade = storage->decal_get_normal_fade(decal);
+
+ RID albedo_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
+ RID emission_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
+ if (albedo_tex.is_valid()) {
+ Rect2 rect = storage->decal_atlas_get_texture_rect(albedo_tex);
+ dd.albedo_rect[0] = rect.position.x;
+ dd.albedo_rect[1] = rect.position.y;
+ dd.albedo_rect[2] = rect.size.x;
+ dd.albedo_rect[3] = rect.size.y;
+ } else {
+
+ if (!emission_tex.is_valid()) {
+ continue; //no albedo, no emission, no decal.
+ }
+ dd.albedo_rect[0] = 0;
+ dd.albedo_rect[1] = 0;
+ dd.albedo_rect[2] = 0;
+ dd.albedo_rect[3] = 0;
+ }
+
+ RID normal_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
+
+ if (normal_tex.is_valid()) {
+ Rect2 rect = storage->decal_atlas_get_texture_rect(normal_tex);
+ dd.normal_rect[0] = rect.position.x;
+ dd.normal_rect[1] = rect.position.y;
+ dd.normal_rect[2] = rect.size.x;
+ dd.normal_rect[3] = rect.size.y;
+
+ Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized();
+ store_basis_3x4(normal_xform, dd.normal_xform);
+ } else {
+ dd.normal_rect[0] = 0;
+ dd.normal_rect[1] = 0;
+ dd.normal_rect[2] = 0;
+ dd.normal_rect[3] = 0;
+ }
+
+ RID orm_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
+ if (orm_tex.is_valid()) {
+ Rect2 rect = storage->decal_atlas_get_texture_rect(orm_tex);
+ dd.orm_rect[0] = rect.position.x;
+ dd.orm_rect[1] = rect.position.y;
+ dd.orm_rect[2] = rect.size.x;
+ dd.orm_rect[3] = rect.size.y;
+ } else {
+ dd.orm_rect[0] = 0;
+ dd.orm_rect[1] = 0;
+ dd.orm_rect[2] = 0;
+ dd.orm_rect[3] = 0;
+ }
+
+ if (emission_tex.is_valid()) {
+ Rect2 rect = storage->decal_atlas_get_texture_rect(emission_tex);
+ dd.emission_rect[0] = rect.position.x;
+ dd.emission_rect[1] = rect.position.y;
+ dd.emission_rect[2] = rect.size.x;
+ dd.emission_rect[3] = rect.size.y;
+ } else {
+ dd.emission_rect[0] = 0;
+ dd.emission_rect[1] = 0;
+ dd.emission_rect[2] = 0;
+ dd.emission_rect[3] = 0;
+ }
+
+ Color modulate = storage->decal_get_modulate(decal);
+ dd.modulate[0] = modulate.r;
+ dd.modulate[1] = modulate.g;
+ dd.modulate[2] = modulate.b;
+ dd.modulate[3] = modulate.a * fade;
+ dd.emission_energy = storage->decal_get_emission_energy(decal) * fade;
+ dd.albedo_mix = storage->decal_get_albedo_mix(decal);
+ dd.mask = storage->decal_get_cull_mask(decal);
+ dd.upper_fade = storage->decal_get_upper_fade(decal);
+ dd.lower_fade = storage->decal_get_lower_fade(decal);
+
+ cluster_builder.add_decal(xform, decal_extents);
+
+ idx++;
+ }
+
+ if (idx > 0) {
+ RD::get_singleton()->buffer_update(scene_state.decal_buffer, 0, sizeof(DecalData) * idx, scene_state.decals, true);
+ }
+}
+
+void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) {
RenderBufferDataHighEnd *render_buffer = nullptr;
if (p_render_buffer.is_valid()) {
@@ -1655,27 +2125,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
render_pass++;
//fill up ubo
-#if 0
- storage->info.render.object_count += p_cull_count;
-
- Environment *env = environment_owner.getornull(p_environment);
- ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
- ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_reflection_atlas);
-
- if (shadow_atlas && shadow_atlas->size) {
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
- glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
- scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / shadow_atlas->size;
- scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / shadow_atlas->size;
- }
-
- if (reflection_atlas && reflection_atlas->size) {
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
- glBindTexture(GL_TEXTURE_2D, reflection_atlas->color);
- }
-#endif
RENDER_TIMESTAMP("Setup 3D Scene");
@@ -1698,9 +2147,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
//scene_state.ubo.subsurface_scatter_width = subsurface_scatter_size;
- scene_state.ubo.shadow_z_offset = 0;
- scene_state.ubo.shadow_z_slope_scale = 0;
-
Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
scene_state.ubo.viewport_size[0] = vp_he.x;
scene_state.ubo.viewport_size[1] = vp_he.y;
@@ -1718,6 +2164,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
bool using_ssr = false;
if (render_buffer) {
+
screen_pixel_size.width = 1.0 / render_buffer->width;
screen_pixel_size.height = 1.0 / render_buffer->height;
screen_size.x = render_buffer->width;
@@ -1784,6 +2231,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
cluster_builder.begin(p_cam_transform.affine_inverse(), p_cam_projection); //prepare cluster
_setup_lights(p_light_cull_result, p_light_cull_count, p_cam_transform.affine_inverse(), p_shadow_atlas, using_shadows);
+ _setup_decals(p_decal_cull_result, p_decal_cull_count, p_cam_transform.affine_inverse());
_setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_environment);
_setup_gi_probes(p_gi_probe_cull_result, p_gi_probe_cull_count, p_cam_transform);
_setup_environment(p_environment, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
@@ -1828,23 +2276,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
clear_color.b *= bg_energy;
} break;
case RS::ENV_BG_SKY: {
- RID sky = environment_get_sky(p_environment);
- if (sky.is_valid()) {
-
- RENDER_TIMESTAMP("Setup Sky");
- CameraMatrix projection = p_cam_projection;
- if (p_reflection_probe.is_valid()) {
- CameraMatrix correction;
- correction.set_depth_correction(true);
- projection = correction * p_cam_projection;
- }
-
- _setup_sky(p_environment, p_cam_transform.origin, screen_size);
- _update_sky(p_environment, projection, p_cam_transform);
- radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET);
-
- draw_sky = true;
- }
+ draw_sky = true;
} break;
case RS::ENV_BG_CANVAS: {
keep_color = true;
@@ -1858,6 +2290,27 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
default: {
}
}
+ // setup sky if used for ambient, reflections, or background
+ if (draw_sky || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
+ RID sky = environment_get_sky(p_environment);
+ if (sky.is_valid()) {
+
+ RENDER_TIMESTAMP("Setup Sky");
+ CameraMatrix projection = p_cam_projection;
+ if (p_reflection_probe.is_valid()) {
+ CameraMatrix correction;
+ correction.set_depth_correction(true);
+ projection = correction * p_cam_projection;
+ }
+
+ _setup_sky(p_environment, p_cam_transform.origin, screen_size);
+ _update_sky(p_environment, projection, p_cam_transform);
+ radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET);
+ } else {
+ // do not try to draw sky if invalid
+ draw_sky = false;
+ }
+ }
} else {
clear_color = p_default_bg_color;
@@ -1879,9 +2332,23 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
if (depth_pre_pass) { //depth pre pass
RENDER_TIMESTAMP("Render Depth Pre-Pass");
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, using_ssao ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
+ bool finish_depth = using_ssao;
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID());
RD::get_singleton()->draw_list_end();
+
+ if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ if (finish_depth) {
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true);
+ }
+
+ if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS) {
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->normal_buffer_msaa, render_buffer->normal_buffer, true);
+ if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS) {
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->roughness_buffer_msaa, render_buffer->roughness_buffer, true);
+ }
+ }
+ }
}
if (using_ssao) {
@@ -1961,6 +2428,19 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
_draw_sky(can_continue_color, can_continue_depth, opaque_framebuffer, p_environment, projection, p_cam_transform);
}
+ if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true);
+ if (using_separate_specular) {
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular, true);
+ }
+ }
+
+ if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true);
+ }
+
if (using_separate_specular) {
if (using_sss) {
@@ -1970,11 +2450,11 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
if (using_ssr) {
RENDER_TIMESTAMP("Screen Space Reflection");
- _process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_buffer, render_buffer->roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, true);
+ _process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_buffer, render_buffer->roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED);
} else {
//just mix specular back
RENDER_TIMESTAMP("Merge Specular");
- storage->get_effects()->merge_specular(render_buffer->color_fb, render_buffer->specular, RID(), RID());
+ storage->get_effects()->merge_specular(render_buffer->color_fb, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID());
}
}
@@ -1992,78 +2472,13 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
RD::get_singleton()->draw_list_end();
}
- //_render_list
-#if 0
- if (state.directional_light_count == 0) {
- directional_light = nullptr;
- _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, false, shadow_atlas != nullptr);
- } else {
- for (int i = 0; i < state.directional_light_count; i++) {
- directional_light = directional_lights[i];
- _setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != nullptr && shadow_atlas->size > 0);
- _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, i > 0, shadow_atlas != nullptr);
- }
- }
-#endif
-
-#if 0
- _post_process(env, p_cam_projection);
- // Needed only for debugging
- /* if (shadow_atlas && storage->frame.current_rt) {
-
- //_copy_texture_to_front_buffer(shadow_atlas->depth);
- storage->canvas->canvas_begin();
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
- storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1));
- }
-
- if (storage->frame.current_rt) {
+ if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- //_copy_texture_to_front_buffer(shadow_atlas->depth);
- storage->canvas->canvas_begin();
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, exposure_shrink[4].color);
- //glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->exposure.color);
- storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 16, storage->frame.current_rt->height / 16), Rect2(0, 0, 1, 1));
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true);
}
-
- if (reflection_atlas && storage->frame.current_rt) {
-
- //_copy_texture_to_front_buffer(shadow_atlas->depth);
- storage->canvas->canvas_begin();
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, reflection_atlas->color);
- storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1));
- }
-
- if (directional_shadow.fbo) {
-
- //_copy_texture_to_front_buffer(shadow_atlas->depth);
- storage->canvas->canvas_begin();
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
- storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1));
- }
-
- if ( env_radiance_tex) {
-
- //_copy_texture_to_front_buffer(shadow_atlas->depth);
- storage->canvas->canvas_begin();
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, env_radiance_tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }*/
- //disable all stuff
-#endif
}
-void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip) {
+
+void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake) {
RENDER_TIMESTAMP("Setup Rendering Shadow");
@@ -2071,11 +2486,9 @@ void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **
render_pass++;
- scene_state.ubo.shadow_z_offset = p_bias;
- scene_state.ubo.shadow_z_slope_scale = p_normal_bias;
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
- _setup_environment(RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar);
+ _setup_environment(RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar, false, p_use_pancake);
render_list.clear();
@@ -2106,8 +2519,6 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform
render_pass++;
- scene_state.ubo.shadow_z_offset = 0;
- scene_state.ubo.shadow_z_slope_scale = 0;
scene_state.ubo.dual_paraboloid_side = 0;
_setup_environment(RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
@@ -2204,7 +2615,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 5;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(scene_state.light_buffer);
uniforms.push_back(u);
}
@@ -2267,17 +2678,40 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
uniforms.push_back(u);
}
-
{
RD::Uniform u;
u.binding = 10;
u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(cluster_builder.get_cluster_texture());
+ RID decal_atlas = storage->decal_atlas_get_texture();
+ u.ids.push_back(decal_atlas);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 11;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ RID decal_atlas = storage->decal_atlas_get_texture_srgb();
+ u.ids.push_back(decal_atlas);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 12;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(scene_state.decal_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.binding = 13;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(cluster_builder.get_cluster_texture());
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 14;
u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(cluster_builder.get_cluster_indices_buffer());
uniforms.push_back(u);
@@ -2285,7 +2719,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
- u.binding = 12;
+ u.binding = 15;
u.type = RD::UNIFORM_TYPE_TEXTURE;
if (directional_shadow_get_texture().is_valid()) {
u.ids.push_back(directional_shadow_get_texture());
@@ -2295,6 +2729,14 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 16;
+ u.ids.push_back(storage->global_variables_get_storage_buffer());
+ uniforms.push_back(u);
+ }
+
render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, SCENE_UNIFORM_SET);
}
}
@@ -2463,11 +2905,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
}
{ //lights
- scene_state.max_lights = MIN(65536, uniform_max_size) / sizeof(LightData);
+ scene_state.max_lights = MIN(1024 * 1024, uniform_max_size) / sizeof(LightData); //1mb of lights
uint32_t light_buffer_size = scene_state.max_lights * sizeof(LightData);
scene_state.lights = memnew_arr(LightData, scene_state.max_lights);
- scene_state.light_buffer = RD::get_singleton()->uniform_buffer_create(light_buffer_size);
- defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(scene_state.max_lights) + "\n";
+ scene_state.light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size);
+ //defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(scene_state.max_lights) + "\n";
scene_state.max_directional_lights = 8;
uint32_t directional_light_buffer_size = scene_state.max_directional_lights * sizeof(DirectionalLightData);
@@ -2506,6 +2948,13 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
defines += "\n#define MAX_GI_PROBES " + itos(scene_state.max_gi_probes) + "\n";
}
+ { //decals
+ scene_state.max_decals = MIN(1024 * 1024, uniform_max_size) / sizeof(DecalData); //1mb of decals
+ uint32_t decal_buffer_size = scene_state.max_decals * sizeof(DecalData);
+ scene_state.decals = memnew_arr(DecalData, scene_state.max_decals);
+ scene_state.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size);
+ }
+
Vector<String> shader_versions;
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n");
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n");
@@ -2569,7 +3018,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.renames["ANISOTROPY"] = "anisotropy";
actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow";
actions.renames["SSS_STRENGTH"] = "sss_strength";
- actions.renames["TRANSMISSION"] = "transmission";
+ actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
+ actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
+ actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
+ actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
+ actions.renames["BACKLIGHT"] = "backlight";
actions.renames["AO"] = "ao";
actions.renames["AO_LIGHT_AFFECT"] = "ao_light_affect";
actions.renames["EMISSION"] = "emission";
@@ -2609,7 +3062,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
- actions.usage_defines["TRANSMISSION"] = "#define LIGHT_TRANSMISSION_USED\n";
+ actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n";
+ actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n";
actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
@@ -2659,6 +3113,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+ actions.global_buffer_array_variable = "global_variables.data";
+ actions.instance_uniform_index_variable = "instances.data[instance_index].instance_uniforms_ofs";
shader.compiler.initialize(actions);
}
@@ -2780,10 +3236,12 @@ RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() {
RD::get_singleton()->free(scene_state.directional_light_buffer);
RD::get_singleton()->free(scene_state.light_buffer);
RD::get_singleton()->free(scene_state.reflection_buffer);
+ RD::get_singleton()->free(scene_state.decal_buffer);
memdelete_arr(scene_state.instances);
memdelete_arr(scene_state.gi_probes);
memdelete_arr(scene_state.directional_lights);
memdelete_arr(scene_state.lights);
memdelete_arr(scene_state.reflections);
+ memdelete_arr(scene_state.decals);
}
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
index e79bf2b378..a48e2e2259 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
@@ -138,6 +138,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
bool unshaded;
bool uses_vertex;
bool uses_sss;
+ bool uses_transmittance;
bool uses_screen_texture;
bool uses_depth_texture;
bool uses_normal_texture;
@@ -151,6 +152,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const;
+
virtual bool is_param_texture(const StringName &p_param) const;
virtual bool is_animated() const;
virtual bool casts_shadows() const;
@@ -197,11 +200,22 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
struct RenderBufferDataHighEnd : public RenderBufferData {
//for rendering, may be MSAAd
+
RID color;
RID depth;
RID specular;
RID normal_buffer;
RID roughness_buffer;
+
+ RS::ViewportMSAA msaa;
+ RD::TextureSamples texture_samples;
+
+ RID color_msaa;
+ RID depth_msaa;
+ RID specular_msaa;
+ RID normal_buffer_msaa;
+ RID roughness_buffer_msaa;
+
RID depth_fb;
RID depth_normal_fb;
RID depth_normal_roughness_fb;
@@ -253,13 +267,21 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
float position[3];
float inv_radius;
float direction[3];
+ float size;
uint16_t attenuation_energy[2]; //16 bits attenuation, then energy
uint8_t color_specular[4]; //rgb color, a specular (8 bit unorm)
uint16_t cone_attenuation_angle[2]; // attenuation and angle, (16bit float)
- uint32_t mask;
uint8_t shadow_color_enabled[4]; //shadow rgb color, a>0.5 enabled (8bit unorm)
float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv
float shadow_matrix[16];
+ float shadow_bias;
+ float shadow_normal_bias;
+ float transmittance_bias;
+ float soft_shadow_size;
+ float soft_shadow_scale;
+ uint32_t mask;
+ uint32_t pad[2];
+ float projector_rect[4];
};
struct DirectionalLightData {
@@ -267,15 +289,30 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
float direction[3];
float energy;
float color[3];
+ float size;
float specular;
- float shadow_color[3];
uint32_t mask;
+ float softshadow_angle;
+ float soft_shadow_scale;
uint32_t blend_splits;
uint32_t shadow_enabled;
float fade_from;
float fade_to;
+ float shadow_bias[4];
+ float shadow_normal_bias[4];
+ float shadow_transmittance_bias[4];
+ float shadow_transmittance_z_scale[4];
+ float shadow_range_begin[4];
float shadow_split_offsets[4];
float shadow_matrices[4][16];
+ float shadow_color1[4];
+ float shadow_color2[4];
+ float shadow_color3[4];
+ float shadow_color4[4];
+ float uv_scale1[2];
+ float uv_scale2[2];
+ float uv_scale3[2];
+ float uv_scale4[2];
};
struct GIProbeData {
@@ -294,6 +331,24 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
uint32_t pad[1];
};
+ struct DecalData {
+ float xform[16];
+ float inv_extents[3];
+ float albedo_mix;
+ float albedo_rect[4];
+ float normal_rect[4];
+ float orm_rect[4];
+ float emission_rect[4];
+ float modulate[4];
+ float emission_energy;
+ uint32_t mask;
+ float upper_fade;
+ float lower_fade;
+ float normal_xform[12];
+ float normal[3];
+ float normal_fade;
+ };
+
enum {
INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
@@ -308,7 +363,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
float transform[16];
float normal_transform[16];
uint32_t flags;
- uint32_t instance_ofs; //instance_offset in instancing/skeleton buffer
+ uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer
uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap)
uint32_t mask;
};
@@ -324,12 +379,22 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
float viewport_size[2];
float screen_pixel_size[2];
- float shadow_z_offset;
- float shadow_z_slope_scale;
-
float time;
float reflection_multiplier;
+ uint32_t pancake_shadows;
+ uint32_t pad;
+
+ float directional_penumbra_shadow_kernel[128]; //32 vec4s
+ float directional_soft_shadow_kernel[128];
+ float penumbra_shadow_kernel[128];
+ float soft_shadow_kernel[128];
+
+ uint32_t directional_penumbra_shadow_samples;
+ uint32_t directional_soft_shadow_samples;
+ uint32_t penumbra_shadow_samples;
+ uint32_t soft_shadow_samples;
+
float ambient_light_color_energy[4];
float ambient_color_sky_mix;
@@ -369,6 +434,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
RID gi_probe_buffer;
uint32_t max_gi_probe_probes_per_instance;
+ DecalData *decals;
+ uint32_t max_decals;
+ RID decal_buffer;
+
LightData *lights;
uint32_t max_lights;
RID light_buffer;
@@ -558,8 +627,9 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
PASS_MODE_DEPTH_MATERIAL,
};
- void _setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false);
+ void _setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false);
void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows);
+ void _setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform);
void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment);
void _setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform);
@@ -571,8 +641,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi);
protected:
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color);
- virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip);
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color);
+ virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake);
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
public:
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
index e4c5f1c984..8877de87ac 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -36,6 +36,18 @@
uint64_t RasterizerSceneRD::auto_exposure_counter = 2;
+void get_vogel_disk(float *r_kernel, int p_sample_count) {
+ const float golden_angle = 2.4;
+
+ for (int i = 0; i < p_sample_count; i++) {
+ float r = Math::sqrt(float(i) + 0.5) / Math::sqrt(float(p_sample_count));
+ float theta = float(i) * golden_angle;
+
+ r_kernel[i * 4] = Math::cos(theta) * r;
+ r_kernel[i * 4 + 1] = Math::sin(theta) * r;
+ }
+}
+
void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) {
rd.layers.clear();
@@ -181,10 +193,9 @@ void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd) {
for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) {
for (int k = 0; k < 6; k++) {
RID view = rd.layers[i].mipmaps[j].views[k];
- RID fb = rd.layers[i].mipmaps[j + 1].framebuffers[k];
- Vector2 size = rd.layers[i].mipmaps[j].size;
- size = Vector2(1.0 / size.x, 1.0 / size.y);
- storage->get_effects()->make_mipmap(view, fb, size);
+ RID texture = rd.layers[i].mipmaps[j + 1].views[k];
+ Size2i size = rd.layers[i].mipmaps[j + 1].size;
+ storage->get_effects()->make_mipmap(view, texture, size);
}
}
}
@@ -644,7 +655,8 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position,
sky_scene_state.directional_lights[i].color[0] != sky_scene_state.last_frame_directional_lights[i].color[0] ||
sky_scene_state.directional_lights[i].color[1] != sky_scene_state.last_frame_directional_lights[i].color[1] ||
sky_scene_state.directional_lights[i].color[2] != sky_scene_state.last_frame_directional_lights[i].color[2] ||
- sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled) {
+ sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled ||
+ sky_scene_state.directional_lights[i].size != sky_scene_state.last_frame_directional_lights[i].size) {
light_data_dirty = true;
break;
}
@@ -840,18 +852,22 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) {
actions.usage_flag_pointers["LIGHT0_ENERGY"] = &uses_light;
actions.usage_flag_pointers["LIGHT0_DIRECTION"] = &uses_light;
actions.usage_flag_pointers["LIGHT0_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_SIZE"] = &uses_light;
actions.usage_flag_pointers["LIGHT1_ENABLED"] = &uses_light;
actions.usage_flag_pointers["LIGHT1_ENERGY"] = &uses_light;
actions.usage_flag_pointers["LIGHT1_DIRECTION"] = &uses_light;
actions.usage_flag_pointers["LIGHT1_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_SIZE"] = &uses_light;
actions.usage_flag_pointers["LIGHT2_ENABLED"] = &uses_light;
actions.usage_flag_pointers["LIGHT2_ENERGY"] = &uses_light;
actions.usage_flag_pointers["LIGHT2_DIRECTION"] = &uses_light;
actions.usage_flag_pointers["LIGHT2_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_SIZE"] = &uses_light;
actions.usage_flag_pointers["LIGHT3_ENABLED"] = &uses_light;
actions.usage_flag_pointers["LIGHT3_ENERGY"] = &uses_light;
actions.usage_flag_pointers["LIGHT3_DIRECTION"] = &uses_light;
actions.usage_flag_pointers["LIGHT3_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_SIZE"] = &uses_light;
actions.uniforms = &uniforms;
@@ -915,6 +931,10 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
if (E->get().texture_order >= 0) {
order[E->get().texture_order + 100000] = E->key();
} else {
@@ -930,6 +950,23 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para
}
}
+void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ RasterizerStorage::InstanceShaderParam p;
+ p.info = ShaderLanguage::uniform_to_property_info(E->get());
+ p.info.name = E->key(); //supply name
+ p.index = E->get().instance_index;
+ p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint);
+ p_param_list->push_back(p);
+ }
+}
+
bool RasterizerSceneRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
@@ -1168,12 +1205,12 @@ Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const {
ERR_FAIL_COND_V(!env, Color());
return env->ambient_light;
}
-RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_light_ambient_source(RID p_env) const {
+RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_source(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG);
return env->ambient_source;
}
-float RasterizerSceneRD::environment_get_ambient_light_ambient_energy(RID p_env) const {
+float RasterizerSceneRD::environment_get_ambient_light_energy(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_light_energy;
@@ -1599,7 +1636,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
if (shadow_atlas->depth.is_valid()) {
RD::get_singleton()->free(shadow_atlas->depth);
shadow_atlas->depth = RID();
- shadow_atlas->fb = RID();
}
for (int i = 0; i < 4; i++) {
//clear subdivisions
@@ -1625,13 +1661,9 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
tf.width = shadow_atlas->size;
tf.height = shadow_atlas->size;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- Vector<RID> fb;
- fb.push_back(shadow_atlas->depth);
- shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb);
}
}
@@ -1901,7 +1933,6 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
if (directional_shadow.depth.is_valid()) {
RD::get_singleton()->free(directional_shadow.depth);
directional_shadow.depth = RID();
- directional_shadow.fb = RID();
}
if (p_size > 0) {
@@ -1910,12 +1941,9 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
tf.width = p_size;
tf.height = p_size;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
- Vector<RID> fb;
- fb.push_back(directional_shadow.depth);
- directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb);
}
_base_uniforms_changed();
@@ -2032,7 +2060,7 @@ void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const
light_instance->transform = p_transform;
}
-void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale) {
+void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -2048,6 +2076,9 @@ void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance
light_instance->shadow_transform[p_pass].farplane = p_far;
light_instance->shadow_transform[p_pass].split = p_split;
light_instance->shadow_transform[p_pass].bias_scale = p_bias_scale;
+ light_instance->shadow_transform[p_pass].range_begin = p_range_begin;
+ light_instance->shadow_transform[p_pass].shadow_texel_size = p_shadow_texel_size;
+ light_instance->shadow_transform[p_pass].uv_scale = p_uv_scale;
}
void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) {
@@ -2111,6 +2142,21 @@ RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p
return &shadow_maps[p_size];
}
+
+//////////////////////////
+
+RID RasterizerSceneRD::decal_instance_create(RID p_decal) {
+ DecalInstance di;
+ di.decal = p_decal;
+ return decal_instance_owner.make_rid(di);
+}
+
+void RasterizerSceneRD::decal_instance_set_transform(RID p_decal, const Transform &p_transform) {
+ DecalInstance *di = decal_instance_owner.getornull(p_decal);
+ ERR_FAIL_COND(!di);
+ di->transform = p_transform;
+}
+
/////////////////////////////////
RID RasterizerSceneRD::gi_probe_instance_create(RID p_base) {
@@ -3059,7 +3105,7 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
tf.width = rb->width;
tf.height = rb->height;
tf.type = RD::TEXTURE_TYPE_2D;
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tf.mipmaps = mipmaps_required;
rb->blur[0].texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -3076,11 +3122,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
RenderBuffers::Blur::Mipmap mm;
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[0].texture, 0, i);
- {
- Vector<RID> fbs;
- fbs.push_back(mm.texture);
- mm.framebuffer = RD::get_singleton()->framebuffer_create(fbs);
- }
mm.width = base_width;
mm.height = base_height;
@@ -3090,11 +3131,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
if (i > 0) {
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, 0, i - 1);
- {
- Vector<RID> fbs;
- fbs.push_back(mm.texture);
- mm.framebuffer = RD::get_singleton()->framebuffer_create(fbs);
- }
rb->blur[1].mipmaps.push_back(mm);
}
@@ -3421,9 +3457,9 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
if (env->auto_exposure && rb->luminance.current.is_valid()) {
luminance_texture = rb->luminance.current;
}
- storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].framebuffer, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].framebuffer, Vector2(1.0 / vp_w, 1.0 / vp_h), env->glow_strength, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale);
+ storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale);
} else {
- storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].framebuffer, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].framebuffer, Vector2(1.0 / vp_w, 1.0 / vp_h), env->glow_strength);
+ storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength);
}
}
}
@@ -3456,6 +3492,12 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
tonemap.glow_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
}
+ if (rb->screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) {
+ tonemap.use_fxaa = true;
+ }
+
+ tonemap.texture_size = Vector2i(rb->width, rb->height);
+
if (env) {
tonemap.tonemap_mode = env->tone_mapper;
tonemap.white = env->white;
@@ -3479,7 +3521,7 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
RID shadow_atlas_texture = shadow_atlas_get_texture(p_shadow_atlas);
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 2), false, true);
+ effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
}
}
@@ -3488,7 +3530,17 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
RID shadow_atlas_texture = directional_shadow_get_texture();
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 2), false, true);
+ effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
+ }
+ }
+
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DECAL_ATLAS) {
+ RID decal_atlas = storage->decal_atlas_get_texture();
+
+ if (decal_atlas.is_valid()) {
+ Size2 rtsize = storage->render_target_get_size(rb->render_target);
+
+ effects->copy_to_fb_rect(decal_atlas, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, false, true);
}
}
@@ -3496,24 +3548,24 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
if (rb->luminance.current.is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true);
+ effects->copy_to_fb_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true);
}
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ssao.ao[0].is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
RID ao_buf = rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0];
- effects->copy_to_rect(ao_buf, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
+ effects->copy_to_fb_rect(ao_buf, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER && _render_buffers_get_roughness_texture(p_render_buffers).is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(_render_buffers_get_roughness_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
+ effects->copy_to_fb_rect(_render_buffers_get_roughness_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER && _render_buffers_get_normal_texture(p_render_buffers).is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize));
+ effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
}
}
@@ -3534,13 +3586,14 @@ RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) {
return rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0];
}
-void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
+void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
rb->width = p_width;
rb->height = p_height;
rb->render_target = p_render_target;
rb->msaa = p_msaa;
+ rb->screen_space_aa = p_screen_space_aa;
_free_render_buffer_data(rb);
{
@@ -3548,7 +3601,12 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = rb->width;
tf.height = rb->height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ } else {
+ tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ }
rb->texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
}
@@ -3559,6 +3617,9 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren
tf.width = p_width;
tf.height = p_height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ }
rb->depth_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
}
@@ -3580,6 +3641,88 @@ void RasterizerSceneRD::sub_surface_scattering_set_scale(float p_scale, float p_
sss_depth_scale = p_depth_scale;
}
+void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) {
+
+ ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum");
+
+ if (shadows_quality != p_quality) {
+ shadows_quality = p_quality;
+
+ switch (shadows_quality) {
+ case RS::SHADOW_QUALITY_HARD: {
+ penumbra_shadow_samples = 4;
+ soft_shadow_samples = 1;
+ shadows_quality_radius = 1.0;
+ } break;
+ case RS::SHADOW_QUALITY_SOFT_LOW: {
+ penumbra_shadow_samples = 8;
+ soft_shadow_samples = 4;
+ shadows_quality_radius = 2.0;
+ } break;
+ case RS::SHADOW_QUALITY_SOFT_MEDIUM: {
+ penumbra_shadow_samples = 12;
+ soft_shadow_samples = 8;
+ shadows_quality_radius = 2.0;
+ } break;
+ case RS::SHADOW_QUALITY_SOFT_HIGH: {
+ penumbra_shadow_samples = 24;
+ soft_shadow_samples = 16;
+ shadows_quality_radius = 3.0;
+ } break;
+ case RS::SHADOW_QUALITY_SOFT_ULTRA: {
+ penumbra_shadow_samples = 32;
+ soft_shadow_samples = 32;
+ shadows_quality_radius = 4.0;
+ } break;
+ case RS::SHADOW_QUALITY_MAX:
+ break;
+ }
+ get_vogel_disk(penumbra_shadow_kernel, penumbra_shadow_samples);
+ get_vogel_disk(soft_shadow_kernel, soft_shadow_samples);
+ }
+}
+
+void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) {
+
+ ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum");
+
+ if (directional_shadow_quality != p_quality) {
+ directional_shadow_quality = p_quality;
+
+ switch (directional_shadow_quality) {
+ case RS::SHADOW_QUALITY_HARD: {
+ directional_penumbra_shadow_samples = 4;
+ directional_soft_shadow_samples = 1;
+ directional_shadow_quality_radius = 1.0;
+ } break;
+ case RS::SHADOW_QUALITY_SOFT_LOW: {
+ directional_penumbra_shadow_samples = 8;
+ directional_soft_shadow_samples = 4;
+ directional_shadow_quality_radius = 2.0;
+ } break;
+ case RS::SHADOW_QUALITY_SOFT_MEDIUM: {
+ directional_penumbra_shadow_samples = 12;
+ directional_soft_shadow_samples = 8;
+ directional_shadow_quality_radius = 2.0;
+ } break;
+ case RS::SHADOW_QUALITY_SOFT_HIGH: {
+ directional_penumbra_shadow_samples = 24;
+ directional_soft_shadow_samples = 16;
+ directional_shadow_quality_radius = 3.0;
+ } break;
+ case RS::SHADOW_QUALITY_SOFT_ULTRA: {
+ directional_penumbra_shadow_samples = 32;
+ directional_soft_shadow_samples = 32;
+ directional_shadow_quality_radius = 4.0;
+ } break;
+ case RS::SHADOW_QUALITY_MAX:
+ break;
+ }
+ get_vogel_disk(directional_penumbra_shadow_kernel, directional_penumbra_shadow_samples);
+ get_vogel_disk(directional_soft_shadow_kernel, directional_soft_shadow_samples);
+ }
+}
+
int RasterizerSceneRD::get_roughness_layers() const {
return roughness_layers;
}
@@ -3594,7 +3737,7 @@ RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data(
return rb->data;
}
-void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
+void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
Color clear_color;
if (p_render_buffers.is_valid()) {
@@ -3605,7 +3748,7 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca
clear_color = storage->get_default_clear_color();
}
- _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color);
+ _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_decal_cull_result, p_decal_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color);
if (p_render_buffers.is_valid()) {
RENDER_TIMESTAMP("Tonemap");
@@ -3621,16 +3764,19 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
ERR_FAIL_COND(!light_instance);
Rect2i atlas_rect;
- RID atlas_fb;
+ RID atlas_texture;
bool using_dual_paraboloid = false;
bool using_dual_paraboloid_flip = false;
+ float znear = 0;
float zfar = 0;
RID render_fb;
RID render_texture;
float bias = 0;
float normal_bias = 0;
+ bool use_pancake = false;
+ bool use_linear_depth = false;
bool render_cubemap = false;
bool finalize_cubemap = false;
@@ -3645,6 +3791,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
light_instance->last_scene_shadow_pass = scene_pass;
}
+ use_pancake = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0;
light_projection = light_instance->shadow_transform[p_pass].camera;
light_transform = light_instance->shadow_transform[p_pass].transform;
@@ -3683,7 +3830,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size;
light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size;
- float bias_mult = Math::lerp(1.0f, light_instance->shadow_transform[p_pass].bias_scale, storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE));
+ float bias_mult = light_instance->shadow_transform[p_pass].bias_scale;
zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult;
normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult;
@@ -3691,7 +3838,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
render_fb = shadow_map->fb;
render_texture = shadow_map->depth;
- atlas_fb = directional_shadow.fb;
+ atlas_texture = directional_shadow.depth;
} else {
//set from shadow atlas
@@ -3718,7 +3865,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
atlas_rect.size.width = shadow_size;
atlas_rect.size.height = shadow_size;
- atlas_fb = shadow_atlas->fb;
+ atlas_texture = shadow_atlas->depth;
zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS);
@@ -3762,26 +3909,33 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
render_fb = shadow_map->fb;
render_texture = shadow_map->depth;
+
+ znear = light_instance->shadow_transform[0].camera.get_z_near();
+ use_linear_depth = true;
}
}
if (render_cubemap) {
//rendering to cubemap
- _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, 0, 0, false, false);
+ _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake);
if (finalize_cubemap) {
//reblit
atlas_rect.size.height /= 2;
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), bias, false);
+ storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false);
atlas_rect.position.y += atlas_rect.size.height;
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), bias, true);
+ storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true);
}
} else {
//render shadow
- _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip);
+ _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake);
//copy to atlas
- storage->get_effects()->copy_to_rect(render_texture, atlas_fb, atlas_rect, true);
+ if (use_linear_depth) {
+ storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar);
+ } else {
+ storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true);
+ }
//does not work from depth to color
//RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true);
@@ -3814,6 +3968,8 @@ bool RasterizerSceneRD::free(RID p_rid) {
//ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_rid);
reflection_probe_release_atlas_index(p_rid);
reflection_probe_instance_owner.free(p_rid);
+ } else if (decal_instance_owner.owns(p_rid)) {
+ decal_instance_owner.free(p_rid);
} else if (gi_probe_instance_owner.owns(p_rid)) {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_rid);
if (gi_probe->texture.is_valid()) {
@@ -4057,21 +4213,25 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color";
actions.renames["RADIANCE"] = "radiance";
actions.renames["LIGHT0_ENABLED"] = "directional_lights.data[0].enabled";
- actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction";
- actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].energy";
- actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color";
+ actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction_energy.xyz";
+ actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].direction_energy.w";
+ actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color_size.xyz";
+ actions.renames["LIGHT0_SIZE"] = "directional_lights.data[0].color_size.w";
actions.renames["LIGHT1_ENABLED"] = "directional_lights.data[1].enabled";
- actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction";
- actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].energy";
- actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color";
+ actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction_energy.xyz";
+ actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].direction_energy.w";
+ actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color_size.xyz";
+ actions.renames["LIGHT1_SIZE"] = "directional_lights.data[1].color_size.w";
actions.renames["LIGHT2_ENABLED"] = "directional_lights.data[2].enabled";
- actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction";
- actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].energy";
- actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color";
+ actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction_energy.xyz";
+ actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].direction_energy.w";
+ actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color_size.xyz";
+ actions.renames["LIGHT2_SIZE"] = "directional_lights.data[2].color_size.w";
actions.renames["LIGHT3_ENABLED"] = "directional_lights.data[3].enabled";
- actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction";
- actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].energy";
- actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color";
+ actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction_energy.xyz";
+ actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].direction_energy.w";
+ actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color_size.xyz";
+ actions.renames["LIGHT3_SIZE"] = "directional_lights.data[3].color_size.w";
actions.renames["AT_CUBEMAP_PASS"] = "AT_CUBEMAP_PASS";
actions.renames["AT_HALF_RES_PASS"] = "AT_HALF_RES_PASS";
actions.renames["AT_QUARTER_RES_PASS"] = "AT_QUARTER_RES_PASS";
@@ -4087,6 +4247,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+ actions.global_buffer_array_variable = "global_variables.data";
sky_shader.compiler.initialize(actions);
}
@@ -4094,7 +4255,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
{
// default material and shader for sky shader
sky_shader.default_shader = storage->shader_create();
- storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = mix(vec3(0.3), vec3(0.2, 0.4, 0.9), smoothstep(0.0, 0.05, EYEDIR.y)); } \n");
+ storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0); } \n");
sky_shader.default_material = storage->material_create();
storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
@@ -4124,19 +4285,33 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(storage->global_variables_get_storage_buffer());
+ uniforms.push_back(u);
+ }
+
sky_scene_state.sampler_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_SAMPLERS);
}
- camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_shape"))));
- camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/filters/depth_of_field_use_jitter"));
+ camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape"))));
+ camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter"));
environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"));
- screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter");
- screen_space_roughness_limiter_curve = GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter_curve");
+ screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter");
+ screen_space_roughness_limiter_curve = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_curve");
glow_bicubic_upscale = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0;
ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality")));
sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality")));
sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale");
sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale");
+ directional_penumbra_shadow_kernel = memnew_arr(float, 128);
+ directional_soft_shadow_kernel = memnew_arr(float, 128);
+ penumbra_shadow_kernel = memnew_arr(float, 128);
+ soft_shadow_kernel = memnew_arr(float, 128);
+ shadows_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality"))));
+ directional_shadow_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality"))));
}
RasterizerSceneRD::~RasterizerSceneRD() {
@@ -4165,4 +4340,8 @@ RasterizerSceneRD::~RasterizerSceneRD() {
memdelete_arr(sky_scene_state.last_frame_directional_lights);
storage->free(sky_shader.default_shader);
storage->free(sky_shader.default_material);
+ memdelete_arr(directional_penumbra_shadow_kernel);
+ memdelete_arr(directional_soft_shadow_kernel);
+ memdelete_arr(penumbra_shadow_kernel);
+ memdelete_arr(soft_shadow_kernel);
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
index 3f71f7dbc1..a511838e16 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
@@ -56,7 +56,9 @@ protected:
float direction[3];
float energy;
float color[3];
+ float size;
uint32_t enabled;
+ uint32_t pad[3];
};
struct SkySceneState {
@@ -78,8 +80,8 @@ protected:
};
virtual RenderBufferData *_create_render_buffer_data() = 0;
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0;
- virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip) = 0;
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0;
+ virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake) = 0;
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
@@ -189,6 +191,7 @@ private:
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const;
virtual bool is_param_texture(const StringName &p_param) const;
virtual bool is_animated() const;
virtual bool casts_shadows() const;
@@ -324,6 +327,16 @@ private:
mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner;
+ /* REFLECTION PROBE INSTANCE */
+
+ struct DecalInstance {
+
+ RID decal;
+ Transform transform;
+ };
+
+ mutable RID_Owner<DecalInstance> decal_instance_owner;
+
/* GIPROBE INSTANCE */
struct GIProbeLight {
@@ -527,11 +540,24 @@ private:
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
+ RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set
+ RS::ShadowQuality directional_shadow_quality = RS::SHADOW_QUALITY_MAX;
+ float shadows_quality_radius = 1.0;
+ float directional_shadow_quality_radius = 1.0;
+
+ float *directional_penumbra_shadow_kernel;
+ float *directional_soft_shadow_kernel;
+ float *penumbra_shadow_kernel;
+ float *soft_shadow_kernel;
+ int directional_penumbra_shadow_samples = 0;
+ int directional_soft_shadow_samples = 0;
+ int penumbra_shadow_samples = 0;
+ int soft_shadow_samples = 0;
+
/* DIRECTIONAL SHADOW */
struct DirectionalShadow {
RID depth;
- RID fb; //for copying
int light_count = 0;
int size = 0;
@@ -570,7 +596,10 @@ private:
float farplane;
float split;
float bias_scale;
+ float shadow_texel_size;
+ float range_begin;
Rect2 atlas_rect;
+ Vector2 uv_scale;
};
RS::LightType light_type = RS::LIGHT_DIRECTIONAL;
@@ -712,6 +741,8 @@ private:
RenderBufferData *data = nullptr;
int width = 0, height = 0;
RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
+ RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;
+
RID render_target;
uint64_t auto_exposure_version = 1;
@@ -725,7 +756,6 @@ private:
struct Mipmap {
RID texture;
- RID framebuffer;
int width;
int height;
};
@@ -839,8 +869,8 @@ public:
float environment_get_bg_energy(RID p_env) const;
int environment_get_canvas_max_layer(RID p_env) const;
Color environment_get_ambient_light_color(RID p_env) const;
- RS::EnvironmentAmbientSource environment_get_ambient_light_ambient_source(RID p_env) const;
- float environment_get_ambient_light_ambient_energy(RID p_env) const;
+ RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const;
+ float environment_get_ambient_light_energy(RID p_env) const;
float environment_get_ambient_sky_contribution(RID p_env) const;
RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const;
Color environment_get_ao_color(RID p_env) const;
@@ -880,7 +910,7 @@ public:
RID light_instance_create(RID p_light);
void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
- void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
+ void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2());
void light_instance_mark_visible(RID p_light_instance);
_FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) {
@@ -926,11 +956,55 @@ public:
return li->shadow_transform[p_index].camera;
}
- _FORCE_INLINE_ Transform light_instance_get_shadow_transform(RID p_light_instance, int p_index) {
+ _FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) {
+
+#ifdef DEBUG_ENABLED
+ LightInstance *li = light_instance_owner.getornull(p_light_instance);
+ ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0);
+#endif
+ ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
+ ERR_FAIL_COND_V(!shadow_atlas, 0);
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_V(!shadow_atlas->shadow_owners.has(p_light_instance), 0);
+#endif
+ uint32_t key = shadow_atlas->shadow_owners[p_light_instance];
+
+ uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
+
+ uint32_t quadrant_size = shadow_atlas->size >> 1;
+
+ uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision);
+
+ return float(1.0) / shadow_size;
+ }
+
+ _FORCE_INLINE_ Transform
+ light_instance_get_shadow_transform(RID p_light_instance, int p_index) {
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].transform;
}
+ _FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) {
+
+ LightInstance *li = light_instance_owner.getornull(p_light_instance);
+ return li->shadow_transform[p_index].bias_scale;
+ }
+ _FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) {
+
+ LightInstance *li = light_instance_owner.getornull(p_light_instance);
+ return li->shadow_transform[p_index].farplane;
+ }
+ _FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) {
+
+ LightInstance *li = light_instance_owner.getornull(p_light_instance);
+ return li->shadow_transform[p_index].range_begin;
+ }
+
+ _FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) {
+
+ LightInstance *li = light_instance_owner.getornull(p_light_instance);
+ return li->shadow_transform[p_index].uv_scale;
+ }
_FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) {
@@ -944,6 +1018,12 @@ public:
return li->shadow_transform[p_index].split;
}
+ _FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) {
+
+ LightInstance *li = light_instance_owner.getornull(p_light_instance);
+ return li->shadow_transform[p_index].shadow_texel_size;
+ }
+
_FORCE_INLINE_ void light_instance_set_render_pass(RID p_light_instance, uint64_t p_pass) {
LightInstance *li = light_instance_owner.getornull(p_light_instance);
li->last_pass = p_pass;
@@ -1036,6 +1116,19 @@ public:
return rpi->atlas_index;
}
+ virtual RID decal_instance_create(RID p_decal);
+ virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform);
+
+ _FORCE_INLINE_ RID decal_instance_get_base(RID p_decal) const {
+ DecalInstance *decal = decal_instance_owner.getornull(p_decal);
+ return decal->decal;
+ }
+
+ _FORCE_INLINE_ Transform decal_instance_get_transform(RID p_decal) const {
+ DecalInstance *decal = decal_instance_owner.getornull(p_decal);
+ return decal->transform;
+ }
+
RID gi_probe_instance_create(RID p_base);
void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
bool gi_probe_needs_update(RID p_probe) const;
@@ -1096,19 +1189,23 @@ public:
GIProbeQuality gi_probe_get_quality() const;
RID render_buffers_create();
- void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa);
+ void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa);
RID render_buffers_get_ao_texture(RID p_render_buffers);
RID render_buffers_get_back_buffer_texture(RID p_render_buffers);
- void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
+ void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
- virtual void set_scene_pass(uint64_t p_pass) { scene_pass = p_pass; }
- _FORCE_INLINE_ uint64_t get_scene_pass() { return scene_pass; }
+ virtual void set_scene_pass(uint64_t p_pass) {
+ scene_pass = p_pass;
+ }
+ _FORCE_INLINE_ uint64_t get_scene_pass() {
+ return scene_pass;
+ }
virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve);
virtual bool screen_space_roughness_limiter_is_active() const;
@@ -1118,6 +1215,23 @@ public:
RS::SubSurfaceScatteringQuality sub_surface_scattering_get_quality() const;
virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale);
+ virtual void shadows_quality_set(RS::ShadowQuality p_quality);
+ virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality);
+ _FORCE_INLINE_ RS::ShadowQuality shadows_quality_get() const { return shadows_quality; }
+ _FORCE_INLINE_ RS::ShadowQuality directional_shadow_quality_get() const { return directional_shadow_quality; }
+ _FORCE_INLINE_ float shadows_quality_radius_get() const { return shadows_quality_radius; }
+ _FORCE_INLINE_ float directional_shadow_quality_radius_get() const { return directional_shadow_quality_radius; }
+
+ _FORCE_INLINE_ float *directional_penumbra_shadow_kernel_get() { return directional_penumbra_shadow_kernel; }
+ _FORCE_INLINE_ float *directional_soft_shadow_kernel_get() { return directional_soft_shadow_kernel; }
+ _FORCE_INLINE_ float *penumbra_shadow_kernel_get() { return penumbra_shadow_kernel; }
+ _FORCE_INLINE_ float *soft_shadow_kernel_get() { return soft_shadow_kernel; }
+
+ _FORCE_INLINE_ int directional_penumbra_shadow_samples_get() const { return directional_penumbra_shadow_samples; }
+ _FORCE_INLINE_ int directional_soft_shadow_samples_get() const { return directional_soft_shadow_samples; }
+ _FORCE_INLINE_ int penumbra_shadow_samples_get() const { return penumbra_shadow_samples; }
+ _FORCE_INLINE_ int soft_shadow_samples_get() const { return soft_shadow_samples; }
+
int get_roughness_layers() const;
bool is_using_radiance_cubemap_array() const;
@@ -1126,7 +1240,9 @@ public:
virtual void update();
virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw);
- _FORCE_INLINE_ RS::ViewportDebugDraw get_debug_draw_mode() const { return debug_draw; }
+ _FORCE_INLINE_ RS::ViewportDebugDraw get_debug_draw_mode() const {
+ return debug_draw;
+ }
virtual void set_time(double p_time, double p_step);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
index 322e89ef9a..0689429014 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -31,6 +31,7 @@
#include "rasterizer_storage_rd.h"
#include "core/engine.h"
+#include "core/io/resource_loader.h"
#include "core/project_settings.h"
#include "servers/rendering/shader_language.h"
@@ -809,6 +810,12 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
}
//delete last, so proxies can be updated
texture_owner.free(p_by_texture);
+
+ if (decal_atlas.textures.has(p_texture)) {
+ //belongs to decal atlas..
+
+ decal_atlas.dirty = true; //mark it dirty since it was most likely modified
+ }
}
void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) {
Texture *tex = texture_owner.getornull(p_texture);
@@ -915,6 +922,7 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) {
Material *material = E->get();
if (shader->data) {
material->data = material_data_request_func[new_type](shader->data);
+ material->data->self = material->self;
material->data->set_next_pass(material->next_pass);
material->data->set_render_priority(material->priority);
}
@@ -1015,8 +1023,8 @@ void RasterizerStorageRD::_material_queue_update(Material *material, bool p_unif
material->update_next = material_update_list;
material_update_list = material;
material->update_requested = true;
- material->uniform_dirty = p_uniform;
- material->texture_dirty = p_texture;
+ material->uniform_dirty = material->uniform_dirty || p_uniform;
+ material->texture_dirty = material->texture_dirty || p_texture;
}
void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) {
@@ -1053,6 +1061,7 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) {
ERR_FAIL_COND(shader->data == nullptr);
material->data = material_data_request_func[shader->type](shader->data);
+ material->data->self = p_material;
material->data->set_next_pass(material->next_pass);
material->data->set_render_priority(material->priority);
//updating happens later
@@ -1138,6 +1147,19 @@ bool RasterizerStorageRD::material_casts_shadows(RID p_material) {
return true; //by default everything casts shadows
}
+void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
+
+ Material *material = material_owner.getornull(p_material);
+ ERR_FAIL_COND(!material);
+ if (material->shader && material->shader->data) {
+ material->shader->data->get_instance_param_list(r_parameters);
+
+ if (material->next_pass.is_valid()) {
+ material_get_instance_shader_parameters(material->next_pass, r_parameters);
+ }
+ }
+}
+
void RasterizerStorageRD::material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1625,11 +1647,36 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type,
void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) {
+ bool uses_global_buffer = false;
+
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_uniforms.front(); E; E = E->next()) {
if (E->get().order < 0)
continue; // texture, does not go here
+ if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue; //instance uniforms don't appear in the bufferr
+ }
+
+ if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
+ //this is a global variable, get the index to it
+ RasterizerStorageRD *rs = base_singleton;
+
+ GlobalVariables::Variable *gv = rs->global_variables.variables.getptr(E->key());
+ uint32_t index = 0;
+ if (gv) {
+ index = gv->buffer_index;
+ } else {
+ WARN_PRINT("Shader uses global uniform '" + E->key() + "', but it was removed at some point. Material will not display correctly.");
+ }
+
+ uint32_t offset = p_uniform_offsets[E->get().order];
+ uint32_t *intptr = (uint32_t *)&p_buffer[offset];
+ *intptr = index;
+ uses_global_buffer = true;
+ continue;
+ }
+
//regular uniform
uint32_t offset = p_uniform_offsets[E->get().order];
#ifdef DEBUG_ENABLED
@@ -1658,6 +1705,38 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa
}
}
}
+
+ if (uses_global_buffer != (global_buffer_E != nullptr)) {
+ RasterizerStorageRD *rs = base_singleton;
+ if (uses_global_buffer) {
+ global_buffer_E = rs->global_variables.materials_using_buffer.push_back(self);
+ } else {
+ rs->global_variables.materials_using_buffer.erase(global_buffer_E);
+ global_buffer_E = nullptr;
+ }
+ }
+}
+
+RasterizerStorageRD::MaterialData::~MaterialData() {
+ if (global_buffer_E) {
+ //unregister global buffers
+ RasterizerStorageRD *rs = base_singleton;
+ rs->global_variables.materials_using_buffer.erase(global_buffer_E);
+ }
+
+ if (global_texture_E) {
+ //unregister global textures
+ RasterizerStorageRD *rs = base_singleton;
+
+ for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) {
+ GlobalVariables::Variable *v = rs->global_variables.variables.getptr(E->key());
+ if (v) {
+ v->texture_materials.erase(self);
+ }
+ }
+ //unregister material from those using global textures
+ rs->global_variables.materials_using_texture.erase(global_texture_E);
+ }
}
void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
@@ -1669,22 +1748,57 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
Texture *normal_detect_texture = nullptr;
#endif
+ bool uses_global_textures = false;
+ global_textures_pass++;
+
for (int i = 0; i < p_texture_uniforms.size(); i++) {
const StringName &uniform_name = p_texture_uniforms[i].name;
RID texture;
- const Map<StringName, Variant>::Element *V = p_parameters.find(uniform_name);
- if (V) {
- texture = V->get();
- }
+ if (p_texture_uniforms[i].global) {
+
+ RasterizerStorageRD *rs = base_singleton;
+
+ uses_global_textures = true;
+
+ GlobalVariables::Variable *v = rs->global_variables.variables.getptr(uniform_name);
+ if (v) {
+ if (v->buffer_index >= 0) {
+ WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!.");
- if (!texture.is_valid()) {
- const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name);
- if (W) {
+ } else {
+
+ Map<StringName, uint64_t>::Element *E = used_global_textures.find(uniform_name);
+ if (!E) {
+ E = used_global_textures.insert(uniform_name, global_textures_pass);
+ v->texture_materials.insert(self);
+ } else {
+ E->get() = global_textures_pass;
+ }
- texture = W->get();
+ texture = v->override.get_type() != Variant::NIL ? v->override : v->value;
+ }
+
+ } else {
+ WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly.");
+ }
+ } else {
+ if (!texture.is_valid()) {
+
+ const Map<StringName, Variant>::Element *V = p_parameters.find(uniform_name);
+ if (V) {
+ texture = V->get();
+ }
+ }
+
+ if (!texture.is_valid()) {
+ const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name);
+ if (W) {
+
+ texture = W->get();
+ }
}
}
@@ -1747,6 +1861,36 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
roughness_detect_texture->detect_roughness_callback(roughness_detect_texture->detect_roughness_callback_ud, normal_detect_texture->path, roughness_channel);
}
#endif
+ {
+ //for textures no longer used, unregister them
+ List<Map<StringName, uint64_t>::Element *> to_delete;
+ RasterizerStorageRD *rs = base_singleton;
+
+ for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) {
+ if (E->get() != global_textures_pass) {
+ to_delete.push_back(E);
+
+ GlobalVariables::Variable *v = rs->global_variables.variables.getptr(E->key());
+ if (v) {
+ v->texture_materials.erase(self);
+ }
+ }
+ }
+
+ while (to_delete.front()) {
+ used_global_textures.erase(to_delete.front()->get());
+ to_delete.pop_front();
+ }
+ //handle registering/unregistering global textures
+ if (uses_global_textures != (global_texture_E != nullptr)) {
+ if (uses_global_textures) {
+ global_texture_E = rs->global_variables.materials_using_texture.push_back(self);
+ } else {
+ rs->global_variables.materials_using_texture.erase(global_texture_E);
+ global_texture_E = nullptr;
+ }
+ }
+ }
}
void RasterizerStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) {
@@ -2197,14 +2341,14 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
Mesh::Surface::Version &v = s->versions[version];
- Vector<RD::VertexDescription> attributes;
+ Vector<RD::VertexAttribute> attributes;
Vector<RID> buffers;
uint32_t stride = 0;
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
RID buffer;
vd.location = i;
@@ -3104,15 +3248,17 @@ RID RasterizerStorageRD::light_create(RS::LightType p_type) {
light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0;
light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;
light.param[RS::LIGHT_PARAM_RANGE] = 1.0;
+ light.param[RS::LIGHT_PARAM_SIZE] = 0.0;
light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;
- light.param[RS::LIGHT_PARAM_CONTACT_SHADOW_SIZE] = 45;
light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
- light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 0.1;
- light.param[RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE] = 0.1;
+ light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
+ light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
+ light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
+ light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
return light_owner.make_rid(light);
}
@@ -3138,6 +3284,7 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f
case RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
case RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:
+ case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
case RS::LIGHT_PARAM_SHADOW_BIAS: {
light->version++;
@@ -3171,7 +3318,19 @@ void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
+ if (light->projector == p_texture) {
+ return;
+ }
+
+ if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
+ texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
+ }
+
light->projector = p_texture;
+
+ if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
+ texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
+ }
}
void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) {
@@ -3550,6 +3709,94 @@ float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribut
return reflection_probe->interior_ambient_probe_contrib;
}
+RID RasterizerStorageRD::decal_create() {
+ return decal_owner.make_rid(Decal());
+}
+
+void RasterizerStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ decal->extents = p_extents;
+ decal->instance_dependency.instance_notify_changed(true, false);
+}
+void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
+
+ if (decal->textures[p_type] == p_texture) {
+ return;
+ }
+
+ ERR_FAIL_COND(p_texture.is_valid() && !texture_owner.owns(p_texture));
+
+ if (decal->textures[p_type].is_valid() && texture_owner.owns(decal->textures[p_type])) {
+ texture_remove_from_decal_atlas(decal->textures[p_type]);
+ }
+
+ decal->textures[p_type] = p_texture;
+
+ if (decal->textures[p_type].is_valid()) {
+ texture_add_to_decal_atlas(decal->textures[p_type]);
+ }
+
+ decal->instance_dependency.instance_notify_changed(false, true);
+}
+void RasterizerStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) {
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ decal->emission_energy = p_energy;
+}
+
+void RasterizerStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) {
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ decal->albedo_mix = p_mix;
+}
+
+void RasterizerStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) {
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ decal->modulate = p_modulate;
+}
+void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ decal->cull_mask = p_layers;
+ decal->instance_dependency.instance_notify_changed(true, false);
+}
+
+void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
+
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ decal->distance_fade = p_enabled;
+ decal->distance_fade_begin = p_begin;
+ decal->distance_fade_length = p_length;
+}
+
+void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) {
+
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ decal->upper_fade = p_above;
+ decal->lower_fade = p_below;
+}
+
+void RasterizerStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) {
+
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND(!decal);
+ decal->normal_fade = p_fade;
+}
+
+AABB RasterizerStorageRD::decal_get_aabb(RID p_decal) const {
+ Decal *decal = decal_owner.getornull(p_decal);
+ ERR_FAIL_COND_V(!decal, AABB());
+
+ return AABB(-decal->extents, decal->extents * 2.0);
+}
+
RID RasterizerStorageRD::gi_probe_create() {
return gi_probe_owner.make_rid(GIProbe());
@@ -3911,7 +4158,6 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
if (rt->backbuffer.is_valid()) {
RD::get_singleton()->free(rt->backbuffer);
rt->backbuffer = RID();
- rt->backbuffer_fb = RID();
for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
//just erase copies, since the rest are erased by dependency
RD::get_singleton()->free(rt->backbuffer_mipmaps[i].mipmap_copy);
@@ -4025,17 +4271,11 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
tf.width = rt->size.width;
tf.height = rt->size.height;
tf.type = RD::TEXTURE_TYPE_2D;
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tf.mipmaps = mipmaps_required;
rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- {
- Vector<RID> backbuffer_att;
- RID backbuffer_fb_tex = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
- backbuffer_att.push_back(backbuffer_fb_tex);
- rt->backbuffer_fb = RD::get_singleton()->framebuffer_create(backbuffer_att);
- }
+ rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
//create mipmaps
for (uint32_t i = 1; i < mipmaps_required; i++) {
@@ -4043,9 +4283,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
RenderTarget::BackbufferMipmap mm;
{
mm.mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
- Vector<RID> mm_fb_at;
- mm_fb_at.push_back(mm.mipmap);
- mm.mipmap_fb = RD::get_singleton()->framebuffer_create(mm_fb_at);
}
{
@@ -4057,9 +4294,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
mmtf.mipmaps = 1;
mm.mipmap_copy = RD::get_singleton()->texture_create(mmtf, RD::TextureView());
- Vector<RID> mm_fb_at;
- mm_fb_at.push_back(mm.mipmap_copy);
- mm.mipmap_copy_fb = RD::get_singleton()->framebuffer_create(mm_fb_at);
}
rt->backbuffer_mipmaps.push_back(mm);
@@ -4135,7 +4369,12 @@ RID RasterizerStorageRD::render_target_get_rd_framebuffer(RID p_render_target) {
return rt->framebuffer;
}
+RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+ return rt->color;
+}
void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
@@ -4185,27 +4424,25 @@ void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target,
}
Rect2i region = p_region;
- Rect2 blur_region;
if (region == Rect2i()) {
region.size = rt->size;
- } else {
- blur_region = region;
- blur_region.position /= rt->size;
- blur_region.size /= rt->size;
}
//single texture copy for backbuffer
- RD::get_singleton()->texture_copy(rt->color, rt->backbuffer, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
+ RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
//effects.copy(rt->color, rt->backbuffer_fb, blur_region);
//then mipmap blur
RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
- Vector2 pixel_size = Vector2(1.0 / rt->size.width, 1.0 / rt->size.height);
for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
- pixel_size *= 2.0; //go halfway
+ region.position.x >>= 1;
+ region.position.y >>= 1;
+ region.size.x = MAX(1, region.size.x >> 1);
+ region.size.y = MAX(1, region.size.y >> 1);
+
const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i];
- effects.gaussian_blur(prev_texture, mm.mipmap_copy_fb, mm.mipmap_copy, mm.mipmap_fb, pixel_size, blur_region);
+ effects.gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true);
prev_texture = mm.mipmap;
}
}
@@ -4250,6 +4487,9 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In
} else if (reflection_probe_owner.owns(p_base)) {
ReflectionProbe *rp = reflection_probe_owner.getornull(p_base);
p_instance->update_dependency(&rp->instance_dependency);
+ } else if (decal_owner.owns(p_base)) {
+ Decal *decal = decal_owner.getornull(p_base);
+ p_instance->update_dependency(&decal->instance_dependency);
} else if (gi_probe_owner.owns(p_base)) {
GIProbe *gip = gi_probe_owner.getornull(p_base);
p_instance->update_dependency(&gip->instance_dependency);
@@ -4278,6 +4518,9 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
if (reflection_probe_owner.owns(p_rid)) {
return RS::INSTANCE_REFLECTION_PROBE;
}
+ if (decal_owner.owns(p_rid)) {
+ return RS::INSTANCE_DECAL;
+ }
if (gi_probe_owner.owns(p_rid)) {
return RS::INSTANCE_GI_PROBE;
}
@@ -4287,10 +4530,924 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
return RS::INSTANCE_NONE;
}
+
+void RasterizerStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
+ if (!decal_atlas.textures.has(p_texture)) {
+ DecalAtlas::Texture t;
+ t.users = 1;
+ t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0;
+ decal_atlas.textures[p_texture] = t;
+ decal_atlas.dirty = true;
+ } else {
+ DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
+ t->users++;
+ if (p_panorama_to_dp) {
+ t->panorama_to_dp_users++;
+ }
+ }
+}
+
+void RasterizerStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
+ DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
+ ERR_FAIL_COND(!t);
+ t->users--;
+ if (p_panorama_to_dp) {
+ ERR_FAIL_COND(t->panorama_to_dp_users == 0);
+ t->panorama_to_dp_users--;
+ }
+ if (t->users == 0) {
+ decal_atlas.textures.erase(p_texture);
+ //do not mark it dirty, there is no need to since it remains working
+ }
+}
+
+RID RasterizerStorageRD::decal_atlas_get_texture() const {
+ return decal_atlas.texture;
+}
+
+RID RasterizerStorageRD::decal_atlas_get_texture_srgb() const {
+ return decal_atlas.texture;
+}
+
+void RasterizerStorageRD::_update_decal_atlas() {
+ if (!decal_atlas.dirty) {
+ return; //nothing to do
+ }
+
+ decal_atlas.dirty = false;
+
+ if (decal_atlas.texture.is_valid()) {
+ RD::get_singleton()->free(decal_atlas.texture);
+ decal_atlas.texture = RID();
+ decal_atlas.texture_srgb = RID();
+ decal_atlas.texture_mipmaps.clear();
+ }
+
+ int border = 1 << decal_atlas.mipmaps;
+
+ if (decal_atlas.textures.size()) {
+ //generate atlas
+ Vector<DecalAtlas::SortItem> itemsv;
+ itemsv.resize(decal_atlas.textures.size());
+ int base_size = 8;
+ const RID *K = NULL;
+
+ int idx = 0;
+ while ((K = decal_atlas.textures.next(K))) {
+ DecalAtlas::SortItem &si = itemsv.write[idx];
+
+ Texture *src_tex = texture_owner.getornull(*K);
+
+ si.size.width = (src_tex->width / border) + 1;
+ si.size.height = (src_tex->height / border) + 1;
+ si.pixel_size = Size2i(src_tex->width, src_tex->height);
+
+ if (base_size < si.size.width) {
+ base_size = nearest_power_of_2_templated(si.size.width);
+ }
+
+ si.texture = *K;
+ idx++;
+ }
+
+ //sort items by size
+ itemsv.sort();
+
+ //attempt to create atlas
+ int item_count = itemsv.size();
+ DecalAtlas::SortItem *items = itemsv.ptrw();
+
+ int atlas_height = 0;
+
+ while (true) {
+
+ Vector<int> v_offsetsv;
+ v_offsetsv.resize(base_size);
+
+ int *v_offsets = v_offsetsv.ptrw();
+ zeromem(v_offsets, sizeof(int) * base_size);
+
+ int max_height = 0;
+
+ for (int i = 0; i < item_count; i++) {
+ //best fit
+ DecalAtlas::SortItem &si = items[i];
+ int best_idx = -1;
+ int best_height = 0x7FFFFFFF;
+ for (int j = 0; j <= base_size - si.size.width; j++) {
+ int height = 0;
+ for (int k = 0; k < si.size.width; k++) {
+ int h = v_offsets[k + j];
+ if (h > height) {
+ height = h;
+ if (height > best_height) {
+ break; //already bad
+ }
+ }
+ }
+
+ if (height < best_height) {
+ best_height = height;
+ best_idx = j;
+ }
+ }
+
+ //update
+ for (int k = 0; k < si.size.width; k++) {
+ v_offsets[k + best_idx] = best_height + si.size.height;
+ }
+
+ si.pos.x = best_idx;
+ si.pos.y = best_height;
+
+ if (si.pos.y + si.size.height > max_height) {
+ max_height = si.pos.y + si.size.height;
+ }
+ }
+
+ if (max_height <= base_size * 2) {
+ atlas_height = max_height;
+ break; //good ratio, break;
+ }
+
+ base_size *= 2;
+ }
+
+ decal_atlas.size.width = base_size * border;
+ decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
+
+ for (int i = 0; i < item_count; i++) {
+ DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
+ t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
+ t->uv_rect.size = items[i].pixel_size;
+ //print_line("blitrect: " + t->uv_rect);
+ t->uv_rect.position /= Size2(decal_atlas.size);
+ t->uv_rect.size /= Size2(decal_atlas.size);
+ }
+ } else {
+
+ //use border as size, so it at least has enough mipmaps
+ decal_atlas.size.width = border;
+ decal_atlas.size.height = border;
+ }
+
+ //blit textures
+
+ RD::TextureFormat tformat;
+ tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ tformat.width = decal_atlas.size.width;
+ tformat.height = decal_atlas.size.height;
+ tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ tformat.type = RD::TEXTURE_TYPE_2D;
+ tformat.mipmaps = decal_atlas.mipmaps;
+ tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
+ tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
+
+ decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+
+ {
+ //create the framebuffer
+
+ Size2i s = decal_atlas.size;
+
+ for (int i = 0; i < decal_atlas.mipmaps; i++) {
+ DecalAtlas::MipMap mm;
+ mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
+ Vector<RID> fb;
+ fb.push_back(mm.texture);
+ mm.fb = RD::get_singleton()->framebuffer_create(fb);
+ mm.size = s;
+ decal_atlas.texture_mipmaps.push_back(mm);
+
+ s.width = MAX(1, s.width >> 1);
+ s.height = MAX(1, s.height >> 1);
+ }
+ {
+ //create the SRGB variant
+ RD::TextureView rd_view;
+ rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
+ decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
+ }
+ }
+
+ RID prev_texture;
+ for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
+ const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
+
+ Color clear_color(0, 0, 0, 0);
+
+ if (decal_atlas.textures.size()) {
+
+ if (i == 0) {
+ Vector<Color> cc;
+ cc.push_back(clear_color);
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
+
+ const RID *K = NULL;
+ while ((K = decal_atlas.textures.next(K))) {
+ DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
+ Texture *src_tex = texture_owner.getornull(*K);
+ effects.copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
+ }
+
+ RD::get_singleton()->draw_list_end();
+
+ prev_texture = mm.texture;
+ } else {
+
+ effects.copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
+ prev_texture = mm.texture;
+ }
+ } else {
+ RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1, false);
+ }
+ }
+}
+
+int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) {
+
+ int32_t idx = 0;
+ while (idx + p_elements <= global_variables.buffer_size) {
+ if (global_variables.buffer_usage[idx].elements == 0) {
+ bool valid = true;
+ for (uint32_t i = 1; i < p_elements; i++) {
+ if (global_variables.buffer_usage[idx + i].elements > 0) {
+ valid = false;
+ idx += i + global_variables.buffer_usage[idx + i].elements;
+ break;
+ }
+ }
+
+ if (!valid) {
+ continue; //if not valid, idx is in new position
+ }
+
+ return idx;
+ } else {
+ idx += global_variables.buffer_usage[idx].elements;
+ }
+ }
+
+ return -1;
+}
+
+void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) {
+
+ switch (p_type) {
+ case RS::GLOBAL_VAR_TYPE_BOOL: {
+
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ bool b = p_value;
+ bv.x = b ? 1.0 : 0.0;
+ bv.y = 0.0;
+ bv.z = 0.0;
+ bv.w = 0.0;
+
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC2: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ uint32_t bvec = p_value;
+ bv.x = (bvec & 1) ? 1.0 : 0.0;
+ bv.y = (bvec & 2) ? 1.0 : 0.0;
+ bv.z = 0.0;
+ bv.w = 0.0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC3: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ uint32_t bvec = p_value;
+ bv.x = (bvec & 1) ? 1.0 : 0.0;
+ bv.y = (bvec & 2) ? 1.0 : 0.0;
+ bv.z = (bvec & 4) ? 1.0 : 0.0;
+ bv.w = 0.0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BVEC4: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ uint32_t bvec = p_value;
+ bv.x = (bvec & 1) ? 1.0 : 0.0;
+ bv.y = (bvec & 2) ? 1.0 : 0.0;
+ bv.z = (bvec & 4) ? 1.0 : 0.0;
+ bv.w = (bvec & 8) ? 1.0 : 0.0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_INT: {
+ GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ int32_t v = p_value;
+ bv.x = v;
+ bv.y = 0;
+ bv.z = 0;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC2: {
+ GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ Vector2i v = p_value;
+ bv.x = v.x;
+ bv.y = v.y;
+ bv.z = 0;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC3: {
+ GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ Vector3i v = p_value;
+ bv.x = v.x;
+ bv.y = v.y;
+ bv.z = v.z;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_IVEC4: {
+ GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ Vector<int32_t> v = p_value;
+ bv.x = v.size() >= 1 ? v[0] : 0;
+ bv.y = v.size() >= 2 ? v[1] : 0;
+ bv.z = v.size() >= 3 ? v[2] : 0;
+ bv.w = v.size() >= 4 ? v[3] : 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_RECT2I: {
+ GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ Rect2i v = p_value;
+ bv.x = v.position.x;
+ bv.y = v.position.y;
+ bv.z = v.size.x;
+ bv.w = v.size.y;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UINT: {
+ GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index];
+ uint32_t v = p_value;
+ bv.x = v;
+ bv.y = 0;
+ bv.z = 0;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC2: {
+ GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index];
+ Vector2i v = p_value;
+ bv.x = v.x;
+ bv.y = v.y;
+ bv.z = 0;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC3: {
+ GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index];
+ Vector3i v = p_value;
+ bv.x = v.x;
+ bv.y = v.y;
+ bv.z = v.z;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_UVEC4: {
+ GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index];
+ Vector<int32_t> v = p_value;
+ bv.x = v.size() >= 1 ? v[0] : 0;
+ bv.y = v.size() >= 2 ? v[1] : 0;
+ bv.z = v.size() >= 3 ? v[2] : 0;
+ bv.w = v.size() >= 4 ? v[3] : 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_FLOAT: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ float v = p_value;
+ bv.x = v;
+ bv.y = 0;
+ bv.z = 0;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC2: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ Vector2 v = p_value;
+ bv.x = v.x;
+ bv.y = v.y;
+ bv.z = 0;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC3: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ Vector3 v = p_value;
+ bv.x = v.x;
+ bv.y = v.y;
+ bv.z = v.z;
+ bv.w = 0;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC4: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ Plane v = p_value;
+ bv.x = v.normal.x;
+ bv.y = v.normal.y;
+ bv.z = v.normal.z;
+ bv.w = v.d;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_COLOR: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ Color v = p_value;
+ bv.x = v.r;
+ bv.y = v.g;
+ bv.z = v.b;
+ bv.w = v.a;
+
+ GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1];
+ v = v.to_linear();
+ bv_linear.x = v.r;
+ bv_linear.y = v.g;
+ bv_linear.z = v.b;
+ bv_linear.w = v.a;
+
+ } break;
+ case RS::GLOBAL_VAR_TYPE_RECT2: {
+ GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ Rect2 v = p_value;
+ bv.x = v.position.x;
+ bv.y = v.position.y;
+ bv.z = v.size.x;
+ bv.w = v.size.y;
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT2: {
+ GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ Vector<float> m2 = p_value;
+ if (m2.size() < 4) {
+ m2.resize(4);
+ }
+ bv[0].x = m2[0];
+ bv[0].y = m2[1];
+ bv[0].z = 0;
+ bv[0].w = 0;
+
+ bv[1].x = m2[2];
+ bv[1].y = m2[3];
+ bv[1].z = 0;
+ bv[1].w = 0;
+
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT3: {
+
+ GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ Basis v = p_value;
+ bv[0].x = v.elements[0][0];
+ bv[0].y = v.elements[1][0];
+ bv[0].z = v.elements[2][0];
+ bv[0].w = 0;
+
+ bv[1].x = v.elements[0][1];
+ bv[1].y = v.elements[1][1];
+ bv[1].z = v.elements[2][1];
+ bv[1].w = 0;
+
+ bv[2].x = v.elements[0][2];
+ bv[2].y = v.elements[1][2];
+ bv[2].z = v.elements[2][2];
+ bv[2].w = 0;
+
+ } break;
+ case RS::GLOBAL_VAR_TYPE_MAT4: {
+
+ GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+
+ Vector<float> m2 = p_value;
+ if (m2.size() < 16) {
+ m2.resize(16);
+ }
+
+ bv[0].x = m2[0];
+ bv[0].y = m2[1];
+ bv[0].z = m2[2];
+ bv[0].w = m2[3];
+
+ bv[1].x = m2[4];
+ bv[1].y = m2[5];
+ bv[1].z = m2[6];
+ bv[1].w = m2[7];
+
+ bv[2].x = m2[8];
+ bv[2].y = m2[9];
+ bv[2].z = m2[10];
+ bv[2].w = m2[11];
+
+ bv[3].x = m2[12];
+ bv[3].y = m2[13];
+ bv[3].z = m2[14];
+ bv[3].w = m2[15];
+
+ } break;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {
+
+ GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ Transform2D v = p_value;
+ bv[0].x = v.elements[0][0];
+ bv[0].y = v.elements[0][1];
+ bv[0].z = 0;
+ bv[0].w = 0;
+
+ bv[1].x = v.elements[1][0];
+ bv[1].y = v.elements[1][1];
+ bv[1].z = 0;
+ bv[1].w = 0;
+
+ bv[2].x = v.elements[2][0];
+ bv[2].y = v.elements[2][1];
+ bv[2].z = 1;
+ bv[2].w = 0;
+
+ } break;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
+
+ GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ Transform v = p_value;
+ bv[0].x = v.basis.elements[0][0];
+ bv[0].y = v.basis.elements[1][0];
+ bv[0].z = v.basis.elements[2][0];
+ bv[0].w = 0;
+
+ bv[1].x = v.basis.elements[0][1];
+ bv[1].y = v.basis.elements[1][1];
+ bv[1].z = v.basis.elements[2][1];
+ bv[1].w = 0;
+
+ bv[2].x = v.basis.elements[0][2];
+ bv[2].y = v.basis.elements[1][2];
+ bv[2].z = v.basis.elements[2][2];
+ bv[2].w = 0;
+
+ bv[2].x = v.origin.x;
+ bv[2].y = v.origin.y;
+ bv[2].z = v.origin.z;
+ bv[2].w = 1;
+
+ } break;
+ default: {
+ ERR_FAIL();
+ }
+ }
+}
+
+void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) {
+
+ int32_t prev_chunk = -1;
+
+ for (int32_t i = 0; i < p_elements; i++) {
+ int32_t chunk = (p_index + i) / GlobalVariables::BUFFER_DIRTY_REGION_SIZE;
+ if (chunk != prev_chunk) {
+ if (!global_variables.buffer_dirty_regions[chunk]) {
+ global_variables.buffer_dirty_regions[chunk] = true;
+ global_variables.buffer_dirty_region_count++;
+ }
+ }
+
+ prev_chunk = chunk;
+ }
+}
+
+void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
+
+ ERR_FAIL_COND(global_variables.variables.has(p_name));
+ GlobalVariables::Variable gv;
+ gv.type = p_type;
+ gv.value = p_value;
+ gv.buffer_index = -1;
+
+ if (p_type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) {
+ //is texture
+ global_variables.must_update_texture_materials = true; //normally ther are no
+ } else {
+
+ gv.buffer_elements = 1;
+ if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) {
+ //color needs to elements to store srgb and linear
+ gv.buffer_elements = 2;
+ }
+ if (p_type == RS::GLOBAL_VAR_TYPE_MAT3 || p_type == RS::GLOBAL_VAR_TYPE_TRANSFORM_2D) {
+ //color needs to elements to store srgb and linear
+ gv.buffer_elements = 3;
+ }
+ if (p_type == RS::GLOBAL_VAR_TYPE_MAT4 || p_type == RS::GLOBAL_VAR_TYPE_TRANSFORM) {
+ //color needs to elements to store srgb and linear
+ gv.buffer_elements = 4;
+ }
+
+ //is vector, allocate in buffer and update index
+ gv.buffer_index = _global_variable_allocate(gv.buffer_elements);
+ ERR_FAIL_COND_MSG(gv.buffer_index < 0, vformat("Failed allocating global variable '%s' out of buffer memory. Consider increasing it in the Project Settings.", String(p_name)));
+ global_variables.buffer_usage[gv.buffer_index].elements = gv.buffer_elements;
+ _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value);
+ _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
+
+ global_variables.must_update_buffer_materials = true; //normally ther are no
+ }
+
+ global_variables.variables[p_name] = gv;
+}
+
+void RasterizerStorageRD::global_variable_remove(const StringName &p_name) {
+ if (!global_variables.variables.has(p_name)) {
+ return;
+ }
+ GlobalVariables::Variable &gv = global_variables.variables[p_name];
+
+ if (gv.buffer_index >= 0) {
+ global_variables.buffer_usage[gv.buffer_index].elements = 0;
+ global_variables.must_update_buffer_materials = true;
+ } else {
+ global_variables.must_update_texture_materials = true;
+ }
+
+ global_variables.variables.erase(p_name);
+}
+Vector<StringName> RasterizerStorageRD::global_variable_get_list() const {
+
+ if (!Engine::get_singleton()->is_editor_hint()) {
+ ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance.");
+ }
+
+ const StringName *K = NULL;
+ Vector<StringName> names;
+ while ((K = global_variables.variables.next(K))) {
+ names.push_back(*K);
+ }
+ names.sort_custom<StringName::AlphCompare>();
+ return names;
+}
+
+void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Variant &p_value) {
+ ERR_FAIL_COND(!global_variables.variables.has(p_name));
+ GlobalVariables::Variable &gv = global_variables.variables[p_name];
+ gv.value = p_value;
+ if (gv.override.get_type() == Variant::NIL) {
+ if (gv.buffer_index >= 0) {
+ //buffer
+ _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value);
+ _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
+ } else {
+ //texture
+ for (Set<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) {
+ Material *material = material_owner.getornull(E->get());
+ ERR_CONTINUE(!material);
+ _material_queue_update(material, false, true);
+ }
+ }
+ }
+}
+void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
+ if (!global_variables.variables.has(p_name)) {
+ return; //variable may not exist
+ }
+ GlobalVariables::Variable &gv = global_variables.variables[p_name];
+
+ gv.override = p_value;
+
+ if (gv.buffer_index >= 0) {
+ //buffer
+ if (gv.override.get_type() == Variant::NIL) {
+ _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value);
+ } else {
+ _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.override);
+ }
+
+ _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
+ } else {
+ //texture
+ //texture
+ for (Set<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) {
+ Material *material = material_owner.getornull(E->get());
+ ERR_CONTINUE(!material);
+ _material_queue_update(material, false, true);
+ }
+ }
+}
+
+Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const {
+
+ if (!Engine::get_singleton()->is_editor_hint()) {
+ ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance.");
+ }
+
+ if (!global_variables.variables.has(p_name)) {
+ return Variant();
+ }
+
+ return global_variables.variables[p_name].value;
+}
+
+RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(const StringName &p_name) const {
+
+ if (!global_variables.variables.has(p_name)) {
+ return RS::GLOBAL_VAR_TYPE_MAX;
+ }
+
+ return global_variables.variables[p_name].type;
+}
+
+RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const StringName &p_name) const {
+ if (!Engine::get_singleton()->is_editor_hint()) {
+ ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance.");
+ }
+
+ return global_variable_get_type_internal(p_name);
+}
+
+void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) {
+
+ List<PropertyInfo> settings;
+ ProjectSettings::get_singleton()->get_property_list(&settings);
+
+ for (List<PropertyInfo>::Element *E = settings.front(); E; E = E->next()) {
+ if (E->get().name.begins_with("shader_globals/")) {
+ StringName name = E->get().name.get_slice("/", 1);
+ Dictionary d = ProjectSettings::get_singleton()->get(E->get().name);
+
+ ERR_CONTINUE(!d.has("type"));
+ ERR_CONTINUE(!d.has("value"));
+
+ String type = d["type"];
+
+ static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = {
+ "bool",
+ "bvec2",
+ "bvec3",
+ "bvec4",
+ "int",
+ "ivec2",
+ "ivec3",
+ "ivec4",
+ "rect2i",
+ "uint",
+ "uvec2",
+ "uvec3",
+ "uvec4",
+ "float",
+ "vec2",
+ "vec3",
+ "vec4",
+ "color",
+ "rect2",
+ "mat2",
+ "mat3",
+ "mat4",
+ "transform_2d",
+ "transform",
+ "sampler2D",
+ "sampler2DArray",
+ "sampler3D",
+ "samplerCube",
+ };
+
+ RS::GlobalVariableType gvtype = RS::GLOBAL_VAR_TYPE_MAX;
+
+ for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) {
+ if (global_var_type_names[i] == type) {
+ gvtype = RS::GlobalVariableType(i);
+ break;
+ }
+ }
+
+ ERR_CONTINUE(gvtype == RS::GLOBAL_VAR_TYPE_MAX); //type invalid
+
+ Variant value = d["value"];
+
+ if (gvtype >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) {
+ //textire
+ if (!p_load_textures) {
+ value = RID();
+ continue;
+ }
+
+ String path = value;
+ RES resource = ResourceLoader::load(path);
+ ERR_CONTINUE(resource.is_null());
+ value = resource;
+ }
+
+ if (global_variables.variables.has(name)) {
+ //has it, update it
+ global_variable_set(name, value);
+ } else {
+ global_variable_add(name, gvtype, value);
+ }
+ }
+ }
+}
+
+void RasterizerStorageRD::global_variables_clear() {
+ global_variables.variables.clear(); //not right but for now enough
+}
+
+RID RasterizerStorageRD::global_variables_get_storage_buffer() const {
+ return global_variables.buffer;
+}
+
+int32_t RasterizerStorageRD::global_variables_instance_allocate(RID p_instance) {
+ ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1);
+ int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
+ global_variables.instance_buffer_pos[p_instance] = pos; //save anyway
+ ERR_FAIL_COND_V_MSG(pos < 0, -1, "Too many instances using shader instance variables. Increase buffer size in Project Settings.");
+ global_variables.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES;
+ return pos;
+}
+
+void RasterizerStorageRD::global_variables_instance_free(RID p_instance) {
+ ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance));
+ int32_t pos = global_variables.instance_buffer_pos[p_instance];
+ if (pos >= 0) {
+ global_variables.buffer_usage[pos].elements = 0;
+ }
+ global_variables.instance_buffer_pos.erase(p_instance);
+}
+void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
+
+ if (!global_variables.instance_buffer_pos.has(p_instance)) {
+ return; //just not allocated, ignore
+ }
+ int32_t pos = global_variables.instance_buffer_pos[p_instance];
+
+ if (pos < 0) {
+ return; //again, not allocated, ignore
+ }
+ ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
+ ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported
+
+ ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = {
+ ShaderLanguage::TYPE_MAX, //nil
+ ShaderLanguage::TYPE_BOOL, //bool
+ ShaderLanguage::TYPE_INT, //int
+ ShaderLanguage::TYPE_FLOAT, //float
+ ShaderLanguage::TYPE_MAX, //string
+ ShaderLanguage::TYPE_VEC2, //vec2
+ ShaderLanguage::TYPE_IVEC2, //vec2i
+ ShaderLanguage::TYPE_VEC4, //rect2
+ ShaderLanguage::TYPE_IVEC4, //rect2i
+ ShaderLanguage::TYPE_VEC3, // vec3
+ ShaderLanguage::TYPE_IVEC3, //vec3i
+ ShaderLanguage::TYPE_MAX, //xform2d not supported here
+ ShaderLanguage::TYPE_VEC4, //plane
+ ShaderLanguage::TYPE_VEC4, //quat
+ ShaderLanguage::TYPE_MAX, //aabb not supported here
+ ShaderLanguage::TYPE_MAX, //basis not supported here
+ ShaderLanguage::TYPE_MAX, //xform not supported here
+ ShaderLanguage::TYPE_VEC4 //color
+ };
+
+ ShaderLanguage::DataType datatype = datatype_from_value[p_value.get_type()];
+
+ ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported
+
+ pos += p_index;
+
+ _fill_std140_variant_ubo_value(datatype, p_value, (uint8_t *)&global_variables.buffer_values[pos], true); //instances always use linear color in this renderer
+ _global_variable_mark_buffer_dirty(pos, 1);
+}
+
+void RasterizerStorageRD::_update_global_variables() {
+
+ if (global_variables.buffer_dirty_region_count > 0) {
+ uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE;
+ if (total_regions / global_variables.buffer_dirty_region_count <= 4) {
+ // 25% of regions dirty, just update all buffer
+ RD::get_singleton()->buffer_update(global_variables.buffer, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size, global_variables.buffer_values);
+ zeromem(global_variables.buffer_dirty_regions, sizeof(bool) * total_regions);
+ } else {
+ uint32_t region_byte_size = sizeof(GlobalVariables::Value) * GlobalVariables::BUFFER_DIRTY_REGION_SIZE;
+
+ for (uint32_t i = 0; i < total_regions; i++) {
+ if (global_variables.buffer_dirty_regions[i]) {
+
+ RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, global_variables.buffer_values);
+
+ global_variables.buffer_dirty_regions[i] = false;
+ }
+ }
+ }
+
+ global_variables.buffer_dirty_region_count = 0;
+ }
+
+ if (global_variables.must_update_buffer_materials) {
+ // only happens in the case of a buffer variable added or removed,
+ // so not often.
+ for (List<RID>::Element *E = global_variables.materials_using_buffer.front(); E; E = E->next()) {
+ Material *material = material_owner.getornull(E->get());
+ ERR_CONTINUE(!material); //wtf
+
+ _material_queue_update(material, true, false);
+ }
+
+ global_variables.must_update_buffer_materials = false;
+ }
+
+ if (global_variables.must_update_texture_materials) {
+ // only happens in the case of a buffer variable added or removed,
+ // so not often.
+ for (List<RID>::Element *E = global_variables.materials_using_texture.front(); E; E = E->next()) {
+ Material *material = material_owner.getornull(E->get());
+ ERR_CONTINUE(!material); //wtf
+
+ _material_queue_update(material, false, true);
+ print_line("update material texture?");
+ }
+
+ global_variables.must_update_texture_materials = false;
+ }
+}
+
void RasterizerStorageRD::update_dirty_resources() {
+ _update_global_variables(); //must do before materials, so it can queue them for update
_update_queued_materials();
_update_dirty_multimeshes();
_update_dirty_skeletons();
+ _update_decal_atlas();
}
bool RasterizerStorageRD::has_os_feature(const String &p_feature) const {
@@ -4339,6 +5496,11 @@ bool RasterizerStorageRD::free(RID p_rid) {
}
}
+ if (decal_atlas.textures.has(p_rid)) {
+ decal_atlas.textures.erase(p_rid);
+ //there is not much a point of making it dirty, just let it be.
+ }
+
for (int i = 0; i < t->proxies.size(); i++) {
Texture *p = texture_owner.getornull(t->proxies[i]);
ERR_CONTINUE(!p);
@@ -4389,6 +5551,15 @@ bool RasterizerStorageRD::free(RID p_rid) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid);
reflection_probe->instance_dependency.instance_notify_deleted(p_rid);
reflection_probe_owner.free(p_rid);
+ } else if (decal_owner.owns(p_rid)) {
+ Decal *decal = decal_owner.getornull(p_rid);
+ for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
+ if (decal->textures[i].is_valid() && texture_owner.owns(decal->textures[i])) {
+ texture_remove_from_decal_atlas(decal->textures[i]);
+ }
+ }
+ decal->instance_dependency.instance_notify_deleted(p_rid);
+ decal_owner.free(p_rid);
} else if (gi_probe_owner.owns(p_rid)) {
gi_probe_allocate(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
GIProbe *gi_probe = gi_probe_owner.getornull(p_rid);
@@ -4397,6 +5568,7 @@ bool RasterizerStorageRD::free(RID p_rid) {
} else if (light_owner.owns(p_rid)) {
+ light_set_projector(p_rid, RID()); //clear projector
// delete the texture
Light *light = light_owner.getornull(p_rid);
light->instance_dependency.instance_notify_deleted(p_rid);
@@ -4450,12 +5622,27 @@ String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const
return RD::get_singleton()->get_captured_timestamp_name(p_index);
}
+RasterizerStorageRD *RasterizerStorageRD::base_singleton = nullptr;
+
RasterizerStorageRD::RasterizerStorageRD() {
+ base_singleton = this;
+
for (int i = 0; i < SHADER_TYPE_MAX; i++) {
shader_data_request_func[i] = nullptr;
}
+ static_assert(sizeof(GlobalVariables::Value) == 16);
+
+ global_variables.buffer_size = GLOBAL_GET("rendering/high_end/global_shader_variables_buffer_size");
+ global_variables.buffer_size = MAX(4096, global_variables.buffer_size);
+ global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size);
+ zeromem(global_variables.buffer_values, sizeof(GlobalVariables::Value) * global_variables.buffer_size);
+ global_variables.buffer_usage = memnew_arr(GlobalVariables::ValueUsage, global_variables.buffer_size);
+ global_variables.buffer_dirty_regions = memnew_arr(bool, global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE);
+ zeromem(global_variables.buffer_dirty_regions, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE);
+ global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size);
+
material_update_list = nullptr;
{ //create default textures
@@ -4492,6 +5679,10 @@ RasterizerStorageRD::RasterizerStorageRD() {
Vector<Vector<uint8_t>> vpv;
vpv.push_back(pv);
default_rd_textures[DEFAULT_RD_TEXTURE_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+
+ //take the chance and initialize decal atlas to something
+ decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+ decal_atlas.texture_srgb = decal_atlas.texture;
}
for (int i = 0; i < 16; i++) {
@@ -4644,14 +5835,14 @@ RasterizerStorageRD::RasterizerStorageRD() {
sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.use_anisotropy = true;
- sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/filters/max_anisotropy");
+ sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/texture_filters/max_anisotropy");
} break;
case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: {
sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.use_anisotropy = true;
- sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/filters/max_anisotropy");
+ sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/texture_filters/max_anisotropy");
} break;
default: {
@@ -4683,9 +5874,11 @@ RasterizerStorageRD::RasterizerStorageRD() {
//default rd buffers
{
- { //vertex
+ //vertex
+ {
Vector<uint8_t> buffer;
+
buffer.resize(sizeof(float) * 3);
{
uint8_t *w = buffer.ptrw();
@@ -4803,6 +5996,11 @@ RasterizerStorageRD::RasterizerStorageRD() {
RasterizerStorageRD::~RasterizerStorageRD() {
+ memdelete_arr(global_variables.buffer_values);
+ memdelete_arr(global_variables.buffer_usage);
+ memdelete_arr(global_variables.buffer_dirty_regions);
+ RD::get_singleton()->free(global_variables.buffer);
+
//def textures
for (int i = 0; i < DEFAULT_RD_TEXTURE_MAX; i++) {
RD::get_singleton()->free(default_rd_textures[i]);
@@ -4820,4 +6018,12 @@ RasterizerStorageRD::~RasterizerStorageRD() {
RD::get_singleton()->free(mesh_default_rd_buffers[i]);
}
giprobe_sdf_shader.version_free(giprobe_sdf_shader_version);
+
+ if (decal_atlas.textures.size()) {
+ ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
+ }
+
+ if (decal_atlas.texture.is_valid()) {
+ RD::get_singleton()->free(decal_atlas.texture);
+ }
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
index 49f77e49e1..f874c3baf8 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
@@ -52,6 +52,8 @@ public:
virtual void set_code(const String &p_Code) = 0;
virtual void set_default_texture_param(const StringName &p_name, RID p_texture) = 0;
virtual void get_param_list(List<PropertyInfo> *p_param_list) const = 0;
+
+ virtual void get_instance_param_list(List<InstanceShaderParam> *p_param_list) const = 0;
virtual bool is_param_texture(const StringName &p_param) const = 0;
virtual bool is_animated() const = 0;
virtual bool casts_shadows() const = 0;
@@ -69,7 +71,15 @@ public:
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0;
- virtual ~MaterialData() {}
+ virtual ~MaterialData();
+
+ private:
+ friend class RasterizerStorageRD;
+ RID self;
+ List<RID>::Element *global_buffer_E = nullptr;
+ List<RID>::Element *global_texture_E = nullptr;
+ uint64_t global_textures_pass = 0;
+ Map<StringName, uint64_t> used_global_textures;
};
typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *);
@@ -173,6 +183,51 @@ private:
RID default_rd_textures[DEFAULT_RD_TEXTURE_MAX];
RID default_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
+ /* DECAL ATLAS */
+
+ struct DecalAtlas {
+ struct Texture {
+
+ int panorama_to_dp_users;
+ int users;
+ Rect2 uv_rect;
+ };
+
+ struct SortItem {
+ RID texture;
+ Size2i pixel_size;
+ Size2i size;
+ Point2i pos;
+
+ bool operator<(const SortItem &p_item) const {
+ //sort larger to smaller
+ if (size.height == p_item.size.height) {
+ return size.width > p_item.size.width;
+ } else {
+ return size.height > p_item.size.height;
+ }
+ }
+ };
+
+ HashMap<RID, Texture> textures;
+ bool dirty = true;
+ int mipmaps = 5;
+
+ RID texture;
+ RID texture_srgb;
+ struct MipMap {
+ RID fb;
+ RID texture;
+ Size2i size;
+ };
+ Vector<MipMap> texture_mipmaps;
+
+ Size2i size;
+
+ } decal_atlas;
+
+ void _update_decal_atlas();
+
/* SHADER */
struct Material;
@@ -403,6 +458,28 @@ private:
mutable RID_Owner<ReflectionProbe> reflection_probe_owner;
+ /* DECAL */
+
+ struct Decal {
+
+ Vector3 extents = Vector3(1, 1, 1);
+ RID textures[RS::DECAL_TEXTURE_MAX];
+ float emission_energy = 1.0;
+ float albedo_mix = 1.0;
+ Color modulate = Color(1, 1, 1, 1);
+ uint32_t cull_mask = (1 << 20) - 1;
+ float upper_fade = 0.3;
+ float lower_fade = 0.3;
+ bool distance_fade = false;
+ float distance_fade_begin = 10;
+ float distance_fade_length = 1;
+ float normal_fade = 0.0;
+
+ RasterizerScene::InstanceDependency instance_dependency;
+ };
+
+ mutable RID_Owner<Decal> decal_owner;
+
/* GI PROBE */
struct GIProbe {
@@ -463,13 +540,11 @@ private:
bool flags[RENDER_TARGET_FLAG_MAX];
RID backbuffer; //used for effects
- RID backbuffer_fb;
+ RID backbuffer_mipmap0;
struct BackbufferMipmap {
RID mipmap;
- RID mipmap_fb;
RID mipmap_copy;
- RID mipmap_copy_fb;
};
Vector<BackbufferMipmap> backbuffer_mipmaps;
@@ -490,6 +565,73 @@ private:
void _update_render_target(RenderTarget *rt);
void _create_render_target_backbuffer(RenderTarget *rt);
+ /* GLOBAL SHADER VARIABLES */
+
+ struct GlobalVariables {
+
+ enum {
+ BUFFER_DIRTY_REGION_SIZE = 1024
+ };
+ struct Variable {
+ Set<RID> texture_materials; // materials using this
+
+ RS::GlobalVariableType type;
+ Variant value;
+ Variant override;
+ int32_t buffer_index; //for vectors
+ int32_t buffer_elements; //for vectors
+ };
+
+ HashMap<StringName, Variable> variables;
+
+ struct Value {
+ float x;
+ float y;
+ float z;
+ float w;
+ };
+
+ struct ValueInt {
+ int32_t x;
+ int32_t y;
+ int32_t z;
+ int32_t w;
+ };
+
+ struct ValueUInt {
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+ uint32_t w;
+ };
+
+ struct ValueUsage {
+ uint32_t elements = 0;
+ };
+
+ List<RID> materials_using_buffer;
+ List<RID> materials_using_texture;
+
+ RID buffer;
+ Value *buffer_values;
+ ValueUsage *buffer_usage;
+ bool *buffer_dirty_regions;
+ uint32_t buffer_dirty_region_count = 0;
+
+ uint32_t buffer_size;
+
+ bool must_update_texture_materials = false;
+ bool must_update_buffer_materials = false;
+
+ HashMap<RID, int32_t> instance_buffer_pos;
+
+ } global_variables;
+
+ int32_t _global_variable_allocate(uint32_t p_elements);
+ void _global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value);
+ void _global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements);
+
+ void _update_global_variables();
/* EFFECTS */
RasterizerEffectsRD effects;
@@ -535,6 +677,20 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy);
+ virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false);
+ virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false);
+
+ RID decal_atlas_get_texture() const;
+ RID decal_atlas_get_texture_srgb() const;
+ _FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
+ DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
+ if (!t) {
+ return Rect2();
+ }
+
+ return t->uv_rect;
+ }
+
//internal usage
_FORCE_INLINE_ RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) {
@@ -596,6 +752,8 @@ public:
bool material_is_animated(RID p_material);
bool material_casts_shadows(RID p_material);
+ void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters);
+
void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance);
void material_force_update_textures(RID p_material, ShaderType p_shader_type);
@@ -886,6 +1044,14 @@ public:
return light->param[p_param];
}
+ _FORCE_INLINE_ RID light_get_projector(RID p_light) {
+
+ const Light *light = light_owner.getornull(p_light);
+ ERR_FAIL_COND_V(!light, RID());
+
+ return light->projector;
+ }
+
_FORCE_INLINE_ Color light_get_color(RID p_light) {
const Light *light = light_owner.getornull(p_light);
@@ -926,6 +1092,14 @@ public:
return light->negative;
}
+ _FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const {
+
+ const Light *light = light_owner.getornull(p_light);
+ ERR_FAIL_COND_V(!light, 0.0);
+
+ return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS];
+ }
+
bool light_get_use_gi(RID p_light);
uint64_t light_get_version(RID p_light) const;
@@ -966,6 +1140,81 @@ public:
void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance);
void skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance);
+ /* DECAL API */
+
+ virtual RID decal_create();
+ virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents);
+ virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture);
+ virtual void decal_set_emission_energy(RID p_decal, float p_energy);
+ virtual void decal_set_albedo_mix(RID p_decal, float p_mix);
+ virtual void decal_set_modulate(RID p_decal, const Color &p_modulate);
+ virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers);
+ virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length);
+ virtual void decal_set_fade(RID p_decal, float p_above, float p_below);
+ virtual void decal_set_normal_fade(RID p_decal, float p_fade);
+
+ _FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->extents;
+ }
+
+ _FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->textures[p_texture];
+ }
+
+ _FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->modulate;
+ }
+
+ _FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->emission_energy;
+ }
+
+ _FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->albedo_mix;
+ }
+
+ _FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->cull_mask;
+ }
+
+ _FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->upper_fade;
+ }
+
+ _FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->lower_fade;
+ }
+
+ _FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->normal_fade;
+ }
+
+ _FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->distance_fade;
+ }
+
+ _FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->distance_fade_begin;
+ }
+
+ _FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
+ const Decal *decal = decal_owner.getornull(p_decal);
+ return decal->distance_fade_length;
+ }
+
+ virtual AABB decal_get_aabb(RID p_decal) const;
+
/* GI PROBE API */
RID gi_probe_create();
@@ -1076,6 +1325,27 @@ public:
virtual bool particles_is_inactive(RID p_particles) const { return false; }
+ /* GLOBAL VARIABLES API */
+
+ virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value);
+ virtual void global_variable_remove(const StringName &p_name);
+ virtual Vector<StringName> global_variable_get_list() const;
+
+ virtual void global_variable_set(const StringName &p_name, const Variant &p_value);
+ virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value);
+ virtual Variant global_variable_get(const StringName &p_name) const;
+ virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const;
+ RS::GlobalVariableType global_variable_get_type_internal(const StringName &p_name) const;
+
+ virtual void global_variables_load_settings(bool p_load_textures = true);
+ virtual void global_variables_clear();
+
+ virtual int32_t global_variables_instance_allocate(RID p_instance);
+ virtual void global_variables_instance_free(RID p_instance);
+ virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value);
+
+ RID global_variables_get_storage_buffer() const;
+
/* RENDER TARGET API */
RID render_target_create();
@@ -1097,6 +1367,7 @@ public:
Size2 render_target_get_size(RID p_render_target);
RID render_target_get_rd_framebuffer(RID p_render_target);
+ RID render_target_get_rd_texture(RID p_render_target);
RS::InstanceType get_base_type(RID p_rid) const;
@@ -1124,7 +1395,7 @@ public:
virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const;
virtual String get_captured_timestamp_name(uint32_t p_index) const;
- static RasterizerStorage *base_singleton;
+ static RasterizerStorageRD *base_singleton;
RasterizerEffectsRD *get_effects();
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
index 4a0b4f02b1..9cbff2571a 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
@@ -32,6 +32,8 @@
#include "core/os/os.h"
#include "core/project_settings.h"
+#include "rasterizer_storage_rd.h"
+#include "servers/rendering_server.h"
#define SL ShaderLanguage
@@ -91,6 +93,9 @@ static int _get_datatype_size(SL::DataType p_type) {
case SL::TYPE_USAMPLER3D: return 16;
case SL::TYPE_SAMPLERCUBE: return 16;
case SL::TYPE_STRUCT: return 0;
+ case SL::TYPE_MAX: {
+ ERR_FAIL_V(0);
+ };
}
ERR_FAIL_V(0);
@@ -131,6 +136,9 @@ static int _get_datatype_alignment(SL::DataType p_type) {
case SL::TYPE_USAMPLER3D: return 16;
case SL::TYPE_SAMPLERCUBE: return 16;
case SL::TYPE_STRUCT: return 0;
+ case SL::TYPE_MAX: {
+ ERR_FAIL_V(0);
+ }
}
ERR_FAIL_V(0);
@@ -341,6 +349,71 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S
}
}
+static String _get_global_variable_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) {
+ switch (p_type) {
+ case ShaderLanguage::TYPE_BOOL: {
+ return "(" + p_buffer + "[" + p_index + "].x != 0.0)";
+ }
+ case ShaderLanguage::TYPE_BVEC2: {
+ return "(" + p_buffer + "[" + p_index + "].xy != vec2(0.0))";
+ }
+ case ShaderLanguage::TYPE_BVEC3: {
+ return "(" + p_buffer + "[" + p_index + "].xyz != vec3(0.0))";
+ }
+ case ShaderLanguage::TYPE_BVEC4: {
+ return "(" + p_buffer + "[" + p_index + "].xyzw != vec4(0.0))";
+ }
+ case ShaderLanguage::TYPE_INT: {
+ return "floatBitsToInt(" + p_buffer + "[" + p_index + "].x)";
+ }
+ case ShaderLanguage::TYPE_IVEC2: {
+ return "floatBitsToInt(" + p_buffer + "[" + p_index + "].xy)";
+ }
+ case ShaderLanguage::TYPE_IVEC3: {
+ return "floatBitsToInt(" + p_buffer + "[" + p_index + "].xyz)";
+ }
+ case ShaderLanguage::TYPE_IVEC4: {
+ return "floatBitsToInt(" + p_buffer + "[" + p_index + "].xyzw)";
+ }
+ case ShaderLanguage::TYPE_UINT: {
+ return "floatBitsToUInt(" + p_buffer + "[" + p_index + "].x)";
+ }
+ case ShaderLanguage::TYPE_UVEC2: {
+ return "floatBitsToUInt(" + p_buffer + "[" + p_index + "].xy)";
+ }
+ case ShaderLanguage::TYPE_UVEC3: {
+ return "floatBitsToUInt(" + p_buffer + "[" + p_index + "].xyz)";
+ }
+ case ShaderLanguage::TYPE_UVEC4: {
+ return "floatBitsToUInt(" + p_buffer + "[" + p_index + "].xyzw)";
+ }
+ case ShaderLanguage::TYPE_FLOAT: {
+ return "(" + p_buffer + "[" + p_index + "].x)";
+ }
+ case ShaderLanguage::TYPE_VEC2: {
+ return "(" + p_buffer + "[" + p_index + "].xy)";
+ }
+ case ShaderLanguage::TYPE_VEC3: {
+ return "(" + p_buffer + "[" + p_index + "].xyz)";
+ }
+ case ShaderLanguage::TYPE_VEC4: {
+ return "(" + p_buffer + "[" + p_index + "].xyzw)";
+ }
+ case ShaderLanguage::TYPE_MAT2: {
+ return "mat2(" + p_buffer + "[" + p_index + "].xy," + p_buffer + "[" + p_index + "+1].xy)";
+ }
+ case ShaderLanguage::TYPE_MAT3: {
+ return "mat3(" + p_buffer + "[" + p_index + "].xyz," + p_buffer + "[" + p_index + "+1].xyz," + p_buffer + "[" + p_index + "+2].xyz)";
+ }
+ case ShaderLanguage::TYPE_MAT4: {
+ return "mat4(" + p_buffer + "[" + p_index + "].xyzw," + p_buffer + "[" + p_index + "+1].xyzw," + p_buffer + "[" + p_index + "+2].xyzw," + p_buffer + "[" + p_index + "+3].xyzw)";
+ }
+ default: {
+ ERR_FAIL_V("void");
+ }
+ }
+}
+
String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) {
String code;
@@ -408,10 +481,17 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
int max_uniforms = 0;
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
- if (SL::is_sampler_type(E->get().type))
+
+ if (SL::is_sampler_type(E->get().type)) {
max_texture_uniforms++;
- else
+ } else {
+
+ if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue; //instances are indexed directly, dont need index uniforms
+ }
+
max_uniforms++;
+ }
}
r_gen_code.texture_uniforms.resize(max_texture_uniforms);
@@ -428,12 +508,25 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
String ucode;
+ if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ //insert, but don't generate any code.
+ p_actions.uniforms->insert(E->key(), E->get());
+ continue; //instances are indexed directly, dont need index uniforms
+ }
if (SL::is_sampler_type(E->get().type)) {
ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + E->get().texture_order) + ") uniform ";
}
- ucode += _prestr(E->get().precision);
- ucode += _typestr(E->get().type);
+ bool is_buffer_global = !SL::is_sampler_type(E->get().type) && E->get().scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL;
+
+ if (is_buffer_global) {
+ //this is an integer to index the global table
+ ucode += _typestr(ShaderLanguage::TYPE_UINT);
+ } else {
+ ucode += _prestr(E->get().precision);
+ ucode += _typestr(E->get().type);
+ }
+
ucode += " " + _mkid(E->key());
ucode += ";\n";
if (SL::is_sampler_type(E->get().type)) {
@@ -446,6 +539,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
texture.type = E->get().type;
texture.filter = E->get().filter;
texture.repeat = E->get().repeat;
+ texture.global = E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL;
+ if (texture.global) {
+ r_gen_code.uses_global_textures = true;
+ }
r_gen_code.texture_uniforms.write[E->get().texture_order] = texture;
} else {
@@ -455,8 +552,14 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
uses_uniforms = true;
}
uniform_defines.write[E->get().order] = ucode;
- uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type);
- uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type);
+ if (is_buffer_global) {
+ //globals are indices into the global table
+ uniform_sizes.write[E->get().order] = _get_datatype_size(ShaderLanguage::TYPE_UINT);
+ uniform_alignments.write[E->get().order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT);
+ } else {
+ uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type);
+ uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type);
+ }
}
p_actions.uniforms->insert(E->key(), E->get());
@@ -690,9 +793,29 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
if (p_default_actions.renames.has(vnode->name))
code = p_default_actions.renames[vnode->name];
else {
- code = _mkid(vnode->name);
- if (actions.base_uniform_string != String() && shader->uniforms.has(vnode->name) && shader->uniforms[vnode->name].texture_order < 0) {
- code = actions.base_uniform_string + code;
+ if (shader->uniforms.has(vnode->name)) {
+ //its a uniform!
+ const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[vnode->name];
+ if (u.texture_order >= 0) {
+ code = _mkid(vnode->name); //texture, use as is
+ } else {
+ //a scalar or vector
+ if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
+ code = actions.base_uniform_string + _mkid(vnode->name); //texture, use as is
+ //global variable, this means the code points to an index to the global table
+ code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type);
+ } else if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ //instance variable, index it as such
+ code = "(" + p_default_actions.instance_uniform_index_variable + "+" + itos(u.instance_index) + ")";
+ code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type);
+ } else {
+ //regular uniform, index from UBO
+ code = actions.base_uniform_string + _mkid(vnode->name);
+ }
+ }
+
+ } else {
+ code = _mkid(vnode->name); //its something else (local var most likely) use as is
}
}
@@ -1037,9 +1160,14 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
return code;
}
+ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &p_type) {
+ RS::GlobalVariableType gvt = ((RasterizerStorageRD *)(RasterizerStorage::base_singleton))->global_variable_get_type_internal(p_type);
+ return RS::global_variable_type_get_shader_datatype(gvt);
+}
+
Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
- Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types());
+ Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types(), _get_variable_type);
if (err != OK) {
@@ -1060,6 +1188,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide
r_gen_code.light = String();
r_gen_code.uses_fragment_time = false;
r_gen_code.uses_vertex_time = false;
+ r_gen_code.uses_global_textures = false;
used_name_defines.clear();
used_rmode_defines.clear();
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/rasterizer_rd/shader_compiler_rd.h
index 7d78469e9c..16d53197a7 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.h
@@ -57,6 +57,7 @@ public:
ShaderLanguage::ShaderNode::Uniform::Hint hint;
ShaderLanguage::TextureFilter filter;
ShaderLanguage::TextureRepeat repeat;
+ bool global;
};
Vector<Texture> texture_uniforms;
@@ -70,6 +71,7 @@ public:
String fragment;
String light;
+ bool uses_global_textures;
bool uses_fragment_time;
bool uses_vertex_time;
};
@@ -86,6 +88,8 @@ public:
int base_texture_binding_index = 0;
int texture_layout_set = 0;
String base_uniform_string;
+ String global_buffer_array_variable;
+ String instance_uniform_index_variable;
uint32_t base_varying_index = 0;
};
@@ -113,6 +117,8 @@ private:
DefaultIdentifierActions actions;
+ static ShaderLanguage::DataType _get_variable_type(const StringName &p_type);
+
public:
Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code);
diff --git a/servers/rendering/rasterizer_rd/shaders/SCsub b/servers/rendering/rasterizer_rd/shaders/SCsub
index 04a43e3251..a454d144aa 100644
--- a/servers/rendering/rasterizer_rd/shaders/SCsub
+++ b/servers/rendering/rasterizer_rd/shaders/SCsub
@@ -5,14 +5,15 @@ Import("env")
if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("canvas.glsl")
env.RD_GLSL("canvas_occlusion.glsl")
- env.RD_GLSL("blur.glsl")
+ env.RD_GLSL("copy.glsl")
+ env.RD_GLSL("copy_to_fb.glsl")
env.RD_GLSL("cubemap_roughness.glsl")
env.RD_GLSL("cubemap_downsampler.glsl")
env.RD_GLSL("cubemap_filter.glsl")
env.RD_GLSL("scene_high_end.glsl")
env.RD_GLSL("sky.glsl")
env.RD_GLSL("tonemap.glsl")
- env.RD_GLSL("copy.glsl")
+ env.RD_GLSL("cube_to_dp.glsl")
env.RD_GLSL("giprobe.glsl")
env.RD_GLSL("giprobe_debug.glsl")
env.RD_GLSL("giprobe_sdf.glsl")
diff --git a/servers/rendering/rasterizer_rd/shaders/blur.glsl b/servers/rendering/rasterizer_rd/shaders/blur.glsl
deleted file mode 100644
index 87c20ebaef..0000000000
--- a/servers/rendering/rasterizer_rd/shaders/blur.glsl
+++ /dev/null
@@ -1,294 +0,0 @@
-/* clang-format off */
-[vertex]
-
-#version 450
-
-VERSION_DEFINES
-
-#include "blur_inc.glsl"
-
-layout(location = 0) out vec2 uv_interp;
-/* clang-format on */
-
-void main() {
-
- vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
- uv_interp = base_arr[gl_VertexIndex];
-
- if (bool(blur.flags & FLAG_USE_BLUR_SECTION)) {
- uv_interp = blur.section.xy + uv_interp * blur.section.zw;
- }
-
- gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
-
- if (bool(blur.flags & FLAG_FLIP_Y)) {
- uv_interp.y = 1.0 - uv_interp.y;
- }
-}
-
-/* clang-format off */
-[fragment]
-
-#version 450
-
-VERSION_DEFINES
-
-#include "blur_inc.glsl"
-
-layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
-
-layout(set = 0, binding = 0) uniform sampler2D source_color;
-
-#ifdef MODE_SSAO_MERGE
-layout(set = 1, binding = 0) uniform sampler2D source_ssao;
-#endif
-
-#ifdef GLOW_USE_AUTO_EXPOSURE
-layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
-#endif
-
-layout(location = 0) out vec4 frag_color;
-
-//DOF
-#if defined(MODE_DOF_FAR_BLUR) || defined(MODE_DOF_NEAR_BLUR)
-
-layout(set = 1, binding = 0) uniform sampler2D dof_source_depth;
-
-#ifdef DOF_NEAR_BLUR_MERGE
-layout(set = 2, binding = 0) uniform sampler2D source_dof_original;
-#endif
-
-#ifdef DOF_QUALITY_LOW
-const int dof_kernel_size = 5;
-const int dof_kernel_from = 2;
-const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388);
-#endif
-
-#ifdef DOF_QUALITY_MEDIUM
-const int dof_kernel_size = 11;
-const int dof_kernel_from = 5;
-const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037);
-
-#endif
-
-#ifdef DOF_QUALITY_HIGH
-const int dof_kernel_size = 21;
-const int dof_kernel_from = 10;
-const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174);
-#endif
-
-#endif
-
-void main() {
-
-#ifdef MODE_MIPMAP
-
- vec2 pix_size = blur.pixel_size;
- vec4 color = texture(source_color, uv_interp + vec2(-0.5, -0.5) * pix_size);
- color += texture(source_color, uv_interp + vec2(0.5, -0.5) * pix_size);
- color += texture(source_color, uv_interp + vec2(0.5, 0.5) * pix_size);
- color += texture(source_color, uv_interp + vec2(-0.5, 0.5) * pix_size);
- frag_color = color / 4.0;
-
-#endif
-
-#ifdef MODE_GAUSSIAN_BLUR
-
- //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
-
- if (bool(blur.flags & FLAG_HORIZONTAL)) {
-
- vec2 pix_size = blur.pixel_size;
- pix_size *= 0.5; //reading from larger buffer, so use more samples
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.214607;
- color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.189879;
- color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.131514;
- color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.071303;
- color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.189879;
- color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.131514;
- color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.071303;
- frag_color = color;
- } else {
-
- vec2 pix_size = blur.pixel_size;
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.38774;
- color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.24477;
- color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.06136;
- color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.24477;
- color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.06136;
- frag_color = color;
- }
-#endif
-
-#ifdef MODE_GAUSSIAN_GLOW
-
- //Glow uses larger sigma 1 for a more rounded blur effect
-
-#define GLOW_ADD(m_ofs, m_mult) \
- { \
- vec2 ofs = uv_interp + m_ofs * pix_size; \
- vec4 c = texture(source_color, ofs) * m_mult; \
- if (any(lessThan(ofs, vec2(0.0))) || any(greaterThan(ofs, vec2(1.0)))) { \
- c *= 0.0; \
- } \
- color += c; \
- }
-
- if (bool(blur.flags & FLAG_HORIZONTAL)) {
-
- vec2 pix_size = blur.pixel_size;
- pix_size *= 0.5; //reading from larger buffer, so use more samples
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.174938;
- GLOW_ADD(vec2(1.0, 0.0), 0.165569);
- GLOW_ADD(vec2(2.0, 0.0), 0.140367);
- GLOW_ADD(vec2(3.0, 0.0), 0.106595);
- GLOW_ADD(vec2(-1.0, 0.0), 0.165569);
- GLOW_ADD(vec2(-2.0, 0.0), 0.140367);
- GLOW_ADD(vec2(-3.0, 0.0), 0.106595);
- color *= blur.glow_strength;
- frag_color = color;
- } else {
-
- vec2 pix_size = blur.pixel_size;
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.288713;
- GLOW_ADD(vec2(0.0, 1.0), 0.233062);
- GLOW_ADD(vec2(0.0, 2.0), 0.122581);
- GLOW_ADD(vec2(0.0, -1.0), 0.233062);
- GLOW_ADD(vec2(0.0, -2.0), 0.122581);
- color *= blur.glow_strength;
- frag_color = color;
- }
-
-#undef GLOW_ADD
-
- if (bool(blur.flags & FLAG_GLOW_FIRST_PASS)) {
-#ifdef GLOW_USE_AUTO_EXPOSURE
-
- frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / blur.glow_auto_exposure_grey;
-#endif
- frag_color *= blur.glow_exposure;
-
- float luminance = max(frag_color.r, max(frag_color.g, frag_color.b));
- float feedback = max(smoothstep(blur.glow_hdr_threshold, blur.glow_hdr_threshold + blur.glow_hdr_scale, luminance), blur.glow_bloom);
-
- frag_color = min(frag_color * feedback, vec4(blur.glow_luminance_cap));
- }
-
-#endif
-
-#ifdef MODE_DOF_FAR_BLUR
-
- vec4 color_accum = vec4(0.0);
-
- float depth = texture(dof_source_depth, uv_interp, 0.0).r;
- depth = depth * 2.0 - 1.0;
-
- if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) {
- depth = ((depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
- } else {
- depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near));
- }
-
- float amount = smoothstep(blur.dof_begin, blur.dof_end, depth);
- float k_accum = 0.0;
-
- for (int i = 0; i < dof_kernel_size; i++) {
-
- int int_ofs = i - dof_kernel_from;
- vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * amount * blur.dof_radius;
-
- float tap_k = dof_kernel[i];
-
- float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r;
- tap_depth = tap_depth * 2.0 - 1.0;
-
- if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) {
-
- tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
- } else {
- tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near));
- }
-
- float tap_amount = mix(smoothstep(blur.dof_begin, blur.dof_end, tap_depth), 1.0, int_ofs == 0);
- tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
-
- vec4 tap_color = texture(source_color, tap_uv, 0.0) * tap_k;
-
- k_accum += tap_k * tap_amount;
- color_accum += tap_color * tap_amount;
- }
-
- if (k_accum > 0.0) {
- color_accum /= k_accum;
- }
-
- frag_color = color_accum; ///k_accum;
-
-#endif
-
-#ifdef MODE_DOF_NEAR_BLUR
-
- vec4 color_accum = vec4(0.0);
-
- float max_accum = 0.0;
-
- for (int i = 0; i < dof_kernel_size; i++) {
-
- int int_ofs = i - dof_kernel_from;
- vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * blur.dof_radius;
- float ofs_influence = max(0.0, 1.0 - float(abs(int_ofs)) / float(dof_kernel_from));
-
- float tap_k = dof_kernel[i];
-
- vec4 tap_color = texture(source_color, tap_uv, 0.0);
-
- float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r;
- tap_depth = tap_depth * 2.0 - 1.0;
- if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) {
-
- tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
- } else {
- tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near));
- }
- float tap_amount = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth);
- tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
-
- if (bool(blur.flags & FLAG_DOF_NEAR_FIRST_TAP)) {
- tap_color.a = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth);
- }
-
- max_accum = max(max_accum, tap_amount * ofs_influence);
-
- color_accum += tap_color * tap_k;
- }
-
- color_accum.a = max(color_accum.a, sqrt(max_accum));
-
-#ifdef DOF_NEAR_BLUR_MERGE
- {
- vec4 original = texture(source_dof_original, uv_interp, 0.0);
- color_accum = mix(original, color_accum, color_accum.a);
- }
-#endif
-
- if (bool(blur.flags & FLAG_DOF_NEAR_FIRST_TAP)) {
- frag_color = color_accum;
- }
-#endif
-
-#ifdef MODE_SIMPLE_COPY
- vec4 color = texture(source_color, uv_interp, 0.0);
- if (bool(blur.flags & FLAG_COPY_FORCE_LUMINANCE)) {
- color.rgb = vec3(max(max(color.r, color.g), color.b));
- }
- frag_color = color;
-#endif
-
-#ifdef MODE_SSAO_MERGE
- vec4 color = texture(source_color, uv_interp, 0.0);
- float ssao = texture(source_ssao, uv_interp, 0.0).r;
- frag_color = vec4(mix(color.rgb, color.rgb * mix(blur.ssao_color.rgb, vec3(1.0), ssao), color.a), 1.0);
-
-#endif
-}
diff --git a/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl b/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl
deleted file mode 100644
index 33ba9de7bb..0000000000
--- a/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl
+++ /dev/null
@@ -1,35 +0,0 @@
-#define FLAG_HORIZONTAL (1 << 0)
-#define FLAG_USE_BLUR_SECTION (1 << 1)
-#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2)
-#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3)
-#define FLAG_GLOW_FIRST_PASS (1 << 4)
-#define FLAG_FLIP_Y (1 << 5)
-#define FLAG_COPY_FORCE_LUMINANCE (1 << 6)
-
-layout(push_constant, binding = 1, std430) uniform Blur {
- vec4 section;
- vec2 pixel_size;
- uint flags;
- uint pad;
- // Glow.
- float glow_strength;
- float glow_bloom;
- float glow_hdr_threshold;
- float glow_hdr_scale;
- float glow_exposure;
- float glow_white;
- float glow_luminance_cap;
- float glow_auto_exposure_grey;
- // DOF.
- float dof_begin;
- float dof_end;
- float dof_radius;
- float dof_pad;
-
- vec2 dof_dir;
- float camera_z_far;
- float camera_z_near;
-
- vec4 ssao_color;
-}
-blur;
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
index 1ac43480cd..a39866004b 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
@@ -132,6 +132,11 @@ layout(set = 2, binding = 6) uniform sampler shadow_sampler;
#endif
+layout(set = 2, binding = 7, std430) restrict readonly buffer GlobalVariableData {
+ vec4 data[];
+}
+global_variables;
+
/* SET3: Render Target Data */
#ifdef SCREEN_TEXTURE_USED
diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl
index cbb9b546a3..2d7661f65f 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl
@@ -1,86 +1,220 @@
/* clang-format off */
-[vertex]
+[compute]
#version 450
VERSION_DEFINES
-layout(location = 0) out vec2 uv_interp;
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
/* clang-format on */
-void main() {
+#define FLAG_HORIZONTAL (1 << 0)
+#define FLAG_USE_BLUR_SECTION (1 << 1)
+#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2)
+#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3)
+#define FLAG_GLOW_FIRST_PASS (1 << 4)
+#define FLAG_FLIP_Y (1 << 5)
+#define FLAG_FORCE_LUMINANCE (1 << 6)
+#define FLAG_COPY_ALL_SOURCE (1 << 7)
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ ivec4 section;
+ ivec2 target;
+ uint flags;
+ uint pad;
+ // Glow.
+ float glow_strength;
+ float glow_bloom;
+ float glow_hdr_threshold;
+ float glow_hdr_scale;
+
+ float glow_exposure;
+ float glow_white;
+ float glow_luminance_cap;
+ float glow_auto_exposure_grey;
+ // DOF.
+ float camera_z_far;
+ float camera_z_near;
+ uint pad2[2];
+}
+params;
- vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
- uv_interp = base_arr[gl_VertexIndex];
+layout(set = 0, binding = 0) uniform sampler2D source_color;
- gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
-}
+#ifdef GLOW_USE_AUTO_EXPOSURE
+layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
+#endif
-/* clang-format off */
-[fragment]
+#if defined(MODE_LINEARIZE_DEPTH_COPY) || defined(MODE_SIMPLE_COPY_DEPTH)
+layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
+#elif defined(DST_IMAGE_8BIT)
+layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
+#else
+layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
+#endif
-#version 450
+void main() {
-VERSION_DEFINES
+ // Pixel being shaded
+ ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+ if (any(greaterThan(pos, params.section.zw))) { //too large, do nothing
+ return;
+ }
-layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
+#ifdef MODE_MIPMAP
+
+ ivec2 base_pos = (pos + params.section.xy) << 1;
+ vec4 color = texelFetch(source_color, base_pos, 0);
+ color += texelFetch(source_color, base_pos + ivec2(0, 1), 0);
+ color += texelFetch(source_color, base_pos + ivec2(1, 0), 0);
+ color += texelFetch(source_color, base_pos + ivec2(1, 1), 0);
+ color /= 4.0;
-#ifdef MODE_CUBE_TO_DP
+ imageStore(dest_buffer, pos + params.target, color);
+#endif
-layout(set = 0, binding = 0) uniform samplerCube source_cube;
+#ifdef MODE_GAUSSIAN_BLUR
-layout(push_constant, binding = 0, std430) uniform Params {
- float bias;
- float z_far;
- float z_near;
- bool z_flip;
-}
-params;
+ //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
-layout(location = 0) out float depth_buffer;
+ if (bool(params.flags & FLAG_HORIZONTAL)) {
+ ivec2 base_pos = (pos + params.section.xy) << 1;
+ vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607;
+ color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879;
+ color += texelFetch(source_color, base_pos + ivec2(2, 0), 0) * 0.131514;
+ color += texelFetch(source_color, base_pos + ivec2(3, 0), 0) * 0.071303;
+ color += texelFetch(source_color, base_pos + ivec2(-1, 0), 0) * 0.189879;
+ color += texelFetch(source_color, base_pos + ivec2(-2, 0), 0) * 0.131514;
+ color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303;
+ imageStore(dest_buffer, pos + params.target, color);
+ } else {
+
+ ivec2 base_pos = (pos + params.section.xy);
+ vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774;
+ color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477;
+ color += texelFetch(source_color, base_pos + ivec2(0, 2), 0) * 0.06136;
+ color += texelFetch(source_color, base_pos + ivec2(0, -1), 0) * 0.24477;
+ color += texelFetch(source_color, base_pos + ivec2(0, -2), 0) * 0.06136;
+ imageStore(dest_buffer, pos + params.target, color);
+ }
#endif
-void main() {
+#ifdef MODE_GAUSSIAN_GLOW
-#ifdef MODE_CUBE_TO_DP
+ //Glow uses larger sigma 1 for a more rounded blur effect
- vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0);
+#define GLOW_ADD(m_ofs, m_mult) \
+ { \
+ ivec2 ofs = base_pos + m_ofs; \
+ if (all(greaterThanEqual(ofs, section_begin)) && all(lessThan(ofs, section_end))) { \
+ color += texelFetch(source_color, ofs, 0) * m_mult; \
+ } \
+ }
+
+ vec4 color = vec4(0.0);
+
+ if (bool(params.flags & FLAG_HORIZONTAL)) {
+
+ ivec2 base_pos = (pos + params.section.xy) << 1;
+ ivec2 section_begin = params.section.xy << 1;
+ ivec2 section_end = section_begin + (params.section.zw << 1);
+
+ GLOW_ADD(ivec2(0, 0), 0.174938);
+ GLOW_ADD(ivec2(1, 0), 0.165569);
+ GLOW_ADD(ivec2(2, 0), 0.140367);
+ GLOW_ADD(ivec2(3, 0), 0.106595);
+ GLOW_ADD(ivec2(-1, 0), 0.165569);
+ GLOW_ADD(ivec2(-2, 0), 0.140367);
+ GLOW_ADD(ivec2(-3, 0), 0.106595);
+ color *= params.glow_strength;
+ } else {
- normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
- normal = normalize(normal);
+ ivec2 base_pos = pos + params.section.xy;
+ ivec2 section_begin = params.section.xy;
+ ivec2 section_end = section_begin + params.section.zw;
- normal.y = -normal.y; //needs to be flipped to match projection matrix
- if (!params.z_flip) {
- normal.z = -normal.z;
+ GLOW_ADD(ivec2(0, 0), 0.288713);
+ GLOW_ADD(ivec2(0, 1), 0.233062);
+ GLOW_ADD(ivec2(0, 2), 0.122581);
+ GLOW_ADD(ivec2(0, -1), 0.233062);
+ GLOW_ADD(ivec2(0, -2), 0.122581);
+ color *= params.glow_strength;
}
- float depth = texture(source_cube, normal).r;
+#undef GLOW_ADD
- // absolute values for direction cosines, bigger value equals closer to basis axis
- vec3 unorm = abs(normal);
+ if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
+#ifdef GLOW_USE_AUTO_EXPOSURE
+
+ color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.glow_auto_exposure_grey;
+#endif
+ color *= params.glow_exposure;
+
+ float luminance = max(color.r, max(color.g, color.b));
+ float feedback = max(smoothstep(params.glow_hdr_threshold, params.glow_hdr_threshold + params.glow_hdr_scale, luminance), params.glow_bloom);
+
+ color = min(color * feedback, vec4(params.glow_luminance_cap));
+ }
+
+ imageStore(dest_buffer, pos + params.target, color);
+
+#endif
+
+#ifdef MODE_SIMPLE_COPY
+
+ vec4 color;
+ if (bool(params.flags & FLAG_COPY_ALL_SOURCE)) {
+ vec2 uv = vec2(pos) / vec2(params.section.zw);
+ if (bool(params.flags & FLAG_FLIP_Y)) {
+ uv.y = 1.0 - uv.y;
+ }
+ color = textureLod(source_color, uv, 0.0);
+
+ if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
+ color.rgb = vec3(max(max(color.r, color.g), color.b));
+ }
+ imageStore(dest_buffer, pos + params.target, color);
- if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) {
- // x code
- unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0);
- } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) {
- // y code
- unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0);
- } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) {
- // z code
- unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
} else {
- // oh-no we messed up code
- // has to be
- unorm = vec3(1.0, 0.0, 0.0);
+ color = texelFetch(source_color, pos + params.section.xy, 0);
+
+ if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
+ color.rgb = vec3(max(max(color.r, color.g), color.b));
+ }
+
+ if (bool(params.flags & FLAG_FLIP_Y)) {
+ pos.y = params.section.w - pos.y - 1;
+ }
+
+ imageStore(dest_buffer, pos + params.target, color);
+ }
+
+#endif
+
+#ifdef MODE_SIMPLE_COPY_DEPTH
+
+ vec4 color = texelFetch(source_color, pos + params.section.xy, 0);
+
+ if (bool(params.flags & FLAG_FLIP_Y)) {
+ pos.y = params.section.w - pos.y - 1;
}
- float depth_fix = 1.0 / dot(normal, unorm);
+ imageStore(dest_buffer, pos + params.target, vec4(color.r));
+
+#endif
+
+#ifdef MODE_LINEARIZE_DEPTH_COPY
+
+ float depth = texelFetch(source_color, pos + params.section.xy, 0).r;
+ depth = depth * 2.0 - 1.0;
+ depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near));
+ vec4 color = vec4(depth / params.camera_z_far);
- depth = 2.0 * depth - 1.0;
- float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
- depth_buffer = (linear_depth * depth_fix + params.bias) / params.z_far;
+ if (bool(params.flags & FLAG_FLIP_Y)) {
+ pos.y = params.section.w - pos.y - 1;
+ }
+ imageStore(dest_buffer, pos + params.target, color);
#endif
}
diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
new file mode 100644
index 0000000000..07f8d09743
--- /dev/null
+++ b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
@@ -0,0 +1,104 @@
+/* clang-format off */
+[vertex]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(location = 0) out vec2 uv_interp;
+/* clang-format on */
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ vec4 section;
+ vec2 pixel_size;
+ bool flip_y;
+ bool use_section;
+
+ bool force_luminance;
+ uint pad[3];
+}
+params;
+
+void main() {
+
+ vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
+ uv_interp = base_arr[gl_VertexIndex];
+
+ vec2 vpos = uv_interp;
+ if (params.use_section) {
+ vpos = params.section.xy + vpos * params.section.zw;
+ }
+
+ gl_Position = vec4(vpos * 2.0 - 1.0, 0.0, 1.0);
+
+ if (params.flip_y) {
+ uv_interp.y = 1.0 - uv_interp.y;
+ }
+}
+
+/* clang-format off */
+[fragment]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ vec4 section;
+ vec2 pixel_size;
+ bool flip_y;
+ bool use_section;
+
+ bool force_luminance;
+ bool alpha_to_zero;
+ uint pad[2];
+} params;
+
+
+layout(location = 0) in vec2 uv_interp;
+/* clang-format on */
+
+layout(set = 0, binding = 0) uniform sampler2D source_color;
+
+layout(location = 0) out vec4 frag_color;
+
+void main() {
+
+ vec2 uv = uv_interp;
+
+#ifdef MODE_PANORAMA_TO_DP
+
+ //obtain normal from dual paraboloid uv
+#define M_PI 3.14159265359
+
+ float side;
+ uv.y = modf(uv.y * 2.0, side);
+ side = side * 2.0 - 1.0;
+ vec3 normal = vec3(uv * 2.0 - 1.0, 0.0);
+ normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
+ normal *= -side;
+ normal = normalize(normal);
+
+ //now convert normal to panorama uv
+
+ vec2 st = vec2(atan(normal.x, normal.z), acos(normal.y));
+
+ if (st.x < 0.0)
+ st.x += M_PI * 2.0;
+
+ uv = st / vec2(M_PI * 2.0, M_PI);
+
+ if (side < 0.0) {
+ //uv.y = 1.0 - uv.y;
+ uv = 1.0 - uv;
+ }
+#endif
+ vec4 color = textureLod(source_color, uv, 0.0);
+ if (params.force_luminance) {
+ color.rgb = vec3(max(max(color.r, color.g), color.b));
+ }
+ if (params.alpha_to_zero) {
+ color.rgb *= color.a;
+ }
+ frag_color = color;
+}
diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
new file mode 100644
index 0000000000..02ebe1a53b
--- /dev/null
+++ b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
@@ -0,0 +1,72 @@
+/* clang-format off */
+[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+/* clang-format on */
+
+layout(set = 0, binding = 0) uniform samplerCube source_cube;
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ ivec2 screen_size;
+ ivec2 offset;
+ float bias;
+ float z_far;
+ float z_near;
+ bool z_flip;
+}
+params;
+
+layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer;
+
+void main() {
+
+ ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+ if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing
+ return;
+ }
+
+ vec2 pixel_size = 1.0 / vec2(params.screen_size);
+ vec2 uv = (vec2(pos) + 0.5) * pixel_size;
+
+ vec3 normal = vec3(uv * 2.0 - 1.0, 0.0);
+
+ normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
+ normal = normalize(normal);
+
+ normal.y = -normal.y; //needs to be flipped to match projection matrix
+ if (!params.z_flip) {
+ normal.z = -normal.z;
+ }
+
+ float depth = texture(source_cube, normal).r;
+
+ // absolute values for direction cosines, bigger value equals closer to basis axis
+ vec3 unorm = abs(normal);
+
+ if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) {
+ // x code
+ unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0);
+ } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) {
+ // y code
+ unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0);
+ } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) {
+ // z code
+ unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
+ } else {
+ // oh-no we messed up code
+ // has to be
+ unorm = vec3(1.0, 0.0, 0.0);
+ }
+
+ float depth_fix = 1.0 / dot(normal, unorm);
+
+ depth = 2.0 * depth - 1.0;
+ float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
+ depth = (linear_depth * depth_fix) / params.z_far;
+
+ imageStore(depth_buffer, pos + params.offset, vec4(depth));
+}
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
index 955ae2e588..ec47887036 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
@@ -20,9 +20,7 @@ layout(location = 2) in vec4 tangent_attrib;
layout(location = 3) in vec4 color_attrib;
#endif
-#if defined(UV_USED)
layout(location = 4) in vec2 uv_attrib;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
layout(location = 5) in vec2 uv2_attrib;
@@ -39,9 +37,7 @@ layout(location = 1) out vec3 normal_interp;
layout(location = 2) out vec4 color_interp;
#endif
-#if defined(UV_USED)
layout(location = 3) out vec2 uv_interp;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
layout(location = 4) out vec2 uv2_interp;
@@ -157,9 +153,7 @@ void main() {
#endif
}
-#if defined(UV_USED)
uv_interp = uv_attrib;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
uv2_interp = uv2_attrib;
@@ -244,19 +238,13 @@ VERTEX_SHADER_CODE
//for dual paraboloid shadow mapping, this is the fastest but least correct way, as it curves straight edges
- vec3 vtx = vertex_interp + normalize(vertex_interp) * scene_data.z_offset;
+ vec3 vtx = vertex_interp;
float distance = length(vtx);
vtx = normalize(vtx);
vtx.xy /= 1.0 - vtx.z;
vtx.z = (distance / scene_data.z_far);
vtx.z = vtx.z * 2.0 - 1.0;
-
vertex_interp = vtx;
-#else
-
- float z_ofs = scene_data.z_offset;
- z_ofs += max(0.0, 1.0 - abs(normalize(normal_interp).z)) * scene_data.z_slope_scale;
- vertex_interp.z -= z_ofs;
#endif
@@ -267,6 +255,14 @@ VERTEX_SHADER_CODE
#else
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
#endif
+
+#ifdef MODE_RENDER_DEPTH
+ if (scene_data.pancake_shadows) {
+ if (gl_Position.z <= 0.00001) {
+ gl_Position.z = 0.00001;
+ }
+ }
+#endif
}
/* clang-format off */
@@ -288,9 +284,7 @@ layout(location = 1) in vec3 normal_interp;
layout(location = 2) in vec4 color_interp;
#endif
-#if defined(UV_USED)
layout(location = 3) in vec2 uv_interp;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
layout(location = 4) in vec2 uv2_interp;
@@ -315,6 +309,11 @@ layout(location = 8) in float dp_clip;
#define world_normal_matrix instances.data[instance_index].normal_transform
#define projection_matrix scene_data.projection_matrix
+#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE)
+//both required for transmittance to be enabled
+#define LIGHT_TRANSMITTANCE_USED
+#endif
+
#ifdef USE_MATERIAL_UNIFORMS
layout(set = 5, binding = 0, std140) uniform MaterialUniforms{
/* clang-format off */
@@ -434,9 +433,16 @@ vec3 F0(float metallic, float specular, vec3 albedo) {
return mix(vec3(dielectric), albedo, vec3(metallic));
}
-void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, vec3 attenuation, vec3 diffuse_color, float roughness, float metallic, float specular, float specular_blob_intensity,
-#ifdef LIGHT_TRANSMISSION_USED
- vec3 transmission,
+void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 shadow_attenuation, vec3 diffuse_color, float roughness, float metallic, float specular, float specular_blob_intensity,
+#ifdef LIGHT_BACKLIGHT_USED
+ vec3 backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ vec4 transmittance_color,
+ float transmittance_depth,
+ float transmittance_curve,
+ float transmittance_boost,
+ float transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
float rim, float rim_tint,
@@ -467,7 +473,7 @@ LIGHT_SHADER_CODE
/* clang-format on */
#else
- float NdotL = dot(N, L);
+ float NdotL = min(A + dot(N, L), 1.0);
float cNdotL = max(NdotL, 0.0); // clamped NdotL
float NdotV = dot(N, V);
float cNdotV = max(NdotV, 0.0);
@@ -477,11 +483,11 @@ LIGHT_SHADER_CODE
#endif
#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
- float cNdotH = max(dot(N, H), 0.0);
+ float cNdotH = clamp(A + dot(N, H), 0.0, 1.0);
#endif
#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
- float cLdotH = max(dot(L, H), 0.0);
+ float cLdotH = clamp(A + dot(L, H), 0.0, 1.0);
#endif
if (metallic < 1.0) {
@@ -538,16 +544,48 @@ LIGHT_SHADER_CODE
diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
#endif
- diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation;
+ diffuse_light += light_color * diffuse_color * shadow_attenuation * diffuse_brdf_NL * attenuation;
-#if defined(LIGHT_TRANSMISSION_USED)
- diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * transmission * attenuation;
+#if defined(LIGHT_BACKLIGHT_USED)
+ diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation;
#endif
#if defined(LIGHT_RIM_USED)
float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
diffuse_light += rim_light * rim * mix(vec3(1.0), diffuse_color, rim_tint) * light_color;
#endif
+
+#ifdef LIGHT_TRANSMITTANCE_USED
+
+#ifdef SSS_MODE_SKIN
+
+ {
+ float scale = 8.25 / transmittance_depth;
+ float d = scale * abs(transmittance_z);
+ float dd = -d * d;
+ vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) +
+ vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) +
+ vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) +
+ vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) +
+ vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) +
+ vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
+
+ diffuse_light += profile * transmittance_color.a * diffuse_color * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI) * attenuation;
+ }
+#else
+
+ if (transmittance_depth > 0.0) {
+ float fade = clamp(abs(transmittance_z / transmittance_depth), 0.0, 1.0);
+
+ fade = pow(max(0.0, 1.0 - fade), transmittance_curve);
+ fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0);
+
+ diffuse_light += diffuse_color * transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade * attenuation;
+ }
+
+#endif //SSS_MODE_SKIN
+
+#endif //LIGHT_TRANSMITTANCE_USED
}
if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely
@@ -562,18 +600,18 @@ LIGHT_SHADER_CODE
blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
float intensity = blinn;
- specular_light += light_color * intensity * specular_blob_intensity * attenuation;
+ specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation;
#elif defined(SPECULAR_PHONG)
vec3 R = normalize(-reflect(L, N));
- float cRdotV = max(0.0, dot(R, V));
+ float cRdotV = clamp(A + dot(R, V), 0.0, 1.0);
float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
float phong = pow(cRdotV, shininess);
phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
float intensity = (phong) / max(4.0 * cNdotV * cNdotL, 0.75);
- specular_light += light_color * intensity * specular_blob_intensity * attenuation;
+ specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation;
#elif defined(SPECULAR_TOON)
@@ -582,7 +620,7 @@ LIGHT_SHADER_CODE
float mid = 1.0 - roughness;
mid *= mid;
float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid;
- diffuse_light += light_color * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection
+ diffuse_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection
#elif defined(SPECULAR_DISABLED)
// none..
@@ -613,7 +651,7 @@ LIGHT_SHADER_CODE
vec3 specular_brdf_NL = cNdotL * D * F * G;
- specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
+ specular_light += specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation;
#endif
#if defined(LIGHT_CLEARCOAT_USED)
@@ -627,12 +665,12 @@ LIGHT_SHADER_CODE
float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL;
- specular_light += clearcoat_specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
+ specular_light += clearcoat_specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation;
#endif
}
#ifdef USE_SHADOW_TO_OPACITY
- alpha = min(alpha, clamp(1.0 - length(attenuation), 0.0, 1.0));
+ alpha = min(alpha, clamp(1.0 - length(shadow_attenuation * attenuation), 0.0, 1.0));
#endif
#endif //defined(USE_LIGHT_SHADER_CODE)
@@ -640,53 +678,121 @@ LIGHT_SHADER_CODE
#ifndef USE_NO_SHADOWS
-float sample_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {
+// Produces cheap but low-quality white noise, nothing special
+float quick_hash(vec2 pos) {
+ return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237);
+}
+
+float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {
- //todo optimize
vec2 pos = coord.xy;
float depth = coord.z;
-#ifdef SHADOW_MODE_PCF_13
+ //if only one sample is taken, take it from the center
+ if (scene_data.directional_soft_shadow_samples == 1) {
+ return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0));
+ }
- float avg = textureProj(shadow, vec4(pos, depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x * 2.0, 0.0), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x * 2.0, 0.0), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y * 2.0), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y * 2.0), depth, 1.0));
- return avg * (1.0 / 13.0);
-#endif
+ mat2 disk_rotation;
+ {
+ float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI;
+ float sr = sin(r);
+ float cr = cos(r);
+ disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr));
+ }
-#ifdef SHADOW_MODE_PCF_5
+ float avg = 0.0;
- float avg = textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0));
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0));
- return avg * (1.0 / 5.0);
+ for (uint i = 0; i < scene_data.directional_soft_shadow_samples; i++) {
+ avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + shadow_pixel_size * (disk_rotation * scene_data.directional_soft_shadow_kernel[i].xy), depth, 1.0));
+ }
-#endif
+ return avg * (1.0 / float(scene_data.directional_soft_shadow_samples));
+}
-#if !defined(SHADOW_MODE_PCF_5) || !defined(SHADOW_MODE_PCF_13)
+float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {
- return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0));
+ vec2 pos = coord.xy;
+ float depth = coord.z;
-#endif
+ //if only one sample is taken, take it from the center
+ if (scene_data.soft_shadow_samples == 1) {
+ return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0));
+ }
+
+ mat2 disk_rotation;
+ {
+ float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI;
+ float sr = sin(r);
+ float cr = cos(r);
+ disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr));
+ }
+
+ float avg = 0.0;
+
+ for (uint i = 0; i < scene_data.soft_shadow_samples; i++) {
+ avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + shadow_pixel_size * (disk_rotation * scene_data.soft_shadow_kernel[i].xy), depth, 1.0));
+ }
+
+ return avg * (1.0 / float(scene_data.soft_shadow_samples));
+}
+
+float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) {
+
+ //find blocker
+ float blocker_count = 0.0;
+ float blocker_average = 0.0;
+
+ mat2 disk_rotation;
+ {
+ float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI;
+ float sr = sin(r);
+ float cr = cos(r);
+ disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr));
+ }
+
+ for (uint i = 0; i < scene_data.directional_penumbra_shadow_samples; i++) {
+
+ vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale;
+ float d = textureLod(sampler2D(shadow, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r;
+ if (d < pssm_coord.z) {
+ blocker_average += d;
+ blocker_count += 1.0;
+ }
+ }
+
+ if (blocker_count > 0.0) {
+
+ //blockers found, do soft shadow
+ blocker_average /= blocker_count;
+ float penumbra = (pssm_coord.z - blocker_average) / blocker_average;
+ tex_scale *= penumbra;
+
+ float s = 0.0;
+ for (uint i = 0; i < scene_data.directional_penumbra_shadow_samples; i++) {
+ vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale;
+ s += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(suv, pssm_coord.z, 1.0));
+ }
+
+ return s / float(scene_data.directional_penumbra_shadow_samples);
+
+ } else {
+ //no blockers found, so no shadow
+ return 1.0;
+ }
}
#endif //USE_NO_SHADOWS
-void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity,
-#ifdef LIGHT_TRANSMISSION_USED
- vec3 transmission,
+void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity,
+#ifdef LIGHT_BACKLIGHT_USED
+ vec3 backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ vec4 transmittance_color,
+ float transmittance_depth,
+ float transmittance_curve,
+ float transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
float rim, float rim_tint,
@@ -707,45 +813,269 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a
float normalized_distance = light_length * lights.data[idx].inv_radius;
vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), attenuation_energy.x);
- vec3 light_attenuation = vec3(omni_attenuation);
+ float light_attenuation = omni_attenuation;
+ vec3 shadow_attenuation = vec3(1.0);
vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
color_specular.rgb *= attenuation_energy.y;
+ float size_A = 0.0;
+
+ if (lights.data[idx].size > 0.0) {
+
+ float t = lights.data[idx].size / max(0.001, light_length);
+ size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
+ }
+
+#ifdef LIGHT_TRANSMITTANCE_USED
+ float transmittance_z = transmittance_depth; //no transmittance by default
+#endif
#ifndef USE_NO_SHADOWS
vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled);
if (shadow_color_enabled.w > 0.5) {
// there is a shadowmap
- vec4 splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0));
- float shadow_len = length(splane);
- splane = normalize(splane);
- vec4 clamp_rect = lights.data[idx].atlas_rect;
+ vec4 v = vec4(vertex, 1.0);
+
+ vec4 splane = (lights.data[idx].shadow_matrix * v);
+ float shadow_len = length(splane.xyz); //need to remember shadow len from here
- if (splane.z >= 0.0) {
+ {
+ vec3 nofs = normal_interp * lights.data[idx].shadow_normal_bias / lights.data[idx].inv_radius;
+ nofs *= (1.0 - max(0.0, dot(normalize(light_rel_vec), normalize(normal_interp))));
+ v.xyz += nofs;
+ splane = (lights.data[idx].shadow_matrix * v);
+ }
- splane.z += 1.0;
+ float shadow;
- clamp_rect.y += clamp_rect.w;
+ if (lights.data[idx].soft_shadow_size > 0.0) {
+ //soft shadow
+
+ //find blocker
+
+ float blocker_count = 0.0;
+ float blocker_average = 0.0;
+
+ mat2 disk_rotation;
+ {
+ float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI;
+ float sr = sin(r);
+ float cr = cos(r);
+ disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr));
+ }
+ vec3 normal = normalize(splane.xyz);
+ vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
+ vec3 tangent = normalize(cross(v0, normal));
+ vec3 bitangent = normalize(cross(tangent, normal));
+ float z_norm = shadow_len * lights.data[idx].inv_radius;
+
+ tangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale;
+ bitangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale;
+
+ for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
+
+ vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy;
+
+ vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y;
+
+ pos = normalize(pos);
+ vec4 uv_rect = lights.data[idx].atlas_rect;
+
+ if (pos.z >= 0.0) {
+
+ pos.z += 1.0;
+ uv_rect.y += uv_rect.w;
+ } else {
+
+ pos.z = 1.0 - pos.z;
+ }
+
+ pos.xy /= pos.z;
+
+ pos.xy = pos.xy * 0.5 + 0.5;
+ pos.xy = uv_rect.xy + pos.xy * uv_rect.zw;
+
+ float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), pos.xy, 0.0).r;
+ if (d < z_norm) {
+ blocker_average += d;
+ blocker_count += 1.0;
+ }
+ }
+
+ if (blocker_count > 0.0) {
+
+ //blockers found, do soft shadow
+ blocker_average /= blocker_count;
+ float penumbra = (z_norm - blocker_average) / blocker_average;
+ tangent *= penumbra;
+ bitangent *= penumbra;
+
+ z_norm -= lights.data[idx].inv_radius * lights.data[idx].shadow_bias;
+
+ shadow = 0.0;
+ for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
+
+ vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy;
+ vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y;
+
+ pos = normalize(pos);
+ vec4 uv_rect = lights.data[idx].atlas_rect;
+
+ if (pos.z >= 0.0) {
+
+ pos.z += 1.0;
+ uv_rect.y += uv_rect.w;
+ } else {
+
+ pos.z = 1.0 - pos.z;
+ }
+
+ pos.xy /= pos.z;
+
+ pos.xy = pos.xy * 0.5 + 0.5;
+ pos.xy = uv_rect.xy + pos.xy * uv_rect.zw;
+ shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(pos.xy, z_norm, 1.0));
+ }
+
+ shadow /= float(scene_data.penumbra_shadow_samples);
+
+ } else {
+ //no blockers found, so no shadow
+ shadow = 1.0;
+ }
} else {
- splane.z = 1.0 - splane.z;
+ splane.xyz = normalize(splane.xyz);
+ vec4 clamp_rect = lights.data[idx].atlas_rect;
+
+ if (splane.z >= 0.0) {
+
+ splane.z += 1.0;
+
+ clamp_rect.y += clamp_rect.w;
+
+ } else {
+ splane.z = 1.0 - splane.z;
+ }
+
+ splane.xy /= splane.z;
+
+ splane.xy = splane.xy * 0.5 + 0.5;
+ splane.z = (shadow_len - lights.data[idx].shadow_bias) * lights.data[idx].inv_radius;
+ splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
+ splane.w = 1.0; //needed? i think it should be 1 already
+ shadow = sample_pcf_shadow(shadow_atlas, lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane);
+ }
+
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+
+ vec4 clamp_rect = lights.data[idx].atlas_rect;
+
+ //redo shadowmapping, but shrink the model a bit to avoid arctifacts
+ splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0));
+
+ shadow_len = length(splane.xyz);
+ splane = normalize(splane.xyz);
+
+ if (splane.z >= 0.0) {
+
+ splane.z += 1.0;
+
+ } else {
+
+ splane.z = 1.0 - splane.z;
+ }
+
+ splane.xy /= splane.z;
+ splane.xy = splane.xy * 0.5 + 0.5;
+ splane.z = shadow_len * lights.data[idx].inv_radius;
+ splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
+ splane.w = 1.0; //needed? i think it should be 1 already
+
+ float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
+ transmittance_z = (splane.z - shadow_z) / lights.data[idx].inv_radius;
}
+#endif
+
+ vec3 no_shadow = vec3(1.0);
+
+ if (lights.data[idx].projector_rect != vec4(0.0)) {
+
+ vec3 local_v = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz;
+ local_v = normalize(local_v);
- splane.xy /= splane.z;
- splane.xy = splane.xy * 0.5 + 0.5;
- splane.z = shadow_len * lights.data[idx].inv_radius;
- splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
- splane.w = 1.0; //needed? i think it should be 1 already
- float shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane);
+ vec4 atlas_rect = lights.data[idx].projector_rect;
- light_attenuation *= mix(shadow_color_enabled.rgb, vec3(1.0), shadow);
+ if (local_v.z >= 0.0) {
+
+ local_v.z += 1.0;
+ atlas_rect.y += atlas_rect.w;
+
+ } else {
+
+ local_v.z = 1.0 - local_v.z;
+ }
+
+ local_v.xy /= local_v.z;
+ local_v.xy = local_v.xy * 0.5 + 0.5;
+ vec2 proj_uv = local_v.xy * atlas_rect.zw;
+
+ vec2 proj_uv_ddx;
+ vec2 proj_uv_ddy;
+ {
+ vec3 local_v_ddx = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)).xyz;
+ local_v_ddx = normalize(local_v_ddx);
+
+ if (local_v_ddx.z >= 0.0) {
+
+ local_v_ddx.z += 1.0;
+ } else {
+
+ local_v_ddx.z = 1.0 - local_v_ddx.z;
+ }
+
+ local_v_ddx.xy /= local_v_ddx.z;
+ local_v_ddx.xy = local_v_ddx.xy * 0.5 + 0.5;
+
+ proj_uv_ddx = local_v_ddx.xy * atlas_rect.zw - proj_uv;
+
+ vec3 local_v_ddy = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)).xyz;
+ local_v_ddy = normalize(local_v_ddy);
+
+ if (local_v_ddy.z >= 0.0) {
+
+ local_v_ddy.z += 1.0;
+ } else {
+
+ local_v_ddy.z = 1.0 - local_v_ddy.z;
+ }
+
+ local_v_ddy.xy /= local_v_ddy.z;
+ local_v_ddy.xy = local_v_ddy.xy * 0.5 + 0.5;
+
+ proj_uv_ddy = local_v_ddy.xy * atlas_rect.zw - proj_uv;
+ }
+
+ vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + atlas_rect.xy, proj_uv_ddx, proj_uv_ddy);
+ no_shadow = mix(no_shadow, proj.rgb, proj.a);
+ }
+
+ shadow_attenuation = mix(shadow_color_enabled.rgb, no_shadow, shadow);
}
#endif //USE_NO_SHADOWS
- light_compute(normal, normalize(light_rel_vec), eye_vec, color_specular.rgb, light_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity,
-#ifdef LIGHT_TRANSMISSION_USED
- transmission,
+ light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity,
+#ifdef LIGHT_BACKLIGHT_USED
+ backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ transmittance_color,
+ transmittance_depth,
+ transmittance_curve,
+ transmittance_boost,
+ transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
rim * omni_attenuation, rim_tint,
@@ -763,9 +1093,15 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a
specular_light);
}
-void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity,
-#ifdef LIGHT_TRANSMISSION_USED
- vec3 transmission,
+void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity,
+#ifdef LIGHT_BACKLIGHT_USED
+ vec3 backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ vec4 transmittance_color,
+ float transmittance_depth,
+ float transmittance_curve,
+ float transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
float rim, float rim_tint,
@@ -792,31 +1128,162 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a
float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y);
float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_att_angle.y));
spot_attenuation *= 1.0 - pow(spot_rim, spot_att_angle.x);
- vec3 light_attenuation = vec3(spot_attenuation);
+ float light_attenuation = spot_attenuation;
+ vec3 shadow_attenuation = vec3(1.0);
vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
color_specular.rgb *= attenuation_energy.y;
+ float size_A = 0.0;
+
+ if (lights.data[idx].size > 0.0) {
+
+ float t = lights.data[idx].size / max(0.001, light_length);
+ size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
+ }
/*
if (lights.data[idx].atlas_rect!=vec4(0.0)) {
//use projector texture
}
*/
+#ifdef LIGHT_TRANSMITTANCE_USED
+ float transmittance_z = transmittance_depth;
+#endif
+
#ifndef USE_NO_SHADOWS
vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled);
if (shadow_color_enabled.w > 0.5) {
//there is a shadowmap
- vec4 splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0));
+ vec4 v = vec4(vertex, 1.0);
+
+ v.xyz -= spot_dir * lights.data[idx].shadow_bias;
+
+ float z_norm = dot(spot_dir, -light_rel_vec) * lights.data[idx].inv_radius;
+
+ float depth_bias_scale = 1.0 / (max(0.0001, z_norm)); //the closer to the light origin, the more you have to offset to reach 1px in the map
+ vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * lights.data[idx].shadow_normal_bias * depth_bias_scale;
+ normal_bias -= spot_dir * dot(spot_dir, normal_bias); //only XY, no Z
+ v.xyz += normal_bias;
+
+ //adjust with bias
+ z_norm = dot(spot_dir, v.xyz - lights.data[idx].position) * lights.data[idx].inv_radius;
+
+ float shadow;
+
+ vec4 splane = (lights.data[idx].shadow_matrix * v);
splane /= splane.w;
- float shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane);
- light_attenuation *= mix(shadow_color_enabled.rgb, vec3(1.0), shadow);
+ if (lights.data[idx].soft_shadow_size > 0.0) {
+ //soft shadow
+
+ //find blocker
+
+ vec2 shadow_uv = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy;
+
+ float blocker_count = 0.0;
+ float blocker_average = 0.0;
+
+ mat2 disk_rotation;
+ {
+ float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI;
+ float sr = sin(r);
+ float cr = cos(r);
+ disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr));
+ }
+
+ float uv_size = lights.data[idx].soft_shadow_size * z_norm * lights.data[idx].soft_shadow_scale;
+ vec2 clamp_max = lights.data[idx].atlas_rect.xy + lights.data[idx].atlas_rect.zw;
+ for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
+
+ vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size;
+ suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max);
+ float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r;
+ if (d < z_norm) {
+ blocker_average += d;
+ blocker_count += 1.0;
+ }
+ }
+
+ if (blocker_count > 0.0) {
+
+ //blockers found, do soft shadow
+ blocker_average /= blocker_count;
+ float penumbra = (z_norm - blocker_average) / blocker_average;
+ uv_size *= penumbra;
+
+ shadow = 0.0;
+ for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
+ vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size;
+ suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max);
+ shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(suv, z_norm, 1.0));
+ }
+
+ shadow /= float(scene_data.penumbra_shadow_samples);
+
+ } else {
+ //no blockers found, so no shadow
+ shadow = 1.0;
+ }
+
+ } else {
+ //hard shadow
+ vec4 shadow_uv = vec4(splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy, z_norm, 1.0);
+
+ shadow = sample_pcf_shadow(shadow_atlas, lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv);
+ }
+
+ vec3 no_shadow = vec3(1.0);
+
+ if (lights.data[idx].projector_rect != vec4(0.0)) {
+
+ splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0));
+ splane /= splane.w;
+
+ vec2 proj_uv = splane.xy * lights.data[idx].projector_rect.zw;
+
+ //ensure we have proper mipmaps
+ vec4 splane_ddx = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0));
+ splane_ddx /= splane_ddx.w;
+ vec2 proj_uv_ddx = splane_ddx.xy * lights.data[idx].projector_rect.zw - proj_uv;
+
+ vec4 splane_ddy = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0));
+ splane_ddy /= splane_ddy.w;
+ vec2 proj_uv_ddy = splane_ddy.xy * lights.data[idx].projector_rect.zw - proj_uv;
+
+ vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + lights.data[idx].projector_rect.xy, proj_uv_ddx, proj_uv_ddy);
+ no_shadow = mix(no_shadow, proj.rgb, proj.a);
+ }
+
+ shadow_attenuation = mix(shadow_color_enabled.rgb, no_shadow, shadow);
+
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+
+ splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0));
+ splane /= splane.w;
+ splane.xy = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy;
+
+ float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
+ //reconstruct depth
+ shadow_z / lights.data[idx].inv_radius;
+ //distance to light plane
+ float z = dot(spot_dir, -light_rel_vec);
+ transmittance_z = z - shadow_z;
+ }
+#endif //LIGHT_TRANSMITTANCE_USED
}
#endif //USE_NO_SHADOWS
- light_compute(normal, normalize(light_rel_vec), eye_vec, color_specular.rgb, light_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity,
-#ifdef LIGHT_TRANSMISSION_USED
- transmission,
+ light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity,
+#ifdef LIGHT_BACKLIGHT_USED
+ backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ transmittance_color,
+ transmittance_depth,
+ transmittance_curve,
+ transmittance_boost,
+ transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
rim * spot_attenuation, rim_tint,
@@ -1185,7 +1652,11 @@ void main() {
vec3 vertex = vertex_interp;
vec3 view = -normalize(vertex_interp);
vec3 albedo = vec3(1.0);
- vec3 transmission = vec3(0.0);
+ vec3 backlight = vec3(0.0);
+ vec4 transmittance_color = vec4(0.0);
+ float transmittance_depth = 0.0;
+ float transmittance_curve = 1.0;
+ float transmittance_boost = 0.0;
float metallic = 0.0;
float specular = 0.5;
vec3 emission = vec3(0.0);
@@ -1223,9 +1694,7 @@ void main() {
}
#endif
-#if defined(UV_USED)
vec2 uv = uv_interp;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
vec2 uv2 = uv2_interp;
@@ -1254,6 +1723,14 @@ FRAGMENT_SHADER_CODE
/* clang-format on */
}
+#if defined(LIGHT_TRANSMITTANCE_USED)
+#ifdef SSS_MODE_SKIN
+ transmittance_color.a = sss_strength;
+#else
+ transmittance_color.a *= sss_strength;
+#endif
+#endif
+
#if !defined(USE_SHADOW_TO_OPACITY)
#if defined(ALPHA_SCISSOR_USED)
@@ -1299,7 +1776,81 @@ FRAGMENT_SHADER_CODE
discard;
}
#endif
+ /////////////////////// DECALS ////////////////////////////////
+
+#ifndef MODE_RENDER_DEPTH
+
+ uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]), vec3(screen_uv, (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)));
+ //used for interpolating anything cluster related
+ vec3 vertex_ddx = dFdx(vertex);
+ vec3 vertex_ddy = dFdy(vertex);
+
+ { // process decals
+
+ uint decal_count = cluster_cell.w >> CLUSTER_COUNTER_SHIFT;
+ uint decal_pointer = cluster_cell.w & CLUSTER_POINTER_MASK;
+
+ //do outside for performance and avoiding arctifacts
+
+ for (uint i = 0; i < decal_count; i++) {
+
+ uint decal_index = cluster_data.indices[decal_pointer + i];
+ if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
+
+ vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
+ if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
+ continue; //out of decal
+ }
+
+ //we need ddx/ddy for mipmaps, so simulate them
+ vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz;
+ vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz;
+
+ float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade);
+
+ if (decals.data[decal_index].normal_fade > 0.0) {
+ fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5);
+ }
+
+ if (decals.data[decal_index].albedo_rect != vec4(0.0)) {
+ //has albedo
+ vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw);
+ decal_albedo *= decals.data[decal_index].modulate;
+ decal_albedo.a *= fade;
+ albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);
+
+ if (decals.data[decal_index].normal_rect != vec4(0.0)) {
+
+ vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
+ decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software
+ decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));
+ //convert to view space, use xzy because y is up
+ decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz;
+
+ normal = normalize(mix(normal, decal_normal, decal_albedo.a));
+ }
+
+ if (decals.data[decal_index].orm_rect != vec4(0.0)) {
+
+ vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
+#if defined(AO_USED)
+ ao = mix(ao, decal_orm.r, decal_albedo.a);
+#endif
+ roughness = mix(roughness, decal_orm.g, decal_albedo.a);
+ metallic = mix(metallic, decal_orm.b, decal_albedo.a);
+ }
+ }
+
+ if (decals.data[decal_index].emission_rect != vec4(0.0)) {
+ //emission is additive, so its independent from albedo
+ emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade;
+ }
+ }
+ }
+#endif //not render depth
/////////////////////// LIGHTING //////////////////////////////
//apply energy conservation
@@ -1404,8 +1955,6 @@ FRAGMENT_SHADER_CODE
}
#endif
- uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]), vec3(screen_uv, (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)));
-
{ // process reflections
vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
@@ -1462,58 +2011,250 @@ FRAGMENT_SHADER_CODE
continue; //not masked
}
- vec3 light_attenuation = vec3(1.0);
+ vec3 shadow_attenuation = vec3(1.0);
+
+#ifdef LIGHT_TRANSMITTANCE_USED
+ float transmittance_z = transmittance_depth;
+#endif
if (directional_lights.data[i].shadow_enabled) {
float depth_z = -vertex.z;
vec4 pssm_coord;
+ vec3 shadow_color = vec3(0.0);
+ vec3 light_dir = directional_lights.data[i].direction;
+
+#define BIAS_FUNC(m_var, m_idx) \
+ m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \
+ vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))) * directional_lights.data[i].shadow_normal_bias[m_idx]; \
+ normal_bias -= light_dir * dot(light_dir, normal_bias); \
+ m_var.xyz += normal_bias;
+
+ float shadow = 0.0;
if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
- pssm_coord = (directional_lights.data[i].shadow_matrix1 * vec4(vertex, 1.0));
+ vec4 v = vec4(vertex, 1.0);
+
+ BIAS_FUNC(v, 0)
+
+ pssm_coord = (directional_lights.data[i].shadow_matrix1 * v);
+ pssm_coord /= pssm_coord.w;
+
+ if (directional_lights.data[i].softshadow_angle > 0) {
+ float range_pos = dot(directional_lights.data[i].direction, v.xyz);
+ float range_begin = directional_lights.data[i].shadow_range_begin.x;
+ float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle;
+ vec2 tex_scale = directional_lights.data[i].uv_scale1 * test_radius;
+ shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale);
+ } else {
+ shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+ }
+
+ shadow_color = directional_lights.data[i].shadow_color1.rgb;
+
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
- pssm_coord = (directional_lights.data[i].shadow_matrix2 * vec4(vertex, 1.0));
+
+ vec4 v = vec4(vertex, 1.0);
+
+ BIAS_FUNC(v, 1)
+
+ pssm_coord = (directional_lights.data[i].shadow_matrix2 * v);
+ pssm_coord /= pssm_coord.w;
+
+ if (directional_lights.data[i].softshadow_angle > 0) {
+ float range_pos = dot(directional_lights.data[i].direction, v.xyz);
+ float range_begin = directional_lights.data[i].shadow_range_begin.y;
+ float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle;
+ vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius;
+ shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale);
+ } else {
+ shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+ }
+
+ shadow_color = directional_lights.data[i].shadow_color2.rgb;
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
- pssm_coord = (directional_lights.data[i].shadow_matrix3 * vec4(vertex, 1.0));
+
+ vec4 v = vec4(vertex, 1.0);
+
+ BIAS_FUNC(v, 2)
+
+ pssm_coord = (directional_lights.data[i].shadow_matrix3 * v);
+ pssm_coord /= pssm_coord.w;
+
+ if (directional_lights.data[i].softshadow_angle > 0) {
+ float range_pos = dot(directional_lights.data[i].direction, v.xyz);
+ float range_begin = directional_lights.data[i].shadow_range_begin.z;
+ float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle;
+ vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius;
+ shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale);
+ } else {
+ shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+ }
+
+ shadow_color = directional_lights.data[i].shadow_color3.rgb;
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
+
} else {
- pssm_coord = (directional_lights.data[i].shadow_matrix4 * vec4(vertex, 1.0));
- }
- pssm_coord /= pssm_coord.w;
+ vec4 v = vec4(vertex, 1.0);
- float shadow = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord);
+ BIAS_FUNC(v, 3)
+
+ pssm_coord = (directional_lights.data[i].shadow_matrix4 * v);
+ pssm_coord /= pssm_coord.w;
+
+ if (directional_lights.data[i].softshadow_angle > 0) {
+ float range_pos = dot(directional_lights.data[i].direction, v.xyz);
+ float range_begin = directional_lights.data[i].shadow_range_begin.w;
+ float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle;
+ vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius;
+ shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale);
+ } else {
+ shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+ }
+
+ shadow_color = directional_lights.data[i].shadow_color4.rgb;
+
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
+ }
if (directional_lights.data[i].blend_splits) {
+ vec3 shadow_color_blend = vec3(0.0);
float pssm_blend;
+ float shadow2;
if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
- pssm_coord = (directional_lights.data[i].shadow_matrix2 * vec4(vertex, 1.0));
+ vec4 v = vec4(vertex, 1.0);
+ BIAS_FUNC(v, 1)
+ pssm_coord = (directional_lights.data[i].shadow_matrix2 * v);
+ pssm_coord /= pssm_coord.w;
+
+ if (directional_lights.data[i].softshadow_angle > 0) {
+ float range_pos = dot(directional_lights.data[i].direction, v.xyz);
+ float range_begin = directional_lights.data[i].shadow_range_begin.y;
+ float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle;
+ vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius;
+ shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale);
+ } else {
+ shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+ }
+
pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z);
+ shadow_color_blend = directional_lights.data[i].shadow_color2.rgb;
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
- pssm_coord = (directional_lights.data[i].shadow_matrix3 * vec4(vertex, 1.0));
+ vec4 v = vec4(vertex, 1.0);
+ BIAS_FUNC(v, 2)
+ pssm_coord = (directional_lights.data[i].shadow_matrix3 * v);
+ pssm_coord /= pssm_coord.w;
+
+ if (directional_lights.data[i].softshadow_angle > 0) {
+ float range_pos = dot(directional_lights.data[i].direction, v.xyz);
+ float range_begin = directional_lights.data[i].shadow_range_begin.z;
+ float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle;
+ vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius;
+ shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale);
+ } else {
+ shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+ }
+
pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z);
+
+ shadow_color_blend = directional_lights.data[i].shadow_color3.rgb;
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
- pssm_coord = (directional_lights.data[i].shadow_matrix4 * vec4(vertex, 1.0));
+ vec4 v = vec4(vertex, 1.0);
+ BIAS_FUNC(v, 3)
+ pssm_coord = (directional_lights.data[i].shadow_matrix4 * v);
+ pssm_coord /= pssm_coord.w;
+ if (directional_lights.data[i].softshadow_angle > 0) {
+ float range_pos = dot(directional_lights.data[i].direction, v.xyz);
+ float range_begin = directional_lights.data[i].shadow_range_begin.w;
+ float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle;
+ vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius;
+ shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale);
+ } else {
+ shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+ }
+
pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z);
+ shadow_color_blend = directional_lights.data[i].shadow_color4.rgb;
} else {
pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached)
}
- pssm_coord /= pssm_coord.w;
+ pssm_blend = sqrt(pssm_blend);
- float shadow2 = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord);
shadow = mix(shadow, shadow2, pssm_blend);
+ shadow_color = mix(shadow_color, shadow_color_blend, pssm_blend);
}
shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance
- light_attenuation = mix(directional_lights.data[i].shadow_color, vec3(1.0), shadow);
+ shadow_attenuation = mix(shadow_color, vec3(1.0), shadow);
+
+#undef BIAS_FUNC
}
- light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, light_attenuation, albedo, roughness, metallic, specular, directional_lights.data[i].specular * specular_blob_intensity,
-#ifdef LIGHT_TRANSMISSION_USED
- transmission,
+ light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].size, directional_lights.data[i].color * directional_lights.data[i].energy, 1.0, shadow_attenuation, albedo, roughness, metallic, specular, directional_lights.data[i].specular * specular_blob_intensity,
+#ifdef LIGHT_BACKLIGHT_USED
+ backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ transmittance_color,
+ transmittance_depth,
+ transmittance_curve,
+ transmittance_boost,
+ transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
rim, rim_tint,
@@ -1545,9 +2286,15 @@ FRAGMENT_SHADER_CODE
continue; //not masked
}
- light_process_omni(light_index, vertex, view, normal, albedo, roughness, metallic, specular, specular_blob_intensity,
-#ifdef LIGHT_TRANSMISSION_USED
- transmission,
+ light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity,
+#ifdef LIGHT_BACKLIGHT_USED
+ backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ transmittance_color,
+ transmittance_depth,
+ transmittance_curve,
+ transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
rim,
@@ -1578,9 +2325,15 @@ FRAGMENT_SHADER_CODE
continue; //not masked
}
- light_process_spot(light_index, vertex, view, normal, albedo, roughness, metallic, specular, specular_blob_intensity,
-#ifdef LIGHT_TRANSMISSION_USED
- transmission,
+ light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity,
+#ifdef LIGHT_BACKLIGHT_USED
+ backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ transmittance_color,
+ transmittance_depth,
+ transmittance_curve,
+ transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
rim,
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
index baef1e060f..ce4fabf9f2 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
@@ -37,13 +37,23 @@ layout(set = 0, binding = 3, std140) uniform SceneData {
vec2 viewport_size;
vec2 screen_pixel_size;
- //used for shadow mapping only
- float z_offset;
- float z_slope_scale;
-
float time;
float reflection_multiplier; // one normally, zero when rendering reflections
+ bool pancake_shadows;
+ uint pad;
+
+ //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted
+ vec4 directional_penumbra_shadow_kernel[32];
+ vec4 directional_soft_shadow_kernel[32];
+ vec4 penumbra_shadow_kernel[32];
+ vec4 soft_shadow_kernel[32];
+
+ uint directional_penumbra_shadow_samples;
+ uint directional_soft_shadow_samples;
+ uint penumbra_shadow_samples;
+ uint soft_shadow_samples;
+
vec4 ambient_light_color_energy;
float ambient_color_sky_mix;
@@ -124,31 +134,39 @@ struct InstanceData {
mat4 transform;
mat4 normal_transform;
uint flags;
- uint instance_ofs; //instance_offset in instancing/skeleton buffer
+ uint instance_uniforms_ofs; //base offset in global buffer for instance variables
uint gi_offset; //GI information when using lightmapping (VCT or lightmap)
uint layer_mask;
};
-layout(set = 0, binding = 4, std430) buffer Instances {
+layout(set = 0, binding = 4, std430) restrict readonly buffer Instances {
InstanceData data[];
}
instances;
-struct LightData { //this structure needs to be 128 bits
+struct LightData { //this structure needs to be as packed as possible
vec3 position;
float inv_radius;
vec3 direction;
+ float size;
uint attenuation_energy; //attenuation
uint color_specular; //rgb color, a specular (8 bit unorm)
uint cone_attenuation_angle; // attenuation and angle, (16bit float)
- uint mask;
uint shadow_color_enabled; //shadow rgb color, a>0.5 enabled (8bit unorm)
- vec4 atlas_rect; //used for shadow atlas uv on omni, and for projection atlas on spot
+ vec4 atlas_rect; // rect in the shadow atlas
mat4 shadow_matrix;
+ float shadow_bias;
+ float shadow_normal_bias;
+ float transmittance_bias;
+ float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle
+ float soft_shadow_scale; // scales the shadow kernel for blurrier shadows
+ uint mask;
+ uint pad[2];
+ vec4 projector_rect; //projector rect in srgb decal atlas
};
-layout(set = 0, binding = 5, std140) uniform Lights {
- LightData data[MAX_LIGHT_DATA_STRUCTS];
+layout(set = 0, binding = 5, std430) restrict readonly buffer Lights {
+ LightData data[];
}
lights;
@@ -173,18 +191,33 @@ struct DirectionalLightData {
vec3 direction;
float energy;
vec3 color;
+ float size;
float specular;
- vec3 shadow_color;
uint mask;
+ float softshadow_angle;
+ float soft_shadow_scale;
bool blend_splits;
bool shadow_enabled;
float fade_from;
float fade_to;
+ vec4 shadow_bias;
+ vec4 shadow_normal_bias;
+ vec4 shadow_transmittance_bias;
+ vec4 shadow_transmittance_z_scale;
+ vec4 shadow_range_begin;
vec4 shadow_split_offsets;
mat4 shadow_matrix1;
mat4 shadow_matrix2;
mat4 shadow_matrix3;
mat4 shadow_matrix4;
+ vec4 shadow_color1;
+ vec4 shadow_color2;
+ vec4 shadow_color3;
+ vec4 shadow_color4;
+ vec2 uv_scale1;
+ vec2 uv_scale2;
+ vec2 uv_scale3;
+ vec2 uv_scale4;
};
layout(set = 0, binding = 7, std140) uniform DirectionalLights {
@@ -219,14 +252,45 @@ layout(set = 0, binding = 9) uniform texture3D gi_probe_textures[MAX_GI_PROBE_TE
#define CLUSTER_POINTER_MASK ((1 << CLUSTER_COUNTER_SHIFT) - 1)
#define CLUSTER_COUNTER_MASK 0xfff
-layout(set = 0, binding = 10) uniform utexture3D cluster_texture;
+layout(set = 0, binding = 10) uniform texture2D decal_atlas;
+layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb;
+
+struct DecalData {
+ mat4 xform; //to decal transform
+ vec3 inv_extents;
+ float albedo_mix;
+ vec4 albedo_rect;
+ vec4 normal_rect;
+ vec4 orm_rect;
+ vec4 emission_rect;
+ vec4 modulate;
+ float emission_energy;
+ uint mask;
+ float upper_fade;
+ float lower_fade;
+ mat3x4 normal_xform;
+ vec3 normal;
+ float normal_fade;
+};
+
+layout(set = 0, binding = 12, std430) restrict readonly buffer Decals {
+ DecalData data[];
+}
+decals;
+
+layout(set = 0, binding = 13) uniform utexture3D cluster_texture;
-layout(set = 0, binding = 11, std430) buffer ClusterData {
+layout(set = 0, binding = 14, std430) restrict readonly buffer ClusterData {
uint indices[];
}
cluster_data;
-layout(set = 0, binding = 12) uniform texture2D directional_shadow_atlas;
+layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas;
+
+layout(set = 0, binding = 16, std430) restrict readonly buffer GlobalVariableData {
+ vec4 data[];
+}
+global_variables;
// decal atlas
@@ -258,7 +322,7 @@ layout(set = 3, binding = 4) uniform texture2D ao_buffer;
/* Set 4 Skeleton & Instancing (Multimesh) */
-layout(set = 4, binding = 0, std430) buffer Transforms {
+layout(set = 4, binding = 0, std430) restrict readonly buffer Transforms {
vec4 data[];
}
transforms;
diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/rasterizer_rd/shaders/sky.glsl
index 469925839a..536077980d 100644
--- a/servers/rendering/rasterizer_rd/shaders/sky.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/sky.glsl
@@ -58,6 +58,11 @@ params;
layout(set = 0, binding = 0) uniform sampler material_samplers[12];
+layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalVariableData {
+ vec4 data[];
+}
+global_variables;
+
#ifdef USE_MATERIAL_UNIFORMS
layout(set = 1, binding = 0, std140) uniform MaterialUniforms{
/* clang-format off */
@@ -96,9 +101,8 @@ layout(set = 2, binding = 2) uniform texture2D quarter_res;
#endif
struct DirectionalLightData {
- vec3 direction;
- float energy;
- vec3 color;
+ vec4 direction_energy;
+ vec4 color_size;
bool enabled;
};
@@ -178,4 +182,10 @@ FRAGMENT_SHADER_CODE
frag_color.rgb = color * params.position_multiplier.w;
frag_color.a = alpha;
+
+ // Blending is disabled for Sky, so alpha doesn't blend
+ // alpha is used for subsurface scattering so make sure it doesn't get applied to Sky
+ if (!AT_CUBEMAP_PASS && !AT_HALF_RES_PASS && !AT_QUARTER_RES_PASS) {
+ frag_color.a = 0.0;
+ }
}
diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
index 524ca5e2ea..a142d263e2 100644
--- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
@@ -48,6 +48,10 @@ layout(push_constant, binding = 1, std430) uniform Params {
float exposure;
float white;
float auto_exposure_grey;
+
+ vec2 pixel_size;
+ bool use_fxaa;
+ uint pad;
}
params;
@@ -255,16 +259,63 @@ vec3 apply_color_correction(vec3 color, sampler3D correction_tex) {
return texture(correction_tex, color).rgb;
}
+vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
+
+ const float FXAA_REDUCE_MIN = (1.0 / 128.0);
+ const float FXAA_REDUCE_MUL = (1.0 / 8.0);
+ const float FXAA_SPAN_MAX = 8.0;
+
+ vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
+ vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
+ vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
+ vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
+ vec3 rgbM = color;
+ vec3 luma = vec3(0.299, 0.587, 0.114);
+ float lumaNW = dot(rgbNW, luma);
+ float lumaNE = dot(rgbNE, luma);
+ float lumaSW = dot(rgbSW, luma);
+ float lumaSE = dot(rgbSE, luma);
+ float lumaM = dot(rgbM, luma);
+ float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
+ float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
+
+ vec2 dir;
+ dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
+ dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
+
+ float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
+ (0.25 * FXAA_REDUCE_MUL),
+ FXAA_REDUCE_MIN);
+
+ float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
+ dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
+ max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
+ dir * rcpDirMin)) *
+ params.pixel_size;
+
+ vec3 rgbA = 0.5 * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz * exposure + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz) * exposure;
+ vec3 rgbB = rgbA * 0.5 + 0.25 * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz * exposure +
+ textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz * exposure);
+
+ float lumaB = dot(rgbB, luma);
+ if ((lumaB < lumaMin) || (lumaB > lumaMax))
+ return rgbA;
+ else
+ return rgbB;
+}
+
void main() {
vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb;
// Exposure
+ float exposure = params.exposure;
+
if (params.use_auto_exposure) {
- color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey;
+ exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey);
}
- color *= params.exposure;
+ color *= exposure;
// Early Tonemap & SRGB Conversion
@@ -274,6 +325,9 @@ void main() {
color.rgb = mix(color.rgb, glow, params.glow_intensity);
}
+ if (params.use_fxaa) {
+ color = do_fxaa(color, exposure, uv_interp);
+ }
color = apply_tonemapping(color, params.white);
color = linear_to_srgb(color); // regular linear -> SRGB conversion
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index a3799b0e4d..a3bb39cd90 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -29,6 +29,8 @@
/*************************************************************************/
#include "rendering_device.h"
+#include "core/method_bind_ext.gen.inc"
+#include "rendering_device_binds.h"
RenderingDevice *RenderingDevice::singleton = nullptr;
@@ -59,6 +61,753 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage,
return compile_function(p_stage, p_source_code, p_language, r_error);
}
+RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) {
+
+ ERR_FAIL_COND_V(p_format.is_null(), RID());
+ ERR_FAIL_COND_V(p_view.is_null(), RID());
+ Vector<Vector<uint8_t>> data;
+ for (int i = 0; i < p_data.size(); i++) {
+ Vector<uint8_t> byte_slice = p_data[i];
+ ERR_FAIL_COND_V(byte_slice.empty(), RID());
+ data.push_back(byte_slice);
+ }
+ return texture_create(p_format->base, p_view->base, data);
+}
+
+RID RenderingDevice::_texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture) {
+ ERR_FAIL_COND_V(p_view.is_null(), RID());
+
+ return texture_create_shared(p_view->base, p_with_texture);
+}
+
+RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) {
+ ERR_FAIL_COND_V(p_view.is_null(), RID());
+
+ return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type);
+}
+
+RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments) {
+
+ Vector<AttachmentFormat> attachments;
+ attachments.resize(p_attachments.size());
+
+ for (int i = 0; i < p_attachments.size(); i++) {
+ Ref<RDAttachmentFormat> af = p_attachments[i];
+ ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID);
+ attachments.write[i] = af->base;
+ }
+ return framebuffer_format_create(attachments);
+}
+
+RID RenderingDevice::_framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check) {
+
+ Vector<RID> textures = Variant(p_textures);
+ return framebuffer_create(textures, p_format_check);
+}
+
+RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) {
+ ERR_FAIL_COND_V(p_state.is_null(), RID());
+
+ return sampler_create(p_state->base);
+}
+
+RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats) {
+
+ Vector<VertexAttribute> descriptions;
+ descriptions.resize(p_vertex_formats.size());
+
+ for (int i = 0; i < p_vertex_formats.size(); i++) {
+ Ref<RDVertexAttribute> af = p_vertex_formats[i];
+ ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID);
+ descriptions.write[i] = af->base;
+ }
+ return vertex_format_create(descriptions);
+}
+
+RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) {
+
+ Vector<RID> buffers = Variant(p_src_buffers);
+
+ return vertex_array_create(p_vertex_count, p_vertex_format, buffers);
+}
+
+Ref<RDShaderBytecode> RenderingDevice::_shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) {
+ ERR_FAIL_COND_V(p_source.is_null(), Ref<RDShaderBytecode>());
+
+ Ref<RDShaderBytecode> bytecode;
+ bytecode.instance();
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ String error;
+
+ ShaderStage stage = ShaderStage(i);
+ Vector<uint8_t> spirv = shader_compile_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache);
+ bytecode->set_stage_bytecode(stage, spirv);
+ bytecode->set_stage_compile_error(stage, error);
+ }
+ return bytecode;
+}
+
+RID RenderingDevice::_shader_create(const Ref<RDShaderBytecode> &p_bytecode) {
+ ERR_FAIL_COND_V(p_bytecode.is_null(), RID());
+
+ Vector<ShaderStageData> stage_data;
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ ShaderStage stage = ShaderStage(i);
+ ShaderStageData sd;
+ sd.shader_stage = stage;
+ String error = p_bytecode->get_stage_compile_error(stage);
+ ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
+ sd.spir_v = p_bytecode->get_stage_bytecode(stage);
+ if (sd.spir_v.empty()) {
+ continue;
+ }
+ stage_data.push_back(sd);
+ }
+
+ return shader_create(stage_data);
+}
+
+RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) {
+
+ Vector<Uniform> uniforms;
+ uniforms.resize(p_uniforms.size());
+ for (int i = 0; i < p_uniforms.size(); i++) {
+ Ref<RDUniform> uniform = p_uniforms[i];
+ ERR_FAIL_COND_V(!uniform.is_valid(), RID());
+ uniforms.write[i] = uniform->base;
+ }
+ return uniform_set_create(uniforms, p_shader, p_shader_set);
+}
+
+Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) {
+
+ return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw);
+}
+
+RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) {
+
+ PipelineRasterizationState rasterization_state;
+ if (p_rasterization_state.is_valid()) {
+ rasterization_state = p_rasterization_state->base;
+ }
+
+ PipelineMultisampleState multisample_state;
+ if (p_multisample_state.is_valid()) {
+ multisample_state = p_multisample_state->base;
+ for (int i = 0; i < p_multisample_state->sample_masks.size(); i++) {
+ int64_t mask = p_multisample_state->sample_masks[i];
+ multisample_state.sample_mask.push_back(mask);
+ }
+ }
+
+ PipelineDepthStencilState depth_stencil_state;
+ if (p_depth_stencil_state.is_valid()) {
+ depth_stencil_state = p_depth_stencil_state->base;
+ }
+
+ PipelineColorBlendState color_blend_state;
+ if (p_blend_state.is_valid()) {
+ color_blend_state = p_blend_state->base;
+ for (int i = 0; i < p_blend_state->attachments.size(); i++) {
+ Ref<RDPipelineColorBlendStateAttachment> attachment = p_blend_state->attachments[i];
+ if (attachment.is_valid()) {
+ color_blend_state.attachments.push_back(attachment->base);
+ }
+ }
+ }
+
+ return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags);
+}
+
+Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
+
+ Vector<DrawListID> splits;
+ splits.resize(p_splits);
+ draw_list_begin_split(p_framebuffer, p_splits, splits.ptrw(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region);
+
+ Vector<int64_t> split_ids;
+ split_ids.resize(splits.size());
+ for (int i = 0; i < splits.size(); i++) {
+ split_ids.write[i] = splits[i];
+ }
+
+ return split_ids;
+}
+
+void RenderingDevice::_draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) {
+ ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size);
+ draw_list_set_push_constant(p_list, p_data.ptr(), p_data_size);
+}
+
+void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) {
+ ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size);
+ compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size);
+}
+
+void RenderingDevice::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array()));
+ ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared);
+ ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D));
+
+ ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "sync_with_draw"), &RenderingDevice::texture_update, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data);
+
+ ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage);
+
+ ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared);
+ ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid);
+
+ ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "sync_with_draw"), &RenderingDevice::texture_copy, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "sync_with_draw"), &RenderingDevice::texture_clear, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "sync_with_draw"), &RenderingDevice::texture_resolve_multisample, DEFVAL(false));
+
+ ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create);
+ ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples);
+ ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID));
+ ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format);
+
+ ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create);
+
+ ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()));
+ ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create);
+
+ ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create);
+
+ ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::_shader_create);
+ ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask);
+
+ ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>()));
+ ClassDB::bind_method(D_METHOD("storage_buffer_create", "size_bytes", "data"), &RenderingDevice::storage_buffer_create, DEFVAL(Vector<uint8_t>()));
+ ClassDB::bind_method(D_METHOD("texture_buffer_create", "size_bytes", "format", "data"), &RenderingDevice::texture_buffer_create, DEFVAL(Vector<uint8_t>()));
+
+ ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create);
+ ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid);
+
+ ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "sync_with_draw"), &RenderingDevice::_buffer_update, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data);
+
+ ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid);
+
+ ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create);
+ ClassDB::bind_method(D_METHOD("compute_pipeline_is_valid", "compute_pieline"), &RenderingDevice::compute_pipeline_is_valid);
+
+ ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("screen_get_height", "screen"), &RenderingDevice::screen_get_height, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("screen_get_framebuffer_format"), &RenderingDevice::screen_get_framebuffer_format);
+
+ ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color()));
+
+ ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::draw_list_begin, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i()));
+ ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i()));
+
+ ClassDB::bind_method(D_METHOD("draw_list_bind_render_pipeline", "draw_list", "render_pipeline"), &RenderingDevice::draw_list_bind_render_pipeline);
+ ClassDB::bind_method(D_METHOD("draw_list_bind_uniform_set", "draw_list", "uniform_set", "set_index"), &RenderingDevice::draw_list_bind_uniform_set);
+ ClassDB::bind_method(D_METHOD("draw_list_bind_vertex_array", "draw_list", "vertex_array"), &RenderingDevice::draw_list_bind_vertex_array);
+ ClassDB::bind_method(D_METHOD("draw_list_bind_index_array", "draw_list", "index_array"), &RenderingDevice::draw_list_bind_index_array);
+ ClassDB::bind_method(D_METHOD("draw_list_set_push_constant", "draw_list", "buffer", "size_bytes"), &RenderingDevice::_draw_list_set_push_constant);
+
+ ClassDB::bind_method(D_METHOD("draw_list_draw", "draw_list", "use_indices", "instances", "procedural_vertex_count"), &RenderingDevice::draw_list_draw, DEFVAL(0));
+
+ ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i()));
+ ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor);
+
+ ClassDB::bind_method(D_METHOD("draw_list_end"), &RenderingDevice::draw_list_end);
+
+ ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin);
+ ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline);
+ ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant);
+ ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set);
+ ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch);
+ ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier);
+ ClassDB::bind_method(D_METHOD("compute_list_end"), &RenderingDevice::compute_list_end);
+
+ ClassDB::bind_method(D_METHOD("free", "rid"), &RenderingDevice::free);
+
+ ClassDB::bind_method(D_METHOD("capture_timestamp", "name", "sync_to_draw"), &RenderingDevice::capture_timestamp);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamps_count"), &RenderingDevice::get_captured_timestamps_count);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamps_frame"), &RenderingDevice::get_captured_timestamps_frame);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamp_gpu_time", "index"), &RenderingDevice::get_captured_timestamp_gpu_time);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamp_cpu_time", "index"), &RenderingDevice::get_captured_timestamp_cpu_time);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamp_name", "index"), &RenderingDevice::get_captured_timestamp_name);
+
+ ClassDB::bind_method(D_METHOD("limit_get", "limit"), &RenderingDevice::limit_get);
+ ClassDB::bind_method(D_METHOD("get_frame_delay"), &RenderingDevice::get_frame_delay);
+ ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit);
+ ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync);
+
+ ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device);
+
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B4G4R4A4_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R5G6B5_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B5G6R5_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R5G5B5A1_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B5G5R5A1_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A1R5G5B5_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_USCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SSCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SRGB_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_USCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SSCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_USCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SSCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B10G11R11_UFLOAT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_X8_D24_UNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_S8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM_S8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D24_UNORM_S8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT_S8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_SNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_SNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_UFLOAT_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_SFLOAT_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_SNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_SNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8B8G8R8_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8G8_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6_UNORM_2PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4_UNORM_2PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16B16G16R16_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B16G16R16G16_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D_ARRAY);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D_ARRAY);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE_ARRAY);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_1);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_2);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_4);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_8);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_16);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_32);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT);
+
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ONE);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_R);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_G);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_B);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_A);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_SLICE_2D);
+ BIND_ENUM_CONSTANT(TEXTURE_SLICE_CUBEMAP);
+ BIND_ENUM_CONSTANT(TEXTURE_SLICE_3D);
+
+ BIND_ENUM_CONSTANT(SAMPLER_FILTER_NEAREST);
+ BIND_ENUM_CONSTANT(SAMPLER_FILTER_LINEAR);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_REPEAT);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRRORED_REPEAT);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MAX);
+
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_MAX);
+
+ BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_VERTEX);
+ BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_INSTANCE);
+
+ BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT16);
+ BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT32);
+
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER); //for sampling only (sampler GLSL type)
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE); // for sampling only); but includes a texture); (samplerXX GLSL type)); first a sampler then a texture
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE); //only texture); (textureXX GLSL type)
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE); // storage image (imageXX GLSL type)); for compute mostly
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE_BUFFER); // buffer texture (or TBO); textureBuffer type)
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER); // buffer texture with a sampler(or TBO); samplerBuffer type)
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE_BUFFER); //texel buffer); (imageBuffer type)); for compute mostly
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_UNIFORM_BUFFER); //regular uniform buffer (or UBO).
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_STORAGE_BUFFER); //storage buffer ("buffer" qualifier) like UBO); but supports storage); for compute mostly
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_INPUT_ATTACHMENT); //used for sub-pass read/write); for mobile mostly
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_MAX);
+
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_POINTS);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES_WITH_ADJACENCY);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TESSELATION_PATCH);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_MAX);
+
+ BIND_ENUM_CONSTANT(POLYGON_CULL_DISABLED);
+ BIND_ENUM_CONSTANT(POLYGON_CULL_FRONT);
+ BIND_ENUM_CONSTANT(POLYGON_CULL_BACK);
+
+ BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_CLOCKWISE);
+ BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_COUNTER_CLOCKWISE);
+
+ BIND_ENUM_CONSTANT(STENCIL_OP_KEEP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_ZERO);
+ BIND_ENUM_CONSTANT(STENCIL_OP_REPLACE);
+ BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_CLAMP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_CLAMP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_INVERT);
+ BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_WRAP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_WRAP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_MAX); //not an actual operator); just the amount of operators :D
+
+ BIND_ENUM_CONSTANT(COMPARE_OP_NEVER);
+ BIND_ENUM_CONSTANT(COMPARE_OP_LESS);
+ BIND_ENUM_CONSTANT(COMPARE_OP_EQUAL);
+ BIND_ENUM_CONSTANT(COMPARE_OP_LESS_OR_EQUAL);
+ BIND_ENUM_CONSTANT(COMPARE_OP_GREATER);
+ BIND_ENUM_CONSTANT(COMPARE_OP_NOT_EQUAL);
+ BIND_ENUM_CONSTANT(COMPARE_OP_GREATER_OR_EQUAL);
+ BIND_ENUM_CONSTANT(COMPARE_OP_ALWAYS);
+ BIND_ENUM_CONSTANT(COMPARE_OP_MAX);
+
+ BIND_ENUM_CONSTANT(LOGIC_OP_CLEAR);
+ BIND_ENUM_CONSTANT(LOGIC_OP_AND);
+ BIND_ENUM_CONSTANT(LOGIC_OP_AND_REVERSE);
+ BIND_ENUM_CONSTANT(LOGIC_OP_COPY);
+ BIND_ENUM_CONSTANT(LOGIC_OP_AND_INVERTED);
+ BIND_ENUM_CONSTANT(LOGIC_OP_NO_OP);
+ BIND_ENUM_CONSTANT(LOGIC_OP_XOR);
+ BIND_ENUM_CONSTANT(LOGIC_OP_OR);
+ BIND_ENUM_CONSTANT(LOGIC_OP_NOR);
+ BIND_ENUM_CONSTANT(LOGIC_OP_EQUIVALENT);
+ BIND_ENUM_CONSTANT(LOGIC_OP_INVERT);
+ BIND_ENUM_CONSTANT(LOGIC_OP_OR_REVERSE);
+ BIND_ENUM_CONSTANT(LOGIC_OP_COPY_INVERTED);
+ BIND_ENUM_CONSTANT(LOGIC_OP_OR_INVERTED);
+ BIND_ENUM_CONSTANT(LOGIC_OP_NAND);
+ BIND_ENUM_CONSTANT(LOGIC_OP_SET);
+ BIND_ENUM_CONSTANT(LOGIC_OP_MAX); //not an actual operator); just the amount of operators :D
+
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ZERO);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA_SATURATE);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_MAX);
+
+ BIND_ENUM_CONSTANT(BLEND_OP_ADD);
+ BIND_ENUM_CONSTANT(BLEND_OP_SUBTRACT);
+ BIND_ENUM_CONSTANT(BLEND_OP_REVERSE_SUBTRACT);
+ BIND_ENUM_CONSTANT(BLEND_OP_MINIMUM);
+ BIND_ENUM_CONSTANT(BLEND_OP_MAXIMUM);
+ BIND_ENUM_CONSTANT(BLEND_OP_MAX);
+
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_LINE_WIDTH);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BIAS);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_BLEND_CONSTANTS);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BOUNDS);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_COMPARE_MASK);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_WRITE_MASK);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE);
+
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params)
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared)
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously)
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_MAX);
+
+ BIND_ENUM_CONSTANT(FINAL_ACTION_READ); //will no longer render to it); allows attached textures to be read again); but depth buffer contents will be dropped (Can't be read from)
+ BIND_ENUM_CONSTANT(FINAL_ACTION_DISCARD); // discard contents after rendering
+ BIND_ENUM_CONSTANT(FINAL_ACTION_CONTINUE); //will continue rendering later); attached textures can't be read until re-bound with "finish"
+ BIND_ENUM_CONSTANT(FINAL_ACTION_MAX);
+
+ BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_MAX);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX_BIT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT_BIT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL_BIT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION_BIT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE_BIT);
+
+ BIND_ENUM_CONSTANT(SHADER_LANGUAGE_GLSL);
+ BIND_ENUM_CONSTANT(SHADER_LANGUAGE_HLSL);
+
+ BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_DRAW_INDEXED_INDEX);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_HEIGHT);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_WIDTH);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_ARRAY_LAYERS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_1D);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_2D);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_3D);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_CUBE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_PUSH_CONSTANT_SIZE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFER_SIZE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDINGS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE);
+ BIND_ENUM_CONSTANT(LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z);
+
+ BIND_CONSTANT(INVALID_ID);
+ BIND_CONSTANT(INVALID_FORMAT_ID);
+}
+
RenderingDevice::RenderingDevice() {
- singleton = this;
+ if (singleton == nullptr) { // there may be more rendering devices later
+ singleton = this;
+ }
}
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index a639ff3641..c76fce5b5c 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -32,8 +32,22 @@
#define RENDERING_DEVICE_H
#include "core/object.h"
+#include "core/typed_array.h"
#include "servers/display_server.h"
+class RDTextureFormat;
+class RDTextureView;
+class RDAttachmentFormat;
+class RDSamplerState;
+class RDVertexAttribute;
+class RDShaderSource;
+class RDShaderBytecode;
+class RDUniforms;
+class RDPipelineRasterizationState;
+class RDPipelineMultisampleState;
+class RDPipelineDepthStencilState;
+class RDPipelineColorBlendState;
+
class RenderingDevice : public Object {
GDCLASS(RenderingDevice, Object)
public:
@@ -65,10 +79,14 @@ private:
static RenderingDevice *singleton;
+protected:
+ static void _bind_methods();
+
public:
//base numeric ID for all types
enum {
- INVALID_ID = -1
+ INVALID_ID = -1,
+ INVALID_FORMAT_ID = -1
};
/*****************/
@@ -428,6 +446,7 @@ public:
virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false) = 0;
virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false) = 0;
+ virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw = false) = 0;
/*********************/
/**** FRAMEBUFFER ****/
@@ -529,13 +548,13 @@ public:
VERTEX_FREQUENCY_INSTANCE,
};
- struct VertexDescription {
+ struct VertexAttribute {
uint32_t location; //shader location
uint32_t offset;
DataFormat format;
uint32_t stride;
VertexFrequency frequency;
- VertexDescription() {
+ VertexAttribute() {
location = 0;
offset = 0;
stride = 0;
@@ -548,7 +567,7 @@ public:
typedef int64_t VertexFormatID;
// This ID is warranted to be unique for the same formats, does not need to be freed
- virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) = 0;
+ virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) = 0;
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0;
enum IndexBufferFormat {
@@ -594,7 +613,7 @@ public:
UNIFORM_TYPE_IMAGE_BUFFER, //texel buffer, (imageBuffer type), for compute mostly
UNIFORM_TYPE_UNIFORM_BUFFER, //regular uniform buffer (or UBO).
UNIFORM_TYPE_STORAGE_BUFFER, //storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly
- UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for compute mostly
+ UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for mobile mostly
UNIFORM_TYPE_MAX
};
@@ -795,8 +814,8 @@ public:
}
};
- StencilOperationState stencil_operation_front;
- StencilOperationState stencil_operation_back;
+ StencilOperationState front_op;
+ StencilOperationState back_op;
PipelineDepthStencilState() {
enable_depth_test = false;
@@ -883,8 +902,8 @@ public:
DYNAMIC_STATE_STENCIL_REFERENCE = (1 << 6),
};
- virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0;
virtual bool render_pipeline_is_valid(RID p_pipeline) = 0;
+ virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0;
/**************************/
/**** COMPUTE PIPELINE ****/
@@ -908,6 +927,7 @@ public:
enum InitialAction {
INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params)
INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared)
+ INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it
INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously)
INITIAL_ACTION_MAX
};
@@ -930,7 +950,7 @@ public:
virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) = 0;
virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array) = 0;
virtual void draw_list_set_line_width(DrawListID p_list, float p_width) = 0;
- virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) = 0;
+ virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) = 0;
virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0) = 0;
@@ -948,7 +968,7 @@ public:
virtual ComputeListID compute_list_begin() = 0;
virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0;
virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0;
- virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) = 0;
+ virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0;
virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0;
virtual void compute_list_add_barrier(ComputeListID p_list) = 0;
@@ -1022,11 +1042,67 @@ public:
virtual uint32_t get_frame_delay() const = 0;
- static RenderingDevice *get_singleton();
+ virtual void submit() = 0;
+ virtual void sync() = 0;
+
+ virtual RenderingDevice *create_local_device() = 0;
+ static RenderingDevice *get_singleton();
RenderingDevice();
+
+protected:
+ //binders to script API
+ RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array());
+ RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture);
+ RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
+
+ FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments);
+ RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID);
+ RID _sampler_create(const Ref<RDSamplerState> &p_state);
+ VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats);
+ RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers);
+
+ Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true);
+ RID _shader_create(const Ref<RDShaderBytecode> &p_bytecode);
+
+ RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set);
+
+ Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false);
+
+ RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0);
+
+ Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2());
+ void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
+ void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
};
+VARIANT_ENUM_CAST(RenderingDevice::ShaderStage)
+VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage)
+VARIANT_ENUM_CAST(RenderingDevice::CompareOperator)
+VARIANT_ENUM_CAST(RenderingDevice::DataFormat)
+VARIANT_ENUM_CAST(RenderingDevice::TextureType)
+VARIANT_ENUM_CAST(RenderingDevice::TextureSamples)
+VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits)
+VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle)
+VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType)
+VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter)
+VARIANT_ENUM_CAST(RenderingDevice::SamplerRepeatMode)
+VARIANT_ENUM_CAST(RenderingDevice::SamplerBorderColor)
+VARIANT_ENUM_CAST(RenderingDevice::VertexFrequency)
+VARIANT_ENUM_CAST(RenderingDevice::IndexBufferFormat)
+VARIANT_ENUM_CAST(RenderingDevice::UniformType)
+VARIANT_ENUM_CAST(RenderingDevice::RenderPrimitive)
+VARIANT_ENUM_CAST(RenderingDevice::PolygonCullMode)
+VARIANT_ENUM_CAST(RenderingDevice::PolygonFrontFace)
+VARIANT_ENUM_CAST(RenderingDevice::StencilOperation)
+VARIANT_ENUM_CAST(RenderingDevice::LogicOperation)
+VARIANT_ENUM_CAST(RenderingDevice::BlendFactor)
+VARIANT_ENUM_CAST(RenderingDevice::BlendOperation)
+VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags)
+VARIANT_ENUM_CAST(RenderingDevice::InitialAction)
+VARIANT_ENUM_CAST(RenderingDevice::FinalAction)
+VARIANT_ENUM_CAST(RenderingDevice::Limit)
+
typedef RenderingDevice RD;
#endif // RENDERING_DEVICE_H
diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp
new file mode 100644
index 0000000000..111755eba3
--- /dev/null
+++ b/servers/rendering/rendering_device_binds.cpp
@@ -0,0 +1,167 @@
+#include "rendering_device_binds.h"
+
+Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func, void *p_include_func_userdata) {
+
+ Vector<String> lines = p_text.split("\n");
+
+ bool reading_versions = false;
+ bool stage_found[RD::SHADER_STAGE_MAX] = { false, false, false, false, false };
+ RD::ShaderStage stage = RD::SHADER_STAGE_MAX;
+ static const char *stage_str[RD::SHADER_STAGE_MAX] = {
+ "vertex",
+ "fragment",
+ "tesselation_control",
+ "tesselation_evaluation",
+ "compute"
+ };
+ String stage_code[RD::SHADER_STAGE_MAX];
+ int stages_found = 0;
+ Map<StringName, String> version_texts;
+
+ versions.clear();
+ base_error = "";
+
+ for (int lidx = 0; lidx < lines.size(); lidx++) {
+ String line = lines[lidx];
+
+ {
+ String ls = line.strip_edges();
+ if (ls.begins_with("[") && ls.ends_with("]")) {
+ String section = ls.substr(1, ls.length() - 2).strip_edges();
+ if (section == "versions") {
+ if (stages_found) {
+ base_error = "Invalid shader file, [version] must be the first section found.";
+ break;
+ }
+ reading_versions = true;
+ } else {
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ if (section == stage_str[i]) {
+ if (stage_found[i]) {
+ base_error = "Invalid shader file, stage appears twice: " + section;
+ break;
+ }
+
+ stage_found[i] = true;
+ stages_found++;
+
+ stage = RD::ShaderStage(i);
+ reading_versions = false;
+ break;
+ }
+ }
+
+ if (base_error != String()) {
+ break;
+ }
+ }
+
+ continue;
+ }
+ }
+
+ if (reading_versions) {
+ String l = line.strip_edges();
+ if (l != "") {
+ int eqpos = l.find("=");
+ if (eqpos == -1) {
+ base_error = "Version syntax is version=\"<defines with C escaping>\".";
+ break;
+ }
+ String version = l.get_slice("=", 0).strip_edges();
+ if (!version.is_valid_identifier()) {
+ base_error = "Version names must be valid identifiers, found '" + version + "' instead.";
+ break;
+ }
+ String define = l.get_slice("=", 1).strip_edges();
+ if (!define.begins_with("\"") || !define.ends_with("\"")) {
+ base_error = "Version text must be quoted using \"\", instead found '" + define + "'.";
+ break;
+ }
+ define = "\n" + define.substr(1, define.length() - 2).c_unescape() + "\n"; //add newline before and after jsut in case
+
+ version_texts[version] = define;
+ }
+ } else {
+ if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") {
+ base_error = "Text was found that does not belong to a valid section: " + line;
+ break;
+ }
+
+ if (stage != RD::SHADER_STAGE_MAX) {
+ if (line.strip_edges().begins_with("#include")) {
+ if (p_include_func) {
+ //process include
+ String include = line.replace("#include", "").strip_edges();
+ if (!include.begins_with("\"") || !include.ends_with("\"")) {
+ base_error = "Malformed #include syntax, expected #include \"<path>\", found instad: " + include;
+ break;
+ }
+ include = include.substr(1, include.length() - 2).strip_edges();
+ String include_text = p_include_func(include, p_include_func_userdata);
+ if (include_text != String()) {
+ stage_code[stage] += "\n" + include_text + "\n";
+ } else {
+ base_error = "#include failed for file '" + include + "'";
+ }
+ } else {
+ base_error = "#include used, but no include function provided.";
+ }
+ } else {
+
+ stage_code[stage] += line + "\n";
+ }
+ }
+ }
+ }
+
+ Ref<RDShaderFile> shader_file;
+ shader_file.instance();
+
+ if (base_error == "") {
+
+ if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) {
+ ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present.");
+ }
+
+ if (version_texts.empty()) {
+ version_texts[""] = ""; //make sure a default version exists
+ }
+
+ bool errors_found = false;
+
+ /* STEP 2, Compile the versions, add to shader file */
+
+ for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) {
+
+ Ref<RDShaderBytecode> bytecode;
+ bytecode.instance();
+
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ String code = stage_code[i];
+ if (code == String()) {
+ continue;
+ }
+ code = code.replace("VERSION_DEFINES", E->get());
+ String error;
+ Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false);
+ bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv);
+ if (error != "") {
+ error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n";
+ Vector<String> sclines = code.split("\n");
+ for (int j = 0; j < sclines.size(); j++) {
+ error += itos(j + 1) + "\t\t" + sclines[j] + "\n";
+ }
+ errors_found = true;
+ }
+ bytecode->set_stage_compile_error(RD::ShaderStage(i), error);
+ }
+
+ set_bytecode(bytecode, E->key());
+ }
+
+ return errors_found ? ERR_PARSE_ERROR : OK;
+ } else {
+ return ERR_PARSE_ERROR;
+ }
+}
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
new file mode 100644
index 0000000000..f57f59876d
--- /dev/null
+++ b/servers/rendering/rendering_device_binds.h
@@ -0,0 +1,579 @@
+#ifndef RENDERING_DEVICE_BINDS_H
+#define RENDERING_DEVICE_BINDS_H
+
+#include "servers/rendering/rendering_device.h"
+
+#define RD_SETGET(m_type, m_member) \
+ void set_##m_member(m_type p_##m_member) { base.m_member = p_##m_member; } \
+ m_type get_##m_member() const { return base.m_member; }
+
+#define RD_BIND(m_variant_type, m_class, m_member) \
+ ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_member); \
+ ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_member)), &m_class::get_##m_member); \
+ ADD_PROPERTY(PropertyInfo(m_variant_type, #m_member), "set_" _MKSTR(m_member), "get_" _MKSTR(m_member))
+
+#define RD_SETGET_SUB(m_type, m_sub, m_member) \
+ void set_##m_sub##_##m_member(m_type p_##m_member) { base.m_sub.m_member = p_##m_member; } \
+ m_type get_##m_sub##_##m_member() const { return base.m_sub.m_member; }
+
+#define RD_BIND_SUB(m_variant_type, m_class, m_sub, m_member) \
+ ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_sub##_##m_member); \
+ ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_sub) "_" _MKSTR(m_member)), &m_class::get_##m_sub##_##m_member); \
+ ADD_PROPERTY(PropertyInfo(m_variant_type, _MKSTR(m_sub) "_" _MKSTR(m_member)), "set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "get_" _MKSTR(m_sub) "_" _MKSTR(m_member))
+
+class RDTextureFormat : public Reference {
+ GDCLASS(RDTextureFormat, Reference)
+ friend class RenderingDevice;
+
+ RD::TextureFormat base;
+
+public:
+ RD_SETGET(RD::DataFormat, format)
+ RD_SETGET(uint32_t, width)
+ RD_SETGET(uint32_t, height)
+ RD_SETGET(uint32_t, depth)
+ RD_SETGET(uint32_t, array_layers)
+ RD_SETGET(uint32_t, mipmaps)
+ RD_SETGET(RD::TextureType, type)
+ RD_SETGET(RD::TextureSamples, samples)
+ RD_SETGET(uint32_t, usage_bits)
+
+ void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); }
+ void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); }
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDTextureFormat, format);
+ RD_BIND(Variant::INT, RDTextureFormat, width);
+ RD_BIND(Variant::INT, RDTextureFormat, height);
+ RD_BIND(Variant::INT, RDTextureFormat, depth);
+ RD_BIND(Variant::INT, RDTextureFormat, array_layers);
+ RD_BIND(Variant::INT, RDTextureFormat, mipmaps);
+ RD_BIND(Variant::INT, RDTextureFormat, type);
+ RD_BIND(Variant::INT, RDTextureFormat, samples);
+ RD_BIND(Variant::INT, RDTextureFormat, usage_bits);
+ ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format);
+ ClassDB::bind_method(D_METHOD("remove_shareable_format", "format"), &RDTextureFormat::remove_shareable_format);
+ }
+};
+
+class RDTextureView : public Reference {
+ GDCLASS(RDTextureView, Reference)
+
+ friend class RenderingDevice;
+
+ RD::TextureView base;
+
+public:
+ RD_SETGET(RD::DataFormat, format_override)
+ RD_SETGET(RD::TextureSwizzle, swizzle_r)
+ RD_SETGET(RD::TextureSwizzle, swizzle_g)
+ RD_SETGET(RD::TextureSwizzle, swizzle_b)
+ RD_SETGET(RD::TextureSwizzle, swizzle_a)
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDTextureView, format_override);
+ RD_BIND(Variant::INT, RDTextureView, swizzle_r);
+ RD_BIND(Variant::INT, RDTextureView, swizzle_g);
+ RD_BIND(Variant::INT, RDTextureView, swizzle_b);
+ RD_BIND(Variant::INT, RDTextureView, swizzle_a);
+ }
+};
+
+class RDAttachmentFormat : public Reference {
+ GDCLASS(RDAttachmentFormat, Reference)
+ friend class RenderingDevice;
+
+ RD::AttachmentFormat base;
+
+public:
+ RD_SETGET(RD::DataFormat, format)
+ RD_SETGET(RD::TextureSamples, samples)
+ RD_SETGET(uint32_t, usage_flags)
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDAttachmentFormat, format);
+ RD_BIND(Variant::INT, RDAttachmentFormat, samples);
+ RD_BIND(Variant::INT, RDAttachmentFormat, usage_flags);
+ }
+};
+
+class RDSamplerState : public Reference {
+ GDCLASS(RDSamplerState, Reference)
+ friend class RenderingDevice;
+
+ RD::SamplerState base;
+
+public:
+ RD_SETGET(RD::SamplerFilter, mag_filter)
+ RD_SETGET(RD::SamplerFilter, min_filter)
+ RD_SETGET(RD::SamplerFilter, mip_filter)
+ RD_SETGET(RD::SamplerRepeatMode, repeat_u)
+ RD_SETGET(RD::SamplerRepeatMode, repeat_v)
+ RD_SETGET(RD::SamplerRepeatMode, repeat_w)
+ RD_SETGET(float, lod_bias)
+ RD_SETGET(bool, use_anisotropy)
+ RD_SETGET(float, anisotropy_max)
+ RD_SETGET(bool, enable_compare)
+ RD_SETGET(RD::CompareOperator, compare_op)
+ RD_SETGET(float, min_lod)
+ RD_SETGET(float, max_lod)
+ RD_SETGET(RD::SamplerBorderColor, border_color)
+ RD_SETGET(bool, unnormalized_uvw)
+
+protected:
+ static void _bind_methods() {
+
+ RD_BIND(Variant::INT, RDSamplerState, mag_filter);
+ RD_BIND(Variant::INT, RDSamplerState, min_filter);
+ RD_BIND(Variant::INT, RDSamplerState, mip_filter);
+ RD_BIND(Variant::INT, RDSamplerState, repeat_u);
+ RD_BIND(Variant::INT, RDSamplerState, repeat_v);
+ RD_BIND(Variant::INT, RDSamplerState, repeat_w);
+ RD_BIND(Variant::FLOAT, RDSamplerState, lod_bias);
+ RD_BIND(Variant::BOOL, RDSamplerState, use_anisotropy);
+ RD_BIND(Variant::FLOAT, RDSamplerState, anisotropy_max);
+ RD_BIND(Variant::BOOL, RDSamplerState, enable_compare);
+ RD_BIND(Variant::INT, RDSamplerState, compare_op);
+ RD_BIND(Variant::FLOAT, RDSamplerState, min_lod);
+ RD_BIND(Variant::FLOAT, RDSamplerState, max_lod);
+ RD_BIND(Variant::INT, RDSamplerState, border_color);
+ RD_BIND(Variant::BOOL, RDSamplerState, unnormalized_uvw);
+ }
+};
+
+class RDVertexAttribute : public Reference {
+ GDCLASS(RDVertexAttribute, Reference)
+ friend class RenderingDevice;
+ RD::VertexAttribute base;
+
+public:
+ RD_SETGET(uint32_t, location)
+ RD_SETGET(uint32_t, offset)
+ RD_SETGET(RD::DataFormat, format)
+ RD_SETGET(uint32_t, stride)
+ RD_SETGET(RD::VertexFrequency, frequency)
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDVertexAttribute, location);
+ RD_BIND(Variant::INT, RDVertexAttribute, offset);
+ RD_BIND(Variant::INT, RDVertexAttribute, format);
+ RD_BIND(Variant::INT, RDVertexAttribute, stride);
+ RD_BIND(Variant::INT, RDVertexAttribute, frequency);
+ }
+};
+class RDShaderSource : public Reference {
+ GDCLASS(RDShaderSource, Reference)
+ String source[RD::SHADER_STAGE_MAX];
+ RD::ShaderLanguage language = RD::SHADER_LANGUAGE_GLSL;
+
+public:
+ void set_stage_source(RD::ShaderStage p_stage, const String &p_source) {
+ ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
+ source[p_stage] = p_source;
+ }
+
+ String get_stage_source(RD::ShaderStage p_stage) const {
+ ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String());
+ return source[p_stage];
+ }
+
+ void set_language(RD::ShaderLanguage p_language) {
+ language = p_language;
+ }
+
+ RD::ShaderLanguage get_language() const {
+ return language;
+ }
+
+protected:
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_stage_source", "stage", "source"), &RDShaderSource::set_stage_source);
+ ClassDB::bind_method(D_METHOD("get_stage_source", "stage"), &RDShaderSource::get_stage_source);
+
+ ClassDB::bind_method(D_METHOD("set_language", "language"), &RDShaderSource::set_language);
+ ClassDB::bind_method(D_METHOD("get_language"), &RDShaderSource::get_language);
+
+ ADD_GROUP("Source", "source_");
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_vertex"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_VERTEX);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_fragment"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_FRAGMENT);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_control"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_CONTROL);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_evaluation"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_EVALUATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_compute"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_COMPUTE);
+ ADD_GROUP("Syntax", "source_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "language", PROPERTY_HINT_RANGE, "GLSL,HLSL"), "set_language", "get_language");
+ }
+};
+
+class RDShaderBytecode : public Resource {
+ GDCLASS(RDShaderBytecode, Resource)
+
+ Vector<uint8_t> bytecode[RD::SHADER_STAGE_MAX];
+ String compile_error[RD::SHADER_STAGE_MAX];
+
+public:
+ void set_stage_bytecode(RD::ShaderStage p_stage, const Vector<uint8_t> &p_bytecode) {
+ ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
+ bytecode[p_stage] = p_bytecode;
+ }
+
+ Vector<uint8_t> get_stage_bytecode(RD::ShaderStage p_stage) const {
+ ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, Vector<uint8_t>());
+ return bytecode[p_stage];
+ }
+
+ void set_stage_compile_error(RD::ShaderStage p_stage, const String &p_compile_error) {
+ ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
+ compile_error[p_stage] = p_compile_error;
+ }
+
+ String get_stage_compile_error(RD::ShaderStage p_stage) const {
+ ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String());
+ return compile_error[p_stage];
+ }
+
+protected:
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderBytecode::set_stage_bytecode);
+ ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderBytecode::get_stage_bytecode);
+
+ ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderBytecode::set_stage_compile_error);
+ ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderBytecode::get_stage_compile_error);
+
+ ADD_GROUP("Bytecode", "bytecode_");
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_vertex"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_VERTEX);
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_fragment"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_FRAGMENT);
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_control"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_CONTROL);
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_evaluation"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_EVALUATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_compute"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_COMPUTE);
+ ADD_GROUP("Compile Error", "compile_error_");
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_vertex"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_VERTEX);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_fragment"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_FRAGMENT);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_control"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_CONTROL);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_evaluation"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_EVALUATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_compute"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_COMPUTE);
+ }
+};
+
+class RDShaderFile : public Resource {
+ GDCLASS(RDShaderFile, Resource)
+
+ Map<StringName, Ref<RDShaderBytecode>> versions;
+ String base_error;
+
+public:
+ void set_bytecode(const Ref<RDShaderBytecode> &p_bytecode, const StringName &p_version = StringName()) {
+ ERR_FAIL_COND(p_bytecode.is_null());
+ versions[p_version] = p_bytecode;
+ emit_changed();
+ }
+
+ Ref<RDShaderBytecode> get_bytecode(const StringName &p_version = StringName()) const {
+ ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderBytecode>());
+ return versions[p_version];
+ }
+
+ Vector<StringName> get_version_list() const {
+ Vector<StringName> vnames;
+ for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) {
+ vnames.push_back(E->key());
+ }
+ vnames.sort_custom<StringName::AlphCompare>();
+ return vnames;
+ }
+
+ void set_base_error(const String &p_error) {
+ base_error = p_error;
+ emit_changed();
+ }
+
+ String get_base_error() const {
+ return base_error;
+ }
+
+ typedef String (*OpenIncludeFunction)(const String &, void *userdata);
+ Error parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr);
+
+protected:
+ Dictionary _get_versions() const {
+ Vector<StringName> vnames = get_version_list();
+ Dictionary ret;
+ for (int i = 0; i < vnames.size(); i++) {
+ ret[vnames[i]] = versions[vnames[i]];
+ }
+ return ret;
+ }
+ void _set_versions(const Dictionary &p_versions) {
+ versions.clear();
+ List<Variant> keys;
+ p_versions.get_key_list(&keys);
+ for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
+ StringName name = E->get();
+ Ref<RDShaderBytecode> bc = p_versions[E->get()];
+ ERR_CONTINUE(bc.is_null());
+ versions[name] = bc;
+ }
+
+ emit_changed();
+ }
+
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_bytecode", "bytecode", "version"), &RDShaderFile::set_bytecode, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("get_bytecode", "version"), &RDShaderFile::get_bytecode, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("get_version_list"), &RDShaderFile::get_version_list);
+
+ ClassDB::bind_method(D_METHOD("set_base_error", "error"), &RDShaderFile::set_base_error);
+ ClassDB::bind_method(D_METHOD("get_base_error"), &RDShaderFile::get_base_error);
+
+ ClassDB::bind_method(D_METHOD("_set_versions", "versions"), &RDShaderFile::_set_versions);
+ ClassDB::bind_method(D_METHOD("_get_versions"), &RDShaderFile::_get_versions);
+
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_versions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_versions", "_get_versions");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_error"), "set_base_error", "get_base_error");
+ }
+};
+
+class RDUniform : public Reference {
+ GDCLASS(RDUniform, Reference)
+ friend class RenderingDevice;
+ RD::Uniform base;
+
+public:
+ RD_SETGET(RD::UniformType, type)
+ RD_SETGET(int32_t, binding)
+
+ void add_id(const RID &p_id) { base.ids.push_back(p_id); }
+ void clear_ids() { base.ids.clear(); }
+ Array get_ids() const {
+ Array ids;
+ for (int i = 0; i < base.ids.size(); i++) {
+ ids.push_back(base.ids[i]);
+ }
+ return ids;
+ }
+
+protected:
+ void _set_ids(const Array &p_ids) {
+ base.ids.clear();
+ for (int i = 0; i < p_ids.size(); i++) {
+ RID id = p_ids[i];
+ ERR_FAIL_COND(id.is_null());
+ base.ids.push_back(id);
+ }
+ }
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDUniform, type);
+ RD_BIND(Variant::INT, RDUniform, binding);
+ ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id);
+ ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids);
+ ClassDB::bind_method(D_METHOD("_set_ids", "ids"), &RDUniform::_set_ids);
+ ClassDB::bind_method(D_METHOD("get_ids"), &RDUniform::get_ids);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids");
+ }
+};
+class RDPipelineRasterizationState : public Reference {
+ GDCLASS(RDPipelineRasterizationState, Reference)
+ friend class RenderingDevice;
+
+ RD::PipelineRasterizationState base;
+
+public:
+ RD_SETGET(bool, enable_depth_clamp)
+ RD_SETGET(bool, discard_primitives)
+ RD_SETGET(bool, wireframe)
+ RD_SETGET(RD::PolygonCullMode, cull_mode)
+ RD_SETGET(RD::PolygonFrontFace, front_face)
+ RD_SETGET(bool, depth_bias_enable)
+ RD_SETGET(float, depth_bias_constant_factor)
+ RD_SETGET(float, depth_bias_clamp)
+ RD_SETGET(float, depth_bias_slope_factor)
+ RD_SETGET(float, line_width)
+ RD_SETGET(uint32_t, patch_control_points)
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::BOOL, RDPipelineRasterizationState, enable_depth_clamp);
+ RD_BIND(Variant::BOOL, RDPipelineRasterizationState, discard_primitives);
+ RD_BIND(Variant::BOOL, RDPipelineRasterizationState, wireframe);
+ RD_BIND(Variant::INT, RDPipelineRasterizationState, cull_mode);
+ RD_BIND(Variant::INT, RDPipelineRasterizationState, front_face);
+ RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enable);
+ RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_constant_factor);
+ RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_clamp);
+ RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor);
+ RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, line_width);
+ RD_BIND(Variant::INT, RDPipelineRasterizationState, patch_control_points);
+ }
+};
+
+class RDPipelineMultisampleState : public Reference {
+ GDCLASS(RDPipelineMultisampleState, Reference)
+ friend class RenderingDevice;
+
+ RD::PipelineMultisampleState base;
+ TypedArray<int64_t> sample_masks;
+
+public:
+ RD_SETGET(RD::TextureSamples, sample_count)
+ RD_SETGET(bool, enable_sample_shading)
+ RD_SETGET(float, min_sample_shading)
+ RD_SETGET(bool, enable_alpha_to_coverage)
+ RD_SETGET(bool, enable_alpha_to_one)
+
+ void set_sample_masks(const TypedArray<int64_t> &p_masks) { sample_masks = p_masks; }
+ TypedArray<int64_t> get_sample_masks() const { return sample_masks; }
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count);
+ RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading);
+ RD_BIND(Variant::FLOAT, RDPipelineMultisampleState, min_sample_shading);
+ RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage);
+ RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one);
+
+ ClassDB::bind_method(D_METHOD("set_sample_masks", "masks"), &RDPipelineMultisampleState::set_sample_masks);
+ ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "sample_masks", PROPERTY_HINT_ARRAY_TYPE, "int"), "set_sample_masks", "get_sample_masks");
+ }
+};
+
+class RDPipelineDepthStencilState : public Reference {
+ GDCLASS(RDPipelineDepthStencilState, Reference)
+ friend class RenderingDevice;
+
+ RD::PipelineDepthStencilState base;
+
+public:
+ RD_SETGET(bool, enable_depth_test)
+ RD_SETGET(bool, enable_depth_write)
+ RD_SETGET(RD::CompareOperator, depth_compare_operator)
+ RD_SETGET(bool, enable_depth_range)
+ RD_SETGET(float, depth_range_min)
+ RD_SETGET(float, depth_range_max)
+ RD_SETGET(bool, enable_stencil)
+
+ RD_SETGET_SUB(RD::StencilOperation, front_op, fail)
+ RD_SETGET_SUB(RD::StencilOperation, front_op, pass)
+ RD_SETGET_SUB(RD::StencilOperation, front_op, depth_fail)
+ RD_SETGET_SUB(RD::CompareOperator, front_op, compare)
+ RD_SETGET_SUB(uint32_t, front_op, compare_mask)
+ RD_SETGET_SUB(uint32_t, front_op, write_mask)
+ RD_SETGET_SUB(uint32_t, front_op, reference)
+
+ RD_SETGET_SUB(RD::StencilOperation, back_op, fail)
+ RD_SETGET_SUB(RD::StencilOperation, back_op, pass)
+ RD_SETGET_SUB(RD::StencilOperation, back_op, depth_fail)
+ RD_SETGET_SUB(RD::CompareOperator, back_op, compare)
+ RD_SETGET_SUB(uint32_t, back_op, compare_mask)
+ RD_SETGET_SUB(uint32_t, back_op, write_mask)
+ RD_SETGET_SUB(uint32_t, back_op, reference)
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_test);
+ RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_write);
+ RD_BIND(Variant::INT, RDPipelineDepthStencilState, depth_compare_operator);
+ RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_range);
+ RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_min);
+ RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_max);
+ RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_stencil);
+
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, fail);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, pass);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, depth_fail);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare_mask);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, write_mask);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, reference);
+
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, fail);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, pass);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, depth_fail);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare_mask);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, write_mask);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, reference);
+ }
+};
+
+class RDPipelineColorBlendStateAttachment : public Reference {
+ GDCLASS(RDPipelineColorBlendStateAttachment, Reference)
+ friend class RenderingDevice;
+ RD::PipelineColorBlendState::Attachment base;
+
+public:
+ RD_SETGET(bool, enable_blend)
+ RD_SETGET(RD::BlendFactor, src_color_blend_factor)
+ RD_SETGET(RD::BlendFactor, dst_color_blend_factor)
+ RD_SETGET(RD::BlendOperation, color_blend_op)
+ RD_SETGET(RD::BlendFactor, src_alpha_blend_factor)
+ RD_SETGET(RD::BlendFactor, dst_alpha_blend_factor)
+ RD_SETGET(RD::BlendOperation, alpha_blend_op)
+ RD_SETGET(bool, write_r)
+ RD_SETGET(bool, write_g)
+ RD_SETGET(bool, write_b)
+ RD_SETGET(bool, write_a)
+
+ void set_as_mix() {
+
+ base = RD::PipelineColorBlendState::Attachment();
+ base.enable_blend = true;
+ base.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ base.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ base.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ base.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ }
+
+protected:
+ static void _bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix);
+
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, color_blend_op);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_alpha_blend_factor);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_alpha_blend_factor);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, alpha_blend_op);
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_r);
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_g);
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_b);
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_a);
+ }
+};
+
+class RDPipelineColorBlendState : public Reference {
+ GDCLASS(RDPipelineColorBlendState, Reference)
+ friend class RenderingDevice;
+ RD::PipelineColorBlendState base;
+
+ TypedArray<RDPipelineColorBlendStateAttachment> attachments;
+
+public:
+ RD_SETGET(bool, enable_logic_op)
+ RD_SETGET(RD::LogicOperation, logic_op)
+ RD_SETGET(Color, blend_constant)
+
+ void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) {
+ attachments.push_back(p_attachments);
+ }
+
+ TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const {
+ return attachments;
+ }
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendState, enable_logic_op);
+ RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op);
+ RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant);
+
+ ClassDB::bind_method(D_METHOD("set_attachments", "atachments"), &RDPipelineColorBlendState::set_attachments);
+ ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "attachments", PROPERTY_HINT_ARRAY_TYPE, "RDPipelineColorBlendStateAttachment"), "set_attachments", "get_attachments");
+ }
+};
+
+#endif // RENDERING_DEVICE_BINDS_H
diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_raster.cpp
index 7cc06527e4..c6f3273339 100644
--- a/servers/rendering/rendering_server_raster.cpp
+++ b/servers/rendering/rendering_server_raster.cpp
@@ -135,16 +135,27 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) {
if (RSG::storage->get_captured_timestamps_count()) {
Vector<FrameProfileArea> new_profile;
- new_profile.resize(RSG::storage->get_captured_timestamps_count());
+ if (RSG::storage->capturing_timestamps) {
+ new_profile.resize(RSG::storage->get_captured_timestamps_count());
+ }
uint64_t base_cpu = RSG::storage->get_captured_timestamp_cpu_time(0);
uint64_t base_gpu = RSG::storage->get_captured_timestamp_gpu_time(0);
for (uint32_t i = 0; i < RSG::storage->get_captured_timestamps_count(); i++) {
- uint64_t time_cpu = RSG::storage->get_captured_timestamp_cpu_time(i) - base_cpu;
- uint64_t time_gpu = RSG::storage->get_captured_timestamp_gpu_time(i) - base_gpu;
- new_profile.write[i].gpu_msec = float(time_gpu / 1000) / 1000.0;
- new_profile.write[i].cpu_msec = float(time_cpu) / 1000.0;
- new_profile.write[i].name = RSG::storage->get_captured_timestamp_name(i);
+ uint64_t time_cpu = RSG::storage->get_captured_timestamp_cpu_time(i);
+ uint64_t time_gpu = RSG::storage->get_captured_timestamp_gpu_time(i);
+
+ String name = RSG::storage->get_captured_timestamp_name(i);
+
+ if (name.begins_with("vp_")) {
+ RSG::viewport->handle_timestamp(name, time_cpu, time_gpu);
+ }
+
+ if (RSG::storage->capturing_timestamps) {
+ new_profile.write[i].gpu_msec = float((time_gpu - base_gpu) / 1000) / 1000.0;
+ new_profile.write[i].cpu_msec = float(time_cpu - base_cpu) / 1000.0;
+ new_profile.write[i].name = RSG::storage->get_captured_timestamp_name(i);
+ }
}
frame_profile = new_profile;
diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h
index 267efdbacb..f7b963a015 100644
--- a/servers/rendering/rendering_server_raster.h
+++ b/servers/rendering/rendering_server_raster.h
@@ -98,6 +98,8 @@ public:
#define BIND0R(m_r, m_name) \
m_r m_name() { return BINDBASE->m_name(); }
+#define BIND0RC(m_r, m_name) \
+ m_r m_name() const { return BINDBASE->m_name(); }
#define BIND1R(m_r, m_name, m_type1) \
m_r m_name(m_type1 arg1) { return BINDBASE->m_name(arg1); }
#define BIND1RC(m_r, m_name, m_type1) \
@@ -111,8 +113,12 @@ public:
#define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \
m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); }
+#define BIND0(m_name) \
+ void m_name() { DISPLAY_CHANGED BINDBASE->m_name(); }
#define BIND1(m_name, m_type1) \
void m_name(m_type1 arg1) { DISPLAY_CHANGED BINDBASE->m_name(arg1); }
+#define BIND1C(m_name, m_type1) \
+ void m_name(m_type1 arg1) const { DISPLAY_CHANGED BINDBASE->m_name(arg1); }
#define BIND2(m_name, m_type1, m_type2) \
void m_name(m_type1 arg1, m_type2 arg2) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2); }
#define BIND2C(m_name, m_type1, m_type2) \
@@ -340,6 +346,20 @@ public:
BIND2(reflection_probe_set_cull_mask, RID, uint32_t)
BIND2(reflection_probe_set_resolution, RID, int)
+ /* DECAL API */
+
+ BIND0R(RID, decal_create)
+
+ BIND2(decal_set_extents, RID, const Vector3 &)
+ BIND3(decal_set_texture, RID, DecalTexture, RID)
+ BIND2(decal_set_emission_energy, RID, float)
+ BIND2(decal_set_albedo_mix, RID, float)
+ BIND2(decal_set_modulate, RID, const Color &)
+ BIND2(decal_set_cull_mask, RID, uint32_t)
+ BIND4(decal_set_distance_fade, RID, bool, float, float)
+ BIND3(decal_set_fade, RID, float, float)
+ BIND2(decal_set_normal_fade, RID, float)
+
/* BAKED LIGHT API */
BIND0R(RID, gi_probe_create)
@@ -456,7 +476,7 @@ public:
BIND0R(RID, viewport_create)
- BIND2(viewport_set_use_arvr, RID, bool)
+ BIND2(viewport_set_use_xr, RID, bool)
BIND3(viewport_set_size, RID, int, int)
BIND2(viewport_set_active, RID, bool)
@@ -489,10 +509,15 @@ public:
BIND2(viewport_set_shadow_atlas_size, RID, int)
BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
BIND2(viewport_set_msaa, RID, ViewportMSAA)
+ BIND2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw)
+ BIND2(viewport_set_measure_render_time, RID, bool)
+ BIND1RC(float, viewport_get_measured_render_time_cpu, RID)
+ BIND1RC(float, viewport_get_measured_render_time_gpu, RID)
+
/* ENVIRONMENT API */
#undef BINDBASE
@@ -554,6 +579,9 @@ public:
BIND8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float)
BIND3(camera_effects_set_custom_exposure, RID, bool, float)
+ BIND1(shadows_quality_set, ShadowQuality);
+ BIND1(directional_shadow_quality_set, ShadowQuality);
+
/* SCENARIO API */
#undef BINDBASE
@@ -598,6 +626,11 @@ public:
BIND5(instance_geometry_set_draw_range, RID, float, float, float, float)
BIND2(instance_geometry_set_as_instance_lod, RID, RID)
+ BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
+ BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
+ BIND2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &)
+ BIND2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *)
+
#undef BINDBASE
//from now on, calls forwarded to this singleton
#define BINDBASE RSG::canvas
@@ -695,6 +728,23 @@ public:
BIND2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
+ /* GLOBAL VARIABLES */
+
+#undef BINDBASE
+//from now on, calls forwarded to this singleton
+#define BINDBASE RSG::storage
+
+ BIND3(global_variable_add, const StringName &, GlobalVariableType, const Variant &)
+ BIND1(global_variable_remove, const StringName &)
+ BIND0RC(Vector<StringName>, global_variable_get_list)
+ BIND2(global_variable_set, const StringName &, const Variant &)
+ BIND2(global_variable_set_override, const StringName &, const Variant &)
+ BIND1RC(GlobalVariableType, global_variable_get_type, const StringName &)
+ BIND1RC(Variant, global_variable_get, const StringName &)
+
+ BIND1(global_variables_load_settings, bool)
+ BIND0(global_variables_clear)
+
/* BLACK BARS */
virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom);
diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp
index 65823e11aa..9d141ea570 100644
--- a/servers/rendering/rendering_server_scene.cpp
+++ b/servers/rendering/rendering_server_scene.cpp
@@ -155,6 +155,20 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan
geom->reflection_dirty = true;
return E; //this element should make freeing faster
+ } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ InstanceDecalData::PairInfo pinfo;
+ pinfo.geometry = A;
+ pinfo.L = geom->decals.push_back(B);
+
+ List<InstanceDecalData::PairInfo>::Element *E = decal->geometries.push_back(pinfo);
+
+ geom->decal_dirty = true;
+
+ return E; //this element should make freeing faster
} else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data);
@@ -233,6 +247,17 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta
reflection_probe->geometries.erase(E);
geom->reflection_dirty = true;
+ } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ List<InstanceDecalData::PairInfo>::Element *E = reinterpret_cast<List<InstanceDecalData::PairInfo>::Element *>(udata);
+
+ geom->decals.erase(E->get().L);
+ decal->geometries.erase(E);
+
+ geom->decal_dirty = true;
} else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data);
@@ -387,6 +412,12 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
reflection_probe_render_list.remove(&reflection_probe->update_list);
}
} break;
+ case RS::INSTANCE_DECAL: {
+
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data);
+ RSG::scene_render->free(decal->instance);
+
+ } break;
case RS::INSTANCE_LIGHTMAP_CAPTURE: {
InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(instance->base_data);
@@ -476,6 +507,14 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
reflection_probe->instance = RSG::scene_render->reflection_probe_instance_create(p_base);
} break;
+ case RS::INSTANCE_DECAL: {
+
+ InstanceDecalData *decal = memnew(InstanceDecalData);
+ decal->owner = instance;
+ instance->base_data = decal;
+
+ decal->instance = RSG::scene_render->decal_instance_create(p_base);
+ } break;
case RS::INSTANCE_LIGHTMAP_CAPTURE: {
InstanceLightmapCaptureData *lightmap_capture = memnew(InstanceLightmapCaptureData);
@@ -691,6 +730,12 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible)
}
} break;
+ case RS::INSTANCE_DECAL: {
+ if (instance->octree_id && instance->scenario) {
+ instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_DECAL, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0);
+ }
+
+ } break;
case RS::INSTANCE_LIGHTMAP_CAPTURE: {
if (instance->octree_id && instance->scenario) {
instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP_CAPTURE, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0);
@@ -923,6 +968,67 @@ void RenderingServerScene::instance_geometry_set_draw_range(RID p_instance, floa
void RenderingServerScene::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) {
}
+void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) {
+
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter);
+
+ if (!E) {
+ RasterizerScene::InstanceBase::InstanceShaderParameter isp;
+ isp.index = -1;
+ isp.info = PropertyInfo();
+ isp.value = p_value;
+ instance->instance_shader_parameters[p_parameter] = isp;
+ } else {
+ E->get().value = p_value;
+ if (E->get().index >= 0 && instance->instance_allocated_shader_parameters) {
+ //update directly
+ RSG::storage->global_variables_instance_update(p_instance, E->get().index, p_value);
+ }
+ }
+}
+
+Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const {
+
+ const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance);
+ ERR_FAIL_COND_V(!instance, Variant());
+
+ if (instance->instance_shader_parameters.has(p_parameter)) {
+ return instance->instance_shader_parameters[p_parameter].value;
+ }
+ return Variant();
+}
+
+Variant RenderingServerScene::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const {
+
+ const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance);
+ ERR_FAIL_COND_V(!instance, Variant());
+
+ if (instance->instance_shader_parameters.has(p_parameter)) {
+ return instance->instance_shader_parameters[p_parameter].default_value;
+ }
+ return Variant();
+}
+
+void RenderingServerScene::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const {
+ const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ const_cast<RenderingServerScene *>(this)->update_dirty_instances();
+
+ Vector<StringName> names;
+ for (Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) {
+ names.push_back(E->key());
+ }
+ names.sort_custom<StringName::AlphCompare>();
+ for (int i = 0; i < names.size(); i++) {
+ PropertyInfo pinfo = instance->instance_shader_parameters[names[i]].info;
+ p_parameters->push_back(pinfo);
+ }
+}
+
void RenderingServerScene::_update_instance(Instance *p_instance) {
p_instance->version++;
@@ -943,6 +1049,13 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
reflection_probe->reflection_dirty = true;
}
+ if (p_instance->base_type == RS::INSTANCE_DECAL) {
+
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
+
+ RSG::scene_render->decal_instance_set_transform(decal->instance, p_instance->transform);
+ }
+
if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data);
@@ -1000,7 +1113,7 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
uint32_t pairable_mask = 0;
bool pairable = false;
- if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE) {
+ if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE) {
pairable_mask = p_instance->visible ? RS::INSTANCE_GEOMETRY_MASK : 0;
pairable = true;
@@ -1080,6 +1193,11 @@ void RenderingServerScene::_update_instance_aabb(Instance *p_instance) {
new_aabb = RSG::storage->reflection_probe_get_aabb(p_instance->base);
} break;
+ case RenderingServer::INSTANCE_DECAL: {
+
+ new_aabb = RSG::storage->decal_get_aabb(p_instance->base);
+
+ } break;
case RenderingServer::INSTANCE_GI_PROBE: {
new_aabb = RSG::storage->gi_probe_get_bounds(p_instance->base);
@@ -1334,7 +1452,7 @@ void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instan
}
}
-bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) {
+bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) {
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
@@ -1347,16 +1465,18 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
case RS::LIGHT_DIRECTIONAL: {
- float max_distance = p_cam_projection.get_z_far();
- float shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
+ real_t max_distance = p_cam_projection.get_z_far();
+ real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
max_distance = MIN(shadow_max, max_distance);
}
max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001);
- float min_distance = MIN(p_cam_projection.get_z_near(), max_distance);
+ real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance);
RS::LightDirectionalShadowDepthRangeMode depth_range_mode = RSG::storage->light_directional_get_shadow_depth_range_mode(p_instance->base);
+ real_t pancake_size = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
+
if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED) {
//optimize min/max
Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
@@ -1365,8 +1485,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
//check distance max and min
bool found_items = false;
- float z_max = -1e20;
- float z_min = 1e20;
+ real_t z_max = -1e20;
+ real_t z_min = 1e20;
for (int i = 0; i < cull_count; i++) {
@@ -1379,7 +1499,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
animated_material_found = true;
}
- float max, min;
+ real_t max, min;
instance->transformed_aabb.project_range_in_plane(base, min, max);
if (max > z_max) {
@@ -1399,7 +1519,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
}
}
- float range = max_distance - min_distance;
+ real_t range = max_distance - min_distance;
int splits = 0;
switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) {
@@ -1408,7 +1528,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: splits = 4; break;
}
- float distances[5];
+ real_t distances[5];
distances[0] = min_distance;
for (int i = 0; i < splits; i++) {
@@ -1417,11 +1537,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
distances[splits] = max_distance;
- float texture_size = RSG::scene_render->get_directional_light_shadow_size(light->instance);
+ real_t texture_size = RSG::scene_render->get_directional_light_shadow_size(light->instance);
bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base);
- float first_radius = 0.0;
+ real_t first_radius = 0.0;
+
+ real_t min_distance_bias_scale = pancake_size > 0 ? distances[1] / 10.0 : 0;
for (int i = 0; i < splits; i++) {
@@ -1430,7 +1552,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
// setup a camera matrix for that range!
CameraMatrix camera_matrix;
- float aspect = p_cam_projection.get_aspect();
+ real_t aspect = p_cam_projection.get_aspect();
if (p_cam_orthogonal) {
@@ -1439,8 +1561,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
} else {
- float fov = p_cam_projection.get_fov();
- camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
+ real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it
+ camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
}
//obtain the frustum endpoints
@@ -1458,26 +1580,27 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized();
//z_vec points agsint the camera, like in default opengl
- float x_min = 0.f, x_max = 0.f;
- float y_min = 0.f, y_max = 0.f;
- float z_min = 0.f, z_max = 0.f;
+ real_t x_min = 0.f, x_max = 0.f;
+ real_t y_min = 0.f, y_max = 0.f;
+ real_t z_min = 0.f, z_max = 0.f;
// FIXME: z_max_cam is defined, computed, but not used below when setting up
// ortho_camera. Commented out for now to fix warnings but should be investigated.
- float x_min_cam = 0.f, x_max_cam = 0.f;
- float y_min_cam = 0.f, y_max_cam = 0.f;
- float z_min_cam = 0.f;
- //float z_max_cam = 0.f;
+ real_t x_min_cam = 0.f, x_max_cam = 0.f;
+ real_t y_min_cam = 0.f, y_max_cam = 0.f;
+ real_t z_min_cam = 0.f;
+ //real_t z_max_cam = 0.f;
- float bias_scale = 1.0;
+ real_t bias_scale = 1.0;
+ real_t aspect_bias_scale = 1.0;
//used for culling
for (int j = 0; j < 8; j++) {
- float d_x = x_vec.dot(endpoints[j]);
- float d_y = y_vec.dot(endpoints[j]);
- float d_z = z_vec.dot(endpoints[j]);
+ real_t d_x = x_vec.dot(endpoints[j]);
+ real_t d_y = y_vec.dot(endpoints[j]);
+ real_t d_z = z_vec.dot(endpoints[j]);
if (j == 0 || d_x < x_min)
x_min = d_x;
@@ -1495,11 +1618,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
z_max = d_z;
}
+ real_t radius = 0;
+ real_t soft_shadow_expand = 0;
+ Vector3 center;
+
{
//camera viewport stuff
- Vector3 center;
-
for (int j = 0; j < 8; j++) {
center += endpoints[j];
@@ -1508,11 +1633,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
//center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5;
- float radius = 0;
-
for (int j = 0; j < 8; j++) {
- float d = center.distance_to(endpoints[j]);
+ real_t d = center.distance_to(endpoints[j]);
if (d > radius)
radius = d;
}
@@ -1525,18 +1648,35 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
bias_scale = radius / first_radius;
}
- x_max_cam = x_vec.dot(center) + radius;
- x_min_cam = x_vec.dot(center) - radius;
- y_max_cam = y_vec.dot(center) + radius;
- y_min_cam = y_vec.dot(center) - radius;
- //z_max_cam = z_vec.dot(center) + radius;
z_min_cam = z_vec.dot(center) - radius;
+ {
+
+ float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
+
+ if (soft_shadow_angle > 0.0 && pancake_size > 0.0) {
+
+ float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam;
+ soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range;
+
+ x_max += soft_shadow_expand;
+ y_max += soft_shadow_expand;
+
+ x_min -= soft_shadow_expand;
+ y_min -= soft_shadow_expand;
+ }
+ }
+
+ x_max_cam = x_vec.dot(center) + radius + soft_shadow_expand;
+ x_min_cam = x_vec.dot(center) - radius - soft_shadow_expand;
+ y_max_cam = y_vec.dot(center) + radius + soft_shadow_expand;
+ y_min_cam = y_vec.dot(center) - radius - soft_shadow_expand;
+
if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) {
//this trick here is what stabilizes the shadow (make potential jaggies to not move)
//at the cost of some wasted resolution. Still the quality increase is very well worth it
- float unit = radius * 2.0 / texture_size;
+ real_t unit = radius * 2.0 / texture_size;
x_max_cam = Math::stepify(x_max_cam, unit);
x_min_cam = Math::stepify(x_min_cam, unit);
@@ -1566,9 +1706,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
+ real_t cull_max = 0;
for (int j = 0; j < cull_count; j++) {
- float min, max;
+ real_t min, max;
Instance *instance = instance_shadow_cull_result[j];
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
cull_count--;
@@ -1580,8 +1721,91 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
instance->transformed_aabb.project_range_in_plane(Plane(z_vec, 0), min, max);
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
- if (max > z_max)
- z_max = max;
+ if (j == 0 || max > cull_max) {
+ cull_max = max;
+ }
+ }
+
+ if (cull_max > z_max) {
+ z_max = cull_max;
+ }
+
+ if (pancake_size > 0) {
+ z_max = z_vec.dot(center) + radius + pancake_size;
+ }
+
+ if (aspect != 1.0) {
+
+ // if the aspect is different, then the radius will become larger.
+ // if this happens, then bias needs to be adjusted too, as depth will increase
+ // to do this, compare the depth of one that would have resulted from a square frustum
+
+ CameraMatrix camera_matrix_square;
+ if (p_cam_orthogonal) {
+
+ Vector2 vp_he = camera_matrix.get_viewport_half_extents();
+ if (p_cam_vaspect) {
+ camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
+ } else {
+ camera_matrix_square.set_orthogonal(vp_he.y * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
+ }
+ } else {
+ Vector2 vp_he = camera_matrix.get_viewport_half_extents();
+ if (p_cam_vaspect) {
+ camera_matrix_square.set_frustum(vp_he.x * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
+ } else {
+ camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
+ }
+
+ if (i == 0) {
+ //print_line("prev he: " + vp_he + " new he: " + camera_matrix_square.get_viewport_half_extents());
+ }
+ }
+
+ Vector3 endpoints_square[8]; // frustum plane endpoints
+ res = camera_matrix_square.get_endpoints(p_cam_transform, endpoints_square);
+ ERR_CONTINUE(!res);
+ Vector3 center_square;
+ real_t z_max_square = 0;
+
+ for (int j = 0; j < 8; j++) {
+
+ center_square += endpoints_square[j];
+
+ real_t d_z = z_vec.dot(endpoints_square[j]);
+
+ if (j == 0 || d_z > z_max_square)
+ z_max_square = d_z;
+ }
+
+ if (cull_max > z_max_square) {
+ z_max_square = cull_max;
+ }
+
+ center_square /= 8.0;
+
+ real_t radius_square = 0;
+
+ for (int j = 0; j < 8; j++) {
+
+ real_t d = center_square.distance_to(endpoints_square[j]);
+ if (d > radius_square)
+ radius_square = d;
+ }
+
+ radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side
+
+ if (pancake_size > 0) {
+ z_max_square = z_vec.dot(center_square) + radius_square + pancake_size;
+ }
+
+ real_t z_min_cam_square = z_vec.dot(center_square) - radius_square;
+
+ aspect_bias_scale = (z_max - z_min_cam) / (z_max_square - z_min_cam_square);
+
+ // this is not entirely perfect, because the cull-adjusted z-max may be different
+ // but at least it's warranted that it results in a greater bias, so no acne should be present either way.
+ // pancaking also helps with this.
}
{
@@ -1592,11 +1816,19 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam));
+ Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam));
+
Transform ortho_transform;
ortho_transform.basis = transform.basis;
ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max;
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i, bias_scale);
+ {
+ Vector3 max_in_view = p_cam_transform.affine_inverse().xform(z_vec * cull_max);
+ Vector3 dir_in_view = p_cam_transform.xform_inv(z_vec).normalized();
+ cull_max = dir_in_view.dot(max_in_view);
+ }
+
+ RSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, z_max - z_min_cam, distances[i + 1], i, radius * 2.0 / texture_size, bias_scale * aspect_bias_scale * min_distance_bias_scale, z_max, uv_scale);
}
RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
@@ -1614,9 +1846,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
//using this one ensures that raster deferred will have it
RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i));
- float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+ real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
- float z = i == 0 ? -1 : 1;
+ real_t z = i == 0 ? -1 : 1;
Vector<Plane> planes;
planes.resize(5);
planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
@@ -1645,12 +1877,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
}
}
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i);
+ RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0);
RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
}
} else { //shadow cube
- float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+ real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
CameraMatrix cm;
cm.set_perspective(90, 1, 0.01, radius);
@@ -1699,12 +1931,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
}
}
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i);
+ RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0);
RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
}
//restore the regular DP matrix
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0);
+ RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0);
}
} break;
@@ -1712,8 +1944,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
RENDER_TIMESTAMP("Culling Spot Light");
- float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
- float angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+ real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+ real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
CameraMatrix cm;
cm.set_perspective(angle * 2.0, 1.0, 0.01, radius);
@@ -1738,7 +1970,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
}
}
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0);
+ RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0);
RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, 0, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
} break;
@@ -1793,12 +2025,12 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID
} break;
}
- _prepare_scene(camera->transform, camera_matrix, ortho, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
+ _prepare_scene(camera->transform, camera_matrix, ortho, camera->vaspect, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
_render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, camera->env, camera->effects, p_scenario, p_shadow_atlas, RID(), -1);
#endif
}
-void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
+void RenderingServerScene::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
// render for AR/VR interface
Camera *camera = camera_owner.getornull(p_camera);
@@ -1810,16 +2042,14 @@ void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface
// We also ignore our camera position, it will have been positioned with a slightly old tracking position.
// Instead we take our origin point and have our ar/vr interface add fresh tracking data! Whoohoo!
- Transform world_origin = ARVRServer::get_singleton()->get_world_origin();
+ Transform world_origin = XRServer::get_singleton()->get_world_origin();
Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin);
// For stereo render we only prepare for our left eye and then reuse the outcome for our right eye
- if (p_eye == ARVRInterface::EYE_LEFT) {
- ///@TODO possibly move responsibility for this into our ARVRServer or ARVRInterface?
-
+ if (p_eye == XRInterface::EYE_LEFT) {
// Center our transform, we assume basis is equal.
Transform mono_transform = cam_transform;
- Transform right_transform = p_interface->get_transform_for_eye(ARVRInterface::EYE_RIGHT, world_origin);
+ Transform right_transform = p_interface->get_transform_for_eye(XRInterface::EYE_RIGHT, world_origin);
mono_transform.origin += right_transform.origin;
mono_transform.origin *= 0.5;
@@ -1872,17 +2102,17 @@ void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface
mono_transform *= apply_z_shift;
// now prepare our scene with our adjusted transform projection matrix
- _prepare_scene(mono_transform, combined_matrix, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
- } else if (p_eye == ARVRInterface::EYE_MONO) {
+ _prepare_scene(mono_transform, combined_matrix, false, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
+ } else if (p_eye == XRInterface::EYE_MONO) {
// For mono render, prepare as per usual
- _prepare_scene(cam_transform, camera_matrix, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
+ _prepare_scene(cam_transform, camera_matrix, false, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
}
// And render our scene...
_render_scene(p_render_buffers, cam_transform, camera_matrix, false, camera->env, camera->effects, p_scenario, p_shadow_atlas, RID(), -1);
};
-void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) {
+void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) {
// Note, in stereo rendering:
// - p_cam_transform will be a transform in the middle of our two eyes
// - p_cam_projection is a wider frustrum that encompasses both eyes
@@ -1908,6 +2138,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
light_cull_count = 0;
reflection_probe_cull_count = 0;
+ decal_cull_count = 0;
gi_probe_cull_count = 0;
//light_samplers_culled=0;
@@ -1977,6 +2208,18 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
}
}
}
+ } else if (ins->base_type == RS::INSTANCE_DECAL && ins->visible) {
+
+ if (decal_cull_count < MAX_DECALS_CULLED) {
+
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(ins->base_data);
+
+ if (!decal->geometries.empty()) {
+ //do not add this decal if no geometry is affected by it..
+ decal_instance_cull_result[decal_cull_count] = decal->instance;
+ decal_cull_count++;
+ }
+ }
} else if (ins->base_type == RS::INSTANCE_GI_PROBE && ins->visible) {
@@ -2112,7 +2355,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i));
- _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
+ _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario);
RENDER_TIMESTAMP("<Rendering Directional Light " + itos(i));
}
@@ -2214,7 +2457,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
if (redraw) {
//must redraw!
RENDER_TIMESTAMP(">Rendering Light " + itos(i));
- light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
+ light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario);
RENDER_TIMESTAMP("<Rendering Light " + itos(i));
}
}
@@ -2244,7 +2487,7 @@ void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p
/* PROCESS GEOMETRY AND DRAW SCENE */
RENDER_TIMESTAMP("Render Scene ");
- RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
+ RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
}
void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
@@ -2259,7 +2502,7 @@ void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenar
else
environment = scenario->fallback_environment;
RENDER_TIMESTAMP("Render Empty Scene ");
- RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
+ RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
#endif
}
@@ -2324,7 +2567,7 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i
}
RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step));
- _prepare_scene(xform, cm, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, use_shadows);
+ _prepare_scene(xform, cm, false, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, use_shadows);
_render_scene(RID(), xform, cm, false, RID(), RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step);
} else {
@@ -2579,6 +2822,35 @@ void RenderingServerScene::render_probes() {
}
}
+void RenderingServerScene::_update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) {
+
+ List<RasterizerStorage::InstanceShaderParam> plist;
+ RSG::storage->material_get_instance_shader_parameters(p_material, &plist);
+ for (List<RasterizerStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) {
+ StringName name = E->get().info.name;
+ if (isparams.has(name)) {
+ if (isparams[name].info.type != E->get().info.type) {
+ WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different data types. Only the first one (in order) will display correctly.");
+ }
+ if (isparams[name].index != E->get().index) {
+ WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different indices. Only the first one (in order) will display correctly.");
+ }
+ continue; //first one found always has priority
+ }
+
+ RasterizerScene::InstanceBase::InstanceShaderParameter isp;
+ isp.index = E->get().index;
+ isp.info = E->get().info;
+ isp.default_value = E->get().default_value;
+ if (existing_isparams.has(name)) {
+ isp.value = existing_isparams[name].value;
+ } else {
+ isp.value = E->get().default_value;
+ }
+ isparams[name] = isp;
+ }
+}
+
void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
if (p_instance->update_aabb) {
@@ -2618,12 +2890,18 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
bool can_cast_shadows = true;
bool is_animated = false;
+ Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> isparams;
if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
can_cast_shadows = false;
- } else if (p_instance->material_override.is_valid()) {
- can_cast_shadows = RSG::storage->material_casts_shadows(p_instance->material_override);
+ }
+
+ if (p_instance->material_override.is_valid()) {
+ if (!RSG::storage->material_casts_shadows(p_instance->material_override)) {
+ can_cast_shadows = false;
+ }
is_animated = RSG::storage->material_is_animated(p_instance->material_override);
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override);
} else {
if (p_instance->base_type == RS::INSTANCE_MESH) {
@@ -2648,6 +2926,8 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
is_animated = true;
}
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
+
RSG::storage->material_update_dependency(mat, p_instance);
}
}
@@ -2680,6 +2960,8 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
is_animated = true;
}
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
+
RSG::storage->material_update_dependency(mat, p_instance);
}
}
@@ -2694,13 +2976,19 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
RID mat = RSG::storage->immediate_get_material(p_instance->base);
- can_cast_shadows = !mat.is_valid() || RSG::storage->material_casts_shadows(mat);
+ if (!(!mat.is_valid() || RSG::storage->material_casts_shadows(mat))) {
+ can_cast_shadows = false;
+ }
if (mat.is_valid() && RSG::storage->material_is_animated(mat)) {
is_animated = true;
}
if (mat.is_valid()) {
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
+ }
+
+ if (mat.is_valid()) {
RSG::storage->material_update_dependency(mat, p_instance);
}
@@ -2733,6 +3021,8 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
is_animated = true;
}
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
+
RSG::storage->material_update_dependency(mat, p_instance);
}
}
@@ -2755,6 +3045,22 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
}
geom->material_is_animated = is_animated;
+ p_instance->instance_shader_parameters = isparams;
+
+ if (p_instance->instance_allocated_shader_parameters != (p_instance->instance_shader_parameters.size() > 0)) {
+ p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0);
+ if (p_instance->instance_allocated_shader_parameters) {
+ p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self);
+ for (Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) {
+ if (E->get().value.get_type() != Variant::NIL) {
+ RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value);
+ }
+ }
+ } else {
+ RSG::storage->global_variables_instance_free(p_instance->self);
+ p_instance->instance_allocated_shader_parameters_offset = -1;
+ }
+ }
}
if (p_instance->skeleton.is_valid()) {
@@ -2816,6 +3122,10 @@ bool RenderingServerScene::free(RID p_rid) {
instance_geometry_set_material_override(p_rid, RID());
instance_attach_skeleton(p_rid, RID());
+ if (instance->instance_allocated_shader_parameters) {
+ //free the used shader parameters
+ RSG::storage->global_variables_instance_free(instance->self);
+ }
update_dirty_instances(); //in case something changed this
instance_owner.free(p_rid);
diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h
index 41641b7c75..db2fbd6707 100644
--- a/servers/rendering/rendering_server_scene.h
+++ b/servers/rendering/rendering_server_scene.h
@@ -39,7 +39,7 @@
#include "core/os/thread.h"
#include "core/rid_owner.h"
#include "core/self_list.h"
-#include "servers/arvr/arvr_interface.h"
+#include "servers/xr/xr_interface.h"
class RenderingServerScene {
public:
@@ -48,6 +48,7 @@ public:
MAX_INSTANCE_CULL = 65536,
MAX_LIGHTS_CULLED = 4096,
MAX_REFLECTION_PROBES_CULLED = 4096,
+ MAX_DECALS_CULLED = 4096,
MAX_GI_PROBES_CULLED = 4096,
MAX_ROOM_CULL = 32,
MAX_EXTERIOR_PORTALS = 128,
@@ -237,6 +238,9 @@ public:
bool can_cast_shadows;
bool material_is_animated;
+ List<Instance *> decals;
+ bool decal_dirty;
+
List<Instance *> reflection_probes;
bool reflection_dirty;
@@ -252,6 +256,7 @@ public:
can_cast_shadows = true;
material_is_animated = true;
gi_probes_dirty = true;
+ decal_dirty = true;
}
};
@@ -279,6 +284,21 @@ public:
}
};
+ struct InstanceDecalData : public InstanceBaseData {
+
+ Instance *owner;
+ RID instance;
+
+ struct PairInfo {
+ List<Instance *>::Element *L; //reflection iterator in geometry
+ Instance *geometry;
+ };
+ List<PairInfo> geometries;
+
+ InstanceDecalData() {
+ }
+ };
+
SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
struct InstanceLightData : public InstanceBaseData {
@@ -376,7 +396,9 @@ public:
int light_cull_count;
int directional_light_count;
RID reflection_probe_instance_cull_result[MAX_REFLECTION_PROBES_CULLED];
+ RID decal_instance_cull_result[MAX_DECALS_CULLED];
int reflection_probe_cull_count;
+ int decal_cull_count;
RID gi_probe_instance_cull_result[MAX_GI_PROBES_CULLED];
int gi_probe_cull_count;
@@ -413,20 +435,27 @@ public:
virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin);
virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance);
+ void _update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material);
+
+ virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value);
+ virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const;
+ virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const;
+ virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const;
+
_FORCE_INLINE_ void _update_instance(Instance *p_instance);
_FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance);
_FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
_FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance);
- _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario);
+ _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario);
bool _render_reflection_probe_step(Instance *p_instance, int p_step);
- void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows = true);
+ void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows = true);
void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas);
void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
- void render_camera(RID p_render_buffers, Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
+ void render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
void update_dirty_instances();
void render_probes();
diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp
index aa65101ddf..6fb8f6ca63 100644
--- a/servers/rendering/rendering_server_viewport.cpp
+++ b/servers/rendering/rendering_server_viewport.cpp
@@ -62,24 +62,30 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi
return xf;
}
-void RenderingServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
+void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) {
RENDER_TIMESTAMP(">Begin Rendering 3D Scene");
- Ref<ARVRInterface> arvr_interface;
- if (ARVRServer::get_singleton() != nullptr) {
- arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
+ Ref<XRInterface> xr_interface;
+ if (XRServer::get_singleton() != nullptr) {
+ xr_interface = XRServer::get_singleton()->get_primary_interface();
}
- if (p_viewport->use_arvr && arvr_interface.is_valid()) {
- RSG::scene->render_camera(p_viewport->render_buffers, arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ if (p_viewport->use_xr && xr_interface.is_valid()) {
+ RSG::scene->render_camera(p_viewport->render_buffers, xr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
} else {
RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
RENDER_TIMESTAMP("<End Rendering 3D Scene");
}
-void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
+void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) {
+
+ if (p_viewport->measure_render_time) {
+ String rt_id = "vp_begin_" + itos(p_viewport->self.get_id());
+ RSG::storage->capture_timestamp(rt_id);
+ timestamp_vp_map[rt_id] = p_viewport->self;
+ }
/* Camera should always be BEFORE any other 3D */
@@ -113,7 +119,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface
if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) {
//wants to draw 3D but there is no render buffer, create
p_viewport->render_buffers = RSG::scene_render->render_buffers_create();
- RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa);
+ RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa);
}
RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor);
@@ -289,21 +295,27 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface
//was never cleared in the end, force clear it
RSG::storage->render_target_do_clear_request(p_viewport->render_target);
}
+
+ if (p_viewport->measure_render_time) {
+ String rt_id = "vp_end_" + itos(p_viewport->self.get_id());
+ RSG::storage->capture_timestamp(rt_id);
+ timestamp_vp_map[rt_id] = p_viewport->self;
+ }
}
void RenderingServerViewport::draw_viewports() {
-#if 0
- // get our arvr interface in case we need it
- Ref<ARVRInterface> arvr_interface;
+ timestamp_vp_map.clear();
+
+ // get our xr interface in case we need it
+ Ref<XRInterface> xr_interface;
- if (ARVRServer::get_singleton() != nullptr) {
- arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
+ if (XRServer::get_singleton() != nullptr) {
+ xr_interface = XRServer::get_singleton()->get_primary_interface();
// process all our active interfaces
- ARVRServer::get_singleton()->_process();
+ XRServer::get_singleton()->_process();
}
-#endif
if (Engine::get_singleton()->is_editor_hint()) {
set_default_clear_color(GLOBAL_GET("rendering/environment/default_clear_color"));
@@ -367,38 +379,41 @@ void RenderingServerViewport::draw_viewports() {
RSG::storage->render_target_set_as_unused(vp->render_target);
#if 0
- if (vp->use_arvr && arvr_interface.is_valid()) {
+ // TODO fix up this code after we change our commit_for_eye to accept our new render targets
+
+ if (vp->use_xr && xr_interface.is_valid()) {
// override our size, make sure it matches our required size
- vp->size = arvr_interface->get_render_targetsize();
+ vp->size = xr_interface->get_render_targetsize();
RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y);
// render mono or left eye first
- ARVRInterface::Eyes leftOrMono = arvr_interface->is_stereo() ? ARVRInterface::EYE_LEFT : ARVRInterface::EYE_MONO;
+ XRInterface::Eyes leftOrMono = xr_interface->is_stereo() ? XRInterface::EYE_LEFT : XRInterface::EYE_MONO;
// check for an external texture destination for our left eye/mono
- RSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(leftOrMono));
+ // TODO investigate how we're going to make external textures work
+ RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono));
// set our render target as current
RSG::rasterizer->set_current_render_target(vp->render_target);
// and draw left eye/mono
_draw_viewport(vp, leftOrMono);
- arvr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect);
+ xr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect);
// render right eye
- if (leftOrMono == ARVRInterface::EYE_LEFT) {
+ if (leftOrMono == XRInterface::EYE_LEFT) {
// check for an external texture destination for our right eye
- RSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(ARVRInterface::EYE_RIGHT));
+ RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(XRInterface::EYE_RIGHT));
// commit for eye may have changed the render target
RSG::rasterizer->set_current_render_target(vp->render_target);
- _draw_viewport(vp, ARVRInterface::EYE_RIGHT);
- arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect);
+ _draw_viewport(vp, XRInterface::EYE_RIGHT);
+ xr_interface->commit_for_eye(XRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect);
}
// and for our frame timing, mark when we've finished committing our eyes
- ARVRServer::get_singleton()->_mark_commit();
+ XRServer::get_singleton()->_mark_commit();
} else {
#endif
{
@@ -470,11 +485,11 @@ RID RenderingServerViewport::viewport_create() {
return rid;
}
-void RenderingServerViewport::viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) {
+void RenderingServerViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
- viewport->use_arvr = p_use_arvr;
+ viewport->use_xr = p_use_xr;
}
void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
@@ -491,7 +506,7 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int
RSG::scene_render->free(viewport->render_buffers);
viewport->render_buffers = RID();
} else {
- RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa);
+ RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa);
}
}
}
@@ -721,7 +736,20 @@ void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA
}
viewport->msaa = p_msaa;
if (viewport->render_buffers.is_valid()) {
- RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa);
+ RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa);
+ }
+}
+
+void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ if (viewport->screen_space_aa == p_mode) {
+ return;
+ }
+ viewport->screen_space_aa = p_mode;
+ if (viewport->render_buffers.is_valid()) {
+ RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode);
}
}
@@ -744,6 +772,30 @@ void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::Viewpo
viewport->debug_draw = p_draw;
}
+void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->measure_render_time = p_enable;
+}
+
+float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND_V(!viewport, 0);
+
+ return double(viewport->time_cpu_end - viewport->time_cpu_begin) / 1000.0;
+}
+
+float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND_V(!viewport, 0);
+
+ return double((viewport->time_gpu_end - viewport->time_gpu_begin) / 1000) / 1000.0;
+}
+
bool RenderingServerViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
@@ -772,6 +824,29 @@ bool RenderingServerViewport::free(RID p_rid) {
return false;
}
+void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) {
+
+ RID *vp = timestamp_vp_map.getptr(p_timestamp);
+ if (!vp) {
+ return;
+ }
+
+ Viewport *viewport = viewport_owner.getornull(*vp);
+ if (!viewport) {
+ return;
+ }
+
+ if (p_timestamp.begins_with("vp_begin")) {
+ viewport->time_cpu_begin = p_cpu_time;
+ viewport->time_gpu_begin = p_gpu_time;
+ }
+
+ if (p_timestamp.begins_with("vp_end")) {
+ viewport->time_cpu_end = p_cpu_time;
+ viewport->time_gpu_end = p_gpu_time;
+ }
+}
+
void RenderingServerViewport::set_default_clear_color(const Color &p_color) {
RSG::storage->set_default_clear_color(p_color);
}
diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h
index f574c58d96..fcba7886c5 100644
--- a/servers/rendering/rendering_server_viewport.h
+++ b/servers/rendering/rendering_server_viewport.h
@@ -34,8 +34,8 @@
#include "core/rid_owner.h"
#include "core/self_list.h"
#include "rasterizer.h"
-#include "servers/arvr/arvr_interface.h"
#include "servers/rendering_server.h"
+#include "servers/xr/xr_interface.h"
class RenderingServerViewport {
public:
@@ -47,7 +47,7 @@ public:
RID self;
RID parent;
- bool use_arvr; /* use arvr interface to override camera positioning and projection matrices and control output */
+ bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */
Size2i size;
RID camera;
@@ -59,6 +59,7 @@ public:
RID render_buffers;
RS::ViewportMSAA msaa;
+ RS::ViewportScreenSpaceAA screen_space_aa;
DisplayServer::WindowID viewport_to_screen;
Rect2 viewport_to_screen_rect;
@@ -67,8 +68,13 @@ public:
bool hide_scenario;
bool hide_canvas;
bool disable_environment;
- bool disable_3d_by_usage;
- bool keep_3d_linear;
+ bool measure_render_time;
+
+ uint64_t time_cpu_begin;
+ uint64_t time_cpu_end;
+
+ uint64_t time_gpu_begin;
+ uint64_t time_gpu_end;
RID shadow_atlas;
int shadow_atlas_size;
@@ -121,16 +127,27 @@ public:
disable_environment = false;
viewport_to_screen = DisplayServer::INVALID_WINDOW_ID;
shadow_atlas_size = 0;
- keep_3d_linear = false;
+ measure_render_time = false;
+
debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
msaa = RS::VIEWPORT_MSAA_DISABLED;
+ screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;
+
for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_MAX; i++) {
render_info[i] = 0;
}
- use_arvr = false;
+ use_xr = false;
+
+ time_cpu_begin = 0;
+ time_cpu_end = 0;
+
+ time_gpu_begin = 0;
+ time_gpu_end = 0;
}
};
+ HashMap<String, RID> timestamp_vp_map;
+
uint64_t draw_viewports_pass = 0;
mutable RID_PtrOwner<Viewport> viewport_owner;
@@ -152,13 +169,13 @@ public:
Vector<Viewport *> active_viewports;
private:
- void _draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye);
- void _draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye = ARVRInterface::EYE_MONO);
+ void _draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye);
+ void _draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye = XRInterface::EYE_MONO);
public:
RID viewport_create();
- void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr);
+ void viewport_set_use_xr(RID p_viewport, bool p_use_xr);
void viewport_set_size(RID p_viewport, int p_width, int p_height);
@@ -192,10 +209,17 @@ public:
void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa);
+ void viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode);
virtual int viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info);
virtual void viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw);
+ void viewport_set_measure_render_time(RID p_viewport, bool p_enable);
+ float viewport_get_measured_render_time_cpu(RID p_viewport) const;
+ float viewport_get_measured_render_time_gpu(RID p_viewport) const;
+
+ void handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time);
+
void set_default_clear_color(const Color &p_color);
void draw_viewports();
diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp
index aa3bf583c7..4ca13dbef9 100644
--- a/servers/rendering/rendering_server_wrap_mt.cpp
+++ b/servers/rendering/rendering_server_wrap_mt.cpp
@@ -126,17 +126,6 @@ void RenderingServerWrapMT::init() {
void RenderingServerWrapMT::finish() {
- if (thread) {
-
- command_queue.push(this, &RenderingServerWrapMT::thread_exit);
- Thread::wait_to_finish(thread);
- memdelete(thread);
-
- thread = nullptr;
- } else {
- rendering_server->finish();
- }
-
sky_free_cached_ids();
shader_free_cached_ids();
material_free_cached_ids();
@@ -161,6 +150,17 @@ void RenderingServerWrapMT::finish() {
canvas_item_free_cached_ids();
canvas_light_occluder_free_cached_ids();
canvas_occluder_polygon_free_cached_ids();
+
+ if (thread) {
+
+ command_queue.push(this, &RenderingServerWrapMT::thread_exit);
+ Thread::wait_to_finish(thread);
+ memdelete(thread);
+
+ thread = nullptr;
+ } else {
+ rendering_server->finish();
+ }
}
void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) {
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index d0f711838c..d4e58485b8 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -264,6 +264,20 @@ public:
FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
FUNC2(reflection_probe_set_resolution, RID, int)
+ /* DECAL API */
+
+ FUNCRID(decal)
+
+ FUNC2(decal_set_extents, RID, const Vector3 &)
+ FUNC3(decal_set_texture, RID, DecalTexture, RID)
+ FUNC2(decal_set_emission_energy, RID, float)
+ FUNC2(decal_set_albedo_mix, RID, float)
+ FUNC2(decal_set_modulate, RID, const Color &)
+ FUNC2(decal_set_cull_mask, RID, uint32_t)
+ FUNC4(decal_set_distance_fade, RID, bool, float, float)
+ FUNC3(decal_set_fade, RID, float, float)
+ FUNC2(decal_set_normal_fade, RID, float)
+
/* BAKED LIGHT API */
FUNCRID(gi_probe)
@@ -370,7 +384,7 @@ public:
FUNCRID(viewport)
- FUNC2(viewport_set_use_arvr, RID, bool)
+ FUNC2(viewport_set_use_xr, RID, bool)
FUNC3(viewport_set_size, RID, int, int)
@@ -403,6 +417,7 @@ public:
FUNC2(viewport_set_shadow_atlas_size, RID, int)
FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
FUNC2(viewport_set_msaa, RID, ViewportMSAA)
+ FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
//this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport
virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) {
@@ -411,6 +426,14 @@ public:
FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
+ FUNC2(viewport_set_measure_render_time, RID, bool)
+ virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const {
+ return rendering_server->viewport_get_measured_render_time_cpu(p_viewport);
+ }
+ virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const {
+ return rendering_server->viewport_get_measured_render_time_gpu(p_viewport);
+ }
+
FUNC1(directional_shadow_atlas_set_size, int)
/* SKY API */
@@ -467,6 +490,9 @@ public:
FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float)
FUNC3(camera_effects_set_custom_exposure, RID, bool, float)
+ FUNC1(shadows_quality_set, ShadowQuality);
+ FUNC1(directional_shadow_quality_set, ShadowQuality);
+
FUNCRID(scenario)
FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
@@ -506,6 +532,11 @@ public:
FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float)
FUNC2(instance_geometry_set_as_instance_lod, RID, RID)
+ FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
+ FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
+ FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &)
+ FUNC2SC(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *)
+
/* CANVAS (2D) */
FUNCRID(canvas)
@@ -599,6 +630,18 @@ public:
FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
+ /* GLOBAL VARIABLES */
+
+ FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &)
+ FUNC1(global_variable_remove, const StringName &)
+ FUNC0RC(Vector<StringName>, global_variable_get_list)
+ FUNC2(global_variable_set, const StringName &, const Variant &)
+ FUNC2(global_variable_set_override, const StringName &, const Variant &)
+ FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &)
+ FUNC1RC(Variant, global_variable_get, const StringName &)
+ FUNC1(global_variables_load_settings, bool)
+ FUNC0(global_variables_clear)
+
/* BLACK BARS */
FUNC4(black_bars_set_margins, int, int, int, int)
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 76a81a4a1c..bec0958f71 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -194,6 +194,8 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"SEMICOLON",
"PERIOD",
"UNIFORM",
+ "INSTANCE",
+ "GLOBAL",
"VARYING",
"IN",
"OUT",
@@ -207,6 +209,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"HINT_BLACK_ALBEDO_TEXTURE",
"HINT_COLOR",
"HINT_RANGE",
+ "HINT_INSTANCE_INDEX",
"FILTER_NEAREST",
"FILTER_LINEAR",
"FILTER_NEAREST_MIPMAP",
@@ -300,6 +303,8 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_CF_RETURN, "return" },
{ TK_CF_DISCARD, "discard" },
{ TK_UNIFORM, "uniform" },
+ { TK_INSTANCE, "instance" },
+ { TK_GLOBAL, "global" },
{ TK_VARYING, "varying" },
{ TK_ARG_IN, "in" },
{ TK_ARG_OUT, "out" },
@@ -319,6 +324,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_HINT_BLACK_ALBEDO_TEXTURE, "hint_black_albedo" },
{ TK_HINT_COLOR, "hint_color" },
{ TK_HINT_RANGE, "hint_range" },
+ { TK_HINT_INSTANCE_INDEX, "instance_index" },
{ TK_FILTER_NEAREST, "filter_nearest" },
{ TK_FILTER_LINEAR, "filter_linear" },
{ TK_FILTER_NEAREST_MIPMAP, "filter_nearest_mipmap" },
@@ -864,6 +870,7 @@ String ShaderLanguage::get_datatype_name(DataType p_type) {
case TYPE_USAMPLER3D: return "usampler3D";
case TYPE_SAMPLERCUBE: return "samplerCube";
case TYPE_STRUCT: return "struct";
+ case TYPE_MAX: return "invalid";
}
return "";
@@ -2678,6 +2685,8 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
break;
case ShaderLanguage::TYPE_VOID:
break;
+ case ShaderLanguage::TYPE_MAX:
+ break;
}
return value;
}
@@ -2774,6 +2783,8 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
case ShaderLanguage::TYPE_STRUCT: {
// FIXME: Implement this.
} break;
+ case ShaderLanguage::TYPE_MAX:
+ break;
}
return pi;
}
@@ -2822,6 +2833,8 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) {
case TYPE_STRUCT:
// FIXME: Implement.
return 0;
+ case ShaderLanguage::TYPE_MAX:
+ return 0;
}
return 0;
}
@@ -5685,6 +5698,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
int texture_uniforms = 0;
int uniforms = 0;
+ int instance_index = 0;
+ ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
while (tk.type != TK_EOF) {
@@ -5853,6 +5868,27 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
shader->vstructs.push_back(st); // struct's order is important!
} break;
+ case TK_GLOBAL: {
+
+ tk = _get_token();
+ if (tk.type != TK_UNIFORM) {
+ _set_error("Expected 'uniform' after 'global'");
+ return ERR_PARSE_ERROR;
+ }
+ uniform_scope = ShaderNode::Uniform::SCOPE_GLOBAL;
+ };
+ [[fallthrough]];
+ case TK_INSTANCE: {
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) {
+ tk = _get_token();
+ if (tk.type != TK_UNIFORM) {
+ _set_error("Expected 'uniform' after 'instance'");
+ return ERR_PARSE_ERROR;
+ }
+ uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE;
+ }
+ };
+ [[fallthrough]];
case TK_UNIFORM:
case TK_VARYING: {
@@ -5910,25 +5946,50 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (uniform) {
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
+ //validate global uniform
+ DataType gvtype = global_var_get_type_func(name);
+ if (gvtype == TYPE_MAX) {
+ _set_error("Global uniform '" + String(name) + "' does not exist. Create it in Project Settings.");
+ return ERR_PARSE_ERROR;
+ }
+
+ if (type != gvtype) {
+ _set_error("Global uniform '" + String(name) + "' must be of type '" + get_datatype_name(gvtype) + "'.");
+ return ERR_PARSE_ERROR;
+ }
+ }
ShaderNode::Uniform uniform2;
if (is_sampler_type(type)) {
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
+ _set_error("Uniforms with 'instance' qualifiers can't be of sampler type.");
+ return ERR_PARSE_ERROR;
+ }
uniform2.texture_order = texture_uniforms++;
uniform2.order = -1;
if (_validate_datatype(type) != OK) {
return ERR_PARSE_ERROR;
}
} else {
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) {
+ _set_error("Uniforms with 'instance' qualifiers can't be of matrix type.");
+ return ERR_PARSE_ERROR;
+ }
+
uniform2.texture_order = -1;
uniform2.order = uniforms++;
}
uniform2.type = type;
+ uniform2.scope = uniform_scope;
uniform2.precision = precision;
//todo parse default value
tk = _get_token();
+ int custom_instance_index = -1;
+
if (tk.type == TK_COLON) {
//hint
do {
@@ -6039,7 +6100,45 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ','");
+ _set_error("Expected ')'");
+ return ERR_PARSE_ERROR;
+ }
+ } else if (tk.type == TK_HINT_INSTANCE_INDEX) {
+
+ if (custom_instance_index != -1) {
+ _set_error("Can only specify 'instance_index' once.");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after 'instance_index'");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type == TK_OP_SUB) {
+ _set_error("The instance index can't be negative.");
+ return ERR_PARSE_ERROR;
+ }
+
+ if (tk.type != TK_INT_CONSTANT) {
+ _set_error("Expected integer constant");
+ return ERR_PARSE_ERROR;
+ }
+
+ custom_instance_index = tk.constant;
+
+ if (custom_instance_index >= MAX_INSTANCE_UNIFORM_INDICES) {
+ _set_error("Allowed instance uniform indices are 0-" + itos(MAX_INSTANCE_UNIFORM_INDICES - 1));
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')'");
return ERR_PARSE_ERROR;
}
} else if (tk.type == TK_FILTER_LINEAR) {
@@ -6072,6 +6171,20 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} while (tk.type == TK_COMMA);
}
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
+ if (custom_instance_index >= 0) {
+ uniform2.instance_index = custom_instance_index;
+ } else {
+ uniform2.instance_index = instance_index++;
+ if (instance_index > MAX_INSTANCE_UNIFORM_INDICES) {
+ _set_error("Too many 'instance' uniforms in shader, maximum supported is " + itos(MAX_INSTANCE_UNIFORM_INDICES));
+ return ERR_PARSE_ERROR;
+ }
+ }
+ }
+
+ //reset scope for next uniform
+
if (tk.type == TK_OP_ASSIGN) {
Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>());
@@ -6094,6 +6207,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
shader->uniforms[name] = uniform2;
+ //reset scope for next uniform
+ uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
if (tk.type != TK_SEMICOLON) {
_set_error("Expected ';'");
@@ -6639,11 +6754,12 @@ String ShaderLanguage::get_shader_type(const String &p_code) {
return String();
}
-Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) {
+Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) {
clear();
code = p_code;
+ global_var_get_type_func = p_global_variable_type_func;
nodes = nullptr;
@@ -6656,13 +6772,14 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi
return OK;
}
-Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) {
+Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) {
clear();
code = p_code;
nodes = nullptr;
+ global_var_get_type_func = p_global_variable_type_func;
shader = alloc_node<ShaderNode>();
_parse_shader(p_functions, p_render_modes, p_shader_types);
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index beabae0dda..48f1d1440f 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -143,6 +143,8 @@ public:
TK_SEMICOLON,
TK_PERIOD,
TK_UNIFORM,
+ TK_INSTANCE,
+ TK_GLOBAL,
TK_VARYING,
TK_ARG_IN,
TK_ARG_OUT,
@@ -162,6 +164,7 @@ public:
TK_HINT_BLACK_ALBEDO_TEXTURE,
TK_HINT_COLOR,
TK_HINT_RANGE,
+ TK_HINT_INSTANCE_INDEX,
TK_FILTER_NEAREST,
TK_FILTER_LINEAR,
TK_FILTER_NEAREST_MIPMAP,
@@ -216,6 +219,7 @@ public:
TYPE_USAMPLER3D,
TYPE_SAMPLERCUBE,
TYPE_STRUCT,
+ TYPE_MAX
};
enum DataPrecision {
@@ -317,6 +321,10 @@ public:
REPEAT_DEFAULT,
};
+ enum {
+ MAX_INSTANCE_UNIFORM_INDICES = 16
+ };
+
struct Node {
Node *next;
@@ -650,15 +658,23 @@ public:
HINT_MAX
};
+ enum Scope {
+ SCOPE_LOCAL,
+ SCOPE_INSTANCE,
+ SCOPE_GLOBAL,
+ };
+
int order;
int texture_order;
DataType type;
DataPrecision precision;
Vector<ConstantNode::Value> default_value;
+ Scope scope;
Hint hint;
TextureFilter filter;
TextureRepeat repeat;
float hint_range[3];
+ int instance_index;
Uniform() :
order(0),
@@ -667,7 +683,8 @@ public:
precision(PRECISION_DEFAULT),
hint(HINT_NONE),
filter(FILTER_DEFAULT),
- repeat(REPEAT_DEFAULT) {
+ repeat(REPEAT_DEFAULT),
+ instance_index(0) {
hint_range[0] = 0.0f;
hint_range[1] = 1.0f;
hint_range[2] = 0.001f;
@@ -764,6 +781,8 @@ public:
};
static bool has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name);
+ typedef DataType (*GlobalVariableGetTypeFunc)(const StringName &p_name);
+
private:
struct KeyWord {
TokenType token;
@@ -772,6 +791,8 @@ private:
static const KeyWord keyword_list[];
+ GlobalVariableGetTypeFunc global_var_get_type_func;
+
bool error_set;
String error_str;
int error_line;
@@ -884,8 +905,8 @@ public:
void clear();
static String get_shader_type(const String &p_code);
- Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types);
- Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint);
+ Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func);
+ Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint);
String get_error_text();
int get_error_line();
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index 78fa2c2690..78bbd73db4 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -108,7 +108,11 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY_FLOW"] = ShaderLanguage::TYPE_VEC2;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["TRANSMISSION"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_CURVE"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_BOOST"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BACKLIGHT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO_LIGHT_AFFECT"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3;
@@ -145,7 +149,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ATTENUATION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ALBEDO"] = constt(ShaderLanguage::TYPE_VEC3);
- shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["TRANSMISSION"] = constt(ShaderLanguage::TYPE_VEC3);
+ shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["BACKLIGHT"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["DIFFUSE_LIGHT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["SPECULAR_LIGHT"] = ShaderLanguage::TYPE_VEC3;
@@ -299,18 +303,22 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
+ shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
+ shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
+ shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
+ shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 9db3294e95..57a34f24cf 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -1565,6 +1565,42 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su
return arr;
}
#endif
+
+ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) {
+
+ switch (p_type) {
+ case RS::GLOBAL_VAR_TYPE_BOOL: return ShaderLanguage::TYPE_BOOL;
+ case RS::GLOBAL_VAR_TYPE_BVEC2: return ShaderLanguage::TYPE_BVEC2;
+ case RS::GLOBAL_VAR_TYPE_BVEC3: return ShaderLanguage::TYPE_BVEC3;
+ case RS::GLOBAL_VAR_TYPE_BVEC4: return ShaderLanguage::TYPE_BVEC4;
+ case RS::GLOBAL_VAR_TYPE_INT: return ShaderLanguage::TYPE_INT;
+ case RS::GLOBAL_VAR_TYPE_IVEC2: return ShaderLanguage::TYPE_IVEC2;
+ case RS::GLOBAL_VAR_TYPE_IVEC3: return ShaderLanguage::TYPE_IVEC3;
+ case RS::GLOBAL_VAR_TYPE_IVEC4: return ShaderLanguage::TYPE_IVEC4;
+ case RS::GLOBAL_VAR_TYPE_RECT2I: return ShaderLanguage::TYPE_IVEC4;
+ case RS::GLOBAL_VAR_TYPE_UINT: return ShaderLanguage::TYPE_UINT;
+ case RS::GLOBAL_VAR_TYPE_UVEC2: return ShaderLanguage::TYPE_UVEC2;
+ case RS::GLOBAL_VAR_TYPE_UVEC3: return ShaderLanguage::TYPE_UVEC3;
+ case RS::GLOBAL_VAR_TYPE_UVEC4: return ShaderLanguage::TYPE_UVEC4;
+ case RS::GLOBAL_VAR_TYPE_FLOAT: return ShaderLanguage::TYPE_FLOAT;
+ case RS::GLOBAL_VAR_TYPE_VEC2: return ShaderLanguage::TYPE_VEC2;
+ case RS::GLOBAL_VAR_TYPE_VEC3: return ShaderLanguage::TYPE_VEC3;
+ case RS::GLOBAL_VAR_TYPE_VEC4: return ShaderLanguage::TYPE_VEC4;
+ case RS::GLOBAL_VAR_TYPE_COLOR: return ShaderLanguage::TYPE_VEC4;
+ case RS::GLOBAL_VAR_TYPE_RECT2: return ShaderLanguage::TYPE_VEC4;
+ case RS::GLOBAL_VAR_TYPE_MAT2: return ShaderLanguage::TYPE_MAT2;
+ case RS::GLOBAL_VAR_TYPE_MAT3: return ShaderLanguage::TYPE_MAT3;
+ case RS::GLOBAL_VAR_TYPE_MAT4: return ShaderLanguage::TYPE_MAT4;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: return ShaderLanguage::TYPE_MAT3;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM: return ShaderLanguage::TYPE_MAT4;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2D: return ShaderLanguage::TYPE_SAMPLER2D;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: return ShaderLanguage::TYPE_SAMPLER2DARRAY;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER3D: return ShaderLanguage::TYPE_SAMPLER3D;
+ case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: return ShaderLanguage::TYPE_SAMPLERCUBE;
+ default: return ShaderLanguage::TYPE_MAX; //invalid or not found
+ }
+}
+
void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("force_sync"), &RenderingServer::sync);
@@ -1766,7 +1802,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("camera_set_use_vertical_aspect", "camera", "enable"), &RenderingServer::camera_set_use_vertical_aspect);
ClassDB::bind_method(D_METHOD("viewport_create"), &RenderingServer::viewport_create);
- ClassDB::bind_method(D_METHOD("viewport_set_use_arvr", "viewport", "use_arvr"), &RenderingServer::viewport_set_use_arvr);
+ ClassDB::bind_method(D_METHOD("viewport_set_use_xr", "viewport", "use_xr"), &RenderingServer::viewport_set_use_xr);
ClassDB::bind_method(D_METHOD("viewport_set_size", "viewport", "width", "height"), &RenderingServer::viewport_set_size);
ClassDB::bind_method(D_METHOD("viewport_set_active", "viewport", "active"), &RenderingServer::viewport_set_active);
ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &RenderingServer::viewport_set_parent_viewport);
@@ -1921,6 +1957,13 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_occluder_polygon_set_shape_as_lines", "occluder_polygon", "shape"), &RenderingServer::canvas_occluder_polygon_set_shape_as_lines);
ClassDB::bind_method(D_METHOD("canvas_occluder_polygon_set_cull_mode", "occluder_polygon", "mode"), &RenderingServer::canvas_occluder_polygon_set_cull_mode);
+ ClassDB::bind_method(D_METHOD("global_variable_add", "name", "type", "default_value"), &RenderingServer::global_variable_add);
+ ClassDB::bind_method(D_METHOD("global_variable_remove", "name"), &RenderingServer::global_variable_remove);
+ ClassDB::bind_method(D_METHOD("global_variable_get_list"), &RenderingServer::global_variable_get_list);
+ ClassDB::bind_method(D_METHOD("global_variable_set", "name", "value"), &RenderingServer::global_variable_set);
+ ClassDB::bind_method(D_METHOD("global_variable_get", "name"), &RenderingServer::global_variable_get);
+ ClassDB::bind_method(D_METHOD("global_variable_get_type", "name"), &RenderingServer::global_variable_get_type);
+
ClassDB::bind_method(D_METHOD("black_bars_set_margins", "left", "top", "right", "bottom"), &RenderingServer::black_bars_set_margins);
ClassDB::bind_method(D_METHOD("black_bars_set_images", "left", "top", "right", "bottom"), &RenderingServer::black_bars_set_images);
@@ -1955,9 +1998,6 @@ void RenderingServer::_bind_methods() {
BIND_CONSTANT(MAX_GLOW_LEVELS);
BIND_CONSTANT(MAX_CURSORS);
- BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN);
- BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX);
-
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY);
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP);
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP_ARRAY);
@@ -1975,6 +2015,9 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(SHADER_SKY);
BIND_ENUM_CONSTANT(SHADER_MAX);
+ BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN);
+ BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX);
+
BIND_ENUM_CONSTANT(ARRAY_VERTEX);
BIND_ENUM_CONSTANT(ARRAY_NORMAL);
BIND_ENUM_CONSTANT(ARRAY_TANGENT);
@@ -2002,9 +2045,10 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT);
+
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES);
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT);
BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
@@ -2027,10 +2071,10 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(LIGHT_PARAM_INDIRECT_ENERGY);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SPECULAR);
BIND_ENUM_CONSTANT(LIGHT_PARAM_RANGE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SIZE);
BIND_ENUM_CONSTANT(LIGHT_PARAM_ATTENUATION);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ANGLE);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ATTENUATION);
- BIND_ENUM_CONSTANT(LIGHT_PARAM_CONTACT_SHADOW_SIZE);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_MAX_DISTANCE);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET);
@@ -2038,7 +2082,9 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_FADE_START);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_NORMAL_BIAS);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS);
- BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BLUR);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS);
BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX);
BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID);
@@ -2054,6 +2100,12 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ONCE);
BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ALWAYS);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_ALBEDO);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_NORMAL);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_ORM);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_EMISSION);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_MAX);
+
BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_INDEX);
BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_LIFETIME);
BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_VIEW_DEPTH);
@@ -2073,8 +2125,11 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_MSAA_4X);
BIND_ENUM_CONSTANT(VIEWPORT_MSAA_8X);
BIND_ENUM_CONSTANT(VIEWPORT_MSAA_16X);
- BIND_ENUM_CONSTANT(VIEWPORT_MSAA_EXT_2X);
- BIND_ENUM_CONSTANT(VIEWPORT_MSAA_EXT_4X);
+ BIND_ENUM_CONSTANT(VIEWPORT_MSAA_MAX);
+
+ BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_DISABLED);
+ BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_FXAA);
+ BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_MAX);
BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME);
BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME);
@@ -2098,6 +2153,8 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SSAO);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER);
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_PSSM_SPLITS);
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DECAL_ATLAS);
BIND_ENUM_CONSTANT(SKY_MODE_QUALITY);
BIND_ENUM_CONSTANT(SKY_MODE_REALTIME);
@@ -2130,6 +2187,11 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES);
+ BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_DISABLED);
+ BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_LOW);
+ BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_MEDIUM);
+ BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_HIGH);
+
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_DISABLED);
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_1x1);
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_2x2);
@@ -2140,6 +2202,11 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_HIGH);
BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_ULTRA);
+ BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_DISABLED);
+ BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_LOW);
+ BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_MEDIUM);
+ BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_HIGH);
+
BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_VERY_LOW);
BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW);
BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM);
@@ -2149,6 +2216,13 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(DOF_BOKEH_HEXAGON);
BIND_ENUM_CONSTANT(DOF_BOKEH_CIRCLE);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_HARD);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_LOW);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_MEDIUM);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_HIGH);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_ULTRA);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_MAX);
+
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_DISABLED);
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_WIREFRAME);
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_OVERDRAW);
@@ -2161,6 +2235,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(INSTANCE_PARTICLES);
BIND_ENUM_CONSTANT(INSTANCE_LIGHT);
BIND_ENUM_CONSTANT(INSTANCE_REFLECTION_PROBE);
+ BIND_ENUM_CONSTANT(INSTANCE_DECAL);
BIND_ENUM_CONSTANT(INSTANCE_GI_PROBE);
BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP_CAPTURE);
BIND_ENUM_CONSTANT(INSTANCE_MAX);
@@ -2209,6 +2284,36 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE);
BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BOOL);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC2);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC3);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC4);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_INT);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_IVEC2);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_IVEC3);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_IVEC4);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_RECT2I);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_UINT);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_UVEC2);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_UVEC3);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_UVEC4);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_FLOAT);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_VEC2);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_VEC3);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_VEC4);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_COLOR);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_RECT2);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAT2);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAT3);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAT4);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_TRANSFORM_2D);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_TRANSFORM);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLER2D);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLER2DARRAY);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLER3D);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLERCUBE);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAX);
+
BIND_ENUM_CONSTANT(INFO_OBJECTS_IN_FRAME);
BIND_ENUM_CONSTANT(INFO_VERTICES_IN_FRAME);
BIND_ENUM_CONSTANT(INFO_MATERIAL_CHANGES_IN_FRAME);
@@ -2298,6 +2403,14 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096);
GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384"));
+ GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality", 2);
+ GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality.mobile", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard(Fastest), Soft Low (Fast), Soft Medium (Average), Soft High (Slow), Soft Ultra (Slowest)"));
+
+ GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality", 2);
+ GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard(Fastest), Soft Low (Fast), Soft Medium (Average), Soft High (Slow), Soft Ultra (Slowest)"));
+
GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
@@ -2310,10 +2423,6 @@ RenderingServer::RenderingServer() {
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- GLOBAL_DEF("rendering/quality/shadows/filter_mode", 1);
- GLOBAL_DEF("rendering/quality/shadows/filter_mode.mobile", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled (Fast),PCF5 (Average),PCF13 (Slow)"));
-
GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8);
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
@@ -2338,23 +2447,23 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/quality/depth_prepass/enable", true);
GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple");
- GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false);
- GLOBAL_DEF("rendering/quality/filters/max_anisotropy", 4);
+ GLOBAL_DEF("rendering/quality/texture_filters/use_nearest_mipmap_filter", false);
+ GLOBAL_DEF("rendering/quality/texture_filters/max_anisotropy", 4);
- GLOBAL_DEF("rendering/quality/filters/depth_of_field_bokeh_shape", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/filters/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)"));
- GLOBAL_DEF("rendering/quality/filters/depth_of_field_bokeh_quality", 2);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/quality/filters/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)"));
- GLOBAL_DEF("rendering/quality/filters/depth_of_field_use_jitter", false);
+ GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)"));
+ GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_quality", 2);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)"));
+ GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_use_jitter", false);
GLOBAL_DEF("rendering/quality/ssao/quality", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/quality", PropertyInfo(Variant::INT, "rendering/quality/ssao/quality", PROPERTY_HINT_ENUM, "Low (Fast),Medium (Average),High (Slow),Ultra (Slower)"));
GLOBAL_DEF("rendering/quality/ssao/half_size", false);
- GLOBAL_DEF("rendering/quality/filters/screen_space_roughness_limiter", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/screen_space_roughness_limiter", PropertyInfo(Variant::INT, "rendering/quality/filters/screen_space_roughness_limiter", PROPERTY_HINT_ENUM, "Disabled (Fast),Enabled (Average)"));
- GLOBAL_DEF("rendering/quality/filters/screen_space_roughness_limiter_curve", 1.0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/screen_space_roughness_limiter_curve", PropertyInfo(Variant::FLOAT, "rendering/quality/filters/screen_space_roughness_limiter_curve", PROPERTY_HINT_EXP_EASING, "0.01,8,0.01"));
+ GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_roughness_limiter", PROPERTY_HINT_ENUM, "Disabled (Fast),Enabled (Average)"));
+ GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_curve", 1.0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter_curve", PropertyInfo(Variant::FLOAT, "rendering/quality/screen_filters/screen_space_roughness_limiter_curve", PROPERTY_HINT_EXP_EASING, "0.01,8,0.01"));
GLOBAL_DEF("rendering/quality/glow/upscale_mode", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/quality/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)"));
@@ -2369,6 +2478,8 @@ RenderingServer::RenderingServer() {
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001"));
GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", 0.01);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001"));
+
+ GLOBAL_DEF("rendering/high_end/global_shader_variables_buffer_size", 65536);
}
RenderingServer::~RenderingServer() {
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index ac8e92be59..8ca070b4a9 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -38,6 +38,7 @@
#include "core/rid.h"
#include "core/variant.h"
#include "servers/display_server.h"
+#include "servers/rendering/shader_language.h"
class RenderingServer : public Object {
@@ -85,7 +86,6 @@ public:
};
enum CubeMapLayer {
-
CUBEMAP_LAYER_LEFT,
CUBEMAP_LAYER_RIGHT,
CUBEMAP_LAYER_BOTTOM,
@@ -157,7 +157,6 @@ public:
/* SHADER API */
enum ShaderMode {
-
SHADER_SPATIAL,
SHADER_CANVAS_ITEM,
SHADER_PARTICLES,
@@ -181,8 +180,8 @@ public:
enum {
MATERIAL_RENDER_PRIORITY_MIN = -128,
MATERIAL_RENDER_PRIORITY_MAX = 127,
-
};
+
virtual RID material_create() = 0;
virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
@@ -197,7 +196,6 @@ public:
/* MESH API */
enum ArrayType {
-
ARRAY_VERTEX = 0,
ARRAY_NORMAL = 1,
ARRAY_TANGENT = 2,
@@ -229,12 +227,10 @@ public:
ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE),
+ ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2,
ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1,
ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3,
-
- ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2
-
};
enum PrimitiveType {
@@ -377,15 +373,14 @@ public:
};
enum LightParam {
-
LIGHT_PARAM_ENERGY,
LIGHT_PARAM_INDIRECT_ENERGY,
LIGHT_PARAM_SPECULAR,
LIGHT_PARAM_RANGE,
+ LIGHT_PARAM_SIZE,
LIGHT_PARAM_ATTENUATION,
LIGHT_PARAM_SPOT_ANGLE,
LIGHT_PARAM_SPOT_ATTENUATION,
- LIGHT_PARAM_CONTACT_SHADOW_SIZE,
LIGHT_PARAM_SHADOW_MAX_DISTANCE,
LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET,
@@ -393,7 +388,9 @@ public:
LIGHT_PARAM_SHADOW_FADE_START,
LIGHT_PARAM_SHADOW_NORMAL_BIAS,
LIGHT_PARAM_SHADOW_BIAS,
- LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
+ LIGHT_PARAM_SHADOW_PANCAKE_SIZE,
+ LIGHT_PARAM_SHADOW_BLUR,
+ LIGHT_PARAM_TRANSMITTANCE_BIAS,
LIGHT_PARAM_MAX
};
@@ -460,6 +457,27 @@ public:
virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0;
virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
+ /* DECAL API */
+
+ enum DecalTexture {
+ DECAL_TEXTURE_ALBEDO,
+ DECAL_TEXTURE_NORMAL,
+ DECAL_TEXTURE_ORM,
+ DECAL_TEXTURE_EMISSION,
+ DECAL_TEXTURE_MAX
+ };
+
+ virtual RID decal_create() = 0;
+ virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
+ virtual void decal_set_texture(RID p_decal, DecalTexture p_type, RID p_texture) = 0;
+ virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
+ virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
+ virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
+ virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
+ virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
+ virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
+ virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
+
/* GI PROBE API */
virtual RID gi_probe_create() = 0;
@@ -575,12 +593,13 @@ public:
};
virtual void particles_set_collision(RID p_particles,ParticlesCollisionMode p_mode,const Transform&, p_xform,const RID p_depth_tex,const RID p_normal_tex)=0;
-*/
+ */
+
/* VIEWPORT TARGET API */
virtual RID viewport_create() = 0;
- virtual void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) = 0;
+ virtual void viewport_set_use_xr(RID p_viewport, bool p_use_xr) = 0;
virtual void viewport_set_size(RID p_viewport, int p_width, int p_height) = 0;
virtual void viewport_set_active(RID p_viewport, bool p_active) = 0;
virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0;
@@ -599,7 +618,6 @@ public:
virtual void viewport_set_update_mode(RID p_viewport, ViewportUpdateMode p_mode) = 0;
enum ViewportClearMode {
-
VIEWPORT_CLEAR_ALWAYS,
VIEWPORT_CLEAR_NEVER,
VIEWPORT_CLEAR_ONLY_NEXT_FRAME
@@ -632,21 +650,27 @@ public:
VIEWPORT_MSAA_4X,
VIEWPORT_MSAA_8X,
VIEWPORT_MSAA_16X,
- VIEWPORT_MSAA_EXT_2X,
- VIEWPORT_MSAA_EXT_4X,
+ VIEWPORT_MSAA_MAX,
};
virtual void viewport_set_msaa(RID p_viewport, ViewportMSAA p_msaa) = 0;
- enum ViewportRenderInfo {
+ enum ViewportScreenSpaceAA {
+ VIEWPORT_SCREEN_SPACE_AA_DISABLED,
+ VIEWPORT_SCREEN_SPACE_AA_FXAA,
+ VIEWPORT_SCREEN_SPACE_AA_MAX,
+ };
+
+ virtual void viewport_set_screen_space_aa(RID p_viewport, ViewportScreenSpaceAA p_mode) = 0;
+ enum ViewportRenderInfo {
VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME,
VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME,
VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME,
VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME,
VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME,
- VIEWPORT_RENDER_INFO_MAX
+ VIEWPORT_RENDER_INFO_MAX,
};
virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0;
@@ -666,11 +690,16 @@ public:
VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE,
VIEWPORT_DEBUG_DRAW_SSAO,
VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER,
-
+ VIEWPORT_DEBUG_DRAW_PSSM_SPLITS,
+ VIEWPORT_DEBUG_DRAW_DECAL_ATLAS,
};
virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
+ virtual void viewport_set_measure_render_time(RID p_viewport, bool p_enable) = 0;
+ virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const = 0;
+ virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const = 0;
+
virtual void directional_shadow_atlas_set_size(int p_size) = 0;
/* SKY API */
@@ -690,7 +719,6 @@ public:
virtual RID environment_create() = 0;
enum EnvironmentBG {
-
ENV_BG_CLEAR_COLOR,
ENV_BG_COLOR,
ENV_BG_SKY,
@@ -733,6 +761,7 @@ public:
ENV_GLOW_BLEND_MODE_REPLACE,
ENV_GLOW_BLEND_MODE_MIX,
};
+
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
@@ -816,6 +845,18 @@ public:
virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0;
virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0;
+ enum ShadowQuality {
+ SHADOW_QUALITY_HARD,
+ SHADOW_QUALITY_SOFT_LOW,
+ SHADOW_QUALITY_SOFT_MEDIUM,
+ SHADOW_QUALITY_SOFT_HIGH,
+ SHADOW_QUALITY_SOFT_ULTRA,
+ SHADOW_QUALITY_MAX
+ };
+
+ virtual void shadows_quality_set(ShadowQuality p_quality) = 0;
+ virtual void directional_shadow_quality_set(ShadowQuality p_quality) = 0;
+
/* SCENARIO API */
virtual RID scenario_create() = 0;
@@ -825,7 +866,6 @@ public:
SCENARIO_DEBUG_WIREFRAME,
SCENARIO_DEBUG_OVERDRAW,
SCENARIO_DEBUG_SHADELESS,
-
};
virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0;
@@ -836,7 +876,6 @@ public:
/* INSTANCING API */
enum InstanceType {
-
INSTANCE_NONE,
INSTANCE_MESH,
INSTANCE_MULTIMESH,
@@ -844,6 +883,7 @@ public:
INSTANCE_PARTICLES,
INSTANCE_LIGHT,
INSTANCE_REFLECTION_PROBE,
+ INSTANCE_DECAL,
INSTANCE_GI_PROBE,
INSTANCE_LIGHTMAP_CAPTURE,
INSTANCE_MAX,
@@ -903,6 +943,11 @@ public:
virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0;
virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) = 0;
+ virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &, const Variant &p_value) = 0;
+ virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &) const = 0;
+ virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &) const = 0;
+ virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0;
+
/* CANVAS (2D) */
virtual RID canvas_create() = 0;
@@ -1041,8 +1086,58 @@ public:
CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE,
CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE,
};
+
virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, CanvasOccluderPolygonCullMode p_mode) = 0;
+ /* GLOBAL VARIABLES */
+
+ enum GlobalVariableType {
+ GLOBAL_VAR_TYPE_BOOL,
+ GLOBAL_VAR_TYPE_BVEC2,
+ GLOBAL_VAR_TYPE_BVEC3,
+ GLOBAL_VAR_TYPE_BVEC4,
+ GLOBAL_VAR_TYPE_INT,
+ GLOBAL_VAR_TYPE_IVEC2,
+ GLOBAL_VAR_TYPE_IVEC3,
+ GLOBAL_VAR_TYPE_IVEC4,
+ GLOBAL_VAR_TYPE_RECT2I,
+ GLOBAL_VAR_TYPE_UINT,
+ GLOBAL_VAR_TYPE_UVEC2,
+ GLOBAL_VAR_TYPE_UVEC3,
+ GLOBAL_VAR_TYPE_UVEC4,
+ GLOBAL_VAR_TYPE_FLOAT,
+ GLOBAL_VAR_TYPE_VEC2,
+ GLOBAL_VAR_TYPE_VEC3,
+ GLOBAL_VAR_TYPE_VEC4,
+ GLOBAL_VAR_TYPE_COLOR,
+ GLOBAL_VAR_TYPE_RECT2,
+ GLOBAL_VAR_TYPE_MAT2,
+ GLOBAL_VAR_TYPE_MAT3,
+ GLOBAL_VAR_TYPE_MAT4,
+ GLOBAL_VAR_TYPE_TRANSFORM_2D,
+ GLOBAL_VAR_TYPE_TRANSFORM,
+ GLOBAL_VAR_TYPE_SAMPLER2D,
+ GLOBAL_VAR_TYPE_SAMPLER2DARRAY,
+ GLOBAL_VAR_TYPE_SAMPLER3D,
+ GLOBAL_VAR_TYPE_SAMPLERCUBE,
+ GLOBAL_VAR_TYPE_MAX
+ };
+
+ virtual void global_variable_add(const StringName &p_name, GlobalVariableType p_type, const Variant &p_value) = 0;
+ virtual void global_variable_remove(const StringName &p_name) = 0;
+ virtual Vector<StringName> global_variable_get_list() const = 0;
+
+ virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0;
+ virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0;
+
+ virtual Variant global_variable_get(const StringName &p_name) const = 0;
+ virtual GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0;
+
+ virtual void global_variables_load_settings(bool p_load_textures) = 0;
+ virtual void global_variables_clear() = 0;
+
+ static ShaderLanguage::DataType global_variable_type_get_shader_datatype(GlobalVariableType p_type);
+
/* BLACK BARS */
virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) = 0;
@@ -1065,7 +1160,6 @@ public:
/* STATUS INFORMATION */
enum RenderInfo {
-
INFO_OBJECTS_IN_FRAME,
INFO_VERTICES_IN_FRAME,
INFO_MATERIAL_CHANGES_IN_FRAME,
@@ -1143,10 +1237,12 @@ VARIANT_ENUM_CAST(RenderingServer::LightOmniShadowMode);
VARIANT_ENUM_CAST(RenderingServer::LightDirectionalShadowMode);
VARIANT_ENUM_CAST(RenderingServer::LightDirectionalShadowDepthRangeMode);
VARIANT_ENUM_CAST(RenderingServer::ReflectionProbeUpdateMode);
+VARIANT_ENUM_CAST(RenderingServer::DecalTexture);
VARIANT_ENUM_CAST(RenderingServer::ParticlesDrawOrder);
VARIANT_ENUM_CAST(RenderingServer::ViewportUpdateMode);
VARIANT_ENUM_CAST(RenderingServer::ViewportClearMode);
VARIANT_ENUM_CAST(RenderingServer::ViewportMSAA);
+VARIANT_ENUM_CAST(RenderingServer::ViewportScreenSpaceAA);
VARIANT_ENUM_CAST(RenderingServer::ViewportRenderInfo);
VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw);
VARIANT_ENUM_CAST(RenderingServer::SkyMode);
@@ -1155,10 +1251,13 @@ VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentReflectionSource);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentGlowBlendMode);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentToneMapper);
-VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality);
+VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSRRoughnessQuality);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOBlur);
+VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality);
+VARIANT_ENUM_CAST(RenderingServer::SubSurfaceScatteringQuality);
VARIANT_ENUM_CAST(RenderingServer::DOFBlurQuality);
VARIANT_ENUM_CAST(RenderingServer::DOFBokehShape);
+VARIANT_ENUM_CAST(RenderingServer::ShadowQuality);
VARIANT_ENUM_CAST(RenderingServer::ScenarioDebugMode);
VARIANT_ENUM_CAST(RenderingServer::InstanceType);
VARIANT_ENUM_CAST(RenderingServer::InstanceFlags);
@@ -1169,10 +1268,11 @@ VARIANT_ENUM_CAST(RenderingServer::CanvasItemTextureRepeat);
VARIANT_ENUM_CAST(RenderingServer::CanvasLightMode);
VARIANT_ENUM_CAST(RenderingServer::CanvasLightShadowFilter);
VARIANT_ENUM_CAST(RenderingServer::CanvasOccluderPolygonCullMode);
+VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType);
VARIANT_ENUM_CAST(RenderingServer::RenderInfo);
VARIANT_ENUM_CAST(RenderingServer::Features);
-//typedef RenderingServer VS; // makes it easier to use
+// Alias to make it easier to use.
#define RS RenderingServer
-#endif
+#endif // RENDERING_SERVER_H
diff --git a/servers/arvr/SCsub b/servers/xr/SCsub
index 86681f9c74..86681f9c74 100644
--- a/servers/arvr/SCsub
+++ b/servers/xr/SCsub
diff --git a/servers/arvr/arvr_interface.cpp b/servers/xr/xr_interface.cpp
index 577b4cdd8a..c1233ae810 100644
--- a/servers/arvr/arvr_interface.cpp
+++ b/servers/xr/xr_interface.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_interface.cpp */
+/* xr_interface.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,24 +28,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "arvr_interface.h"
+#include "xr_interface.h"
-void ARVRInterface::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_name"), &ARVRInterface::get_name);
- ClassDB::bind_method(D_METHOD("get_capabilities"), &ARVRInterface::get_capabilities);
+void XRInterface::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_name"), &XRInterface::get_name);
+ ClassDB::bind_method(D_METHOD("get_capabilities"), &XRInterface::get_capabilities);
- ClassDB::bind_method(D_METHOD("is_primary"), &ARVRInterface::is_primary);
- ClassDB::bind_method(D_METHOD("set_is_primary", "enable"), &ARVRInterface::set_is_primary);
+ ClassDB::bind_method(D_METHOD("is_primary"), &XRInterface::is_primary);
+ ClassDB::bind_method(D_METHOD("set_is_primary", "enable"), &XRInterface::set_is_primary);
- ClassDB::bind_method(D_METHOD("is_initialized"), &ARVRInterface::is_initialized);
- ClassDB::bind_method(D_METHOD("set_is_initialized", "initialized"), &ARVRInterface::set_is_initialized);
- ClassDB::bind_method(D_METHOD("initialize"), &ARVRInterface::initialize);
- ClassDB::bind_method(D_METHOD("uninitialize"), &ARVRInterface::uninitialize);
+ ClassDB::bind_method(D_METHOD("is_initialized"), &XRInterface::is_initialized);
+ ClassDB::bind_method(D_METHOD("set_is_initialized", "initialized"), &XRInterface::set_is_initialized);
+ ClassDB::bind_method(D_METHOD("initialize"), &XRInterface::initialize);
+ ClassDB::bind_method(D_METHOD("uninitialize"), &XRInterface::uninitialize);
- ClassDB::bind_method(D_METHOD("get_tracking_status"), &ARVRInterface::get_tracking_status);
+ ClassDB::bind_method(D_METHOD("get_tracking_status"), &XRInterface::get_tracking_status);
- ClassDB::bind_method(D_METHOD("get_render_targetsize"), &ARVRInterface::get_render_targetsize);
- ClassDB::bind_method(D_METHOD("is_stereo"), &ARVRInterface::is_stereo);
+ ClassDB::bind_method(D_METHOD("get_render_targetsize"), &XRInterface::get_render_targetsize);
+ ClassDB::bind_method(D_METHOD("is_stereo"), &XRInterface::is_stereo);
ADD_GROUP("Interface", "interface_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interface_is_primary"), "set_is_primary", "is_primary");
@@ -54,55 +54,55 @@ void ARVRInterface::_bind_methods() {
// we don't have any properties specific to VR yet....
// but we do have properties specific to AR....
- ClassDB::bind_method(D_METHOD("get_anchor_detection_is_enabled"), &ARVRInterface::get_anchor_detection_is_enabled);
- ClassDB::bind_method(D_METHOD("set_anchor_detection_is_enabled", "enable"), &ARVRInterface::set_anchor_detection_is_enabled);
- ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &ARVRInterface::get_camera_feed_id);
+ ClassDB::bind_method(D_METHOD("get_anchor_detection_is_enabled"), &XRInterface::get_anchor_detection_is_enabled);
+ ClassDB::bind_method(D_METHOD("set_anchor_detection_is_enabled", "enable"), &XRInterface::set_anchor_detection_is_enabled);
+ ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &XRInterface::get_camera_feed_id);
ADD_GROUP("AR", "ar_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled");
- BIND_ENUM_CONSTANT(ARVR_NONE);
- BIND_ENUM_CONSTANT(ARVR_MONO);
- BIND_ENUM_CONSTANT(ARVR_STEREO);
- BIND_ENUM_CONSTANT(ARVR_AR);
- BIND_ENUM_CONSTANT(ARVR_EXTERNAL);
+ BIND_ENUM_CONSTANT(XR_NONE);
+ BIND_ENUM_CONSTANT(XR_MONO);
+ BIND_ENUM_CONSTANT(XR_STEREO);
+ BIND_ENUM_CONSTANT(XR_AR);
+ BIND_ENUM_CONSTANT(XR_EXTERNAL);
BIND_ENUM_CONSTANT(EYE_MONO);
BIND_ENUM_CONSTANT(EYE_LEFT);
BIND_ENUM_CONSTANT(EYE_RIGHT);
- BIND_ENUM_CONSTANT(ARVR_NORMAL_TRACKING);
- BIND_ENUM_CONSTANT(ARVR_EXCESSIVE_MOTION);
- BIND_ENUM_CONSTANT(ARVR_INSUFFICIENT_FEATURES);
- BIND_ENUM_CONSTANT(ARVR_UNKNOWN_TRACKING);
- BIND_ENUM_CONSTANT(ARVR_NOT_TRACKING);
+ BIND_ENUM_CONSTANT(XR_NORMAL_TRACKING);
+ BIND_ENUM_CONSTANT(XR_EXCESSIVE_MOTION);
+ BIND_ENUM_CONSTANT(XR_INSUFFICIENT_FEATURES);
+ BIND_ENUM_CONSTANT(XR_UNKNOWN_TRACKING);
+ BIND_ENUM_CONSTANT(XR_NOT_TRACKING);
};
-StringName ARVRInterface::get_name() const {
+StringName XRInterface::get_name() const {
return "Unknown";
};
-bool ARVRInterface::is_primary() {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, false);
+bool XRInterface::is_primary() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, false);
- return arvr_server->get_primary_interface() == this;
+ return xr_server->get_primary_interface() == this;
};
-void ARVRInterface::set_is_primary(bool p_is_primary) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void XRInterface::set_is_primary(bool p_is_primary) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
if (p_is_primary) {
ERR_FAIL_COND(!is_initialized());
- arvr_server->set_primary_interface(this);
+ xr_server->set_primary_interface(this);
} else {
- arvr_server->clear_primary_interface_if(this);
+ xr_server->clear_primary_interface_if(this);
};
};
-void ARVRInterface::set_is_initialized(bool p_initialized) {
+void XRInterface::set_is_initialized(bool p_initialized) {
if (p_initialized) {
if (!is_initialized()) {
initialize();
@@ -114,31 +114,31 @@ void ARVRInterface::set_is_initialized(bool p_initialized) {
};
};
-ARVRInterface::Tracking_status ARVRInterface::get_tracking_status() const {
+XRInterface::Tracking_status XRInterface::get_tracking_status() const {
return tracking_state;
};
-ARVRInterface::ARVRInterface() {
- tracking_state = ARVR_UNKNOWN_TRACKING;
+XRInterface::XRInterface() {
+ tracking_state = XR_UNKNOWN_TRACKING;
};
-ARVRInterface::~ARVRInterface(){};
+XRInterface::~XRInterface(){};
// optional render to external texture which enhances performance on those platforms that require us to submit our end result into special textures.
-unsigned int ARVRInterface::get_external_texture_for_eye(ARVRInterface::Eyes p_eye) {
+unsigned int XRInterface::get_external_texture_for_eye(XRInterface::Eyes p_eye) {
return 0;
};
/** these will only be implemented on AR interfaces, so we want dummies for VR **/
-bool ARVRInterface::get_anchor_detection_is_enabled() const {
+bool XRInterface::get_anchor_detection_is_enabled() const {
return false;
};
-void ARVRInterface::set_anchor_detection_is_enabled(bool p_enable){
+void XRInterface::set_anchor_detection_is_enabled(bool p_enable){
// don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc.
};
-int ARVRInterface::get_camera_feed_id() {
+int XRInterface::get_camera_feed_id() {
// don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc.
return 0;
diff --git a/servers/arvr/arvr_interface.h b/servers/xr/xr_interface.h
index 861061cbf5..99fcef7925 100644
--- a/servers/arvr/arvr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_interface.h */
+/* xr_interface.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,18 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARVR_INTERFACE_H
-#define ARVR_INTERFACE_H
+#ifndef XR_INTERFACE_H
+#define XR_INTERFACE_H
#include "core/math/camera_matrix.h"
#include "core/os/thread_safe.h"
#include "scene/main/window.h"
-#include "servers/arvr_server.h"
+#include "servers/xr_server.h"
/**
@author Bastiaan Olij <mux213@gmail.com>
- The ARVR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs.
+ The XR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs.
The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface
when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server.
@@ -48,16 +48,16 @@
Note that we may make this into a fully instantiable class for GDNative support.
*/
-class ARVRInterface : public Reference {
- GDCLASS(ARVRInterface, Reference);
+class XRInterface : public Reference {
+ GDCLASS(XRInterface, Reference);
public:
enum Capabilities { /* purely meta data, provides some info about what this interface supports */
- ARVR_NONE = 0, /* no capabilities */
- ARVR_MONO = 1, /* can be used with mono output */
- ARVR_STEREO = 2, /* can be used with stereo output */
- ARVR_AR = 4, /* offers a camera feed for AR */
- ARVR_EXTERNAL = 8 /* renders to external device */
+ XR_NONE = 0, /* no capabilities */
+ XR_MONO = 1, /* can be used with mono output */
+ XR_STEREO = 2, /* can be used with stereo output */
+ XR_AR = 4, /* offers a camera feed for AR */
+ XR_EXTERNAL = 8 /* renders to external device */
};
enum Eyes {
@@ -67,11 +67,11 @@ public:
};
enum Tracking_status { /* tracking status currently based on AR but we can start doing more with this for VR as well */
- ARVR_NORMAL_TRACKING,
- ARVR_EXCESSIVE_MOTION,
- ARVR_INSUFFICIENT_FEATURES,
- ARVR_UNKNOWN_TRACKING,
- ARVR_NOT_TRACKING
+ XR_NORMAL_TRACKING,
+ XR_EXCESSIVE_MOTION,
+ XR_INSUFFICIENT_FEATURES,
+ XR_UNKNOWN_TRACKING,
+ XR_NOT_TRACKING
};
protected:
@@ -107,20 +107,20 @@ public:
virtual Size2 get_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */
virtual bool is_stereo() = 0; /* returns true if this interface requires stereo rendering (for VR HMDs) or mono rendering (for mobile AR) */
- virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */
- virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */
- virtual unsigned int get_external_texture_for_eye(ARVRInterface::Eyes p_eye); /* if applicable return external texture to render to */
- virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */
+ virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */
+ virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */
+ virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye); /* if applicable return external texture to render to */
+ virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */
virtual void process() = 0;
virtual void notification(int p_what) = 0;
- ARVRInterface();
- ~ARVRInterface();
+ XRInterface();
+ ~XRInterface();
};
-VARIANT_ENUM_CAST(ARVRInterface::Capabilities);
-VARIANT_ENUM_CAST(ARVRInterface::Eyes);
-VARIANT_ENUM_CAST(ARVRInterface::Tracking_status);
+VARIANT_ENUM_CAST(XRInterface::Capabilities);
+VARIANT_ENUM_CAST(XRInterface::Eyes);
+VARIANT_ENUM_CAST(XRInterface::Tracking_status);
#endif
diff --git a/servers/arvr/arvr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp
index dabeb7b86f..808b0a608f 100644
--- a/servers/arvr/arvr_positional_tracker.cpp
+++ b/servers/xr/xr_positional_tracker.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_positional_tracker.cpp */
+/* xr_positional_tracker.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,192 +28,192 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "arvr_positional_tracker.h"
+#include "xr_positional_tracker.h"
#include "core/input/input_filter.h"
-void ARVRPositionalTracker::_bind_methods() {
+void XRPositionalTracker::_bind_methods() {
BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN);
BIND_ENUM_CONSTANT(TRACKER_LEFT_HAND);
BIND_ENUM_CONSTANT(TRACKER_RIGHT_HAND);
// this class is read only from GDScript, so we only have access to getters..
- ClassDB::bind_method(D_METHOD("get_type"), &ARVRPositionalTracker::get_type);
- ClassDB::bind_method(D_METHOD("get_tracker_id"), &ARVRPositionalTracker::get_tracker_id);
- ClassDB::bind_method(D_METHOD("get_name"), &ARVRPositionalTracker::get_name);
- ClassDB::bind_method(D_METHOD("get_joy_id"), &ARVRPositionalTracker::get_joy_id);
- ClassDB::bind_method(D_METHOD("get_tracks_orientation"), &ARVRPositionalTracker::get_tracks_orientation);
- ClassDB::bind_method(D_METHOD("get_orientation"), &ARVRPositionalTracker::get_orientation);
- ClassDB::bind_method(D_METHOD("get_tracks_position"), &ARVRPositionalTracker::get_tracks_position);
- ClassDB::bind_method(D_METHOD("get_position"), &ARVRPositionalTracker::get_position);
- ClassDB::bind_method(D_METHOD("get_hand"), &ARVRPositionalTracker::get_hand);
- ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &ARVRPositionalTracker::get_transform);
- ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRPositionalTracker::get_mesh);
+ ClassDB::bind_method(D_METHOD("get_type"), &XRPositionalTracker::get_type);
+ ClassDB::bind_method(D_METHOD("get_tracker_id"), &XRPositionalTracker::get_tracker_id);
+ ClassDB::bind_method(D_METHOD("get_name"), &XRPositionalTracker::get_name);
+ ClassDB::bind_method(D_METHOD("get_joy_id"), &XRPositionalTracker::get_joy_id);
+ ClassDB::bind_method(D_METHOD("get_tracks_orientation"), &XRPositionalTracker::get_tracks_orientation);
+ ClassDB::bind_method(D_METHOD("get_orientation"), &XRPositionalTracker::get_orientation);
+ ClassDB::bind_method(D_METHOD("get_tracks_position"), &XRPositionalTracker::get_tracks_position);
+ ClassDB::bind_method(D_METHOD("get_position"), &XRPositionalTracker::get_position);
+ ClassDB::bind_method(D_METHOD("get_hand"), &XRPositionalTracker::get_hand);
+ ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &XRPositionalTracker::get_transform);
+ ClassDB::bind_method(D_METHOD("get_mesh"), &XRPositionalTracker::get_mesh);
// these functions we don't want to expose to normal users but do need to be callable from GDNative
- ClassDB::bind_method(D_METHOD("_set_type", "type"), &ARVRPositionalTracker::set_type);
- ClassDB::bind_method(D_METHOD("_set_name", "name"), &ARVRPositionalTracker::set_name);
- ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &ARVRPositionalTracker::set_joy_id);
- ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &ARVRPositionalTracker::set_orientation);
- ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &ARVRPositionalTracker::set_rw_position);
- ClassDB::bind_method(D_METHOD("_set_mesh", "mesh"), &ARVRPositionalTracker::set_mesh);
- ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRPositionalTracker::get_rumble);
- ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRPositionalTracker::set_rumble);
+ ClassDB::bind_method(D_METHOD("_set_type", "type"), &XRPositionalTracker::set_type);
+ ClassDB::bind_method(D_METHOD("_set_name", "name"), &XRPositionalTracker::set_name);
+ ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &XRPositionalTracker::set_joy_id);
+ ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &XRPositionalTracker::set_orientation);
+ ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &XRPositionalTracker::set_rw_position);
+ ClassDB::bind_method(D_METHOD("_set_mesh", "mesh"), &XRPositionalTracker::set_mesh);
+ ClassDB::bind_method(D_METHOD("get_rumble"), &XRPositionalTracker::get_rumble);
+ ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRPositionalTracker::set_rumble);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble"), "set_rumble", "get_rumble");
};
-void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) {
+void XRPositionalTracker::set_type(XRServer::TrackerType p_type) {
if (type != p_type) {
type = p_type;
- hand = ARVRPositionalTracker::TRACKER_HAND_UNKNOWN;
+ hand = XRPositionalTracker::TRACKER_HAND_UNKNOWN;
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
// get a tracker id for our type
// note if this is a controller this will be 3 or higher but we may change it later.
- tracker_id = arvr_server->get_free_tracker_id_for_type(p_type);
+ tracker_id = xr_server->get_free_tracker_id_for_type(p_type);
};
};
-ARVRServer::TrackerType ARVRPositionalTracker::get_type() const {
+XRServer::TrackerType XRPositionalTracker::get_type() const {
return type;
};
-void ARVRPositionalTracker::set_name(const String &p_name) {
+void XRPositionalTracker::set_name(const String &p_name) {
name = p_name;
};
-StringName ARVRPositionalTracker::get_name() const {
+StringName XRPositionalTracker::get_name() const {
return name;
};
-int ARVRPositionalTracker::get_tracker_id() const {
+int XRPositionalTracker::get_tracker_id() const {
return tracker_id;
};
-void ARVRPositionalTracker::set_joy_id(int p_joy_id) {
+void XRPositionalTracker::set_joy_id(int p_joy_id) {
joy_id = p_joy_id;
};
-int ARVRPositionalTracker::get_joy_id() const {
+int XRPositionalTracker::get_joy_id() const {
return joy_id;
};
-bool ARVRPositionalTracker::get_tracks_orientation() const {
+bool XRPositionalTracker::get_tracks_orientation() const {
return tracks_orientation;
};
-void ARVRPositionalTracker::set_orientation(const Basis &p_orientation) {
+void XRPositionalTracker::set_orientation(const Basis &p_orientation) {
_THREAD_SAFE_METHOD_
tracks_orientation = true; // obviously we have this
orientation = p_orientation;
};
-Basis ARVRPositionalTracker::get_orientation() const {
+Basis XRPositionalTracker::get_orientation() const {
_THREAD_SAFE_METHOD_
return orientation;
};
-bool ARVRPositionalTracker::get_tracks_position() const {
+bool XRPositionalTracker::get_tracks_position() const {
return tracks_position;
};
-void ARVRPositionalTracker::set_position(const Vector3 &p_position) {
+void XRPositionalTracker::set_position(const Vector3 &p_position) {
_THREAD_SAFE_METHOD_
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
- real_t world_scale = arvr_server->get_world_scale();
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+ real_t world_scale = xr_server->get_world_scale();
ERR_FAIL_COND(world_scale == 0);
tracks_position = true; // obviously we have this
rw_position = p_position / world_scale;
};
-Vector3 ARVRPositionalTracker::get_position() const {
+Vector3 XRPositionalTracker::get_position() const {
_THREAD_SAFE_METHOD_
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, rw_position);
- real_t world_scale = arvr_server->get_world_scale();
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, rw_position);
+ real_t world_scale = xr_server->get_world_scale();
return rw_position * world_scale;
};
-void ARVRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) {
+void XRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) {
_THREAD_SAFE_METHOD_
tracks_position = true; // obviously we have this
rw_position = p_rw_position;
};
-Vector3 ARVRPositionalTracker::get_rw_position() const {
+Vector3 XRPositionalTracker::get_rw_position() const {
_THREAD_SAFE_METHOD_
return rw_position;
};
-void ARVRPositionalTracker::set_mesh(const Ref<Mesh> &p_mesh) {
+void XRPositionalTracker::set_mesh(const Ref<Mesh> &p_mesh) {
_THREAD_SAFE_METHOD_
mesh = p_mesh;
};
-Ref<Mesh> ARVRPositionalTracker::get_mesh() const {
+Ref<Mesh> XRPositionalTracker::get_mesh() const {
_THREAD_SAFE_METHOD_
return mesh;
};
-ARVRPositionalTracker::TrackerHand ARVRPositionalTracker::get_hand() const {
+XRPositionalTracker::TrackerHand XRPositionalTracker::get_hand() const {
return hand;
};
-void ARVRPositionalTracker::set_hand(const ARVRPositionalTracker::TrackerHand p_hand) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
+void XRPositionalTracker::set_hand(const XRPositionalTracker::TrackerHand p_hand) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
if (hand != p_hand) {
// we can only set this if we've previously set this to be a controller!!
- ERR_FAIL_COND((type != ARVRServer::TRACKER_CONTROLLER) && (p_hand != ARVRPositionalTracker::TRACKER_HAND_UNKNOWN));
+ ERR_FAIL_COND((type != XRServer::TRACKER_CONTROLLER) && (p_hand != XRPositionalTracker::TRACKER_HAND_UNKNOWN));
hand = p_hand;
- if (hand == ARVRPositionalTracker::TRACKER_LEFT_HAND) {
- if (!arvr_server->is_tracker_id_in_use_for_type(type, 1)) {
+ if (hand == XRPositionalTracker::TRACKER_LEFT_HAND) {
+ if (!xr_server->is_tracker_id_in_use_for_type(type, 1)) {
tracker_id = 1;
};
- } else if (hand == ARVRPositionalTracker::TRACKER_RIGHT_HAND) {
- if (!arvr_server->is_tracker_id_in_use_for_type(type, 2)) {
+ } else if (hand == XRPositionalTracker::TRACKER_RIGHT_HAND) {
+ if (!xr_server->is_tracker_id_in_use_for_type(type, 2)) {
tracker_id = 2;
};
};
};
};
-Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const {
+Transform XRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const {
Transform new_transform;
new_transform.basis = get_orientation();
new_transform.origin = get_position();
if (p_adjust_by_reference_frame) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, new_transform);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, new_transform);
- new_transform = arvr_server->get_reference_frame() * new_transform;
+ new_transform = xr_server->get_reference_frame() * new_transform;
};
return new_transform;
};
-real_t ARVRPositionalTracker::get_rumble() const {
+real_t XRPositionalTracker::get_rumble() const {
return rumble;
};
-void ARVRPositionalTracker::set_rumble(real_t p_rumble) {
+void XRPositionalTracker::set_rumble(real_t p_rumble) {
if (p_rumble > 0.0) {
rumble = p_rumble;
} else {
@@ -221,8 +221,8 @@ void ARVRPositionalTracker::set_rumble(real_t p_rumble) {
};
};
-ARVRPositionalTracker::ARVRPositionalTracker() {
- type = ARVRServer::TRACKER_UNKNOWN;
+XRPositionalTracker::XRPositionalTracker() {
+ type = XRServer::TRACKER_UNKNOWN;
name = "Unknown";
joy_id = -1;
tracker_id = 0;
@@ -232,6 +232,6 @@ ARVRPositionalTracker::ARVRPositionalTracker() {
rumble = 0.0;
};
-ARVRPositionalTracker::~ARVRPositionalTracker(){
+XRPositionalTracker::~XRPositionalTracker(){
};
diff --git a/servers/arvr/arvr_positional_tracker.h b/servers/xr/xr_positional_tracker.h
index 03c6b33ffe..d9d1f909e9 100644
--- a/servers/arvr/arvr_positional_tracker.h
+++ b/servers/xr/xr_positional_tracker.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_positional_tracker.h */
+/* xr_positional_tracker.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARVR_POSITIONAL_TRACKER_H
-#define ARVR_POSITIONAL_TRACKER_H
+#ifndef XR_POSITIONAL_TRACKER_H
+#define XR_POSITIONAL_TRACKER_H
#include "core/os/thread_safe.h"
#include "scene/resources/mesh.h"
-#include "servers/arvr_server.h"
+#include "servers/xr_server.h"
/**
@author Bastiaan Olij <mux213@gmail.com>
@@ -43,8 +43,8 @@
This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking.
*/
-class ARVRPositionalTracker : public Object {
- GDCLASS(ARVRPositionalTracker, Object);
+class XRPositionalTracker : public Object {
+ GDCLASS(XRPositionalTracker, Object);
_THREAD_SAFE_CLASS_
public:
@@ -55,7 +55,7 @@ public:
};
private:
- ARVRServer::TrackerType type; // type of tracker
+ XRServer::TrackerType type; // type of tracker
StringName name; // (unique) name of the tracker
int tracker_id; // tracker index id that is unique per type
int joy_id; // if we also have a related joystick entity, the id of the joystick
@@ -65,14 +65,14 @@ private:
Vector3 rw_position; // our position "in the real world, so without world_scale applied"
Ref<Mesh> mesh; // when available, a mesh that can be used to render this tracker
TrackerHand hand; // if known, the hand this tracker is held in
- real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, arvr_interface is responsible for execution
+ real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, xr_interface is responsible for execution
protected:
static void _bind_methods();
public:
- void set_type(ARVRServer::TrackerType p_type);
- ARVRServer::TrackerType get_type() const;
+ void set_type(XRServer::TrackerType p_type);
+ XRServer::TrackerType get_type() const;
void set_name(const String &p_name);
StringName get_name() const;
int get_tracker_id() const;
@@ -86,8 +86,8 @@ public:
Vector3 get_position() const; // get position with world_scale applied
void set_rw_position(const Vector3 &p_rw_position);
Vector3 get_rw_position() const;
- ARVRPositionalTracker::TrackerHand get_hand() const;
- void set_hand(const ARVRPositionalTracker::TrackerHand p_hand);
+ XRPositionalTracker::TrackerHand get_hand() const;
+ void set_hand(const XRPositionalTracker::TrackerHand p_hand);
real_t get_rumble() const;
void set_rumble(real_t p_rumble);
void set_mesh(const Ref<Mesh> &p_mesh);
@@ -95,10 +95,10 @@ public:
Transform get_transform(bool p_adjust_by_reference_frame) const;
- ARVRPositionalTracker();
- ~ARVRPositionalTracker();
+ XRPositionalTracker();
+ ~XRPositionalTracker();
};
-VARIANT_ENUM_CAST(ARVRPositionalTracker::TrackerHand);
+VARIANT_ENUM_CAST(XRPositionalTracker::TrackerHand);
#endif
diff --git a/servers/arvr_server.cpp b/servers/xr_server.cpp
index f5597d8974..a93b99025f 100644
--- a/servers/arvr_server.cpp
+++ b/servers/xr_server.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_server.cpp */
+/* xr_server.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,41 +28,41 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "arvr_server.h"
-#include "arvr/arvr_interface.h"
-#include "arvr/arvr_positional_tracker.h"
+#include "xr_server.h"
#include "core/project_settings.h"
+#include "xr/xr_interface.h"
+#include "xr/xr_positional_tracker.h"
-ARVRServer *ARVRServer::singleton = nullptr;
+XRServer *XRServer::singleton = nullptr;
-ARVRServer *ARVRServer::get_singleton() {
+XRServer *XRServer::get_singleton() {
return singleton;
};
-void ARVRServer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVRServer::get_world_scale);
- ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale);
- ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame);
- ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &ARVRServer::center_on_hmd);
- ClassDB::bind_method(D_METHOD("get_hmd_transform"), &ARVRServer::get_hmd_transform);
+void XRServer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_world_scale"), &XRServer::get_world_scale);
+ ClassDB::bind_method(D_METHOD("set_world_scale"), &XRServer::set_world_scale);
+ ClassDB::bind_method(D_METHOD("get_reference_frame"), &XRServer::get_reference_frame);
+ ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &XRServer::center_on_hmd);
+ ClassDB::bind_method(D_METHOD("get_hmd_transform"), &XRServer::get_hmd_transform);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale");
- ClassDB::bind_method(D_METHOD("get_interface_count"), &ARVRServer::get_interface_count);
- ClassDB::bind_method(D_METHOD("get_interface", "idx"), &ARVRServer::get_interface);
- ClassDB::bind_method(D_METHOD("get_interfaces"), &ARVRServer::get_interfaces);
- ClassDB::bind_method(D_METHOD("find_interface", "name"), &ARVRServer::find_interface);
- ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count);
- ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &ARVRServer::get_tracker);
+ ClassDB::bind_method(D_METHOD("get_interface_count"), &XRServer::get_interface_count);
+ ClassDB::bind_method(D_METHOD("get_interface", "idx"), &XRServer::get_interface);
+ ClassDB::bind_method(D_METHOD("get_interfaces"), &XRServer::get_interfaces);
+ ClassDB::bind_method(D_METHOD("find_interface", "name"), &XRServer::find_interface);
+ ClassDB::bind_method(D_METHOD("get_tracker_count"), &XRServer::get_tracker_count);
+ ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &XRServer::get_tracker);
- ClassDB::bind_method(D_METHOD("get_primary_interface"), &ARVRServer::get_primary_interface);
- ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &ARVRServer::set_primary_interface);
+ ClassDB::bind_method(D_METHOD("get_primary_interface"), &XRServer::get_primary_interface);
+ ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &XRServer::set_primary_interface);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "primary_interface"), "set_primary_interface", "get_primary_interface");
- ClassDB::bind_method(D_METHOD("get_last_process_usec"), &ARVRServer::get_last_process_usec);
- ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &ARVRServer::get_last_commit_usec);
- ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &ARVRServer::get_last_frame_usec);
+ ClassDB::bind_method(D_METHOD("get_last_process_usec"), &XRServer::get_last_process_usec);
+ ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &XRServer::get_last_commit_usec);
+ ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &XRServer::get_last_frame_usec);
BIND_ENUM_CONSTANT(TRACKER_CONTROLLER);
BIND_ENUM_CONSTANT(TRACKER_BASESTATION);
@@ -82,11 +82,11 @@ void ARVRServer::_bind_methods() {
ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::INT, "id")));
};
-real_t ARVRServer::get_world_scale() const {
+real_t XRServer::get_world_scale() const {
return world_scale;
};
-void ARVRServer::set_world_scale(real_t p_world_scale) {
+void XRServer::set_world_scale(real_t p_world_scale) {
if (p_world_scale < 0.01) {
p_world_scale = 0.01;
} else if (p_world_scale > 1000.0) {
@@ -96,25 +96,25 @@ void ARVRServer::set_world_scale(real_t p_world_scale) {
world_scale = p_world_scale;
};
-Transform ARVRServer::get_world_origin() const {
+Transform XRServer::get_world_origin() const {
return world_origin;
};
-void ARVRServer::set_world_origin(const Transform &p_world_origin) {
+void XRServer::set_world_origin(const Transform &p_world_origin) {
world_origin = p_world_origin;
};
-Transform ARVRServer::get_reference_frame() const {
+Transform XRServer::get_reference_frame() const {
return reference_frame;
};
-void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) {
+void XRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) {
if (primary_interface != nullptr) {
// clear our current reference frame or we'll end up double adjusting it
reference_frame = Transform();
// requesting our EYE_MONO transform should return our current HMD position
- Transform new_reference_frame = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform());
+ Transform new_reference_frame = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform());
// remove our tilt
if (p_rotation_mode == 1) {
@@ -140,15 +140,15 @@ void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height)
};
};
-Transform ARVRServer::get_hmd_transform() {
+Transform XRServer::get_hmd_transform() {
Transform hmd_transform;
if (primary_interface != nullptr) {
- hmd_transform = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, hmd_transform);
+ hmd_transform = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, hmd_transform);
};
return hmd_transform;
};
-void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) {
+void XRServer::add_interface(const Ref<XRInterface> &p_interface) {
ERR_FAIL_COND(p_interface.is_null());
for (int i = 0; i < interfaces.size(); i++) {
@@ -163,7 +163,7 @@ void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) {
emit_signal("interface_added", p_interface->get_name());
};
-void ARVRServer::remove_interface(const Ref<ARVRInterface> &p_interface) {
+void XRServer::remove_interface(const Ref<XRInterface> &p_interface) {
ERR_FAIL_COND(p_interface.is_null());
int idx = -1;
@@ -178,23 +178,23 @@ void ARVRServer::remove_interface(const Ref<ARVRInterface> &p_interface) {
ERR_FAIL_COND(idx == -1);
- print_verbose("ARVR: Removed interface" + p_interface->get_name());
+ print_verbose("XR: Removed interface" + p_interface->get_name());
emit_signal("interface_removed", p_interface->get_name());
interfaces.remove(idx);
};
-int ARVRServer::get_interface_count() const {
+int XRServer::get_interface_count() const {
return interfaces.size();
};
-Ref<ARVRInterface> ARVRServer::get_interface(int p_index) const {
+Ref<XRInterface> XRServer::get_interface(int p_index) const {
ERR_FAIL_INDEX_V(p_index, interfaces.size(), nullptr);
return interfaces[p_index];
};
-Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const {
+Ref<XRInterface> XRServer::find_interface(const String &p_name) const {
int idx = -1;
for (int i = 0; i < interfaces.size(); i++) {
@@ -210,7 +210,7 @@ Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const {
return interfaces[idx];
};
-Array ARVRServer::get_interfaces() const {
+Array XRServer::get_interfaces() const {
Array ret;
for (int i = 0; i < interfaces.size(); i++) {
@@ -238,7 +238,7 @@ Array ARVRServer::get_interfaces() const {
- using this approach the shield disappears or is no longer tracked, but the gun stays firmly in your right hand because that is still controller 2, further more, if controller 1 is replaced the shield will return.
*/
-bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const {
+bool XRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const {
for (int i = 0; i < trackers.size(); i++) {
if (trackers[i]->get_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) {
return true;
@@ -249,13 +249,13 @@ bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p
return false;
};
-int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
+int XRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
// We start checking at 1, 0 means that it's not a controller..
// Note that for controller we reserve:
// - 1 for the left hand controller and
// - 2 for the right hand controller
// so we start at 3 :)
- int tracker_id = p_tracker_type == ARVRServer::TRACKER_CONTROLLER ? 3 : 1;
+ int tracker_id = p_tracker_type == XRServer::TRACKER_CONTROLLER ? 3 : 1;
while (is_tracker_id_in_use_for_type(p_tracker_type, tracker_id)) {
// try the next one
@@ -265,14 +265,14 @@ int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
return tracker_id;
};
-void ARVRServer::add_tracker(ARVRPositionalTracker *p_tracker) {
+void XRServer::add_tracker(XRPositionalTracker *p_tracker) {
ERR_FAIL_NULL(p_tracker);
trackers.push_back(p_tracker);
emit_signal("tracker_added", p_tracker->get_name(), p_tracker->get_type(), p_tracker->get_tracker_id());
};
-void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) {
+void XRServer::remove_tracker(XRPositionalTracker *p_tracker) {
ERR_FAIL_NULL(p_tracker);
int idx = -1;
@@ -291,17 +291,17 @@ void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) {
trackers.remove(idx);
};
-int ARVRServer::get_tracker_count() const {
+int XRServer::get_tracker_count() const {
return trackers.size();
};
-ARVRPositionalTracker *ARVRServer::get_tracker(int p_index) const {
+XRPositionalTracker *XRServer::get_tracker(int p_index) const {
ERR_FAIL_INDEX_V(p_index, trackers.size(), nullptr);
return trackers[p_index];
};
-ARVRPositionalTracker *ARVRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const {
+XRPositionalTracker *XRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const {
ERR_FAIL_COND_V(p_tracker_id == 0, nullptr);
for (int i = 0; i < trackers.size(); i++) {
@@ -313,36 +313,36 @@ ARVRPositionalTracker *ARVRServer::find_by_type_and_id(TrackerType p_tracker_typ
return nullptr;
};
-Ref<ARVRInterface> ARVRServer::get_primary_interface() const {
+Ref<XRInterface> XRServer::get_primary_interface() const {
return primary_interface;
};
-void ARVRServer::set_primary_interface(const Ref<ARVRInterface> &p_primary_interface) {
+void XRServer::set_primary_interface(const Ref<XRInterface> &p_primary_interface) {
primary_interface = p_primary_interface;
- print_verbose("ARVR: Primary interface set to: " + primary_interface->get_name());
+ print_verbose("XR: Primary interface set to: " + primary_interface->get_name());
};
-void ARVRServer::clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_interface) {
+void XRServer::clear_primary_interface_if(const Ref<XRInterface> &p_primary_interface) {
if (primary_interface == p_primary_interface) {
- print_verbose("ARVR: Clearing primary interface");
+ print_verbose("XR: Clearing primary interface");
primary_interface.unref();
};
};
-uint64_t ARVRServer::get_last_process_usec() {
+uint64_t XRServer::get_last_process_usec() {
return last_process_usec;
};
-uint64_t ARVRServer::get_last_commit_usec() {
+uint64_t XRServer::get_last_commit_usec() {
return last_commit_usec;
};
-uint64_t ARVRServer::get_last_frame_usec() {
+uint64_t XRServer::get_last_frame_usec() {
return last_frame_usec;
};
-void ARVRServer::_process() {
+void XRServer::_process() {
/* called from rendering_server_viewport.draw_viewports right before we start drawing our viewports */
/* mark for our frame timing */
@@ -358,7 +358,7 @@ void ARVRServer::_process() {
};
};
-void ARVRServer::_mark_commit() {
+void XRServer::_mark_commit() {
/* time this */
last_commit_usec = OS::get_singleton()->get_ticks_usec();
@@ -366,12 +366,12 @@ void ARVRServer::_mark_commit() {
last_frame_usec = last_commit_usec - last_process_usec;
};
-ARVRServer::ARVRServer() {
+XRServer::XRServer() {
singleton = this;
world_scale = 1.0;
};
-ARVRServer::~ARVRServer() {
+XRServer::~XRServer() {
primary_interface.unref();
while (interfaces.size() > 0) {
diff --git a/servers/arvr_server.h b/servers/xr_server.h
index ab2f0d721b..e04c7b3592 100644
--- a/servers/arvr_server.h
+++ b/servers/xr_server.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_server.h */
+/* xr_server.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARVR_SERVER_H
-#define ARVR_SERVER_H
+#ifndef XR_SERVER_H
+#define XR_SERVER_H
#include "core/os/os.h"
#include "core/os/thread_safe.h"
@@ -37,16 +37,16 @@
#include "core/rid.h"
#include "core/variant.h"
-class ARVRInterface;
-class ARVRPositionalTracker;
+class XRInterface;
+class XRPositionalTracker;
/**
@author Bastiaan Olij <mux213@gmail.com>
- The ARVR server is a singleton object that gives access to the various
+ The XR server is a singleton object that gives access to the various
objects and SDKs that are available on the system.
Because there can be multiple SDKs active this is exposed as an array
- and our ARVR server object acts as a pass through
+ and our XR server object acts as a pass through
Also each positioning tracker is accessible from here.
I've added some additional info into this header file that should move
@@ -54,8 +54,8 @@ class ARVRPositionalTracker;
or as a separate PR once this has been merged into the master branch.
**/
-class ARVRServer : public Object {
- GDCLASS(ARVRServer, Object);
+class XRServer : public Object {
+ GDCLASS(XRServer, Object);
_THREAD_SAFE_CLASS_
public:
@@ -76,10 +76,10 @@ public:
};
private:
- Vector<Ref<ARVRInterface>> interfaces;
- Vector<ARVRPositionalTracker *> trackers;
+ Vector<Ref<XRInterface>> interfaces;
+ Vector<XRPositionalTracker *> trackers;
- Ref<ARVRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */
+ Ref<XRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */
real_t world_scale; /* scale by which we multiply our tracker positions */
Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */
@@ -90,12 +90,12 @@ private:
uint64_t last_frame_usec; /* time it took between process and committing, we should probably average this over the last x frames */
protected:
- static ARVRServer *singleton;
+ static XRServer *singleton;
static void _bind_methods();
public:
- static ARVRServer *get_singleton();
+ static XRServer *get_singleton();
/*
World scale allows you to specify a scale factor that is applied to all positioning vectors in our VR world in essence scaling up, or scaling down the world.
@@ -105,7 +105,7 @@ public:
Most VR platforms, and our assumption, is that 1 unit in our virtual world equates to 1 meter in the real mode.
This scale basically effects the unit size relationship to real world size.
- I may remove access to this property in GDScript in favour of exposing it on the ARVROrigin node
+ I may remove access to this property in GDScript in favour of exposing it on the XROrigin3D node
*/
real_t get_world_scale() const;
void set_world_scale(real_t p_world_scale);
@@ -116,7 +116,7 @@ public:
actions be it straffing, teleporting, etc. Movement of the player by moving through the physical space is always tracked
in relation to this point.
- Note that the ARVROrigin spatial node in your scene automatically updates this property and it should be used instead of
+ Note that the XROrigin3D spatial node in your scene automatically updates this property and it should be used instead of
direct access to this property and it therefore is not available in GDScript
Note: this should not be used in AR and should be ignored by an AR based interface as it would throw what you're looking at in the real world
@@ -146,20 +146,20 @@ public:
/*
Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc.
*/
- void add_interface(const Ref<ARVRInterface> &p_interface);
- void remove_interface(const Ref<ARVRInterface> &p_interface);
+ void add_interface(const Ref<XRInterface> &p_interface);
+ void remove_interface(const Ref<XRInterface> &p_interface);
int get_interface_count() const;
- Ref<ARVRInterface> get_interface(int p_index) const;
- Ref<ARVRInterface> find_interface(const String &p_name) const;
+ Ref<XRInterface> get_interface(int p_index) const;
+ Ref<XRInterface> find_interface(const String &p_name) const;
Array get_interfaces() const;
/*
note, more then one interface can technically be active, especially on mobile, but only one interface is used for
rendering. This interface identifies itself by calling set_primary_interface when it is initialized
*/
- Ref<ARVRInterface> get_primary_interface() const;
- void set_primary_interface(const Ref<ARVRInterface> &p_primary_interface);
- void clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_interface); /* this is automatically called if an interface destructs */
+ Ref<XRInterface> get_primary_interface() const;
+ void set_primary_interface(const Ref<XRInterface> &p_primary_interface);
+ void clear_primary_interface_if(const Ref<XRInterface> &p_primary_interface); /* this is automatically called if an interface destructs */
/*
Our trackers are objects that expose the orientation and position of physical devices such as controller, anchor points, etc.
@@ -167,11 +167,11 @@ public:
*/
bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const;
int get_free_tracker_id_for_type(TrackerType p_tracker_type);
- void add_tracker(ARVRPositionalTracker *p_tracker);
- void remove_tracker(ARVRPositionalTracker *p_tracker);
+ void add_tracker(XRPositionalTracker *p_tracker);
+ void remove_tracker(XRPositionalTracker *p_tracker);
int get_tracker_count() const;
- ARVRPositionalTracker *get_tracker(int p_index) const;
- ARVRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const;
+ XRPositionalTracker *get_tracker(int p_index) const;
+ XRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const;
uint64_t get_last_process_usec();
uint64_t get_last_commit_usec();
@@ -180,13 +180,13 @@ public:
void _process();
void _mark_commit();
- ARVRServer();
- ~ARVRServer();
+ XRServer();
+ ~XRServer();
};
-#define ARVR ARVRServer
+#define XR XRServer
-VARIANT_ENUM_CAST(ARVRServer::TrackerType);
-VARIANT_ENUM_CAST(ARVRServer::RotationMode);
+VARIANT_ENUM_CAST(XRServer::TrackerType);
+VARIANT_ENUM_CAST(XRServer::RotationMode);
#endif
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 95a6902089..3c6885fd1a 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -182,12 +182,14 @@ Patches in the `patches` directory should be re-applied after updates.
## jpeg-compressor
- Upstream: https://github.com/richgel999/jpeg-compressor
-- Version: 1.04
+- Version: 2.00 (1eb17d558b9d3b7442d256642a5745974e9eeb1e, 2020)
- License: Public domain
Files extracted from upstream source:
-- `jpgd.{c,h}`
+- `jpgd*.{c,h}`
+
+Patches in the `patches` directory should be re-applied after updates.
## libogg
@@ -302,7 +304,7 @@ changes are marked with `// -- GODOT --` comments.
## mbedtls
- Upstream: https://tls.mbed.org/
-- Version: 2.16.5
+- Version: 2.16.6
- License: Apache 2.0
File extracted from upstream release tarball (`-apache.tgz` variant):
diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp
index 62fbd1b72d..257d0b7574 100644
--- a/thirdparty/jpeg-compressor/jpgd.cpp
+++ b/thirdparty/jpeg-compressor/jpgd.cpp
@@ -1,27 +1,55 @@
-// jpgd.cpp - C++ class for JPEG decompression.
-// Public domain, Rich Geldreich <richgel99@gmail.com>
+// jpgd.cpp - C++ class for JPEG decompression. Written by Richard Geldreich <richgel99@gmail.com> between 1994-2020.
+// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2.
+// Supports box and linear chroma upsampling.
+//
+// Released under two licenses. You are free to choose which license you want:
+// License 1:
+// Public Domain
+//
+// License 2:
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
// Alex Evans: Linear memory allocator (taken from jpge.h).
-// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings (all looked harmless)
+// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings
+// v2.00, March 20, 2020: Fuzzed with zzuf and afl. Fixed several issues, converted most assert()'s to run-time checks. Added chroma upsampling. Removed freq. domain upsampling. gcc/clang warnings.
//
-// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2.
+// Important:
+// #define JPGD_USE_SSE2 to 0 to completely disable SSE2 usage.
//
-// Chroma upsampling quality: H2V2 is upsampled in the frequency domain, H2V1 and H1V2 are upsampled using point sampling.
-// Chroma upsampling reference: "Fast Scheme for Image Size Change in the Compressed Domain"
-// http://vision.ai.uiuc.edu/~dugad/research/dct/index.html
-
#include "jpgd.h"
#include <string.h>
-
+#include <algorithm>
#include <assert.h>
-#define JPGD_ASSERT(x) assert(x)
#ifdef _MSC_VER
#pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable
#endif
-// Set to 1 to enable freq. domain chroma upsampling on images using H2V2 subsampling (0=faster nearest neighbor sampling).
-// This is slower, but results in higher quality on images with highly saturated colors.
-#define JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING 1
+#ifndef JPGD_USE_SSE2
+
+ #if defined(__GNUC__)
+
+ #if (defined(__x86_64__) || defined(_M_X64))
+ #if defined(__SSE2__)
+ #define JPGD_USE_SSE2 (1)
+ #endif
+ #endif
+
+ #else
+ #define JPGD_USE_SSE2 (1)
+ #endif
+
+#endif
#define JPGD_TRUE (1)
#define JPGD_FALSE (0)
@@ -29,28 +57,28 @@
#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b))
#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b))
-// TODO: Move to header and use these constants when declaring the arrays.
-#define JPGD_HUFF_TREE_MAX_LENGTH 512
-#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256
-
namespace jpgd {
-static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); }
-static inline void jpgd_free(void *p) { free(p); }
+ static inline void* jpgd_malloc(size_t nSize) { return malloc(nSize); }
+ static inline void jpgd_free(void* p) { free(p); }
-// DCT coefficients are stored in this sequence.
-static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 };
+ // DCT coefficients are stored in this sequence.
+ static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 };
-enum JPEG_MARKER
-{
- M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8,
- M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC,
- M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7,
- M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF,
- M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0
-};
+ enum JPEG_MARKER
+ {
+ M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8,
+ M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC,
+ M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7,
+ M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF,
+ M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0
+ };
-enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 };
+ enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 };
+
+#if JPGD_USE_SSE2
+#include "jpgd_idct.h"
+#endif
#define CONST_BITS 13
#define PASS1_BITS 2
@@ -76,3130 +104,3182 @@ enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2,
#define CLAMP(i) ((static_cast<uint>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i))
-// Compiler creates a fast path 1D IDCT for X non-zero columns
-template <int NONZERO_COLS>
-struct Row
-{
- static void idct(int* pTemp, const jpgd_block_t* pSrc)
- {
- // ACCESS_COL() will be optimized at compile time to either an array access, or 0.
- #define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0)
-
- const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6);
-
- const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
- const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
- const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
-
- const int tmp0 = (ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS;
- const int tmp1 = (ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS;
-
- const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
-
- const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1);
-
- const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
- const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
-
- const int az1 = MULTIPLY(bz1, - FIX_0_899976223);
- const int az2 = MULTIPLY(bz2, - FIX_2_562915447);
- const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5;
- const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5;
-
- const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
- const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
- const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
- const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
-
- pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS-PASS1_BITS);
- pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS-PASS1_BITS);
- pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS-PASS1_BITS);
- pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS-PASS1_BITS);
- pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS-PASS1_BITS);
- pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS-PASS1_BITS);
- pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS-PASS1_BITS);
- pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS-PASS1_BITS);
- }
-};
-
-template <>
-struct Row<0>
-{
- static void idct(int* pTemp, const jpgd_block_t* pSrc)
- {
-#ifdef _MSC_VER
- pTemp; pSrc;
+ static inline int left_shifti(int val, uint32_t bits)
+ {
+ return static_cast<int>(static_cast<uint32_t>(val) << bits);
+ }
+
+ // Compiler creates a fast path 1D IDCT for X non-zero columns
+ template <int NONZERO_COLS>
+ struct Row
+ {
+ static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)
+ {
+ // ACCESS_COL() will be optimized at compile time to either an array access, or 0. Good compilers will then optimize out muls against 0.
+#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0)
+
+ const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6);
+
+ const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+ const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);
+ const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+
+ const int tmp0 = left_shifti(ACCESS_COL(0) + ACCESS_COL(4), CONST_BITS);
+ const int tmp1 = left_shifti(ACCESS_COL(0) - ACCESS_COL(4), CONST_BITS);
+
+ const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
+
+ const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1);
+
+ const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
+ const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
+
+ const int az1 = MULTIPLY(bz1, -FIX_0_899976223);
+ const int az2 = MULTIPLY(bz2, -FIX_2_562915447);
+ const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5;
+ const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5;
+
+ const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
+ const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
+ const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
+ const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
+
+ pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS - PASS1_BITS);
+ pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS - PASS1_BITS);
+ pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS - PASS1_BITS);
+ pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS - PASS1_BITS);
+ pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS - PASS1_BITS);
+ pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS - PASS1_BITS);
+ pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS - PASS1_BITS);
+ pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS - PASS1_BITS);
+ }
+ };
+
+ template <>
+ struct Row<0>
+ {
+ static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)
+ {
+ (void)pTemp;
+ (void)pSrc;
+ }
+ };
+
+ template <>
+ struct Row<1>
+ {
+ static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)
+ {
+ const int dcval = left_shifti(pSrc[0], PASS1_BITS);
+
+ pTemp[0] = dcval;
+ pTemp[1] = dcval;
+ pTemp[2] = dcval;
+ pTemp[3] = dcval;
+ pTemp[4] = dcval;
+ pTemp[5] = dcval;
+ pTemp[6] = dcval;
+ pTemp[7] = dcval;
+ }
+ };
+
+ // Compiler creates a fast path 1D IDCT for X non-zero rows
+ template <int NONZERO_ROWS>
+ struct Col
+ {
+ static void idct(uint8* pDst_ptr, const int* pTemp)
+ {
+ // ACCESS_ROW() will be optimized at compile time to either an array access, or 0.
+#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0)
+
+ const int z2 = ACCESS_ROW(2);
+ const int z3 = ACCESS_ROW(6);
+
+ const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+ const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);
+ const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+
+ const int tmp0 = left_shifti(ACCESS_ROW(0) + ACCESS_ROW(4), CONST_BITS);
+ const int tmp1 = left_shifti(ACCESS_ROW(0) - ACCESS_ROW(4), CONST_BITS);
+
+ const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
+
+ const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1);
+
+ const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
+ const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
+
+ const int az1 = MULTIPLY(bz1, -FIX_0_899976223);
+ const int az2 = MULTIPLY(bz2, -FIX_2_562915447);
+ const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5;
+ const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5;
+
+ const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
+ const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
+ const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
+ const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
+
+ int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 0] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 7] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 1] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 6] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 2] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 5] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 3] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 4] = (uint8)CLAMP(i);
+ }
+ };
+
+ template <>
+ struct Col<1>
+ {
+ static void idct(uint8* pDst_ptr, const int* pTemp)
+ {
+ int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS + 3);
+ const uint8 dcval_clamped = (uint8)CLAMP(dcval);
+ pDst_ptr[0 * 8] = dcval_clamped;
+ pDst_ptr[1 * 8] = dcval_clamped;
+ pDst_ptr[2 * 8] = dcval_clamped;
+ pDst_ptr[3 * 8] = dcval_clamped;
+ pDst_ptr[4 * 8] = dcval_clamped;
+ pDst_ptr[5 * 8] = dcval_clamped;
+ pDst_ptr[6 * 8] = dcval_clamped;
+ pDst_ptr[7 * 8] = dcval_clamped;
+ }
+ };
+
+ static const uint8 s_idct_row_table[] =
+ {
+ 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0,
+ 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0,
+ 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0,
+ 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0,
+ 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2,
+ 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2,
+ 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4,
+ 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8,
+ };
+
+ static const uint8 s_idct_col_table[] =
+ {
+ 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
+ };
+
+ // Scalar "fast pathing" IDCT.
+ static void idct(const jpgd_block_coeff_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag, bool use_simd)
+ {
+ (void)use_simd;
+
+ assert(block_max_zag >= 1);
+ assert(block_max_zag <= 64);
+
+ if (block_max_zag <= 1)
+ {
+ int k = ((pSrc_ptr[0] + 4) >> 3) + 128;
+ k = CLAMP(k);
+ k = k | (k << 8);
+ k = k | (k << 16);
+
+ for (int i = 8; i > 0; i--)
+ {
+ *(int*)&pDst_ptr[0] = k;
+ *(int*)&pDst_ptr[4] = k;
+ pDst_ptr += 8;
+ }
+ return;
+ }
+
+#if JPGD_USE_SSE2
+ if (use_simd)
+ {
+ assert((((uintptr_t)pSrc_ptr) & 15) == 0);
+ assert((((uintptr_t)pDst_ptr) & 15) == 0);
+ idctSSEShortU8(pSrc_ptr, pDst_ptr);
+ return;
+ }
#endif
- }
-};
-
-template <>
-struct Row<1>
-{
- static void idct(int* pTemp, const jpgd_block_t* pSrc)
- {
- const int dcval = (pSrc[0] << PASS1_BITS);
-
- pTemp[0] = dcval;
- pTemp[1] = dcval;
- pTemp[2] = dcval;
- pTemp[3] = dcval;
- pTemp[4] = dcval;
- pTemp[5] = dcval;
- pTemp[6] = dcval;
- pTemp[7] = dcval;
- }
-};
-
-// Compiler creates a fast path 1D IDCT for X non-zero rows
-template <int NONZERO_ROWS>
-struct Col
-{
- static void idct(uint8* pDst_ptr, const int* pTemp)
- {
- // ACCESS_ROW() will be optimized at compile time to either an array access, or 0.
- #define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0)
-
- const int z2 = ACCESS_ROW(2);
- const int z3 = ACCESS_ROW(6);
-
- const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
- const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
- const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
-
- const int tmp0 = (ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS;
- const int tmp1 = (ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS;
-
- const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
-
- const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1);
-
- const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
- const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
-
- const int az1 = MULTIPLY(bz1, - FIX_0_899976223);
- const int az2 = MULTIPLY(bz2, - FIX_2_562915447);
- const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5;
- const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5;
-
- const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
- const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
- const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
- const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
-
- int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*0] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*7] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*1] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*6] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*2] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*5] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*3] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*4] = (uint8)CLAMP(i);
- }
-};
-
-template <>
-struct Col<1>
-{
- static void idct(uint8* pDst_ptr, const int* pTemp)
- {
- int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS+3);
- const uint8 dcval_clamped = (uint8)CLAMP(dcval);
- pDst_ptr[0*8] = dcval_clamped;
- pDst_ptr[1*8] = dcval_clamped;
- pDst_ptr[2*8] = dcval_clamped;
- pDst_ptr[3*8] = dcval_clamped;
- pDst_ptr[4*8] = dcval_clamped;
- pDst_ptr[5*8] = dcval_clamped;
- pDst_ptr[6*8] = dcval_clamped;
- pDst_ptr[7*8] = dcval_clamped;
- }
-};
-
-static const uint8 s_idct_row_table[] =
-{
- 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0,
- 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0,
- 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0,
- 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0,
- 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2,
- 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2,
- 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4,
- 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8,
-};
-
-static const uint8 s_idct_col_table[] = { 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
-
-void idct(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag)
-{
- JPGD_ASSERT(block_max_zag >= 1);
- JPGD_ASSERT(block_max_zag <= 64);
-
- if (block_max_zag <= 1)
- {
- int k = ((pSrc_ptr[0] + 4) >> 3) + 128;
- k = CLAMP(k);
- k = k | (k<<8);
- k = k | (k<<16);
-
- for (int i = 8; i > 0; i--)
- {
- *(int*)&pDst_ptr[0] = k;
- *(int*)&pDst_ptr[4] = k;
- pDst_ptr += 8;
- }
- return;
- }
-
- int temp[64];
-
- const jpgd_block_t* pSrc = pSrc_ptr;
- int* pTemp = temp;
-
- const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8];
- int i;
- for (i = 8; i > 0; i--, pRow_tab++)
- {
- switch (*pRow_tab)
- {
- case 0: Row<0>::idct(pTemp, pSrc); break;
- case 1: Row<1>::idct(pTemp, pSrc); break;
- case 2: Row<2>::idct(pTemp, pSrc); break;
- case 3: Row<3>::idct(pTemp, pSrc); break;
- case 4: Row<4>::idct(pTemp, pSrc); break;
- case 5: Row<5>::idct(pTemp, pSrc); break;
- case 6: Row<6>::idct(pTemp, pSrc); break;
- case 7: Row<7>::idct(pTemp, pSrc); break;
- case 8: Row<8>::idct(pTemp, pSrc); break;
- }
-
- pSrc += 8;
- pTemp += 8;
- }
-
- pTemp = temp;
-
- const int nonzero_rows = s_idct_col_table[block_max_zag - 1];
- for (i = 8; i > 0; i--)
- {
- switch (nonzero_rows)
- {
- case 1: Col<1>::idct(pDst_ptr, pTemp); break;
- case 2: Col<2>::idct(pDst_ptr, pTemp); break;
- case 3: Col<3>::idct(pDst_ptr, pTemp); break;
- case 4: Col<4>::idct(pDst_ptr, pTemp); break;
- case 5: Col<5>::idct(pDst_ptr, pTemp); break;
- case 6: Col<6>::idct(pDst_ptr, pTemp); break;
- case 7: Col<7>::idct(pDst_ptr, pTemp); break;
- case 8: Col<8>::idct(pDst_ptr, pTemp); break;
- }
-
- pTemp++;
- pDst_ptr++;
- }
-}
-
-void idct_4x4(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr)
-{
- int temp[64];
- int* pTemp = temp;
- const jpgd_block_t* pSrc = pSrc_ptr;
-
- for (int i = 4; i > 0; i--)
- {
- Row<4>::idct(pTemp, pSrc);
- pSrc += 8;
- pTemp += 8;
- }
-
- pTemp = temp;
- for (int i = 8; i > 0; i--)
- {
- Col<4>::idct(pDst_ptr, pTemp);
- pTemp++;
- pDst_ptr++;
- }
-}
-
-// Retrieve one character from the input stream.
-inline uint jpeg_decoder::get_char()
-{
- // Any bytes remaining in buffer?
- if (!m_in_buf_left)
- {
- // Try to get more bytes.
- prep_in_buffer();
- // Still nothing to get?
- if (!m_in_buf_left)
- {
- // Pad the end of the stream with 0xFF 0xD9 (EOI marker)
- int t = m_tem_flag;
- m_tem_flag ^= 1;
- if (t)
- return 0xD9;
- else
- return 0xFF;
- }
- }
-
- uint c = *m_pIn_buf_ofs++;
- m_in_buf_left--;
-
- return c;
-}
-
-// Same as previous method, except can indicate if the character is a pad character or not.
-inline uint jpeg_decoder::get_char(bool *pPadding_flag)
-{
- if (!m_in_buf_left)
- {
- prep_in_buffer();
- if (!m_in_buf_left)
- {
- *pPadding_flag = true;
- int t = m_tem_flag;
- m_tem_flag ^= 1;
- if (t)
- return 0xD9;
- else
- return 0xFF;
- }
- }
-
- *pPadding_flag = false;
-
- uint c = *m_pIn_buf_ofs++;
- m_in_buf_left--;
-
- return c;
-}
-
-// Inserts a previously retrieved character back into the input buffer.
-inline void jpeg_decoder::stuff_char(uint8 q)
-{
- *(--m_pIn_buf_ofs) = q;
- m_in_buf_left++;
-}
-
-// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered.
-inline uint8 jpeg_decoder::get_octet()
-{
- bool padding_flag;
- int c = get_char(&padding_flag);
-
- if (c == 0xFF)
- {
- if (padding_flag)
- return 0xFF;
-
- c = get_char(&padding_flag);
- if (padding_flag)
- {
- stuff_char(0xFF);
- return 0xFF;
- }
-
- if (c == 0x00)
- return 0xFF;
- else
- {
- stuff_char(static_cast<uint8>(c));
- stuff_char(0xFF);
- return 0xFF;
- }
- }
-
- return static_cast<uint8>(c);
-}
-
-// Retrieves a variable number of bits from the input stream. Does not recognize markers.
-inline uint jpeg_decoder::get_bits(int num_bits)
-{
- if (!num_bits)
- return 0;
-
- uint i = m_bit_buf >> (32 - num_bits);
-
- if ((m_bits_left -= num_bits) <= 0)
- {
- m_bit_buf <<= (num_bits += m_bits_left);
-
- uint c1 = get_char();
- uint c2 = get_char();
- m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2;
-
- m_bit_buf <<= -m_bits_left;
-
- m_bits_left += 16;
-
- JPGD_ASSERT(m_bits_left >= 0);
- }
- else
- m_bit_buf <<= num_bits;
-
- return i;
-}
-
-// Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered.
-inline uint jpeg_decoder::get_bits_no_markers(int num_bits)
-{
- if (!num_bits)
- return 0;
-
- uint i = m_bit_buf >> (32 - num_bits);
-
- if ((m_bits_left -= num_bits) <= 0)
- {
- m_bit_buf <<= (num_bits += m_bits_left);
-
- if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF))
- {
- uint c1 = get_octet();
- uint c2 = get_octet();
- m_bit_buf |= (c1 << 8) | c2;
- }
- else
- {
- m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1];
- m_in_buf_left -= 2;
- m_pIn_buf_ofs += 2;
- }
-
- m_bit_buf <<= -m_bits_left;
-
- m_bits_left += 16;
-
- JPGD_ASSERT(m_bits_left >= 0);
- }
- else
- m_bit_buf <<= num_bits;
-
- return i;
-}
-
-// Decodes a Huffman encoded symbol.
-inline int jpeg_decoder::huff_decode(huff_tables *pH)
-{
- JPGD_ASSERT(pH);
-
- int symbol;
- // Check first 8-bits: do we have a complete symbol?
- if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)
- {
- // Decode more bits, use a tree traversal to find symbol.
- int ofs = 23;
- do
- {
- unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
- JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
- symbol = pH->tree[idx];
- ofs--;
- } while (symbol < 0);
-
- get_bits_no_markers(8 + (23 - ofs));
- }
- else
- {
- JPGD_ASSERT(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
- get_bits_no_markers(pH->code_size[symbol]);
- }
-
- return symbol;
-}
-
-// Decodes a Huffman encoded symbol.
-inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits)
-{
- int symbol;
-
- JPGD_ASSERT(pH);
-
- // Check first 8-bits: do we have a complete symbol?
- if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)
- {
- // Use a tree traversal to find symbol.
- int ofs = 23;
- do
- {
- unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
- JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
- symbol = pH->tree[idx];
- ofs--;
- } while (symbol < 0);
-
- get_bits_no_markers(8 + (23 - ofs));
-
- extra_bits = get_bits_no_markers(symbol & 0xF);
- }
- else
- {
- JPGD_ASSERT(((symbol >> 8) & 31) == pH->code_size[symbol & 255] + ((symbol & 0x8000) ? (symbol & 15) : 0));
-
- if (symbol & 0x8000)
- {
- get_bits_no_markers((symbol >> 8) & 31);
- extra_bits = symbol >> 16;
- }
- else
- {
- int code_size = (symbol >> 8) & 31;
- int num_extra_bits = symbol & 0xF;
- int bits = code_size + num_extra_bits;
- if (bits <= (m_bits_left + 16))
- extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1);
- else
- {
- get_bits_no_markers(code_size);
- extra_bits = get_bits_no_markers(num_extra_bits);
- }
- }
-
- symbol &= 0xFF;
- }
-
- return symbol;
-}
-
-// Tables and macro used to fully decode the DPCM differences.
-static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
-static const int s_extend_offset[16] = { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
-static const int s_extend_mask[] = { 0, (1<<0), (1<<1), (1<<2), (1<<3), (1<<4), (1<<5), (1<<6), (1<<7), (1<<8), (1<<9), (1<<10), (1<<11), (1<<12), (1<<13), (1<<14), (1<<15), (1<<16) };
-// The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this)
+
+ int temp[64];
+
+ const jpgd_block_coeff_t* pSrc = pSrc_ptr;
+ int* pTemp = temp;
+
+ const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8];
+ int i;
+ for (i = 8; i > 0; i--, pRow_tab++)
+ {
+ switch (*pRow_tab)
+ {
+ case 0: Row<0>::idct(pTemp, pSrc); break;
+ case 1: Row<1>::idct(pTemp, pSrc); break;
+ case 2: Row<2>::idct(pTemp, pSrc); break;
+ case 3: Row<3>::idct(pTemp, pSrc); break;
+ case 4: Row<4>::idct(pTemp, pSrc); break;
+ case 5: Row<5>::idct(pTemp, pSrc); break;
+ case 6: Row<6>::idct(pTemp, pSrc); break;
+ case 7: Row<7>::idct(pTemp, pSrc); break;
+ case 8: Row<8>::idct(pTemp, pSrc); break;
+ }
+
+ pSrc += 8;
+ pTemp += 8;
+ }
+
+ pTemp = temp;
+
+ const int nonzero_rows = s_idct_col_table[block_max_zag - 1];
+ for (i = 8; i > 0; i--)
+ {
+ switch (nonzero_rows)
+ {
+ case 1: Col<1>::idct(pDst_ptr, pTemp); break;
+ case 2: Col<2>::idct(pDst_ptr, pTemp); break;
+ case 3: Col<3>::idct(pDst_ptr, pTemp); break;
+ case 4: Col<4>::idct(pDst_ptr, pTemp); break;
+ case 5: Col<5>::idct(pDst_ptr, pTemp); break;
+ case 6: Col<6>::idct(pDst_ptr, pTemp); break;
+ case 7: Col<7>::idct(pDst_ptr, pTemp); break;
+ case 8: Col<8>::idct(pDst_ptr, pTemp); break;
+ }
+
+ pTemp++;
+ pDst_ptr++;
+ }
+ }
+
+ // Retrieve one character from the input stream.
+ inline uint jpeg_decoder::get_char()
+ {
+ // Any bytes remaining in buffer?
+ if (!m_in_buf_left)
+ {
+ // Try to get more bytes.
+ prep_in_buffer();
+ // Still nothing to get?
+ if (!m_in_buf_left)
+ {
+ // Pad the end of the stream with 0xFF 0xD9 (EOI marker)
+ int t = m_tem_flag;
+ m_tem_flag ^= 1;
+ if (t)
+ return 0xD9;
+ else
+ return 0xFF;
+ }
+ }
+
+ uint c = *m_pIn_buf_ofs++;
+ m_in_buf_left--;
+
+ return c;
+ }
+
+ // Same as previous method, except can indicate if the character is a pad character or not.
+ inline uint jpeg_decoder::get_char(bool* pPadding_flag)
+ {
+ if (!m_in_buf_left)
+ {
+ prep_in_buffer();
+ if (!m_in_buf_left)
+ {
+ *pPadding_flag = true;
+ int t = m_tem_flag;
+ m_tem_flag ^= 1;
+ if (t)
+ return 0xD9;
+ else
+ return 0xFF;
+ }
+ }
+
+ *pPadding_flag = false;
+
+ uint c = *m_pIn_buf_ofs++;
+ m_in_buf_left--;
+
+ return c;
+ }
+
+ // Inserts a previously retrieved character back into the input buffer.
+ inline void jpeg_decoder::stuff_char(uint8 q)
+ {
+ // This could write before the input buffer, but we've placed another array there.
+ *(--m_pIn_buf_ofs) = q;
+ m_in_buf_left++;
+ }
+
+ // Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered.
+ inline uint8 jpeg_decoder::get_octet()
+ {
+ bool padding_flag;
+ int c = get_char(&padding_flag);
+
+ if (c == 0xFF)
+ {
+ if (padding_flag)
+ return 0xFF;
+
+ c = get_char(&padding_flag);
+ if (padding_flag)
+ {
+ stuff_char(0xFF);
+ return 0xFF;
+ }
+
+ if (c == 0x00)
+ return 0xFF;
+ else
+ {
+ stuff_char(static_cast<uint8>(c));
+ stuff_char(0xFF);
+ return 0xFF;
+ }
+ }
+
+ return static_cast<uint8>(c);
+ }
+
+ // Retrieves a variable number of bits from the input stream. Does not recognize markers.
+ inline uint jpeg_decoder::get_bits(int num_bits)
+ {
+ if (!num_bits)
+ return 0;
+
+ uint i = m_bit_buf >> (32 - num_bits);
+
+ if ((m_bits_left -= num_bits) <= 0)
+ {
+ m_bit_buf <<= (num_bits += m_bits_left);
+
+ uint c1 = get_char();
+ uint c2 = get_char();
+ m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2;
+
+ m_bit_buf <<= -m_bits_left;
+
+ m_bits_left += 16;
+
+ assert(m_bits_left >= 0);
+ }
+ else
+ m_bit_buf <<= num_bits;
+
+ return i;
+ }
+
+ // Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered.
+ inline uint jpeg_decoder::get_bits_no_markers(int num_bits)
+ {
+ if (!num_bits)
+ return 0;
+
+ assert(num_bits <= 16);
+
+ uint i = m_bit_buf >> (32 - num_bits);
+
+ if ((m_bits_left -= num_bits) <= 0)
+ {
+ m_bit_buf <<= (num_bits += m_bits_left);
+
+ if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF))
+ {
+ uint c1 = get_octet();
+ uint c2 = get_octet();
+ m_bit_buf |= (c1 << 8) | c2;
+ }
+ else
+ {
+ m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1];
+ m_in_buf_left -= 2;
+ m_pIn_buf_ofs += 2;
+ }
+
+ m_bit_buf <<= -m_bits_left;
+
+ m_bits_left += 16;
+
+ assert(m_bits_left >= 0);
+ }
+ else
+ m_bit_buf <<= num_bits;
+
+ return i;
+ }
+
+ // Decodes a Huffman encoded symbol.
+ inline int jpeg_decoder::huff_decode(huff_tables* pH)
+ {
+ if (!pH)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ int symbol;
+ // Check first 8-bits: do we have a complete symbol?
+ if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)
+ {
+ // Decode more bits, use a tree traversal to find symbol.
+ int ofs = 23;
+ do
+ {
+ unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+
+ // This should never happen, but to be safe I'm turning these asserts into a run-time check.
+ if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0))
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ symbol = pH->tree[idx];
+ ofs--;
+ } while (symbol < 0);
+
+ get_bits_no_markers(8 + (23 - ofs));
+ }
+ else
+ {
+ assert(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
+ get_bits_no_markers(pH->code_size[symbol]);
+ }
+
+ return symbol;
+ }
+
+ // Decodes a Huffman encoded symbol.
+ inline int jpeg_decoder::huff_decode(huff_tables* pH, int& extra_bits)
+ {
+ int symbol;
+
+ if (!pH)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ // Check first 8-bits: do we have a complete symbol?
+ if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)
+ {
+ // Use a tree traversal to find symbol.
+ int ofs = 23;
+ do
+ {
+ unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+
+ // This should never happen, but to be safe I'm turning these asserts into a run-time check.
+ if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0))
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ symbol = pH->tree[idx];
+ ofs--;
+ } while (symbol < 0);
+
+ get_bits_no_markers(8 + (23 - ofs));
+
+ extra_bits = get_bits_no_markers(symbol & 0xF);
+ }
+ else
+ {
+ if (symbol & 0x8000)
+ {
+ //get_bits_no_markers((symbol >> 8) & 31);
+ assert(((symbol >> 8) & 31) <= 15);
+ get_bits_no_markers((symbol >> 8) & 15);
+ extra_bits = symbol >> 16;
+ }
+ else
+ {
+ int code_size = (symbol >> 8) & 31;
+ int num_extra_bits = symbol & 0xF;
+ int bits = code_size + num_extra_bits;
+
+ if (bits <= 16)
+ extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1);
+ else
+ {
+ get_bits_no_markers(code_size);
+ extra_bits = get_bits_no_markers(num_extra_bits);
+ }
+ }
+
+ symbol &= 0xFF;
+ }
+
+ return symbol;
+ }
+
+ // Tables and macro used to fully decode the DPCM differences.
+ static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
+ static const int s_extend_offset[16] = { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 };
+ //static const int s_extend_mask[] = { 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16) };
+
#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x))
-// Clamps a value between 0-255.
-inline uint8 jpeg_decoder::clamp(int i)
-{
- if (static_cast<uint>(i) > 255)
- i = (((~i) >> 31) & 0xFF);
-
- return static_cast<uint8>(i);
-}
-
-namespace DCT_Upsample
-{
- struct Matrix44
- {
- typedef int Element_Type;
- enum { NUM_ROWS = 4, NUM_COLS = 4 };
-
- Element_Type v[NUM_ROWS][NUM_COLS];
-
- inline int rows() const { return NUM_ROWS; }
- inline int cols() const { return NUM_COLS; }
-
- inline const Element_Type & at(int r, int c) const { return v[r][c]; }
- inline Element_Type & at(int r, int c) { return v[r][c]; }
-
- inline Matrix44() { }
-
- inline Matrix44& operator += (const Matrix44& a)
- {
- for (int r = 0; r < NUM_ROWS; r++)
- {
- at(r, 0) += a.at(r, 0);
- at(r, 1) += a.at(r, 1);
- at(r, 2) += a.at(r, 2);
- at(r, 3) += a.at(r, 3);
- }
- return *this;
- }
-
- inline Matrix44& operator -= (const Matrix44& a)
- {
- for (int r = 0; r < NUM_ROWS; r++)
- {
- at(r, 0) -= a.at(r, 0);
- at(r, 1) -= a.at(r, 1);
- at(r, 2) -= a.at(r, 2);
- at(r, 3) -= a.at(r, 3);
- }
- return *this;
- }
-
- friend inline Matrix44 operator + (const Matrix44& a, const Matrix44& b)
- {
- Matrix44 ret;
- for (int r = 0; r < NUM_ROWS; r++)
- {
- ret.at(r, 0) = a.at(r, 0) + b.at(r, 0);
- ret.at(r, 1) = a.at(r, 1) + b.at(r, 1);
- ret.at(r, 2) = a.at(r, 2) + b.at(r, 2);
- ret.at(r, 3) = a.at(r, 3) + b.at(r, 3);
- }
- return ret;
- }
-
- friend inline Matrix44 operator - (const Matrix44& a, const Matrix44& b)
- {
- Matrix44 ret;
- for (int r = 0; r < NUM_ROWS; r++)
- {
- ret.at(r, 0) = a.at(r, 0) - b.at(r, 0);
- ret.at(r, 1) = a.at(r, 1) - b.at(r, 1);
- ret.at(r, 2) = a.at(r, 2) - b.at(r, 2);
- ret.at(r, 3) = a.at(r, 3) - b.at(r, 3);
- }
- return ret;
- }
-
- static inline void add_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b)
- {
- for (int r = 0; r < 4; r++)
- {
- pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) + b.at(r, 0));
- pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) + b.at(r, 1));
- pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) + b.at(r, 2));
- pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) + b.at(r, 3));
- }
- }
-
- static inline void sub_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b)
- {
- for (int r = 0; r < 4; r++)
- {
- pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) - b.at(r, 0));
- pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) - b.at(r, 1));
- pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) - b.at(r, 2));
- pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) - b.at(r, 3));
- }
- }
- };
-
- const int FRACT_BITS = 10;
- const int SCALE = 1 << FRACT_BITS;
-
- typedef int Temp_Type;
- #define D(i) (((i) + (SCALE >> 1)) >> FRACT_BITS)
- #define F(i) ((int)((i) * SCALE + .5f))
-
- // Any decent C++ compiler will optimize this at compile time to a 0, or an array access.
- #define AT(c, r) ((((c)>=NUM_COLS)||((r)>=NUM_ROWS)) ? 0 : pSrc[(c)+(r)*8])
-
- // NUM_ROWS/NUM_COLS = # of non-zero rows/cols in input matrix
- template<int NUM_ROWS, int NUM_COLS>
- struct P_Q
- {
- static void calc(Matrix44& P, Matrix44& Q, const jpgd_block_t* pSrc)
- {
- // 4x8 = 4x8 times 8x8, matrix 0 is constant
- const Temp_Type X000 = AT(0, 0);
- const Temp_Type X001 = AT(0, 1);
- const Temp_Type X002 = AT(0, 2);
- const Temp_Type X003 = AT(0, 3);
- const Temp_Type X004 = AT(0, 4);
- const Temp_Type X005 = AT(0, 5);
- const Temp_Type X006 = AT(0, 6);
- const Temp_Type X007 = AT(0, 7);
- const Temp_Type X010 = D(F(0.415735f) * AT(1, 0) + F(0.791065f) * AT(3, 0) + F(-0.352443f) * AT(5, 0) + F(0.277785f) * AT(7, 0));
- const Temp_Type X011 = D(F(0.415735f) * AT(1, 1) + F(0.791065f) * AT(3, 1) + F(-0.352443f) * AT(5, 1) + F(0.277785f) * AT(7, 1));
- const Temp_Type X012 = D(F(0.415735f) * AT(1, 2) + F(0.791065f) * AT(3, 2) + F(-0.352443f) * AT(5, 2) + F(0.277785f) * AT(7, 2));
- const Temp_Type X013 = D(F(0.415735f) * AT(1, 3) + F(0.791065f) * AT(3, 3) + F(-0.352443f) * AT(5, 3) + F(0.277785f) * AT(7, 3));
- const Temp_Type X014 = D(F(0.415735f) * AT(1, 4) + F(0.791065f) * AT(3, 4) + F(-0.352443f) * AT(5, 4) + F(0.277785f) * AT(7, 4));
- const Temp_Type X015 = D(F(0.415735f) * AT(1, 5) + F(0.791065f) * AT(3, 5) + F(-0.352443f) * AT(5, 5) + F(0.277785f) * AT(7, 5));
- const Temp_Type X016 = D(F(0.415735f) * AT(1, 6) + F(0.791065f) * AT(3, 6) + F(-0.352443f) * AT(5, 6) + F(0.277785f) * AT(7, 6));
- const Temp_Type X017 = D(F(0.415735f) * AT(1, 7) + F(0.791065f) * AT(3, 7) + F(-0.352443f) * AT(5, 7) + F(0.277785f) * AT(7, 7));
- const Temp_Type X020 = AT(4, 0);
- const Temp_Type X021 = AT(4, 1);
- const Temp_Type X022 = AT(4, 2);
- const Temp_Type X023 = AT(4, 3);
- const Temp_Type X024 = AT(4, 4);
- const Temp_Type X025 = AT(4, 5);
- const Temp_Type X026 = AT(4, 6);
- const Temp_Type X027 = AT(4, 7);
- const Temp_Type X030 = D(F(0.022887f) * AT(1, 0) + F(-0.097545f) * AT(3, 0) + F(0.490393f) * AT(5, 0) + F(0.865723f) * AT(7, 0));
- const Temp_Type X031 = D(F(0.022887f) * AT(1, 1) + F(-0.097545f) * AT(3, 1) + F(0.490393f) * AT(5, 1) + F(0.865723f) * AT(7, 1));
- const Temp_Type X032 = D(F(0.022887f) * AT(1, 2) + F(-0.097545f) * AT(3, 2) + F(0.490393f) * AT(5, 2) + F(0.865723f) * AT(7, 2));
- const Temp_Type X033 = D(F(0.022887f) * AT(1, 3) + F(-0.097545f) * AT(3, 3) + F(0.490393f) * AT(5, 3) + F(0.865723f) * AT(7, 3));
- const Temp_Type X034 = D(F(0.022887f) * AT(1, 4) + F(-0.097545f) * AT(3, 4) + F(0.490393f) * AT(5, 4) + F(0.865723f) * AT(7, 4));
- const Temp_Type X035 = D(F(0.022887f) * AT(1, 5) + F(-0.097545f) * AT(3, 5) + F(0.490393f) * AT(5, 5) + F(0.865723f) * AT(7, 5));
- const Temp_Type X036 = D(F(0.022887f) * AT(1, 6) + F(-0.097545f) * AT(3, 6) + F(0.490393f) * AT(5, 6) + F(0.865723f) * AT(7, 6));
- const Temp_Type X037 = D(F(0.022887f) * AT(1, 7) + F(-0.097545f) * AT(3, 7) + F(0.490393f) * AT(5, 7) + F(0.865723f) * AT(7, 7));
-
- // 4x4 = 4x8 times 8x4, matrix 1 is constant
- P.at(0, 0) = X000;
- P.at(0, 1) = D(X001 * F(0.415735f) + X003 * F(0.791065f) + X005 * F(-0.352443f) + X007 * F(0.277785f));
- P.at(0, 2) = X004;
- P.at(0, 3) = D(X001 * F(0.022887f) + X003 * F(-0.097545f) + X005 * F(0.490393f) + X007 * F(0.865723f));
- P.at(1, 0) = X010;
- P.at(1, 1) = D(X011 * F(0.415735f) + X013 * F(0.791065f) + X015 * F(-0.352443f) + X017 * F(0.277785f));
- P.at(1, 2) = X014;
- P.at(1, 3) = D(X011 * F(0.022887f) + X013 * F(-0.097545f) + X015 * F(0.490393f) + X017 * F(0.865723f));
- P.at(2, 0) = X020;
- P.at(2, 1) = D(X021 * F(0.415735f) + X023 * F(0.791065f) + X025 * F(-0.352443f) + X027 * F(0.277785f));
- P.at(2, 2) = X024;
- P.at(2, 3) = D(X021 * F(0.022887f) + X023 * F(-0.097545f) + X025 * F(0.490393f) + X027 * F(0.865723f));
- P.at(3, 0) = X030;
- P.at(3, 1) = D(X031 * F(0.415735f) + X033 * F(0.791065f) + X035 * F(-0.352443f) + X037 * F(0.277785f));
- P.at(3, 2) = X034;
- P.at(3, 3) = D(X031 * F(0.022887f) + X033 * F(-0.097545f) + X035 * F(0.490393f) + X037 * F(0.865723f));
- // 40 muls 24 adds
-
- // 4x4 = 4x8 times 8x4, matrix 1 is constant
- Q.at(0, 0) = D(X001 * F(0.906127f) + X003 * F(-0.318190f) + X005 * F(0.212608f) + X007 * F(-0.180240f));
- Q.at(0, 1) = X002;
- Q.at(0, 2) = D(X001 * F(-0.074658f) + X003 * F(0.513280f) + X005 * F(0.768178f) + X007 * F(-0.375330f));
- Q.at(0, 3) = X006;
- Q.at(1, 0) = D(X011 * F(0.906127f) + X013 * F(-0.318190f) + X015 * F(0.212608f) + X017 * F(-0.180240f));
- Q.at(1, 1) = X012;
- Q.at(1, 2) = D(X011 * F(-0.074658f) + X013 * F(0.513280f) + X015 * F(0.768178f) + X017 * F(-0.375330f));
- Q.at(1, 3) = X016;
- Q.at(2, 0) = D(X021 * F(0.906127f) + X023 * F(-0.318190f) + X025 * F(0.212608f) + X027 * F(-0.180240f));
- Q.at(2, 1) = X022;
- Q.at(2, 2) = D(X021 * F(-0.074658f) + X023 * F(0.513280f) + X025 * F(0.768178f) + X027 * F(-0.375330f));
- Q.at(2, 3) = X026;
- Q.at(3, 0) = D(X031 * F(0.906127f) + X033 * F(-0.318190f) + X035 * F(0.212608f) + X037 * F(-0.180240f));
- Q.at(3, 1) = X032;
- Q.at(3, 2) = D(X031 * F(-0.074658f) + X033 * F(0.513280f) + X035 * F(0.768178f) + X037 * F(-0.375330f));
- Q.at(3, 3) = X036;
- // 40 muls 24 adds
- }
- };
-
- template<int NUM_ROWS, int NUM_COLS>
- struct R_S
- {
- static void calc(Matrix44& R, Matrix44& S, const jpgd_block_t* pSrc)
- {
- // 4x8 = 4x8 times 8x8, matrix 0 is constant
- const Temp_Type X100 = D(F(0.906127f) * AT(1, 0) + F(-0.318190f) * AT(3, 0) + F(0.212608f) * AT(5, 0) + F(-0.180240f) * AT(7, 0));
- const Temp_Type X101 = D(F(0.906127f) * AT(1, 1) + F(-0.318190f) * AT(3, 1) + F(0.212608f) * AT(5, 1) + F(-0.180240f) * AT(7, 1));
- const Temp_Type X102 = D(F(0.906127f) * AT(1, 2) + F(-0.318190f) * AT(3, 2) + F(0.212608f) * AT(5, 2) + F(-0.180240f) * AT(7, 2));
- const Temp_Type X103 = D(F(0.906127f) * AT(1, 3) + F(-0.318190f) * AT(3, 3) + F(0.212608f) * AT(5, 3) + F(-0.180240f) * AT(7, 3));
- const Temp_Type X104 = D(F(0.906127f) * AT(1, 4) + F(-0.318190f) * AT(3, 4) + F(0.212608f) * AT(5, 4) + F(-0.180240f) * AT(7, 4));
- const Temp_Type X105 = D(F(0.906127f) * AT(1, 5) + F(-0.318190f) * AT(3, 5) + F(0.212608f) * AT(5, 5) + F(-0.180240f) * AT(7, 5));
- const Temp_Type X106 = D(F(0.906127f) * AT(1, 6) + F(-0.318190f) * AT(3, 6) + F(0.212608f) * AT(5, 6) + F(-0.180240f) * AT(7, 6));
- const Temp_Type X107 = D(F(0.906127f) * AT(1, 7) + F(-0.318190f) * AT(3, 7) + F(0.212608f) * AT(5, 7) + F(-0.180240f) * AT(7, 7));
- const Temp_Type X110 = AT(2, 0);
- const Temp_Type X111 = AT(2, 1);
- const Temp_Type X112 = AT(2, 2);
- const Temp_Type X113 = AT(2, 3);
- const Temp_Type X114 = AT(2, 4);
- const Temp_Type X115 = AT(2, 5);
- const Temp_Type X116 = AT(2, 6);
- const Temp_Type X117 = AT(2, 7);
- const Temp_Type X120 = D(F(-0.074658f) * AT(1, 0) + F(0.513280f) * AT(3, 0) + F(0.768178f) * AT(5, 0) + F(-0.375330f) * AT(7, 0));
- const Temp_Type X121 = D(F(-0.074658f) * AT(1, 1) + F(0.513280f) * AT(3, 1) + F(0.768178f) * AT(5, 1) + F(-0.375330f) * AT(7, 1));
- const Temp_Type X122 = D(F(-0.074658f) * AT(1, 2) + F(0.513280f) * AT(3, 2) + F(0.768178f) * AT(5, 2) + F(-0.375330f) * AT(7, 2));
- const Temp_Type X123 = D(F(-0.074658f) * AT(1, 3) + F(0.513280f) * AT(3, 3) + F(0.768178f) * AT(5, 3) + F(-0.375330f) * AT(7, 3));
- const Temp_Type X124 = D(F(-0.074658f) * AT(1, 4) + F(0.513280f) * AT(3, 4) + F(0.768178f) * AT(5, 4) + F(-0.375330f) * AT(7, 4));
- const Temp_Type X125 = D(F(-0.074658f) * AT(1, 5) + F(0.513280f) * AT(3, 5) + F(0.768178f) * AT(5, 5) + F(-0.375330f) * AT(7, 5));
- const Temp_Type X126 = D(F(-0.074658f) * AT(1, 6) + F(0.513280f) * AT(3, 6) + F(0.768178f) * AT(5, 6) + F(-0.375330f) * AT(7, 6));
- const Temp_Type X127 = D(F(-0.074658f) * AT(1, 7) + F(0.513280f) * AT(3, 7) + F(0.768178f) * AT(5, 7) + F(-0.375330f) * AT(7, 7));
- const Temp_Type X130 = AT(6, 0);
- const Temp_Type X131 = AT(6, 1);
- const Temp_Type X132 = AT(6, 2);
- const Temp_Type X133 = AT(6, 3);
- const Temp_Type X134 = AT(6, 4);
- const Temp_Type X135 = AT(6, 5);
- const Temp_Type X136 = AT(6, 6);
- const Temp_Type X137 = AT(6, 7);
- // 80 muls 48 adds
-
- // 4x4 = 4x8 times 8x4, matrix 1 is constant
- R.at(0, 0) = X100;
- R.at(0, 1) = D(X101 * F(0.415735f) + X103 * F(0.791065f) + X105 * F(-0.352443f) + X107 * F(0.277785f));
- R.at(0, 2) = X104;
- R.at(0, 3) = D(X101 * F(0.022887f) + X103 * F(-0.097545f) + X105 * F(0.490393f) + X107 * F(0.865723f));
- R.at(1, 0) = X110;
- R.at(1, 1) = D(X111 * F(0.415735f) + X113 * F(0.791065f) + X115 * F(-0.352443f) + X117 * F(0.277785f));
- R.at(1, 2) = X114;
- R.at(1, 3) = D(X111 * F(0.022887f) + X113 * F(-0.097545f) + X115 * F(0.490393f) + X117 * F(0.865723f));
- R.at(2, 0) = X120;
- R.at(2, 1) = D(X121 * F(0.415735f) + X123 * F(0.791065f) + X125 * F(-0.352443f) + X127 * F(0.277785f));
- R.at(2, 2) = X124;
- R.at(2, 3) = D(X121 * F(0.022887f) + X123 * F(-0.097545f) + X125 * F(0.490393f) + X127 * F(0.865723f));
- R.at(3, 0) = X130;
- R.at(3, 1) = D(X131 * F(0.415735f) + X133 * F(0.791065f) + X135 * F(-0.352443f) + X137 * F(0.277785f));
- R.at(3, 2) = X134;
- R.at(3, 3) = D(X131 * F(0.022887f) + X133 * F(-0.097545f) + X135 * F(0.490393f) + X137 * F(0.865723f));
- // 40 muls 24 adds
- // 4x4 = 4x8 times 8x4, matrix 1 is constant
- S.at(0, 0) = D(X101 * F(0.906127f) + X103 * F(-0.318190f) + X105 * F(0.212608f) + X107 * F(-0.180240f));
- S.at(0, 1) = X102;
- S.at(0, 2) = D(X101 * F(-0.074658f) + X103 * F(0.513280f) + X105 * F(0.768178f) + X107 * F(-0.375330f));
- S.at(0, 3) = X106;
- S.at(1, 0) = D(X111 * F(0.906127f) + X113 * F(-0.318190f) + X115 * F(0.212608f) + X117 * F(-0.180240f));
- S.at(1, 1) = X112;
- S.at(1, 2) = D(X111 * F(-0.074658f) + X113 * F(0.513280f) + X115 * F(0.768178f) + X117 * F(-0.375330f));
- S.at(1, 3) = X116;
- S.at(2, 0) = D(X121 * F(0.906127f) + X123 * F(-0.318190f) + X125 * F(0.212608f) + X127 * F(-0.180240f));
- S.at(2, 1) = X122;
- S.at(2, 2) = D(X121 * F(-0.074658f) + X123 * F(0.513280f) + X125 * F(0.768178f) + X127 * F(-0.375330f));
- S.at(2, 3) = X126;
- S.at(3, 0) = D(X131 * F(0.906127f) + X133 * F(-0.318190f) + X135 * F(0.212608f) + X137 * F(-0.180240f));
- S.at(3, 1) = X132;
- S.at(3, 2) = D(X131 * F(-0.074658f) + X133 * F(0.513280f) + X135 * F(0.768178f) + X137 * F(-0.375330f));
- S.at(3, 3) = X136;
- // 40 muls 24 adds
- }
- };
-} // end namespace DCT_Upsample
-
-// Unconditionally frees all allocated m_blocks.
-void jpeg_decoder::free_all_blocks()
-{
- m_pStream = NULL;
- for (mem_block *b = m_pMem_blocks; b; )
- {
- mem_block *n = b->m_pNext;
- jpgd_free(b);
- b = n;
- }
- m_pMem_blocks = NULL;
-}
-
-// This method handles all errors. It will never return.
-// It could easily be changed to use C++ exceptions.
-JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status)
-{
- m_error_code = status;
- free_all_blocks();
- longjmp(m_jmp_state, status);
-}
-
-void *jpeg_decoder::alloc(size_t nSize, bool zero)
-{
- nSize = (JPGD_MAX(nSize, 1) + 3) & ~3;
- char *rv = NULL;
- for (mem_block *b = m_pMem_blocks; b; b = b->m_pNext)
- {
- if ((b->m_used_count + nSize) <= b->m_size)
- {
- rv = b->m_data + b->m_used_count;
- b->m_used_count += nSize;
- break;
- }
- }
- if (!rv)
- {
- int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047);
- mem_block *b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity);
- if (!b) { stop_decoding(JPGD_NOTENOUGHMEM); }
- b->m_pNext = m_pMem_blocks; m_pMem_blocks = b;
- b->m_used_count = nSize;
- b->m_size = capacity;
- rv = b->m_data;
- }
- if (zero) memset(rv, 0, nSize);
- return rv;
-}
-
-void jpeg_decoder::word_clear(void *p, uint16 c, uint n)
-{
- uint8 *pD = (uint8*)p;
- const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF;
- while (n)
- {
- pD[0] = l; pD[1] = h; pD += 2;
- n--;
- }
-}
-
-// Refill the input buffer.
-// This method will sit in a loop until (A) the buffer is full or (B)
-// the stream's read() method reports and end of file condition.
-void jpeg_decoder::prep_in_buffer()
-{
- m_in_buf_left = 0;
- m_pIn_buf_ofs = m_in_buf;
-
- if (m_eof_flag)
- return;
-
- do
- {
- int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag);
- if (bytes_read == -1)
- stop_decoding(JPGD_STREAM_READ);
-
- m_in_buf_left += bytes_read;
- } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag));
-
- m_total_bytes_read += m_in_buf_left;
-
- // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid).
- // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.)
- word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64);
-}
-
-// Read a Huffman code table.
-void jpeg_decoder::read_dht_marker()
-{
- int i, index, count;
- uint8 huff_num[17];
- uint8 huff_val[256];
-
- uint num_left = get_bits(16);
-
- if (num_left < 2)
- stop_decoding(JPGD_BAD_DHT_MARKER);
-
- num_left -= 2;
-
- while (num_left)
- {
- index = get_bits(8);
-
- huff_num[0] = 0;
-
- count = 0;
-
- for (i = 1; i <= 16; i++)
- {
- huff_num[i] = static_cast<uint8>(get_bits(8));
- count += huff_num[i];
- }
-
- if (count > 255)
- stop_decoding(JPGD_BAD_DHT_COUNTS);
-
- for (i = 0; i < count; i++)
- huff_val[i] = static_cast<uint8>(get_bits(8));
+ // Unconditionally frees all allocated m_blocks.
+ void jpeg_decoder::free_all_blocks()
+ {
+ m_pStream = nullptr;
+ for (mem_block* b = m_pMem_blocks; b; )
+ {
+ mem_block* n = b->m_pNext;
+ jpgd_free(b);
+ b = n;
+ }
+ m_pMem_blocks = nullptr;
+ }
+
+ // This method handles all errors. It will never return.
+ // It could easily be changed to use C++ exceptions.
+ JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status)
+ {
+ m_error_code = status;
+ free_all_blocks();
+ longjmp(m_jmp_state, status);
+ }
+
+ void* jpeg_decoder::alloc(size_t nSize, bool zero)
+ {
+ nSize = (JPGD_MAX(nSize, 1) + 3) & ~3;
+ char* rv = nullptr;
+ for (mem_block* b = m_pMem_blocks; b; b = b->m_pNext)
+ {
+ if ((b->m_used_count + nSize) <= b->m_size)
+ {
+ rv = b->m_data + b->m_used_count;
+ b->m_used_count += nSize;
+ break;
+ }
+ }
+ if (!rv)
+ {
+ int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047);
+ mem_block* b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity);
+ if (!b)
+ {
+ stop_decoding(JPGD_NOTENOUGHMEM);
+ }
+
+ b->m_pNext = m_pMem_blocks;
+ m_pMem_blocks = b;
+ b->m_used_count = nSize;
+ b->m_size = capacity;
+ rv = b->m_data;
+ }
+ if (zero) memset(rv, 0, nSize);
+ return rv;
+ }
+
+ void* jpeg_decoder::alloc_aligned(size_t nSize, uint32_t align, bool zero)
+ {
+ assert((align >= 1U) && ((align & (align - 1U)) == 0U));
+ void *p = alloc(nSize + align - 1U, zero);
+ p = (void *)( ((uintptr_t)p + (align - 1U)) & ~((uintptr_t)(align - 1U)) );
+ return p;
+ }
+
+ void jpeg_decoder::word_clear(void* p, uint16 c, uint n)
+ {
+ uint8* pD = (uint8*)p;
+ const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF;
+ while (n)
+ {
+ pD[0] = l;
+ pD[1] = h;
+ pD += 2;
+ n--;
+ }
+ }
+
+ // Refill the input buffer.
+ // This method will sit in a loop until (A) the buffer is full or (B)
+ // the stream's read() method reports and end of file condition.
+ void jpeg_decoder::prep_in_buffer()
+ {
+ m_in_buf_left = 0;
+ m_pIn_buf_ofs = m_in_buf;
+
+ if (m_eof_flag)
+ return;
+
+ do
+ {
+ int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag);
+ if (bytes_read == -1)
+ stop_decoding(JPGD_STREAM_READ);
+
+ m_in_buf_left += bytes_read;
+ } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag));
+
+ m_total_bytes_read += m_in_buf_left;
+
+ // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid).
+ // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.)
+ word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64);
+ }
+
+ // Read a Huffman code table.
+ void jpeg_decoder::read_dht_marker()
+ {
+ int i, index, count;
+ uint8 huff_num[17];
+ uint8 huff_val[256];
+
+ uint num_left = get_bits(16);
+
+ if (num_left < 2)
+ stop_decoding(JPGD_BAD_DHT_MARKER);
+
+ num_left -= 2;
+
+ while (num_left)
+ {
+ index = get_bits(8);
+
+ huff_num[0] = 0;
+
+ count = 0;
+
+ for (i = 1; i <= 16; i++)
+ {
+ huff_num[i] = static_cast<uint8>(get_bits(8));
+ count += huff_num[i];
+ }
+
+ if (count > 255)
+ stop_decoding(JPGD_BAD_DHT_COUNTS);
+
+ bool symbol_present[256];
+ memset(symbol_present, 0, sizeof(symbol_present));
- i = 1 + 16 + count;
+ for (i = 0; i < count; i++)
+ {
+ const int s = get_bits(8);
+
+ // Check for obviously bogus tables.
+ if (symbol_present[s])
+ stop_decoding(JPGD_BAD_DHT_COUNTS);
+
+ huff_val[i] = static_cast<uint8_t>(s);
+ symbol_present[s] = true;
+ }
- if (num_left < (uint)i)
- stop_decoding(JPGD_BAD_DHT_MARKER);
+ i = 1 + 16 + count;
- num_left -= i;
+ if (num_left < (uint)i)
+ stop_decoding(JPGD_BAD_DHT_MARKER);
- if ((index & 0x10) > 0x10)
- stop_decoding(JPGD_BAD_DHT_INDEX);
+ num_left -= i;
- index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1);
+ if ((index & 0x10) > 0x10)
+ stop_decoding(JPGD_BAD_DHT_INDEX);
- if (index >= JPGD_MAX_HUFF_TABLES)
- stop_decoding(JPGD_BAD_DHT_INDEX);
+ index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1);
- if (!m_huff_num[index])
- m_huff_num[index] = (uint8 *)alloc(17);
+ if (index >= JPGD_MAX_HUFF_TABLES)
+ stop_decoding(JPGD_BAD_DHT_INDEX);
- if (!m_huff_val[index])
- m_huff_val[index] = (uint8 *)alloc(256);
+ if (!m_huff_num[index])
+ m_huff_num[index] = (uint8*)alloc(17);
- m_huff_ac[index] = (index & 0x10) != 0;
- memcpy(m_huff_num[index], huff_num, 17);
- memcpy(m_huff_val[index], huff_val, 256);
- }
-}
+ if (!m_huff_val[index])
+ m_huff_val[index] = (uint8*)alloc(256);
-// Read a quantization table.
-void jpeg_decoder::read_dqt_marker()
-{
- int n, i, prec;
- uint num_left;
- uint temp;
+ m_huff_ac[index] = (index & 0x10) != 0;
+ memcpy(m_huff_num[index], huff_num, 17);
+ memcpy(m_huff_val[index], huff_val, 256);
+ }
+ }
- num_left = get_bits(16);
+ // Read a quantization table.
+ void jpeg_decoder::read_dqt_marker()
+ {
+ int n, i, prec;
+ uint num_left;
+ uint temp;
- if (num_left < 2)
- stop_decoding(JPGD_BAD_DQT_MARKER);
+ num_left = get_bits(16);
- num_left -= 2;
+ if (num_left < 2)
+ stop_decoding(JPGD_BAD_DQT_MARKER);
- while (num_left)
- {
- n = get_bits(8);
- prec = n >> 4;
- n &= 0x0F;
+ num_left -= 2;
- if (n >= JPGD_MAX_QUANT_TABLES)
- stop_decoding(JPGD_BAD_DQT_TABLE);
+ while (num_left)
+ {
+ n = get_bits(8);
+ prec = n >> 4;
+ n &= 0x0F;
- if (!m_quant[n])
- m_quant[n] = (jpgd_quant_t *)alloc(64 * sizeof(jpgd_quant_t));
+ if (n >= JPGD_MAX_QUANT_TABLES)
+ stop_decoding(JPGD_BAD_DQT_TABLE);
- // read quantization entries, in zag order
- for (i = 0; i < 64; i++)
- {
- temp = get_bits(8);
+ if (!m_quant[n])
+ m_quant[n] = (jpgd_quant_t*)alloc(64 * sizeof(jpgd_quant_t));
- if (prec)
- temp = (temp << 8) + get_bits(8);
+ // read quantization entries, in zag order
+ for (i = 0; i < 64; i++)
+ {
+ temp = get_bits(8);
- m_quant[n][i] = static_cast<jpgd_quant_t>(temp);
- }
+ if (prec)
+ temp = (temp << 8) + get_bits(8);
- i = 64 + 1;
+ m_quant[n][i] = static_cast<jpgd_quant_t>(temp);
+ }
- if (prec)
- i += 64;
+ i = 64 + 1;
- if (num_left < (uint)i)
- stop_decoding(JPGD_BAD_DQT_LENGTH);
+ if (prec)
+ i += 64;
- num_left -= i;
- }
-}
+ if (num_left < (uint)i)
+ stop_decoding(JPGD_BAD_DQT_LENGTH);
-// Read the start of frame (SOF) marker.
-void jpeg_decoder::read_sof_marker()
-{
- int i;
- uint num_left;
+ num_left -= i;
+ }
+ }
- num_left = get_bits(16);
+ // Read the start of frame (SOF) marker.
+ void jpeg_decoder::read_sof_marker()
+ {
+ int i;
+ uint num_left;
- if (get_bits(8) != 8) /* precision: sorry, only 8-bit precision is supported right now */
- stop_decoding(JPGD_BAD_PRECISION);
+ num_left = get_bits(16);
- m_image_y_size = get_bits(16);
+ /* precision: sorry, only 8-bit precision is supported */
+ if (get_bits(8) != 8)
+ stop_decoding(JPGD_BAD_PRECISION);
- if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT))
- stop_decoding(JPGD_BAD_HEIGHT);
+ m_image_y_size = get_bits(16);
- m_image_x_size = get_bits(16);
+ if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT))
+ stop_decoding(JPGD_BAD_HEIGHT);
- if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH))
- stop_decoding(JPGD_BAD_WIDTH);
+ m_image_x_size = get_bits(16);
- m_comps_in_frame = get_bits(8);
+ if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH))
+ stop_decoding(JPGD_BAD_WIDTH);
- if (m_comps_in_frame > JPGD_MAX_COMPONENTS)
- stop_decoding(JPGD_TOO_MANY_COMPONENTS);
+ m_comps_in_frame = get_bits(8);
- if (num_left != (uint)(m_comps_in_frame * 3 + 8))
- stop_decoding(JPGD_BAD_SOF_LENGTH);
+ if (m_comps_in_frame > JPGD_MAX_COMPONENTS)
+ stop_decoding(JPGD_TOO_MANY_COMPONENTS);
- for (i = 0; i < m_comps_in_frame; i++)
- {
- m_comp_ident[i] = get_bits(8);
- m_comp_h_samp[i] = get_bits(4);
- m_comp_v_samp[i] = get_bits(4);
- m_comp_quant[i] = get_bits(8);
- }
-}
+ if (num_left != (uint)(m_comps_in_frame * 3 + 8))
+ stop_decoding(JPGD_BAD_SOF_LENGTH);
-// Used to skip unrecognized markers.
-void jpeg_decoder::skip_variable_marker()
-{
- uint num_left;
+ for (i = 0; i < m_comps_in_frame; i++)
+ {
+ m_comp_ident[i] = get_bits(8);
+ m_comp_h_samp[i] = get_bits(4);
+ m_comp_v_samp[i] = get_bits(4);
- num_left = get_bits(16);
+ if (!m_comp_h_samp[i] || !m_comp_v_samp[i] || (m_comp_h_samp[i] > 2) || (m_comp_v_samp[i] > 2))
+ stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
- if (num_left < 2)
- stop_decoding(JPGD_BAD_VARIABLE_MARKER);
+ m_comp_quant[i] = get_bits(8);
+ if (m_comp_quant[i] >= JPGD_MAX_QUANT_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+ }
+ }
+
+ // Used to skip unrecognized markers.
+ void jpeg_decoder::skip_variable_marker()
+ {
+ uint num_left;
+
+ num_left = get_bits(16);
+
+ if (num_left < 2)
+ stop_decoding(JPGD_BAD_VARIABLE_MARKER);
+
+ num_left -= 2;
+
+ while (num_left)
+ {
+ get_bits(8);
+ num_left--;
+ }
+ }
+
+ // Read a define restart interval (DRI) marker.
+ void jpeg_decoder::read_dri_marker()
+ {
+ if (get_bits(16) != 4)
+ stop_decoding(JPGD_BAD_DRI_LENGTH);
+
+ m_restart_interval = get_bits(16);
+ }
+
+ // Read a start of scan (SOS) marker.
+ void jpeg_decoder::read_sos_marker()
+ {
+ uint num_left;
+ int i, ci, n, c, cc;
+
+ num_left = get_bits(16);
+
+ n = get_bits(8);
+
+ m_comps_in_scan = n;
+
+ num_left -= 3;
+
+ if ((num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN))
+ stop_decoding(JPGD_BAD_SOS_LENGTH);
+
+ for (i = 0; i < n; i++)
+ {
+ cc = get_bits(8);
+ c = get_bits(8);
+ num_left -= 2;
+
+ for (ci = 0; ci < m_comps_in_frame; ci++)
+ if (cc == m_comp_ident[ci])
+ break;
+
+ if (ci >= m_comps_in_frame)
+ stop_decoding(JPGD_BAD_SOS_COMP_ID);
+
+ if (ci >= JPGD_MAX_COMPONENTS)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ m_comp_list[i] = ci;
+
+ m_comp_dc_tab[ci] = (c >> 4) & 15;
+ m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1);
+
+ if (m_comp_dc_tab[ci] >= JPGD_MAX_HUFF_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ if (m_comp_ac_tab[ci] >= JPGD_MAX_HUFF_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+ }
+
+ m_spectral_start = get_bits(8);
+ m_spectral_end = get_bits(8);
+ m_successive_high = get_bits(4);
+ m_successive_low = get_bits(4);
+
+ if (!m_progressive_flag)
+ {
+ m_spectral_start = 0;
+ m_spectral_end = 63;
+ }
+
+ num_left -= 3;
+
+ /* read past whatever is num_left */
+ while (num_left)
+ {
+ get_bits(8);
+ num_left--;
+ }
+ }
+
+ // Finds the next marker.
+ int jpeg_decoder::next_marker()
+ {
+ uint c, bytes;
+
+ bytes = 0;
+
+ do
+ {
+ do
+ {
+ bytes++;
+ c = get_bits(8);
+ } while (c != 0xFF);
- num_left -= 2;
+ do
+ {
+ c = get_bits(8);
+ } while (c == 0xFF);
+
+ } while (c == 0);
+
+ // If bytes > 0 here, there where extra bytes before the marker (not good).
+
+ return c;
+ }
+
+ // Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is
+ // encountered.
+ int jpeg_decoder::process_markers()
+ {
+ int c;
+
+ for (; ; )
+ {
+ c = next_marker();
+
+ switch (c)
+ {
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF2:
+ case M_SOF3:
+ case M_SOF5:
+ case M_SOF6:
+ case M_SOF7:
+ // case M_JPG:
+ case M_SOF9:
+ case M_SOF10:
+ case M_SOF11:
+ case M_SOF13:
+ case M_SOF14:
+ case M_SOF15:
+ case M_SOI:
+ case M_EOI:
+ case M_SOS:
+ {
+ return c;
+ }
+ case M_DHT:
+ {
+ read_dht_marker();
+ break;
+ }
+ // No arithmitic support - dumb patents!
+ case M_DAC:
+ {
+ stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
+ break;
+ }
+ case M_DQT:
+ {
+ read_dqt_marker();
+ break;
+ }
+ case M_DRI:
+ {
+ read_dri_marker();
+ break;
+ }
+ //case M_APP0: /* no need to read the JFIF marker */
+ case M_JPG:
+ case M_RST0: /* no parameters */
+ case M_RST1:
+ case M_RST2:
+ case M_RST3:
+ case M_RST4:
+ case M_RST5:
+ case M_RST6:
+ case M_RST7:
+ case M_TEM:
+ {
+ stop_decoding(JPGD_UNEXPECTED_MARKER);
+ break;
+ }
+ default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */
+ {
+ skip_variable_marker();
+ break;
+ }
+ }
+ }
+ }
+
+ // Finds the start of image (SOI) marker.
+ void jpeg_decoder::locate_soi_marker()
+ {
+ uint lastchar, thischar;
+ uint bytesleft;
+
+ lastchar = get_bits(8);
+
+ thischar = get_bits(8);
+
+ /* ok if it's a normal JPEG file without a special header */
+
+ if ((lastchar == 0xFF) && (thischar == M_SOI))
+ return;
+
+ bytesleft = 4096;
+
+ for (; ; )
+ {
+ if (--bytesleft == 0)
+ stop_decoding(JPGD_NOT_JPEG);
+
+ lastchar = thischar;
+
+ thischar = get_bits(8);
+
+ if (lastchar == 0xFF)
+ {
+ if (thischar == M_SOI)
+ break;
+ else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end
+ stop_decoding(JPGD_NOT_JPEG);
+ }
+ }
+
+ // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad.
+ thischar = (m_bit_buf >> 24) & 0xFF;
+
+ if (thischar != 0xFF)
+ stop_decoding(JPGD_NOT_JPEG);
+ }
+
+ // Find a start of frame (SOF) marker.
+ void jpeg_decoder::locate_sof_marker()
+ {
+ locate_soi_marker();
+
+ int c = process_markers();
+
+ switch (c)
+ {
+ case M_SOF2:
+ {
+ m_progressive_flag = JPGD_TRUE;
+ read_sof_marker();
+ break;
+ }
+ case M_SOF0: /* baseline DCT */
+ case M_SOF1: /* extended sequential DCT */
+ {
+ read_sof_marker();
+ break;
+ }
+ case M_SOF9: /* Arithmitic coding */
+ {
+ stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
+ break;
+ }
+ default:
+ {
+ stop_decoding(JPGD_UNSUPPORTED_MARKER);
+ break;
+ }
+ }
+ }
- while (num_left)
- {
- get_bits(8);
- num_left--;
- }
-}
+ // Find a start of scan (SOS) marker.
+ int jpeg_decoder::locate_sos_marker()
+ {
+ int c;
-// Read a define restart interval (DRI) marker.
-void jpeg_decoder::read_dri_marker()
-{
- if (get_bits(16) != 4)
- stop_decoding(JPGD_BAD_DRI_LENGTH);
+ c = process_markers();
- m_restart_interval = get_bits(16);
-}
+ if (c == M_EOI)
+ return JPGD_FALSE;
+ else if (c != M_SOS)
+ stop_decoding(JPGD_UNEXPECTED_MARKER);
-// Read a start of scan (SOS) marker.
-void jpeg_decoder::read_sos_marker()
-{
- uint num_left;
- int i, ci, n, c, cc;
+ read_sos_marker();
- num_left = get_bits(16);
+ return JPGD_TRUE;
+ }
- n = get_bits(8);
-
- m_comps_in_scan = n;
-
- num_left -= 3;
-
- if ( (num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN) )
- stop_decoding(JPGD_BAD_SOS_LENGTH);
-
- for (i = 0; i < n; i++)
- {
- cc = get_bits(8);
- c = get_bits(8);
- num_left -= 2;
-
- for (ci = 0; ci < m_comps_in_frame; ci++)
- if (cc == m_comp_ident[ci])
- break;
-
- if (ci >= m_comps_in_frame)
- stop_decoding(JPGD_BAD_SOS_COMP_ID);
-
- m_comp_list[i] = ci;
- m_comp_dc_tab[ci] = (c >> 4) & 15;
- m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1);
- }
-
- m_spectral_start = get_bits(8);
- m_spectral_end = get_bits(8);
- m_successive_high = get_bits(4);
- m_successive_low = get_bits(4);
-
- if (!m_progressive_flag)
- {
- m_spectral_start = 0;
- m_spectral_end = 63;
- }
-
- num_left -= 3;
-
- while (num_left) /* read past whatever is num_left */
- {
- get_bits(8);
- num_left--;
- }
-}
-
-// Finds the next marker.
-int jpeg_decoder::next_marker()
-{
- uint c, bytes;
-
- bytes = 0;
-
- do
- {
- do
- {
- bytes++;
- c = get_bits(8);
- } while (c != 0xFF);
-
- do
- {
- c = get_bits(8);
- } while (c == 0xFF);
-
- } while (c == 0);
-
- // If bytes > 0 here, there where extra bytes before the marker (not good).
-
- return c;
-}
-
-// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is
-// encountered.
-int jpeg_decoder::process_markers()
-{
- int c;
-
- for ( ; ; )
- {
- c = next_marker();
-
- switch (c)
- {
- case M_SOF0:
- case M_SOF1:
- case M_SOF2:
- case M_SOF3:
- case M_SOF5:
- case M_SOF6:
- case M_SOF7:
-// case M_JPG:
- case M_SOF9:
- case M_SOF10:
- case M_SOF11:
- case M_SOF13:
- case M_SOF14:
- case M_SOF15:
- case M_SOI:
- case M_EOI:
- case M_SOS:
- {
- return c;
- }
- case M_DHT:
- {
- read_dht_marker();
- break;
- }
- // No arithmitic support - dumb patents!
- case M_DAC:
- {
- stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
- break;
- }
- case M_DQT:
- {
- read_dqt_marker();
- break;
- }
- case M_DRI:
- {
- read_dri_marker();
- break;
- }
- //case M_APP0: /* no need to read the JFIF marker */
-
- case M_JPG:
- case M_RST0: /* no parameters */
- case M_RST1:
- case M_RST2:
- case M_RST3:
- case M_RST4:
- case M_RST5:
- case M_RST6:
- case M_RST7:
- case M_TEM:
- {
- stop_decoding(JPGD_UNEXPECTED_MARKER);
- break;
- }
- default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */
- {
- skip_variable_marker();
- break;
- }
- }
- }
-}
-
-// Finds the start of image (SOI) marker.
-// This code is rather defensive: it only checks the first 512 bytes to avoid
-// false positives.
-void jpeg_decoder::locate_soi_marker()
-{
- uint lastchar, thischar;
- uint bytesleft;
-
- lastchar = get_bits(8);
-
- thischar = get_bits(8);
-
- /* ok if it's a normal JPEG file without a special header */
-
- if ((lastchar == 0xFF) && (thischar == M_SOI))
- return;
-
- bytesleft = 4096; //512;
-
- for ( ; ; )
- {
- if (--bytesleft == 0)
- stop_decoding(JPGD_NOT_JPEG);
-
- lastchar = thischar;
-
- thischar = get_bits(8);
-
- if (lastchar == 0xFF)
- {
- if (thischar == M_SOI)
- break;
- else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end
- stop_decoding(JPGD_NOT_JPEG);
- }
- }
-
- // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad.
- thischar = (m_bit_buf >> 24) & 0xFF;
-
- if (thischar != 0xFF)
- stop_decoding(JPGD_NOT_JPEG);
-}
-
-// Find a start of frame (SOF) marker.
-void jpeg_decoder::locate_sof_marker()
-{
- locate_soi_marker();
-
- int c = process_markers();
-
- switch (c)
- {
- case M_SOF2:
- m_progressive_flag = JPGD_TRUE;
- case M_SOF0: /* baseline DCT */
- case M_SOF1: /* extended sequential DCT */
- {
- read_sof_marker();
- break;
- }
- case M_SOF9: /* Arithmitic coding */
- {
- stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
- break;
- }
- default:
- {
- stop_decoding(JPGD_UNSUPPORTED_MARKER);
- break;
- }
- }
-}
-
-// Find a start of scan (SOS) marker.
-int jpeg_decoder::locate_sos_marker()
-{
- int c;
-
- c = process_markers();
-
- if (c == M_EOI)
- return JPGD_FALSE;
- else if (c != M_SOS)
- stop_decoding(JPGD_UNEXPECTED_MARKER);
-
- read_sos_marker();
-
- return JPGD_TRUE;
-}
-
-// Reset everything to default/uninitialized state.
-void jpeg_decoder::init(jpeg_decoder_stream *pStream)
-{
- m_pMem_blocks = NULL;
- m_error_code = JPGD_SUCCESS;
- m_ready_flag = false;
- m_image_x_size = m_image_y_size = 0;
- m_pStream = pStream;
- m_progressive_flag = JPGD_FALSE;
-
- memset(m_huff_ac, 0, sizeof(m_huff_ac));
- memset(m_huff_num, 0, sizeof(m_huff_num));
- memset(m_huff_val, 0, sizeof(m_huff_val));
- memset(m_quant, 0, sizeof(m_quant));
-
- m_scan_type = 0;
- m_comps_in_frame = 0;
-
- memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp));
- memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp));
- memset(m_comp_quant, 0, sizeof(m_comp_quant));
- memset(m_comp_ident, 0, sizeof(m_comp_ident));
- memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks));
- memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks));
-
- m_comps_in_scan = 0;
- memset(m_comp_list, 0, sizeof(m_comp_list));
- memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab));
- memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab));
-
- m_spectral_start = 0;
- m_spectral_end = 0;
- m_successive_low = 0;
- m_successive_high = 0;
- m_max_mcu_x_size = 0;
- m_max_mcu_y_size = 0;
- m_blocks_per_mcu = 0;
- m_max_blocks_per_row = 0;
- m_mcus_per_row = 0;
- m_mcus_per_col = 0;
- m_expanded_blocks_per_component = 0;
- m_expanded_blocks_per_mcu = 0;
- m_expanded_blocks_per_row = 0;
- m_freq_domain_chroma_upsample = false;
-
- memset(m_mcu_org, 0, sizeof(m_mcu_org));
-
- m_total_lines_left = 0;
- m_mcu_lines_left = 0;
- m_real_dest_bytes_per_scan_line = 0;
- m_dest_bytes_per_scan_line = 0;
- m_dest_bytes_per_pixel = 0;
-
- memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs));
-
- memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs));
- memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs));
- memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
-
- m_eob_run = 0;
-
- memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
-
- m_pIn_buf_ofs = m_in_buf;
- m_in_buf_left = 0;
- m_eof_flag = false;
- m_tem_flag = 0;
-
- memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start));
- memset(m_in_buf, 0, sizeof(m_in_buf));
- memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end));
-
- m_restart_interval = 0;
- m_restarts_left = 0;
- m_next_restart_num = 0;
-
- m_max_mcus_per_row = 0;
- m_max_blocks_per_mcu = 0;
- m_max_mcus_per_col = 0;
-
- memset(m_last_dc_val, 0, sizeof(m_last_dc_val));
- m_pMCU_coefficients = NULL;
- m_pSample_buf = NULL;
-
- m_total_bytes_read = 0;
-
- m_pScan_line_0 = NULL;
- m_pScan_line_1 = NULL;
-
- // Ready the input buffer.
- prep_in_buffer();
-
- // Prime the bit buffer.
- m_bits_left = 16;
- m_bit_buf = 0;
-
- get_bits(16);
- get_bits(16);
-
- for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++)
- m_mcu_block_max_zag[i] = 64;
-}
+ // Reset everything to default/uninitialized state.
+ void jpeg_decoder::init(jpeg_decoder_stream* pStream, uint32_t flags)
+ {
+ m_flags = flags;
+ m_pMem_blocks = nullptr;
+ m_error_code = JPGD_SUCCESS;
+ m_ready_flag = false;
+ m_image_x_size = m_image_y_size = 0;
+ m_pStream = pStream;
+ m_progressive_flag = JPGD_FALSE;
+
+ memset(m_huff_ac, 0, sizeof(m_huff_ac));
+ memset(m_huff_num, 0, sizeof(m_huff_num));
+ memset(m_huff_val, 0, sizeof(m_huff_val));
+ memset(m_quant, 0, sizeof(m_quant));
+
+ m_scan_type = 0;
+ m_comps_in_frame = 0;
+
+ memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp));
+ memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp));
+ memset(m_comp_quant, 0, sizeof(m_comp_quant));
+ memset(m_comp_ident, 0, sizeof(m_comp_ident));
+ memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks));
+ memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks));
+
+ m_comps_in_scan = 0;
+ memset(m_comp_list, 0, sizeof(m_comp_list));
+ memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab));
+ memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab));
+
+ m_spectral_start = 0;
+ m_spectral_end = 0;
+ m_successive_low = 0;
+ m_successive_high = 0;
+ m_max_mcu_x_size = 0;
+ m_max_mcu_y_size = 0;
+ m_blocks_per_mcu = 0;
+ m_max_blocks_per_row = 0;
+ m_mcus_per_row = 0;
+ m_mcus_per_col = 0;
+
+ memset(m_mcu_org, 0, sizeof(m_mcu_org));
+
+ m_total_lines_left = 0;
+ m_mcu_lines_left = 0;
+ m_num_buffered_scanlines = 0;
+ m_real_dest_bytes_per_scan_line = 0;
+ m_dest_bytes_per_scan_line = 0;
+ m_dest_bytes_per_pixel = 0;
+
+ memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs));
+
+ memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs));
+ memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs));
+ memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
+
+ m_eob_run = 0;
+
+ m_pIn_buf_ofs = m_in_buf;
+ m_in_buf_left = 0;
+ m_eof_flag = false;
+ m_tem_flag = 0;
+
+ memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start));
+ memset(m_in_buf, 0, sizeof(m_in_buf));
+ memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end));
+
+ m_restart_interval = 0;
+ m_restarts_left = 0;
+ m_next_restart_num = 0;
+
+ m_max_mcus_per_row = 0;
+ m_max_blocks_per_mcu = 0;
+ m_max_mcus_per_col = 0;
+
+ memset(m_last_dc_val, 0, sizeof(m_last_dc_val));
+ m_pMCU_coefficients = nullptr;
+ m_pSample_buf = nullptr;
+ m_pSample_buf_prev = nullptr;
+ m_sample_buf_prev_valid = false;
+
+ m_total_bytes_read = 0;
+
+ m_pScan_line_0 = nullptr;
+ m_pScan_line_1 = nullptr;
+
+ // Ready the input buffer.
+ prep_in_buffer();
+
+ // Prime the bit buffer.
+ m_bits_left = 16;
+ m_bit_buf = 0;
+
+ get_bits(16);
+ get_bits(16);
+
+ for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++)
+ m_mcu_block_max_zag[i] = 64;
+
+ m_has_sse2 = false;
+
+#if JPGD_USE_SSE2
+#ifdef _MSC_VER
+ int cpu_info[4];
+ __cpuid(cpu_info, 1);
+ const int cpu_info3 = cpu_info[3];
+ m_has_sse2 = ((cpu_info3 >> 26U) & 1U) != 0U;
+#else
+ m_has_sse2 = true;
+#endif
+#endif
+ }
#define SCALEBITS 16
#define ONE_HALF ((int) 1 << (SCALEBITS-1))
#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f))
-// Create a few tables that allow us to quickly convert YCbCr to RGB.
-void jpeg_decoder::create_look_ups()
-{
- for (int i = 0; i <= 255; i++)
- {
- int k = i - 128;
- m_crr[i] = ( FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS;
- m_cbb[i] = ( FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS;
- m_crg[i] = (-FIX(0.71414f)) * k;
- m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF;
- }
-}
-
-// This method throws back into the stream any bytes that where read
-// into the bit buffer during initial marker scanning.
-void jpeg_decoder::fix_in_buffer()
-{
- // In case any 0xFF's where pulled into the buffer during marker scanning.
- JPGD_ASSERT((m_bits_left & 7) == 0);
-
- if (m_bits_left == 16)
- stuff_char( (uint8)(m_bit_buf & 0xFF));
-
- if (m_bits_left >= 8)
- stuff_char( (uint8)((m_bit_buf >> 8) & 0xFF));
-
- stuff_char((uint8)((m_bit_buf >> 16) & 0xFF));
- stuff_char((uint8)((m_bit_buf >> 24) & 0xFF));
-
- m_bits_left = 16;
- get_bits_no_markers(16);
- get_bits_no_markers(16);
-}
-
-void jpeg_decoder::transform_mcu(int mcu_row)
-{
- jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
- if (m_freq_domain_chroma_upsample) {
- JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_expanded_blocks_per_row);
- }
- else {
- JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_max_blocks_per_row);
- }
- uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;
-
- for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
- {
- idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]);
- pSrc_ptr += 64;
- pDst_ptr += 64;
- }
-}
-
-static const uint8 s_max_rc[64] =
-{
- 17, 18, 34, 50, 50, 51, 52, 52, 52, 68, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86,
- 102, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, 120, 120, 136,
- 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
- 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136
-};
-
-void jpeg_decoder::transform_mcu_expand(int mcu_row)
-{
- jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
- uint8* pDst_ptr = m_pSample_buf + mcu_row * m_expanded_blocks_per_mcu * 64;
-
- // Y IDCT
- int mcu_block;
- for (mcu_block = 0; mcu_block < m_expanded_blocks_per_component; mcu_block++)
- {
- idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]);
- pSrc_ptr += 64;
- pDst_ptr += 64;
- }
-
- // Chroma IDCT, with upsampling
- jpgd_block_t temp_block[64];
-
- for (int i = 0; i < 2; i++)
- {
- DCT_Upsample::Matrix44 P, Q, R, S;
-
- JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] >= 1);
- JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] <= 64);
-
- int max_zag = m_mcu_block_max_zag[mcu_block++] - 1;
- if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis
- switch (s_max_rc[max_zag])
- {
- case 1*16+1:
- DCT_Upsample::P_Q<1, 1>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<1, 1>::calc(R, S, pSrc_ptr);
- break;
- case 1*16+2:
- DCT_Upsample::P_Q<1, 2>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<1, 2>::calc(R, S, pSrc_ptr);
- break;
- case 2*16+2:
- DCT_Upsample::P_Q<2, 2>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<2, 2>::calc(R, S, pSrc_ptr);
- break;
- case 3*16+2:
- DCT_Upsample::P_Q<3, 2>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<3, 2>::calc(R, S, pSrc_ptr);
- break;
- case 3*16+3:
- DCT_Upsample::P_Q<3, 3>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<3, 3>::calc(R, S, pSrc_ptr);
- break;
- case 3*16+4:
- DCT_Upsample::P_Q<3, 4>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<3, 4>::calc(R, S, pSrc_ptr);
- break;
- case 4*16+4:
- DCT_Upsample::P_Q<4, 4>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<4, 4>::calc(R, S, pSrc_ptr);
- break;
- case 5*16+4:
- DCT_Upsample::P_Q<5, 4>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<5, 4>::calc(R, S, pSrc_ptr);
- break;
- case 5*16+5:
- DCT_Upsample::P_Q<5, 5>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<5, 5>::calc(R, S, pSrc_ptr);
- break;
- case 5*16+6:
- DCT_Upsample::P_Q<5, 6>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<5, 6>::calc(R, S, pSrc_ptr);
- break;
- case 6*16+6:
- DCT_Upsample::P_Q<6, 6>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<6, 6>::calc(R, S, pSrc_ptr);
- break;
- case 7*16+6:
- DCT_Upsample::P_Q<7, 6>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<7, 6>::calc(R, S, pSrc_ptr);
- break;
- case 7*16+7:
- DCT_Upsample::P_Q<7, 7>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<7, 7>::calc(R, S, pSrc_ptr);
- break;
- case 7*16+8:
- DCT_Upsample::P_Q<7, 8>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<7, 8>::calc(R, S, pSrc_ptr);
- break;
- case 8*16+8:
- DCT_Upsample::P_Q<8, 8>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<8, 8>::calc(R, S, pSrc_ptr);
- break;
- default:
- JPGD_ASSERT(false);
- }
-
- DCT_Upsample::Matrix44 a(P + Q); P -= Q;
- DCT_Upsample::Matrix44& b = P;
- DCT_Upsample::Matrix44 c(R + S); R -= S;
- DCT_Upsample::Matrix44& d = R;
-
- DCT_Upsample::Matrix44::add_and_store(temp_block, a, c);
- idct_4x4(temp_block, pDst_ptr);
- pDst_ptr += 64;
-
- DCT_Upsample::Matrix44::sub_and_store(temp_block, a, c);
- idct_4x4(temp_block, pDst_ptr);
- pDst_ptr += 64;
-
- DCT_Upsample::Matrix44::add_and_store(temp_block, b, d);
- idct_4x4(temp_block, pDst_ptr);
- pDst_ptr += 64;
-
- DCT_Upsample::Matrix44::sub_and_store(temp_block, b, d);
- idct_4x4(temp_block, pDst_ptr);
- pDst_ptr += 64;
-
- pSrc_ptr += 64;
- }
-}
-
-// Loads and dequantizes the next row of (already decoded) coefficients.
-// Progressive images only.
-void jpeg_decoder::load_next_row()
-{
- int i;
- jpgd_block_t *p;
- jpgd_quant_t *q;
- int mcu_row, mcu_block, row_block = 0;
- int component_num, component_id;
- int block_x_mcu[JPGD_MAX_COMPONENTS];
-
- memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int));
-
- for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
- {
- int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
-
- for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
- {
- component_id = m_mcu_org[mcu_block];
- JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
- q = m_quant[m_comp_quant[component_id]];
-
- p = m_pMCU_coefficients + 64 * mcu_block;
-
- jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
- jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
- p[0] = pDC[0];
- memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t));
-
- for (i = 63; i > 0; i--)
- if (p[g_ZAG[i]])
- break;
-
- m_mcu_block_max_zag[mcu_block] = i + 1;
-
- for ( ; i >= 0; i--)
- if (p[g_ZAG[i]])
- p[g_ZAG[i]] = static_cast<jpgd_block_t>(p[g_ZAG[i]] * q[i]);
-
- row_block++;
-
- if (m_comps_in_scan == 1)
- block_x_mcu[component_id]++;
- else
- {
- if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
- {
- block_x_mcu_ofs = 0;
-
- if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
- {
- block_y_mcu_ofs = 0;
-
- block_x_mcu[component_id] += m_comp_h_samp[component_id];
- }
- }
- }
- }
-
- if (m_freq_domain_chroma_upsample)
- transform_mcu_expand(mcu_row);
- else
- transform_mcu(mcu_row);
- }
-
- if (m_comps_in_scan == 1)
- m_block_y_mcu[m_comp_list[0]]++;
- else
- {
- for (component_num = 0; component_num < m_comps_in_scan; component_num++)
- {
- component_id = m_comp_list[component_num];
-
- m_block_y_mcu[component_id] += m_comp_v_samp[component_id];
- }
- }
-}
-
-// Restart interval processing.
-void jpeg_decoder::process_restart()
-{
- int i;
- int c = 0;
-
- // Align to a byte boundry
- // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers!
- //get_bits_no_markers(m_bits_left & 7);
-
- // Let's scan a little bit to find the marker, but not _too_ far.
- // 1536 is a "fudge factor" that determines how much to scan.
- for (i = 1536; i > 0; i--)
- if (get_char() == 0xFF)
- break;
-
- if (i == 0)
- stop_decoding(JPGD_BAD_RESTART_MARKER);
-
- for ( ; i > 0; i--)
- if ((c = get_char()) != 0xFF)
- break;
-
- if (i == 0)
- stop_decoding(JPGD_BAD_RESTART_MARKER);
-
- // Is it the expected marker? If not, something bad happened.
- if (c != (m_next_restart_num + M_RST0))
- stop_decoding(JPGD_BAD_RESTART_MARKER);
-
- // Reset each component's DC prediction values.
- memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
-
- m_eob_run = 0;
-
- m_restarts_left = m_restart_interval;
-
- m_next_restart_num = (m_next_restart_num + 1) & 7;
-
- // Get the bit buffer going again...
-
- m_bits_left = 16;
- get_bits_no_markers(16);
- get_bits_no_markers(16);
-}
-
-static inline int dequantize_ac(int c, int q) { c *= q; return c; }
-
-// Decodes and dequantizes the next row of coefficients.
-void jpeg_decoder::decode_next_row()
-{
- int row_block = 0;
-
- for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
- {
- if ((m_restart_interval) && (m_restarts_left == 0))
- process_restart();
-
- jpgd_block_t* p = m_pMCU_coefficients;
- for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)
- {
- int component_id = m_mcu_org[mcu_block];
- JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
- jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];
-
- int r, s;
- s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r);
- s = JPGD_HUFF_EXTEND(r, s);
-
- m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]);
-
- p[0] = static_cast<jpgd_block_t>(s * q[0]);
-
- int prev_num_set = m_mcu_block_max_zag[mcu_block];
-
- huff_tables *pH = m_pHuff_tabs[m_comp_ac_tab[component_id]];
-
- int k;
- for (k = 1; k < 64; k++)
- {
- int extra_bits;
- s = huff_decode(pH, extra_bits);
-
- r = s >> 4;
- s &= 15;
-
- if (s)
- {
- if (r)
- {
- if ((k + r) > 63)
- stop_decoding(JPGD_DECODE_ERROR);
-
- if (k < prev_num_set)
- {
- int n = JPGD_MIN(r, prev_num_set - k);
- int kt = k;
- while (n--)
- p[g_ZAG[kt++]] = 0;
- }
-
- k += r;
- }
-
- s = JPGD_HUFF_EXTEND(extra_bits, s);
-
- JPGD_ASSERT(k < 64);
-
- p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k];
- }
- else
- {
- if (r == 15)
- {
- if ((k + 16) > 64)
- stop_decoding(JPGD_DECODE_ERROR);
-
- if (k < prev_num_set)
- {
- int n = JPGD_MIN(16, prev_num_set - k);
- int kt = k;
- while (n--)
- {
- JPGD_ASSERT(kt <= 63);
- p[g_ZAG[kt++]] = 0;
- }
- }
-
- k += 16 - 1; // - 1 because the loop counter is k
- JPGD_ASSERT(p[g_ZAG[k]] == 0);
- }
- else
- break;
- }
- }
-
- if (k < prev_num_set)
- {
- int kt = k;
- while (kt < prev_num_set)
- p[g_ZAG[kt++]] = 0;
- }
-
- m_mcu_block_max_zag[mcu_block] = k;
-
- row_block++;
- }
-
- if (m_freq_domain_chroma_upsample)
- transform_mcu_expand(mcu_row);
- else
- transform_mcu(mcu_row);
-
- m_restarts_left--;
- }
-}
-
-// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB
-void jpeg_decoder::H1V1Convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d = m_pScan_line_0;
- uint8 *s = m_pSample_buf + row * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int j = 0; j < 8; j++)
- {
- int y = s[j];
- int cb = s[64+j];
- int cr = s[128+j];
-
- d[0] = clamp(y + m_crr[cr]);
- d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));
- d[2] = clamp(y + m_cbb[cb]);
- d[3] = 255;
-
- d += 4;
- }
-
- s += 64*3;
- }
-}
-
-// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB
-void jpeg_decoder::H2V1Convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d0 = m_pScan_line_0;
- uint8 *y = m_pSample_buf + row * 8;
- uint8 *c = m_pSample_buf + 2*64 + row * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int l = 0; l < 2; l++)
- {
- for (int j = 0; j < 4; j++)
- {
- int cb = c[0];
- int cr = c[64];
-
- int rc = m_crr[cr];
- int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
- int bc = m_cbb[cb];
-
- int yy = y[j<<1];
- d0[0] = clamp(yy+rc);
- d0[1] = clamp(yy+gc);
- d0[2] = clamp(yy+bc);
- d0[3] = 255;
-
- yy = y[(j<<1)+1];
- d0[4] = clamp(yy+rc);
- d0[5] = clamp(yy+gc);
- d0[6] = clamp(yy+bc);
- d0[7] = 255;
-
- d0 += 8;
-
- c++;
- }
- y += 64;
- }
-
- y += 64*4 - 64*2;
- c += 64*4 - 8;
- }
-}
-
-// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB
-void jpeg_decoder::H1V2Convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d0 = m_pScan_line_0;
- uint8 *d1 = m_pScan_line_1;
- uint8 *y;
- uint8 *c;
-
- if (row < 8)
- y = m_pSample_buf + row * 8;
- else
- y = m_pSample_buf + 64*1 + (row & 7) * 8;
-
- c = m_pSample_buf + 64*2 + (row >> 1) * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int j = 0; j < 8; j++)
- {
- int cb = c[0+j];
- int cr = c[64+j];
-
- int rc = m_crr[cr];
- int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
- int bc = m_cbb[cb];
-
- int yy = y[j];
- d0[0] = clamp(yy+rc);
- d0[1] = clamp(yy+gc);
- d0[2] = clamp(yy+bc);
- d0[3] = 255;
-
- yy = y[8+j];
- d1[0] = clamp(yy+rc);
- d1[1] = clamp(yy+gc);
- d1[2] = clamp(yy+bc);
- d1[3] = 255;
-
- d0 += 4;
- d1 += 4;
- }
-
- y += 64*4;
- c += 64*4;
- }
-}
-
-// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB
-void jpeg_decoder::H2V2Convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d0 = m_pScan_line_0;
- uint8 *d1 = m_pScan_line_1;
- uint8 *y;
- uint8 *c;
-
- if (row < 8)
- y = m_pSample_buf + row * 8;
- else
- y = m_pSample_buf + 64*2 + (row & 7) * 8;
-
- c = m_pSample_buf + 64*4 + (row >> 1) * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int l = 0; l < 2; l++)
- {
- for (int j = 0; j < 8; j += 2)
- {
- int cb = c[0];
- int cr = c[64];
+ // Create a few tables that allow us to quickly convert YCbCr to RGB.
+ void jpeg_decoder::create_look_ups()
+ {
+ for (int i = 0; i <= 255; i++)
+ {
+ int k = i - 128;
+ m_crr[i] = (FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS;
+ m_cbb[i] = (FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS;
+ m_crg[i] = (-FIX(0.71414f)) * k;
+ m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF;
+ }
+ }
+
+ // This method throws back into the stream any bytes that where read
+ // into the bit buffer during initial marker scanning.
+ void jpeg_decoder::fix_in_buffer()
+ {
+ // In case any 0xFF's where pulled into the buffer during marker scanning.
+ assert((m_bits_left & 7) == 0);
+
+ if (m_bits_left == 16)
+ stuff_char((uint8)(m_bit_buf & 0xFF));
+
+ if (m_bits_left >= 8)
+ stuff_char((uint8)((m_bit_buf >> 8) & 0xFF));
+
+ stuff_char((uint8)((m_bit_buf >> 16) & 0xFF));
+ stuff_char((uint8)((m_bit_buf >> 24) & 0xFF));
+
+ m_bits_left = 16;
+ get_bits_no_markers(16);
+ get_bits_no_markers(16);
+ }
+
+ void jpeg_decoder::transform_mcu(int mcu_row)
+ {
+ jpgd_block_coeff_t* pSrc_ptr = m_pMCU_coefficients;
+ if (mcu_row * m_blocks_per_mcu >= m_max_blocks_per_row)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;
+
+ for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
+ {
+ idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block], ((m_flags & cFlagDisableSIMD) == 0) && m_has_sse2);
+ pSrc_ptr += 64;
+ pDst_ptr += 64;
+ }
+ }
+
+ // Loads and dequantizes the next row of (already decoded) coefficients.
+ // Progressive images only.
+ void jpeg_decoder::load_next_row()
+ {
+ int i;
+ jpgd_block_coeff_t* p;
+ jpgd_quant_t* q;
+ int mcu_row, mcu_block, row_block = 0;
+ int component_num, component_id;
+ int block_x_mcu[JPGD_MAX_COMPONENTS];
+
+ memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int));
+
+ for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
+ {
+ int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
+
+ for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
+ {
+ component_id = m_mcu_org[mcu_block];
+ if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ q = m_quant[m_comp_quant[component_id]];
+
+ p = m_pMCU_coefficients + 64 * mcu_block;
+
+ jpgd_block_coeff_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
+ jpgd_block_coeff_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
+ p[0] = pDC[0];
+ memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_coeff_t));
+
+ for (i = 63; i > 0; i--)
+ if (p[g_ZAG[i]])
+ break;
+
+ m_mcu_block_max_zag[mcu_block] = i + 1;
+
+ for (; i >= 0; i--)
+ if (p[g_ZAG[i]])
+ p[g_ZAG[i]] = static_cast<jpgd_block_coeff_t>(p[g_ZAG[i]] * q[i]);
+
+ row_block++;
+
+ if (m_comps_in_scan == 1)
+ block_x_mcu[component_id]++;
+ else
+ {
+ if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
+ {
+ block_x_mcu_ofs = 0;
+
+ if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
+ {
+ block_y_mcu_ofs = 0;
+
+ block_x_mcu[component_id] += m_comp_h_samp[component_id];
+ }
+ }
+ }
+ }
+
+ transform_mcu(mcu_row);
+ }
+
+ if (m_comps_in_scan == 1)
+ m_block_y_mcu[m_comp_list[0]]++;
+ else
+ {
+ for (component_num = 0; component_num < m_comps_in_scan; component_num++)
+ {
+ component_id = m_comp_list[component_num];
+
+ m_block_y_mcu[component_id] += m_comp_v_samp[component_id];
+ }
+ }
+ }
+
+ // Restart interval processing.
+ void jpeg_decoder::process_restart()
+ {
+ int i;
+ int c = 0;
+
+ // Align to a byte boundry
+ // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers!
+ //get_bits_no_markers(m_bits_left & 7);
+
+ // Let's scan a little bit to find the marker, but not _too_ far.
+ // 1536 is a "fudge factor" that determines how much to scan.
+ for (i = 1536; i > 0; i--)
+ if (get_char() == 0xFF)
+ break;
+
+ if (i == 0)
+ stop_decoding(JPGD_BAD_RESTART_MARKER);
+
+ for (; i > 0; i--)
+ if ((c = get_char()) != 0xFF)
+ break;
+
+ if (i == 0)
+ stop_decoding(JPGD_BAD_RESTART_MARKER);
+
+ // Is it the expected marker? If not, something bad happened.
+ if (c != (m_next_restart_num + M_RST0))
+ stop_decoding(JPGD_BAD_RESTART_MARKER);
+
+ // Reset each component's DC prediction values.
+ memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
+
+ m_eob_run = 0;
+
+ m_restarts_left = m_restart_interval;
+
+ m_next_restart_num = (m_next_restart_num + 1) & 7;
+
+ // Get the bit buffer going again...
+
+ m_bits_left = 16;
+ get_bits_no_markers(16);
+ get_bits_no_markers(16);
+ }
+
+ static inline int dequantize_ac(int c, int q) { c *= q; return c; }
+
+ // Decodes and dequantizes the next row of coefficients.
+ void jpeg_decoder::decode_next_row()
+ {
+ int row_block = 0;
+
+ for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
+ {
+ if ((m_restart_interval) && (m_restarts_left == 0))
+ process_restart();
+
+ jpgd_block_coeff_t* p = m_pMCU_coefficients;
+ for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)
+ {
+ int component_id = m_mcu_org[mcu_block];
+ if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];
+
+ int r, s;
+ s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r);
+ if (s >= 16)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ s = JPGD_HUFF_EXTEND(r, s);
+
+ m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]);
+
+ p[0] = static_cast<jpgd_block_coeff_t>(s * q[0]);
+
+ int prev_num_set = m_mcu_block_max_zag[mcu_block];
+
+ huff_tables* pH = m_pHuff_tabs[m_comp_ac_tab[component_id]];
+
+ int k;
+ for (k = 1; k < 64; k++)
+ {
+ int extra_bits;
+ s = huff_decode(pH, extra_bits);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s)
+ {
+ if (r)
+ {
+ if ((k + r) > 63)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ if (k < prev_num_set)
+ {
+ int n = JPGD_MIN(r, prev_num_set - k);
+ int kt = k;
+ while (n--)
+ p[g_ZAG[kt++]] = 0;
+ }
+
+ k += r;
+ }
+
+ s = JPGD_HUFF_EXTEND(extra_bits, s);
+
+ if (k >= 64)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(dequantize_ac(s, q[k])); //s * q[k];
+ }
+ else
+ {
+ if (r == 15)
+ {
+ if ((k + 16) > 64)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ if (k < prev_num_set)
+ {
+ int n = JPGD_MIN(16, prev_num_set - k);
+ int kt = k;
+ while (n--)
+ {
+ if (kt > 63)
+ stop_decoding(JPGD_DECODE_ERROR);
+ p[g_ZAG[kt++]] = 0;
+ }
+ }
+
+ k += 16 - 1; // - 1 because the loop counter is k
+
+ if (p[g_ZAG[k & 63]] != 0)
+ stop_decoding(JPGD_DECODE_ERROR);
+ }
+ else
+ break;
+ }
+ }
+
+ if (k < prev_num_set)
+ {
+ int kt = k;
+ while (kt < prev_num_set)
+ p[g_ZAG[kt++]] = 0;
+ }
+
+ m_mcu_block_max_zag[mcu_block] = k;
+
+ row_block++;
+ }
+
+ transform_mcu(mcu_row);
+
+ m_restarts_left--;
+ }
+ }
+
+ // YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB
+ void jpeg_decoder::H1V1Convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d = m_pScan_line_0;
+ uint8* s = m_pSample_buf + row * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ int y = s[j];
+ int cb = s[64 + j];
+ int cr = s[128 + j];
+
+ d[0] = clamp(y + m_crr[cr]);
+ d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));
+ d[2] = clamp(y + m_cbb[cb]);
+ d[3] = 255;
+
+ d += 4;
+ }
+
+ s += 64 * 3;
+ }
+ }
+
+ // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB
+ void jpeg_decoder::H2V1Convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d0 = m_pScan_line_0;
+ uint8* y = m_pSample_buf + row * 8;
+ uint8* c = m_pSample_buf + 2 * 64 + row * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ for (int l = 0; l < 2; l++)
+ {
+ for (int j = 0; j < 4; j++)
+ {
+ int cb = c[0];
+ int cr = c[64];
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ int yy = y[j << 1];
+ d0[0] = clamp(yy + rc);
+ d0[1] = clamp(yy + gc);
+ d0[2] = clamp(yy + bc);
+ d0[3] = 255;
+
+ yy = y[(j << 1) + 1];
+ d0[4] = clamp(yy + rc);
+ d0[5] = clamp(yy + gc);
+ d0[6] = clamp(yy + bc);
+ d0[7] = 255;
+
+ d0 += 8;
+
+ c++;
+ }
+ y += 64;
+ }
+
+ y += 64 * 4 - 64 * 2;
+ c += 64 * 4 - 8;
+ }
+ }
+
+ // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB
+ void jpeg_decoder::H2V1ConvertFiltered()
+ {
+ const uint BLOCKS_PER_MCU = 4;
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d0 = m_pScan_line_0;
+
+ const int half_image_x_size = (m_image_x_size >> 1) - 1;
+ const int row_x8 = row * 8;
+
+ for (int x = 0; x < m_image_x_size; x++)
+ {
+ int y = m_pSample_buf[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + row_x8)];
+
+ int c_x0 = (x - 1) >> 1;
+ int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);
+ c_x0 = JPGD_MAX(c_x0, 0);
+
+ int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7) + row_x8 + 128;
+ int cb0 = m_pSample_buf[check_sample_buf_ofs(a)];
+ int cr0 = m_pSample_buf[check_sample_buf_ofs(a + 64)];
+
+ int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7) + row_x8 + 128;
+ int cb1 = m_pSample_buf[check_sample_buf_ofs(b)];
+ int cr1 = m_pSample_buf[check_sample_buf_ofs(b + 64)];
+
+ int w0 = (x & 1) ? 3 : 1;
+ int w1 = (x & 1) ? 1 : 3;
+
+ int cb = (cb0 * w0 + cb1 * w1 + 2) >> 2;
+ int cr = (cr0 * w0 + cr1 * w1 + 2) >> 2;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y + rc);
+ d0[1] = clamp(y + gc);
+ d0[2] = clamp(y + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+ }
+
+ // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB
+ void jpeg_decoder::H1V2Convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d0 = m_pScan_line_0;
+ uint8* d1 = m_pScan_line_1;
+ uint8* y;
+ uint8* c;
+
+ if (row < 8)
+ y = m_pSample_buf + row * 8;
+ else
+ y = m_pSample_buf + 64 * 1 + (row & 7) * 8;
+
+ c = m_pSample_buf + 64 * 2 + (row >> 1) * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ int cb = c[0 + j];
+ int cr = c[64 + j];
int rc = m_crr[cr];
int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
int bc = m_cbb[cb];
int yy = y[j];
- d0[0] = clamp(yy+rc);
- d0[1] = clamp(yy+gc);
- d0[2] = clamp(yy+bc);
+ d0[0] = clamp(yy + rc);
+ d0[1] = clamp(yy + gc);
+ d0[2] = clamp(yy + bc);
d0[3] = 255;
- yy = y[j+1];
- d0[4] = clamp(yy+rc);
- d0[5] = clamp(yy+gc);
- d0[6] = clamp(yy+bc);
- d0[7] = 255;
-
- yy = y[j+8];
- d1[0] = clamp(yy+rc);
- d1[1] = clamp(yy+gc);
- d1[2] = clamp(yy+bc);
+ yy = y[8 + j];
+ d1[0] = clamp(yy + rc);
+ d1[1] = clamp(yy + gc);
+ d1[2] = clamp(yy + bc);
d1[3] = 255;
- yy = y[j+8+1];
- d1[4] = clamp(yy+rc);
- d1[5] = clamp(yy+gc);
- d1[6] = clamp(yy+bc);
- d1[7] = 255;
+ d0 += 4;
+ d1 += 4;
+ }
+
+ y += 64 * 4;
+ c += 64 * 4;
+ }
+ }
+
+ // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB
+ void jpeg_decoder::H1V2ConvertFiltered()
+ {
+ const uint BLOCKS_PER_MCU = 4;
+ int y = m_image_y_size - m_total_lines_left;
+ int row = y & 15;
+
+ const int half_image_y_size = (m_image_y_size >> 1) - 1;
+
+ uint8* d0 = m_pScan_line_0;
+
+ const int w0 = (row & 1) ? 3 : 1;
+ const int w1 = (row & 1) ? 1 : 3;
+
+ int c_y0 = (y - 1) >> 1;
+ int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size);
+
+ const uint8_t* p_YSamples = m_pSample_buf;
+ const uint8_t* p_C0Samples = m_pSample_buf;
+ if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1))
+ {
+ assert(y > 0);
+ assert(m_sample_buf_prev_valid);
+
+ if ((row & 15) == 15)
+ p_YSamples = m_pSample_buf_prev;
- d0 += 8;
- d1 += 8;
+ p_C0Samples = m_pSample_buf_prev;
+ }
+
+ const int y_sample_base_ofs = ((row & 8) ? 64 : 0) + (row & 7) * 8;
+ const int y0_base = (c_y0 & 7) * 8 + 128;
+ const int y1_base = (c_y1 & 7) * 8 + 128;
+
+ for (int x = 0; x < m_image_x_size; x++)
+ {
+ const int base_ofs = (x >> 3) * BLOCKS_PER_MCU * 64 + (x & 7);
+
+ int y_sample = p_YSamples[check_sample_buf_ofs(base_ofs + y_sample_base_ofs)];
+
+ int a = base_ofs + y0_base;
+ int cb0_sample = p_C0Samples[check_sample_buf_ofs(a)];
+ int cr0_sample = p_C0Samples[check_sample_buf_ofs(a + 64)];
+
+ int b = base_ofs + y1_base;
+ int cb1_sample = m_pSample_buf[check_sample_buf_ofs(b)];
+ int cr1_sample = m_pSample_buf[check_sample_buf_ofs(b + 64)];
+
+ int cb = (cb0_sample * w0 + cb1_sample * w1 + 2) >> 2;
+ int cr = (cr0_sample * w0 + cr1_sample * w1 + 2) >> 2;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y_sample + rc);
+ d0[1] = clamp(y_sample + gc);
+ d0[2] = clamp(y_sample + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+ }
+
+ // YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB
+ void jpeg_decoder::H2V2Convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d0 = m_pScan_line_0;
+ uint8* d1 = m_pScan_line_1;
+ uint8* y;
+ uint8* c;
- c++;
+ if (row < 8)
+ y = m_pSample_buf + row * 8;
+ else
+ y = m_pSample_buf + 64 * 2 + (row & 7) * 8;
+
+ c = m_pSample_buf + 64 * 4 + (row >> 1) * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ for (int l = 0; l < 2; l++)
+ {
+ for (int j = 0; j < 8; j += 2)
+ {
+ int cb = c[0];
+ int cr = c[64];
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ int yy = y[j];
+ d0[0] = clamp(yy + rc);
+ d0[1] = clamp(yy + gc);
+ d0[2] = clamp(yy + bc);
+ d0[3] = 255;
+
+ yy = y[j + 1];
+ d0[4] = clamp(yy + rc);
+ d0[5] = clamp(yy + gc);
+ d0[6] = clamp(yy + bc);
+ d0[7] = 255;
+
+ yy = y[j + 8];
+ d1[0] = clamp(yy + rc);
+ d1[1] = clamp(yy + gc);
+ d1[2] = clamp(yy + bc);
+ d1[3] = 255;
+
+ yy = y[j + 8 + 1];
+ d1[4] = clamp(yy + rc);
+ d1[5] = clamp(yy + gc);
+ d1[6] = clamp(yy + bc);
+ d1[7] = 255;
+
+ d0 += 8;
+ d1 += 8;
+
+ c++;
+ }
+ y += 64;
}
- y += 64;
- }
-
- y += 64*6 - 64*2;
- c += 64*6 - 8;
- }
-}
-
-// Y (1 block per MCU) to 8-bit grayscale
-void jpeg_decoder::gray_convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d = m_pScan_line_0;
- uint8 *s = m_pSample_buf + row * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- *(uint *)d = *(uint *)s;
- *(uint *)(&d[4]) = *(uint *)(&s[4]);
-
- s += 64;
- d += 8;
- }
-}
-
-void jpeg_decoder::expanded_convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
-
- uint8* Py = m_pSample_buf + (row / 8) * 64 * m_comp_h_samp[0] + (row & 7) * 8;
-
- uint8* d = m_pScan_line_0;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int k = 0; k < m_max_mcu_x_size; k += 8)
- {
- const int Y_ofs = k * 8;
- const int Cb_ofs = Y_ofs + 64 * m_expanded_blocks_per_component;
- const int Cr_ofs = Y_ofs + 64 * m_expanded_blocks_per_component * 2;
- for (int j = 0; j < 8; j++)
- {
- int y = Py[Y_ofs + j];
- int cb = Py[Cb_ofs + j];
- int cr = Py[Cr_ofs + j];
-
- d[0] = clamp(y + m_crr[cr]);
- d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));
- d[2] = clamp(y + m_cbb[cb]);
- d[3] = 255;
-
- d += 4;
- }
- }
-
- Py += 64 * m_expanded_blocks_per_mcu;
- }
-}
-
-// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream.
-void jpeg_decoder::find_eoi()
-{
- if (!m_progressive_flag)
- {
- // Attempt to read the EOI marker.
- //get_bits_no_markers(m_bits_left & 7);
-
- // Prime the bit buffer
- m_bits_left = 16;
- get_bits(16);
- get_bits(16);
-
- // The next marker _should_ be EOI
- process_markers();
- }
-
- m_total_bytes_read -= m_in_buf_left;
-}
-
-int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len)
-{
- if ((m_error_code) || (!m_ready_flag))
- return JPGD_FAILED;
-
- if (m_total_lines_left == 0)
- return JPGD_DONE;
-
- if (m_mcu_lines_left == 0)
- {
- if (setjmp(m_jmp_state))
- return JPGD_FAILED;
-
- if (m_progressive_flag)
- load_next_row();
- else
- decode_next_row();
-
- // Find the EOI marker if that was the last row.
- if (m_total_lines_left <= m_max_mcu_y_size)
- find_eoi();
-
- m_mcu_lines_left = m_max_mcu_y_size;
- }
-
- if (m_freq_domain_chroma_upsample)
- {
- expanded_convert();
- *pScan_line = m_pScan_line_0;
- }
- else
- {
- switch (m_scan_type)
- {
- case JPGD_YH2V2:
- {
- if ((m_mcu_lines_left & 1) == 0)
- {
- H2V2Convert();
- *pScan_line = m_pScan_line_0;
- }
- else
- *pScan_line = m_pScan_line_1;
-
- break;
- }
- case JPGD_YH2V1:
- {
- H2V1Convert();
- *pScan_line = m_pScan_line_0;
- break;
- }
- case JPGD_YH1V2:
- {
- if ((m_mcu_lines_left & 1) == 0)
- {
- H1V2Convert();
- *pScan_line = m_pScan_line_0;
- }
- else
- *pScan_line = m_pScan_line_1;
-
- break;
- }
- case JPGD_YH1V1:
- {
- H1V1Convert();
- *pScan_line = m_pScan_line_0;
- break;
- }
- case JPGD_GRAYSCALE:
- {
- gray_convert();
- *pScan_line = m_pScan_line_0;
-
- break;
- }
- }
- }
-
- *pScan_line_len = m_real_dest_bytes_per_scan_line;
-
- m_mcu_lines_left--;
- m_total_lines_left--;
-
- return JPGD_SUCCESS;
-}
-
-// Creates the tables needed for efficient Huffman decoding.
-void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
-{
- int p, i, l, si;
- uint8 huffsize[257];
- uint huffcode[257];
- uint code;
- uint subtree;
- int code_size;
- int lastp;
- int nextfreeentry;
- int currententry;
-
- pH->ac_table = m_huff_ac[index] != 0;
-
- p = 0;
-
- for (l = 1; l <= 16; l++)
- {
- for (i = 1; i <= m_huff_num[index][l]; i++)
- {
- JPGD_ASSERT(p < 257);
- huffsize[p++] = static_cast<uint8>(l);
- }
- }
-
- huffsize[p] = 0;
-
- lastp = p;
-
- code = 0;
- si = huffsize[0];
- p = 0;
-
- while (huffsize[p])
- {
- while (huffsize[p] == si)
- {
- JPGD_ASSERT(p < 257);
- huffcode[p++] = code;
- code++;
- }
-
- code <<= 1;
- si++;
- }
-
- memset(pH->look_up, 0, sizeof(pH->look_up));
- memset(pH->look_up2, 0, sizeof(pH->look_up2));
- memset(pH->tree, 0, sizeof(pH->tree));
- memset(pH->code_size, 0, sizeof(pH->code_size));
-
- nextfreeentry = -1;
-
- p = 0;
-
- while (p < lastp)
- {
- i = m_huff_val[index][p];
- code = huffcode[p];
- code_size = huffsize[p];
-
- pH->code_size[i] = static_cast<uint8>(code_size);
-
- if (code_size <= 8)
- {
- code <<= (8 - code_size);
-
- for (l = 1 << (8 - code_size); l > 0; l--)
- {
- JPGD_ASSERT(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
- JPGD_ASSERT(code < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
-
- pH->look_up[code] = i;
-
- bool has_extrabits = false;
- int extra_bits = 0;
- int num_extra_bits = i & 15;
-
- int bits_to_fetch = code_size;
- if (num_extra_bits)
- {
- int total_codesize = code_size + num_extra_bits;
- if (total_codesize <= 8)
- {
- has_extrabits = true;
- extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize));
- JPGD_ASSERT(extra_bits <= 0x7FFF);
- bits_to_fetch += num_extra_bits;
- }
- }
-
- if (!has_extrabits)
- pH->look_up2[code] = i | (bits_to_fetch << 8);
- else
- pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8);
-
- code++;
- }
- }
- else
- {
- subtree = (code >> (code_size - 8)) & 0xFF;
-
- currententry = pH->look_up[subtree];
-
- if (currententry == 0)
- {
- pH->look_up[subtree] = currententry = nextfreeentry;
- pH->look_up2[subtree] = currententry = nextfreeentry;
-
- nextfreeentry -= 2;
- }
-
- code <<= (16 - (code_size - 8));
-
- for (l = code_size; l > 9; l--)
- {
- if ((code & 0x8000) == 0)
- currententry--;
-
- unsigned int idx = -currententry - 1;
- JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
- if (pH->tree[idx] == 0)
- {
- pH->tree[idx] = nextfreeentry;
-
- currententry = nextfreeentry;
-
- nextfreeentry -= 2;
- }
- else {
- currententry = pH->tree[idx];
- }
-
- code <<= 1;
- }
-
- if ((code & 0x8000) == 0)
- currententry--;
-
- pH->tree[-currententry - 1] = i;
- }
-
- p++;
- }
-}
-
-// Verifies the quantization tables needed for this scan are available.
-void jpeg_decoder::check_quant_tables()
-{
- for (int i = 0; i < m_comps_in_scan; i++)
- if (m_quant[m_comp_quant[m_comp_list[i]]] == NULL)
- stop_decoding(JPGD_UNDEFINED_QUANT_TABLE);
-}
-
-// Verifies that all the Huffman tables needed for this scan are available.
-void jpeg_decoder::check_huff_tables()
-{
- for (int i = 0; i < m_comps_in_scan; i++)
- {
- if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == NULL))
- stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
-
- if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == NULL))
- stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
- }
-
- for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++)
- if (m_huff_num[i])
- {
- if (!m_pHuff_tabs[i])
- m_pHuff_tabs[i] = (huff_tables *)alloc(sizeof(huff_tables));
-
- make_huff_table(i, m_pHuff_tabs[i]);
- }
-}
-
-// Determines the component order inside each MCU.
-// Also calcs how many MCU's are on each row, etc.
-void jpeg_decoder::calc_mcu_block_order()
-{
- int component_num, component_id;
- int max_h_samp = 0, max_v_samp = 0;
-
- for (component_id = 0; component_id < m_comps_in_frame; component_id++)
- {
- if (m_comp_h_samp[component_id] > max_h_samp)
- max_h_samp = m_comp_h_samp[component_id];
-
- if (m_comp_v_samp[component_id] > max_v_samp)
- max_v_samp = m_comp_v_samp[component_id];
- }
-
- for (component_id = 0; component_id < m_comps_in_frame; component_id++)
- {
- m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8;
- m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8;
- }
-
- if (m_comps_in_scan == 1)
- {
- m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]];
- m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]];
- }
- else
- {
- m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp;
- m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp;
- }
-
- if (m_comps_in_scan == 1)
- {
- m_mcu_org[0] = m_comp_list[0];
-
- m_blocks_per_mcu = 1;
- }
- else
- {
- m_blocks_per_mcu = 0;
-
- for (component_num = 0; component_num < m_comps_in_scan; component_num++)
- {
- int num_blocks;
-
- component_id = m_comp_list[component_num];
-
- num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id];
-
- while (num_blocks--)
- m_mcu_org[m_blocks_per_mcu++] = component_id;
- }
- }
-}
-
-// Starts a new scan.
-int jpeg_decoder::init_scan()
-{
- if (!locate_sos_marker())
- return JPGD_FALSE;
-
- calc_mcu_block_order();
-
- check_huff_tables();
-
- check_quant_tables();
-
- memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
-
- m_eob_run = 0;
-
- if (m_restart_interval)
- {
- m_restarts_left = m_restart_interval;
- m_next_restart_num = 0;
- }
-
- fix_in_buffer();
-
- return JPGD_TRUE;
-}
-
-// Starts a frame. Determines if the number of components or sampling factors
-// are supported.
-void jpeg_decoder::init_frame()
-{
- int i;
-
- if (m_comps_in_frame == 1)
- {
- if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1))
- stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
-
- m_scan_type = JPGD_GRAYSCALE;
- m_max_blocks_per_mcu = 1;
- m_max_mcu_x_size = 8;
- m_max_mcu_y_size = 8;
- }
- else if (m_comps_in_frame == 3)
- {
- if ( ((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) ||
- ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)) )
- stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
-
- if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1))
- {
- m_scan_type = JPGD_YH1V1;
-
- m_max_blocks_per_mcu = 3;
- m_max_mcu_x_size = 8;
- m_max_mcu_y_size = 8;
- }
- else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1))
- {
- m_scan_type = JPGD_YH2V1;
- m_max_blocks_per_mcu = 4;
- m_max_mcu_x_size = 16;
- m_max_mcu_y_size = 8;
- }
- else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2))
- {
- m_scan_type = JPGD_YH1V2;
- m_max_blocks_per_mcu = 4;
- m_max_mcu_x_size = 8;
- m_max_mcu_y_size = 16;
- }
- else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2))
- {
- m_scan_type = JPGD_YH2V2;
- m_max_blocks_per_mcu = 6;
- m_max_mcu_x_size = 16;
- m_max_mcu_y_size = 16;
- }
- else
- stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
- }
- else
- stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
-
- m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size;
- m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size;
-
- // These values are for the *destination* pixels: after conversion.
- if (m_scan_type == JPGD_GRAYSCALE)
- m_dest_bytes_per_pixel = 1;
- else
- m_dest_bytes_per_pixel = 4;
-
- m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel;
-
- m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel);
-
- // Initialize two scan line buffers.
- m_pScan_line_0 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true);
- if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2))
- m_pScan_line_1 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true);
-
- m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu;
-
- // Should never happen
- if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW)
- stop_decoding(JPGD_ASSERTION_ERROR);
-
- // Allocate the coefficient buffer, enough for one MCU
- m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t));
-
- for (i = 0; i < m_max_blocks_per_mcu; i++)
- m_mcu_block_max_zag[i] = 64;
-
- m_expanded_blocks_per_component = m_comp_h_samp[0] * m_comp_v_samp[0];
- m_expanded_blocks_per_mcu = m_expanded_blocks_per_component * m_comps_in_frame;
- m_expanded_blocks_per_row = m_max_mcus_per_row * m_expanded_blocks_per_mcu;
- // Freq. domain chroma upsampling is only supported for H2V2 subsampling factor (the most common one I've seen).
- m_freq_domain_chroma_upsample = false;
-#if JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING
- m_freq_domain_chroma_upsample = (m_expanded_blocks_per_mcu == 4*3);
-#endif
- if (m_freq_domain_chroma_upsample)
- m_pSample_buf = (uint8 *)alloc(m_expanded_blocks_per_row * 64);
- else
- m_pSample_buf = (uint8 *)alloc(m_max_blocks_per_row * 64);
-
- m_total_lines_left = m_image_y_size;
-
- m_mcu_lines_left = 0;
-
- create_look_ups();
-}
-
-// The coeff_buf series of methods originally stored the coefficients
-// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache
-// was used to make this process more efficient. Now, we can store the entire
-// thing in RAM.
-jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y)
-{
- coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf));
-
- cb->block_num_x = block_num_x;
- cb->block_num_y = block_num_y;
- cb->block_len_x = block_len_x;
- cb->block_len_y = block_len_y;
- cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t);
- cb->pData = (uint8 *)alloc(cb->block_size * block_num_x * block_num_y, true);
- return cb;
-}
-
-inline jpgd_block_t *jpeg_decoder::coeff_buf_getp(coeff_buf *cb, int block_x, int block_y)
-{
- JPGD_ASSERT((block_x < cb->block_num_x) && (block_y < cb->block_num_y));
- return (jpgd_block_t *)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x));
-}
-
-// The following methods decode the various types of m_blocks encountered
-// in progressively encoded images.
-void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y)
-{
- int s, r;
- jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
-
- if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0)
- {
- r = pD->get_bits_no_markers(s);
- s = JPGD_HUFF_EXTEND(r, s);
- }
-
- pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]);
-
- p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low);
-}
-
-void jpeg_decoder::decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y)
-{
- if (pD->get_bits_no_markers(1))
- {
- jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
-
- p[0] |= (1 << pD->m_successive_low);
- }
-}
-
-void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y)
-{
- int k, s, r;
-
- if (pD->m_eob_run)
- {
- pD->m_eob_run--;
- return;
- }
-
- jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
-
- for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)
- {
- unsigned int idx = pD->m_comp_ac_tab[component_id];
- JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
- s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
-
- r = s >> 4;
- s &= 15;
-
- if (s)
- {
- if ((k += r) > 63)
- pD->stop_decoding(JPGD_DECODE_ERROR);
-
- r = pD->get_bits_no_markers(s);
- s = JPGD_HUFF_EXTEND(r, s);
-
- p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low);
- }
- else
- {
- if (r == 15)
- {
- if ((k += 15) > 63)
- pD->stop_decoding(JPGD_DECODE_ERROR);
- }
- else
- {
- pD->m_eob_run = 1 << r;
-
- if (r)
- pD->m_eob_run += pD->get_bits_no_markers(r);
-
- pD->m_eob_run--;
-
- break;
- }
- }
- }
-}
-
-void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y)
-{
- int s, k, r;
- int p1 = 1 << pD->m_successive_low;
- int m1 = (-1) << pD->m_successive_low;
- jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
- JPGD_ASSERT(pD->m_spectral_end <= 63);
-
- k = pD->m_spectral_start;
-
- if (pD->m_eob_run == 0)
- {
- for ( ; k <= pD->m_spectral_end; k++)
- {
- unsigned int idx = pD->m_comp_ac_tab[component_id];
- JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
- s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
-
- r = s >> 4;
- s &= 15;
-
- if (s)
- {
- if (s != 1)
- pD->stop_decoding(JPGD_DECODE_ERROR);
-
- if (pD->get_bits_no_markers(1))
- s = p1;
- else
- s = m1;
- }
- else
- {
- if (r != 15)
- {
- pD->m_eob_run = 1 << r;
-
- if (r)
- pD->m_eob_run += pD->get_bits_no_markers(r);
-
- break;
- }
- }
-
- do
- {
- jpgd_block_t *this_coef = p + g_ZAG[k & 63];
-
- if (*this_coef != 0)
- {
- if (pD->get_bits_no_markers(1))
- {
- if ((*this_coef & p1) == 0)
- {
- if (*this_coef >= 0)
- *this_coef = static_cast<jpgd_block_t>(*this_coef + p1);
- else
- *this_coef = static_cast<jpgd_block_t>(*this_coef + m1);
- }
- }
- }
- else
- {
- if (--r < 0)
- break;
- }
-
- k++;
-
- } while (k <= pD->m_spectral_end);
-
- if ((s) && (k < 64))
- {
- p[g_ZAG[k]] = static_cast<jpgd_block_t>(s);
- }
- }
- }
-
- if (pD->m_eob_run > 0)
- {
- for ( ; k <= pD->m_spectral_end; k++)
- {
- jpgd_block_t *this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis
-
- if (*this_coef != 0)
- {
- if (pD->get_bits_no_markers(1))
- {
- if ((*this_coef & p1) == 0)
- {
- if (*this_coef >= 0)
- *this_coef = static_cast<jpgd_block_t>(*this_coef + p1);
- else
- *this_coef = static_cast<jpgd_block_t>(*this_coef + m1);
- }
- }
- }
- }
-
- pD->m_eob_run--;
- }
-}
-
-// Decode a scan in a progressively encoded image.
-void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func)
-{
- int mcu_row, mcu_col, mcu_block;
- int block_x_mcu[JPGD_MAX_COMPONENTS], m_block_y_mcu[JPGD_MAX_COMPONENTS];
-
- memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
-
- for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++)
- {
- int component_num, component_id;
-
- memset(block_x_mcu, 0, sizeof(block_x_mcu));
-
- for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
- {
- int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
-
- if ((m_restart_interval) && (m_restarts_left == 0))
- process_restart();
-
- for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
- {
- component_id = m_mcu_org[mcu_block];
-
- decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
-
- if (m_comps_in_scan == 1)
- block_x_mcu[component_id]++;
- else
- {
- if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
- {
- block_x_mcu_ofs = 0;
-
- if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
- {
- block_y_mcu_ofs = 0;
- block_x_mcu[component_id] += m_comp_h_samp[component_id];
- }
- }
- }
- }
-
- m_restarts_left--;
- }
-
- if (m_comps_in_scan == 1)
- m_block_y_mcu[m_comp_list[0]]++;
- else
- {
- for (component_num = 0; component_num < m_comps_in_scan; component_num++)
- {
- component_id = m_comp_list[component_num];
- m_block_y_mcu[component_id] += m_comp_v_samp[component_id];
- }
- }
- }
-}
-
-// Decode a progressively encoded image.
-void jpeg_decoder::init_progressive()
-{
- int i;
-
- if (m_comps_in_frame == 4)
- stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
-
- // Allocate the coefficient buffers.
- for (i = 0; i < m_comps_in_frame; i++)
- {
- m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1);
- m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8);
- }
-
- for ( ; ; )
- {
- int dc_only_scan, refinement_scan;
- pDecode_block_func decode_block_func;
-
- if (!init_scan())
- break;
-
- dc_only_scan = (m_spectral_start == 0);
- refinement_scan = (m_successive_high != 0);
-
- if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63))
- stop_decoding(JPGD_BAD_SOS_SPECTRAL);
-
- if (dc_only_scan)
- {
- if (m_spectral_end)
- stop_decoding(JPGD_BAD_SOS_SPECTRAL);
- }
- else if (m_comps_in_scan != 1) /* AC scans can only contain one component */
- stop_decoding(JPGD_BAD_SOS_SPECTRAL);
-
- if ((refinement_scan) && (m_successive_low != m_successive_high - 1))
- stop_decoding(JPGD_BAD_SOS_SUCCESSIVE);
-
- if (dc_only_scan)
- {
- if (refinement_scan)
- decode_block_func = decode_block_dc_refine;
- else
- decode_block_func = decode_block_dc_first;
- }
- else
- {
- if (refinement_scan)
- decode_block_func = decode_block_ac_refine;
- else
- decode_block_func = decode_block_ac_first;
- }
-
- decode_scan(decode_block_func);
-
- m_bits_left = 16;
- get_bits(16);
- get_bits(16);
- }
-
- m_comps_in_scan = m_comps_in_frame;
-
- for (i = 0; i < m_comps_in_frame; i++)
- m_comp_list[i] = i;
-
- calc_mcu_block_order();
-}
-
-void jpeg_decoder::init_sequential()
-{
- if (!init_scan())
- stop_decoding(JPGD_UNEXPECTED_MARKER);
-}
-
-void jpeg_decoder::decode_start()
-{
- init_frame();
-
- if (m_progressive_flag)
- init_progressive();
- else
- init_sequential();
-}
-
-void jpeg_decoder::decode_init(jpeg_decoder_stream *pStream)
-{
- init(pStream);
- locate_sof_marker();
-}
-
-jpeg_decoder::jpeg_decoder(jpeg_decoder_stream *pStream)
-{
- if (setjmp(m_jmp_state))
- return;
- decode_init(pStream);
-}
-
-int jpeg_decoder::begin_decoding()
-{
- if (m_ready_flag)
- return JPGD_SUCCESS;
-
- if (m_error_code)
- return JPGD_FAILED;
-
- if (setjmp(m_jmp_state))
- return JPGD_FAILED;
-
- decode_start();
-
- m_ready_flag = true;
-
- return JPGD_SUCCESS;
-}
-
-jpeg_decoder::~jpeg_decoder()
-{
- free_all_blocks();
-}
-
-jpeg_decoder_file_stream::jpeg_decoder_file_stream()
-{
- m_pFile = NULL;
- m_eof_flag = false;
- m_error_flag = false;
-}
-
-void jpeg_decoder_file_stream::close()
-{
- if (m_pFile)
- {
- fclose(m_pFile);
- m_pFile = NULL;
- }
-
- m_eof_flag = false;
- m_error_flag = false;
-}
-
-jpeg_decoder_file_stream::~jpeg_decoder_file_stream()
-{
- close();
-}
-
-bool jpeg_decoder_file_stream::open(const char *Pfilename)
-{
- close();
-
- m_eof_flag = false;
- m_error_flag = false;
+ y += 64 * 6 - 64 * 2;
+ c += 64 * 6 - 8;
+ }
+ }
+
+ uint32_t jpeg_decoder::H2V2ConvertFiltered()
+ {
+ const uint BLOCKS_PER_MCU = 6;
+ int y = m_image_y_size - m_total_lines_left;
+ int row = y & 15;
+
+ const int half_image_y_size = (m_image_y_size >> 1) - 1;
+
+ uint8* d0 = m_pScan_line_0;
+
+ int c_y0 = (y - 1) >> 1;
+ int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size);
+
+ const uint8_t* p_YSamples = m_pSample_buf;
+ const uint8_t* p_C0Samples = m_pSample_buf;
+ if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1))
+ {
+ assert(y > 0);
+ assert(m_sample_buf_prev_valid);
+
+ if ((row & 15) == 15)
+ p_YSamples = m_pSample_buf_prev;
+
+ p_C0Samples = m_pSample_buf_prev;
+ }
+
+ const int y_sample_base_ofs = ((row & 8) ? 128 : 0) + (row & 7) * 8;
+ const int y0_base = (c_y0 & 7) * 8 + 256;
+ const int y1_base = (c_y1 & 7) * 8 + 256;
+
+ const int half_image_x_size = (m_image_x_size >> 1) - 1;
+
+ static const uint8_t s_muls[2][2][4] =
+ {
+ { { 1, 3, 3, 9 }, { 3, 9, 1, 3 }, },
+ { { 3, 1, 9, 3 }, { 9, 3, 3, 1 } }
+ };
+
+ if (((row & 15) >= 1) && ((row & 15) <= 14))
+ {
+ assert((row & 1) == 1);
+ assert(((y + 1 - 1) >> 1) == c_y0);
+
+ assert(p_YSamples == m_pSample_buf);
+ assert(p_C0Samples == m_pSample_buf);
+
+ uint8* d1 = m_pScan_line_1;
+ const int y_sample_base_ofs1 = (((row + 1) & 8) ? 128 : 0) + ((row + 1) & 7) * 8;
+
+ for (int x = 0; x < m_image_x_size; x++)
+ {
+ int k = (x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7);
+ int y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)];
+ int y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)];
+
+ int c_x0 = (x - 1) >> 1;
+ int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);
+ c_x0 = JPGD_MAX(c_x0, 0);
+
+ int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7);
+ int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)];
+ int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)];
+
+ int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)];
+ int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)];
+
+ int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7);
+ int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)];
+ int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)];
+
+ int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)];
+ int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)];
+
+ {
+ const uint8_t* pMuls = &s_muls[row & 1][x & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y_sample0 + rc);
+ d0[1] = clamp(y_sample0 + gc);
+ d0[2] = clamp(y_sample0 + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+
+ {
+ const uint8_t* pMuls = &s_muls[(row + 1) & 1][x & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d1[0] = clamp(y_sample1 + rc);
+ d1[1] = clamp(y_sample1 + gc);
+ d1[2] = clamp(y_sample1 + bc);
+ d1[3] = 255;
+
+ d1 += 4;
+ }
+
+ if (((x & 1) == 1) && (x < m_image_x_size - 1))
+ {
+ const int nx = x + 1;
+ assert(c_x0 == (nx - 1) >> 1);
+
+ k = (nx >> 4) * BLOCKS_PER_MCU * 64 + ((nx & 8) ? 64 : 0) + (nx & 7);
+ y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)];
+ y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)];
+
+ {
+ const uint8_t* pMuls = &s_muls[row & 1][nx & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y_sample0 + rc);
+ d0[1] = clamp(y_sample0 + gc);
+ d0[2] = clamp(y_sample0 + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+
+ {
+ const uint8_t* pMuls = &s_muls[(row + 1) & 1][nx & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d1[0] = clamp(y_sample1 + rc);
+ d1[1] = clamp(y_sample1 + gc);
+ d1[2] = clamp(y_sample1 + bc);
+ d1[3] = 255;
+
+ d1 += 4;
+ }
+
+ ++x;
+ }
+ }
+
+ return 2;
+ }
+ else
+ {
+ for (int x = 0; x < m_image_x_size; x++)
+ {
+ int y_sample = p_YSamples[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + y_sample_base_ofs)];
+
+ int c_x0 = (x - 1) >> 1;
+ int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);
+ c_x0 = JPGD_MAX(c_x0, 0);
+
+ int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7);
+ int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)];
+ int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)];
+
+ int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)];
+ int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)];
+
+ int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7);
+ int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)];
+ int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)];
+
+ int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)];
+ int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)];
+
+ const uint8_t* pMuls = &s_muls[row & 1][x & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y_sample + rc);
+ d0[1] = clamp(y_sample + gc);
+ d0[2] = clamp(y_sample + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+
+ return 1;
+ }
+ }
+
+ // Y (1 block per MCU) to 8-bit grayscale
+ void jpeg_decoder::gray_convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d = m_pScan_line_0;
+ uint8* s = m_pSample_buf + row * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ *(uint*)d = *(uint*)s;
+ *(uint*)(&d[4]) = *(uint*)(&s[4]);
+
+ s += 64;
+ d += 8;
+ }
+ }
+
+ // Find end of image (EOI) marker, so we can return to the user the exact size of the input stream.
+ void jpeg_decoder::find_eoi()
+ {
+ if (!m_progressive_flag)
+ {
+ // Attempt to read the EOI marker.
+ //get_bits_no_markers(m_bits_left & 7);
+
+ // Prime the bit buffer
+ m_bits_left = 16;
+ get_bits(16);
+ get_bits(16);
+
+ // The next marker _should_ be EOI
+ process_markers();
+ }
+
+ m_total_bytes_read -= m_in_buf_left;
+ }
+
+ int jpeg_decoder::decode_next_mcu_row()
+ {
+ if (::setjmp(m_jmp_state))
+ return JPGD_FAILED;
+
+ const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));
+ if (chroma_y_filtering)
+ {
+ std::swap(m_pSample_buf, m_pSample_buf_prev);
+
+ m_sample_buf_prev_valid = true;
+ }
+
+ if (m_progressive_flag)
+ load_next_row();
+ else
+ decode_next_row();
+
+ // Find the EOI marker if that was the last row.
+ if (m_total_lines_left <= m_max_mcu_y_size)
+ find_eoi();
+
+ m_mcu_lines_left = m_max_mcu_y_size;
+ return 0;
+ }
+
+ int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len)
+ {
+ if ((m_error_code) || (!m_ready_flag))
+ return JPGD_FAILED;
+
+ if (m_total_lines_left == 0)
+ return JPGD_DONE;
+
+ const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));
+
+ bool get_another_mcu_row = false;
+ bool got_mcu_early = false;
+ if (chroma_y_filtering)
+ {
+ if (m_total_lines_left == m_image_y_size)
+ get_another_mcu_row = true;
+ else if ((m_mcu_lines_left == 1) && (m_total_lines_left > 1))
+ {
+ get_another_mcu_row = true;
+ got_mcu_early = true;
+ }
+ }
+ else
+ {
+ get_another_mcu_row = (m_mcu_lines_left == 0);
+ }
+
+ if (get_another_mcu_row)
+ {
+ int status = decode_next_mcu_row();
+ if (status != 0)
+ return status;
+ }
+
+ switch (m_scan_type)
+ {
+ case JPGD_YH2V2:
+ {
+ if ((m_flags & cFlagBoxChromaFiltering) == 0)
+ {
+ if (m_num_buffered_scanlines == 1)
+ {
+ *pScan_line = m_pScan_line_1;
+ }
+ else if (m_num_buffered_scanlines == 0)
+ {
+ m_num_buffered_scanlines = H2V2ConvertFiltered();
+ *pScan_line = m_pScan_line_0;
+ }
+
+ m_num_buffered_scanlines--;
+ }
+ else
+ {
+ if ((m_mcu_lines_left & 1) == 0)
+ {
+ H2V2Convert();
+ *pScan_line = m_pScan_line_0;
+ }
+ else
+ *pScan_line = m_pScan_line_1;
+ }
+
+ break;
+ }
+ case JPGD_YH2V1:
+ {
+ if ((m_flags & cFlagBoxChromaFiltering) == 0)
+ H2V1ConvertFiltered();
+ else
+ H2V1Convert();
+ *pScan_line = m_pScan_line_0;
+ break;
+ }
+ case JPGD_YH1V2:
+ {
+ if (chroma_y_filtering)
+ {
+ H1V2ConvertFiltered();
+ *pScan_line = m_pScan_line_0;
+ }
+ else
+ {
+ if ((m_mcu_lines_left & 1) == 0)
+ {
+ H1V2Convert();
+ *pScan_line = m_pScan_line_0;
+ }
+ else
+ *pScan_line = m_pScan_line_1;
+ }
+
+ break;
+ }
+ case JPGD_YH1V1:
+ {
+ H1V1Convert();
+ *pScan_line = m_pScan_line_0;
+ break;
+ }
+ case JPGD_GRAYSCALE:
+ {
+ gray_convert();
+ *pScan_line = m_pScan_line_0;
+
+ break;
+ }
+ }
+
+ *pScan_line_len = m_real_dest_bytes_per_scan_line;
+
+ if (!got_mcu_early)
+ {
+ m_mcu_lines_left--;
+ }
+
+ m_total_lines_left--;
+
+ return JPGD_SUCCESS;
+ }
+
+ // Creates the tables needed for efficient Huffman decoding.
+ void jpeg_decoder::make_huff_table(int index, huff_tables* pH)
+ {
+ int p, i, l, si;
+ uint8 huffsize[258];
+ uint huffcode[258];
+ uint code;
+ uint subtree;
+ int code_size;
+ int lastp;
+ int nextfreeentry;
+ int currententry;
+
+ pH->ac_table = m_huff_ac[index] != 0;
+
+ p = 0;
+
+ for (l = 1; l <= 16; l++)
+ {
+ for (i = 1; i <= m_huff_num[index][l]; i++)
+ {
+ if (p >= 257)
+ stop_decoding(JPGD_DECODE_ERROR);
+ huffsize[p++] = static_cast<uint8>(l);
+ }
+ }
+
+ assert(p < 258);
+ huffsize[p] = 0;
+
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+
+ while (huffsize[p])
+ {
+ while (huffsize[p] == si)
+ {
+ if (p >= 257)
+ stop_decoding(JPGD_DECODE_ERROR);
+ huffcode[p++] = code;
+ code++;
+ }
+
+ code <<= 1;
+ si++;
+ }
+
+ memset(pH->look_up, 0, sizeof(pH->look_up));
+ memset(pH->look_up2, 0, sizeof(pH->look_up2));
+ memset(pH->tree, 0, sizeof(pH->tree));
+ memset(pH->code_size, 0, sizeof(pH->code_size));
+
+ nextfreeentry = -1;
+
+ p = 0;
+
+ while (p < lastp)
+ {
+ i = m_huff_val[index][p];
+
+ code = huffcode[p];
+ code_size = huffsize[p];
+
+ assert(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
+ pH->code_size[i] = static_cast<uint8>(code_size);
+
+ if (code_size <= 8)
+ {
+ code <<= (8 - code_size);
+
+ for (l = 1 << (8 - code_size); l > 0; l--)
+ {
+ if (code >= 256)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ pH->look_up[code] = i;
+
+ bool has_extrabits = false;
+ int extra_bits = 0;
+ int num_extra_bits = i & 15;
+
+ int bits_to_fetch = code_size;
+ if (num_extra_bits)
+ {
+ int total_codesize = code_size + num_extra_bits;
+ if (total_codesize <= 8)
+ {
+ has_extrabits = true;
+ extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize));
+
+ if (extra_bits > 0x7FFF)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ bits_to_fetch += num_extra_bits;
+ }
+ }
+
+ if (!has_extrabits)
+ pH->look_up2[code] = i | (bits_to_fetch << 8);
+ else
+ pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8);
+
+ code++;
+ }
+ }
+ else
+ {
+ subtree = (code >> (code_size - 8)) & 0xFF;
+
+ currententry = pH->look_up[subtree];
+
+ if (currententry == 0)
+ {
+ pH->look_up[subtree] = currententry = nextfreeentry;
+ pH->look_up2[subtree] = currententry = nextfreeentry;
+
+ nextfreeentry -= 2;
+ }
+
+ code <<= (16 - (code_size - 8));
+
+ for (l = code_size; l > 9; l--)
+ {
+ if ((code & 0x8000) == 0)
+ currententry--;
+
+ unsigned int idx = -currententry - 1;
+
+ if (idx >= JPGD_HUFF_TREE_MAX_LENGTH)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ if (pH->tree[idx] == 0)
+ {
+ pH->tree[idx] = nextfreeentry;
+
+ currententry = nextfreeentry;
+
+ nextfreeentry -= 2;
+ }
+ else
+ {
+ currententry = pH->tree[idx];
+ }
+
+ code <<= 1;
+ }
+
+ if ((code & 0x8000) == 0)
+ currententry--;
+
+ if ((-currententry - 1) >= JPGD_HUFF_TREE_MAX_LENGTH)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ pH->tree[-currententry - 1] = i;
+ }
+
+ p++;
+ }
+ }
+
+ // Verifies the quantization tables needed for this scan are available.
+ void jpeg_decoder::check_quant_tables()
+ {
+ for (int i = 0; i < m_comps_in_scan; i++)
+ if (m_quant[m_comp_quant[m_comp_list[i]]] == nullptr)
+ stop_decoding(JPGD_UNDEFINED_QUANT_TABLE);
+ }
+
+ // Verifies that all the Huffman tables needed for this scan are available.
+ void jpeg_decoder::check_huff_tables()
+ {
+ for (int i = 0; i < m_comps_in_scan; i++)
+ {
+ if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == nullptr))
+ stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
+
+ if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == nullptr))
+ stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
+ }
+
+ for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++)
+ if (m_huff_num[i])
+ {
+ if (!m_pHuff_tabs[i])
+ m_pHuff_tabs[i] = (huff_tables*)alloc(sizeof(huff_tables));
+
+ make_huff_table(i, m_pHuff_tabs[i]);
+ }
+ }
+
+ // Determines the component order inside each MCU.
+ // Also calcs how many MCU's are on each row, etc.
+ bool jpeg_decoder::calc_mcu_block_order()
+ {
+ int component_num, component_id;
+ int max_h_samp = 0, max_v_samp = 0;
+
+ for (component_id = 0; component_id < m_comps_in_frame; component_id++)
+ {
+ if (m_comp_h_samp[component_id] > max_h_samp)
+ max_h_samp = m_comp_h_samp[component_id];
+
+ if (m_comp_v_samp[component_id] > max_v_samp)
+ max_v_samp = m_comp_v_samp[component_id];
+ }
+
+ for (component_id = 0; component_id < m_comps_in_frame; component_id++)
+ {
+ m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8;
+ m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8;
+ }
+
+ if (m_comps_in_scan == 1)
+ {
+ m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]];
+ m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]];
+ }
+ else
+ {
+ m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp;
+ m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp;
+ }
+
+ if (m_comps_in_scan == 1)
+ {
+ m_mcu_org[0] = m_comp_list[0];
+
+ m_blocks_per_mcu = 1;
+ }
+ else
+ {
+ m_blocks_per_mcu = 0;
+
+ for (component_num = 0; component_num < m_comps_in_scan; component_num++)
+ {
+ int num_blocks;
+
+ component_id = m_comp_list[component_num];
+
+ num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id];
+
+ while (num_blocks--)
+ m_mcu_org[m_blocks_per_mcu++] = component_id;
+ }
+ }
+
+ if (m_blocks_per_mcu > m_max_blocks_per_mcu)
+ return false;
+
+ for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
+ {
+ int comp_id = m_mcu_org[mcu_block];
+ if (comp_id >= JPGD_MAX_QUANT_TABLES)
+ return false;
+ }
+
+ return true;
+ }
+
+ // Starts a new scan.
+ int jpeg_decoder::init_scan()
+ {
+ if (!locate_sos_marker())
+ return JPGD_FALSE;
+
+ if (!calc_mcu_block_order())
+ return JPGD_FALSE;
+
+ check_huff_tables();
+
+ check_quant_tables();
+
+ memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
+
+ m_eob_run = 0;
+
+ if (m_restart_interval)
+ {
+ m_restarts_left = m_restart_interval;
+ m_next_restart_num = 0;
+ }
+
+ fix_in_buffer();
+
+ return JPGD_TRUE;
+ }
+
+ // Starts a frame. Determines if the number of components or sampling factors
+ // are supported.
+ void jpeg_decoder::init_frame()
+ {
+ int i;
+
+ if (m_comps_in_frame == 1)
+ {
+ if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1))
+ stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
+
+ m_scan_type = JPGD_GRAYSCALE;
+ m_max_blocks_per_mcu = 1;
+ m_max_mcu_x_size = 8;
+ m_max_mcu_y_size = 8;
+ }
+ else if (m_comps_in_frame == 3)
+ {
+ if (((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) ||
+ ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)))
+ stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
+
+ if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1))
+ {
+ m_scan_type = JPGD_YH1V1;
+
+ m_max_blocks_per_mcu = 3;
+ m_max_mcu_x_size = 8;
+ m_max_mcu_y_size = 8;
+ }
+ else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1))
+ {
+ m_scan_type = JPGD_YH2V1;
+ m_max_blocks_per_mcu = 4;
+ m_max_mcu_x_size = 16;
+ m_max_mcu_y_size = 8;
+ }
+ else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2))
+ {
+ m_scan_type = JPGD_YH1V2;
+ m_max_blocks_per_mcu = 4;
+ m_max_mcu_x_size = 8;
+ m_max_mcu_y_size = 16;
+ }
+ else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2))
+ {
+ m_scan_type = JPGD_YH2V2;
+ m_max_blocks_per_mcu = 6;
+ m_max_mcu_x_size = 16;
+ m_max_mcu_y_size = 16;
+ }
+ else
+ stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
+ }
+ else
+ stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
+
+ m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size;
+ m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size;
+
+ // These values are for the *destination* pixels: after conversion.
+ if (m_scan_type == JPGD_GRAYSCALE)
+ m_dest_bytes_per_pixel = 1;
+ else
+ m_dest_bytes_per_pixel = 4;
+
+ m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel;
+
+ m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel);
+
+ // Initialize two scan line buffers.
+ m_pScan_line_0 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true);
+ if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2))
+ m_pScan_line_1 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true);
+
+ m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu;
+
+ // Should never happen
+ if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ // Allocate the coefficient buffer, enough for one MCU
+ m_pMCU_coefficients = (jpgd_block_coeff_t *)alloc_aligned(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_coeff_t));
+
+ for (i = 0; i < m_max_blocks_per_mcu; i++)
+ m_mcu_block_max_zag[i] = 64;
+
+ m_pSample_buf = (uint8*)alloc_aligned(m_max_blocks_per_row * 64);
+ m_pSample_buf_prev = (uint8*)alloc_aligned(m_max_blocks_per_row * 64);
+
+ m_total_lines_left = m_image_y_size;
+
+ m_mcu_lines_left = 0;
+
+ create_look_ups();
+ }
+
+ // The coeff_buf series of methods originally stored the coefficients
+ // into a "virtual" file which was located in EMS, XMS, or a disk file. A cache
+ // was used to make this process more efficient. Now, we can store the entire
+ // thing in RAM.
+ jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y)
+ {
+ coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf));
+
+ cb->block_num_x = block_num_x;
+ cb->block_num_y = block_num_y;
+ cb->block_len_x = block_len_x;
+ cb->block_len_y = block_len_y;
+ cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_coeff_t);
+ cb->pData = (uint8*)alloc(cb->block_size * block_num_x * block_num_y, true);
+ return cb;
+ }
+
+ inline jpgd_block_coeff_t* jpeg_decoder::coeff_buf_getp(coeff_buf* cb, int block_x, int block_y)
+ {
+ if ((block_x >= cb->block_num_x) || (block_y >= cb->block_num_y))
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ return (jpgd_block_coeff_t*)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x));
+ }
+
+ // The following methods decode the various types of m_blocks encountered
+ // in progressively encoded images.
+ void jpeg_decoder::decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y)
+ {
+ int s, r;
+ jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
+
+ if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0)
+ {
+ if (s >= 16)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ r = pD->get_bits_no_markers(s);
+ s = JPGD_HUFF_EXTEND(r, s);
+ }
+
+ pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]);
+
+ p[0] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low);
+ }
+
+ void jpeg_decoder::decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y)
+ {
+ if (pD->get_bits_no_markers(1))
+ {
+ jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
+
+ p[0] |= (1 << pD->m_successive_low);
+ }
+ }
+
+ void jpeg_decoder::decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y)
+ {
+ int k, s, r;
+
+ if (pD->m_eob_run)
+ {
+ pD->m_eob_run--;
+ return;
+ }
+
+ jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
+
+ for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)
+ {
+ unsigned int idx = pD->m_comp_ac_tab[component_id];
+ if (idx >= JPGD_MAX_HUFF_TABLES)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s)
+ {
+ if ((k += r) > 63)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ r = pD->get_bits_no_markers(s);
+ s = JPGD_HUFF_EXTEND(r, s);
+
+ p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low);
+ }
+ else
+ {
+ if (r == 15)
+ {
+ if ((k += 15) > 63)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+ }
+ else
+ {
+ pD->m_eob_run = 1 << r;
+
+ if (r)
+ pD->m_eob_run += pD->get_bits_no_markers(r);
+
+ pD->m_eob_run--;
+
+ break;
+ }
+ }
+ }
+ }
+
+ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y)
+ {
+ int s, k, r;
+
+ int p1 = 1 << pD->m_successive_low;
+
+ //int m1 = (-1) << pD->m_successive_low;
+ int m1 = static_cast<int>((UINT32_MAX << pD->m_successive_low));
+
+ jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
+ if (pD->m_spectral_end > 63)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ k = pD->m_spectral_start;
+
+ if (pD->m_eob_run == 0)
+ {
+ for (; k <= pD->m_spectral_end; k++)
+ {
+ unsigned int idx = pD->m_comp_ac_tab[component_id];
+ if (idx >= JPGD_MAX_HUFF_TABLES)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s)
+ {
+ if (s != 1)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ if (pD->get_bits_no_markers(1))
+ s = p1;
+ else
+ s = m1;
+ }
+ else
+ {
+ if (r != 15)
+ {
+ pD->m_eob_run = 1 << r;
+
+ if (r)
+ pD->m_eob_run += pD->get_bits_no_markers(r);
+
+ break;
+ }
+ }
+
+ do
+ {
+ jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63];
+
+ if (*this_coef != 0)
+ {
+ if (pD->get_bits_no_markers(1))
+ {
+ if ((*this_coef & p1) == 0)
+ {
+ if (*this_coef >= 0)
+ *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1);
+ else
+ *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1);
+ }
+ }
+ }
+ else
+ {
+ if (--r < 0)
+ break;
+ }
+
+ k++;
+
+ } while (k <= pD->m_spectral_end);
+
+ if ((s) && (k < 64))
+ {
+ p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s);
+ }
+ }
+ }
+
+ if (pD->m_eob_run > 0)
+ {
+ for (; k <= pD->m_spectral_end; k++)
+ {
+ jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis
+
+ if (*this_coef != 0)
+ {
+ if (pD->get_bits_no_markers(1))
+ {
+ if ((*this_coef & p1) == 0)
+ {
+ if (*this_coef >= 0)
+ *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1);
+ else
+ *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1);
+ }
+ }
+ }
+ }
+
+ pD->m_eob_run--;
+ }
+ }
+
+ // Decode a scan in a progressively encoded image.
+ void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func)
+ {
+ int mcu_row, mcu_col, mcu_block;
+ int block_x_mcu[JPGD_MAX_COMPONENTS], block_y_mcu[JPGD_MAX_COMPONENTS];
+
+ memset(block_y_mcu, 0, sizeof(block_y_mcu));
+
+ for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++)
+ {
+ int component_num, component_id;
+
+ memset(block_x_mcu, 0, sizeof(block_x_mcu));
+
+ for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
+ {
+ int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
+
+ if ((m_restart_interval) && (m_restarts_left == 0))
+ process_restart();
+
+ for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
+ {
+ component_id = m_mcu_org[mcu_block];
+
+ decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, block_y_mcu[component_id] + block_y_mcu_ofs);
+
+ if (m_comps_in_scan == 1)
+ block_x_mcu[component_id]++;
+ else
+ {
+ if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
+ {
+ block_x_mcu_ofs = 0;
+
+ if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
+ {
+ block_y_mcu_ofs = 0;
+ block_x_mcu[component_id] += m_comp_h_samp[component_id];
+ }
+ }
+ }
+ }
+
+ m_restarts_left--;
+ }
+
+ if (m_comps_in_scan == 1)
+ block_y_mcu[m_comp_list[0]]++;
+ else
+ {
+ for (component_num = 0; component_num < m_comps_in_scan; component_num++)
+ {
+ component_id = m_comp_list[component_num];
+ block_y_mcu[component_id] += m_comp_v_samp[component_id];
+ }
+ }
+ }
+ }
+
+ // Decode a progressively encoded image.
+ void jpeg_decoder::init_progressive()
+ {
+ int i;
+
+ if (m_comps_in_frame == 4)
+ stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
+
+ // Allocate the coefficient buffers.
+ for (i = 0; i < m_comps_in_frame; i++)
+ {
+ m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1);
+ m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8);
+ }
+
+ // See https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
+ uint32_t total_scans = 0;
+ const uint32_t MAX_SCANS_TO_PROCESS = 1000;
+
+ for (; ; )
+ {
+ int dc_only_scan, refinement_scan;
+ pDecode_block_func decode_block_func;
+
+ if (!init_scan())
+ break;
+
+ dc_only_scan = (m_spectral_start == 0);
+ refinement_scan = (m_successive_high != 0);
+
+ if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63))
+ stop_decoding(JPGD_BAD_SOS_SPECTRAL);
+
+ if (dc_only_scan)
+ {
+ if (m_spectral_end)
+ stop_decoding(JPGD_BAD_SOS_SPECTRAL);
+ }
+ else if (m_comps_in_scan != 1) /* AC scans can only contain one component */
+ stop_decoding(JPGD_BAD_SOS_SPECTRAL);
+
+ if ((refinement_scan) && (m_successive_low != m_successive_high - 1))
+ stop_decoding(JPGD_BAD_SOS_SUCCESSIVE);
+
+ if (dc_only_scan)
+ {
+ if (refinement_scan)
+ decode_block_func = decode_block_dc_refine;
+ else
+ decode_block_func = decode_block_dc_first;
+ }
+ else
+ {
+ if (refinement_scan)
+ decode_block_func = decode_block_ac_refine;
+ else
+ decode_block_func = decode_block_ac_first;
+ }
+
+ decode_scan(decode_block_func);
+
+ m_bits_left = 16;
+ get_bits(16);
+ get_bits(16);
+
+ total_scans++;
+ if (total_scans > MAX_SCANS_TO_PROCESS)
+ stop_decoding(JPGD_TOO_MANY_SCANS);
+ }
+
+ m_comps_in_scan = m_comps_in_frame;
+
+ for (i = 0; i < m_comps_in_frame; i++)
+ m_comp_list[i] = i;
+
+ if (!calc_mcu_block_order())
+ stop_decoding(JPGD_DECODE_ERROR);
+ }
+
+ void jpeg_decoder::init_sequential()
+ {
+ if (!init_scan())
+ stop_decoding(JPGD_UNEXPECTED_MARKER);
+ }
+
+ void jpeg_decoder::decode_start()
+ {
+ init_frame();
+
+ if (m_progressive_flag)
+ init_progressive();
+ else
+ init_sequential();
+ }
+
+ void jpeg_decoder::decode_init(jpeg_decoder_stream* pStream, uint32_t flags)
+ {
+ init(pStream, flags);
+ locate_sof_marker();
+ }
+
+ jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags)
+ {
+ if (::setjmp(m_jmp_state))
+ return;
+ decode_init(pStream, flags);
+ }
+
+ int jpeg_decoder::begin_decoding()
+ {
+ if (m_ready_flag)
+ return JPGD_SUCCESS;
+
+ if (m_error_code)
+ return JPGD_FAILED;
+
+ if (::setjmp(m_jmp_state))
+ return JPGD_FAILED;
+
+ decode_start();
+
+ m_ready_flag = true;
+
+ return JPGD_SUCCESS;
+ }
+
+ jpeg_decoder::~jpeg_decoder()
+ {
+ free_all_blocks();
+ }
+
+ jpeg_decoder_file_stream::jpeg_decoder_file_stream()
+ {
+ m_pFile = nullptr;
+ m_eof_flag = false;
+ m_error_flag = false;
+ }
+
+ void jpeg_decoder_file_stream::close()
+ {
+ if (m_pFile)
+ {
+ fclose(m_pFile);
+ m_pFile = nullptr;
+ }
+
+ m_eof_flag = false;
+ m_error_flag = false;
+ }
+
+ jpeg_decoder_file_stream::~jpeg_decoder_file_stream()
+ {
+ close();
+ }
+
+ bool jpeg_decoder_file_stream::open(const char* Pfilename)
+ {
+ close();
+
+ m_eof_flag = false;
+ m_error_flag = false;
#if defined(_MSC_VER)
- m_pFile = NULL;
- fopen_s(&m_pFile, Pfilename, "rb");
+ m_pFile = nullptr;
+ fopen_s(&m_pFile, Pfilename, "rb");
#else
- m_pFile = fopen(Pfilename, "rb");
+ m_pFile = fopen(Pfilename, "rb");
#endif
- return m_pFile != NULL;
-}
-
-int jpeg_decoder_file_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag)
-{
- if (!m_pFile)
- return -1;
-
- if (m_eof_flag)
- {
- *pEOF_flag = true;
- return 0;
- }
-
- if (m_error_flag)
- return -1;
-
- int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile));
- if (bytes_read < max_bytes_to_read)
- {
- if (ferror(m_pFile))
- {
- m_error_flag = true;
- return -1;
- }
-
- m_eof_flag = true;
- *pEOF_flag = true;
- }
-
- return bytes_read;
-}
-
-bool jpeg_decoder_mem_stream::open(const uint8 *pSrc_data, uint size)
-{
- close();
- m_pSrc_data = pSrc_data;
- m_ofs = 0;
- m_size = size;
- return true;
-}
-
-int jpeg_decoder_mem_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag)
-{
- *pEOF_flag = false;
-
- if (!m_pSrc_data)
- return -1;
-
- uint bytes_remaining = m_size - m_ofs;
- if ((uint)max_bytes_to_read > bytes_remaining)
- {
- max_bytes_to_read = bytes_remaining;
- *pEOF_flag = true;
- }
-
- memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read);
- m_ofs += max_bytes_to_read;
-
- return max_bytes_to_read;
-}
-
-unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps)
-{
- if (!actual_comps)
- return NULL;
- *actual_comps = 0;
-
- if ((!pStream) || (!width) || (!height) || (!req_comps))
- return NULL;
-
- if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4))
- return NULL;
-
- jpeg_decoder decoder(pStream);
- if (decoder.get_error_code() != JPGD_SUCCESS)
- return NULL;
-
- const int image_width = decoder.get_width(), image_height = decoder.get_height();
- *width = image_width;
- *height = image_height;
- *actual_comps = decoder.get_num_components();
-
- if (decoder.begin_decoding() != JPGD_SUCCESS)
- return NULL;
-
- const int dst_bpl = image_width * req_comps;
-
- uint8 *pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height);
- if (!pImage_data)
- return NULL;
-
- for (int y = 0; y < image_height; y++)
- {
- const uint8* pScan_line;
- uint scan_line_len;
- if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS)
- {
- jpgd_free(pImage_data);
- return NULL;
- }
-
- uint8 *pDst = pImage_data + y * dst_bpl;
-
- if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3)))
- memcpy(pDst, pScan_line, dst_bpl);
- else if (decoder.get_num_components() == 1)
- {
- if (req_comps == 3)
- {
- for (int x = 0; x < image_width; x++)
- {
- uint8 luma = pScan_line[x];
- pDst[0] = luma;
- pDst[1] = luma;
- pDst[2] = luma;
- pDst += 3;
- }
- }
- else
- {
- for (int x = 0; x < image_width; x++)
- {
- uint8 luma = pScan_line[x];
- pDst[0] = luma;
- pDst[1] = luma;
- pDst[2] = luma;
- pDst[3] = 255;
- pDst += 4;
- }
- }
- }
- else if (decoder.get_num_components() == 3)
- {
- if (req_comps == 1)
- {
- const int YR = 19595, YG = 38470, YB = 7471;
- for (int x = 0; x < image_width; x++)
- {
- int r = pScan_line[x*4+0];
- int g = pScan_line[x*4+1];
- int b = pScan_line[x*4+2];
- *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16);
- }
- }
- else
- {
- for (int x = 0; x < image_width; x++)
- {
- pDst[0] = pScan_line[x*4+0];
- pDst[1] = pScan_line[x*4+1];
- pDst[2] = pScan_line[x*4+2];
- pDst += 3;
- }
- }
- }
- }
-
- return pImage_data;
-}
-
-unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps)
-{
- jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size);
- return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps);
-}
-
-unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps)
-{
- jpgd::jpeg_decoder_file_stream file_stream;
- if (!file_stream.open(pSrc_filename))
- return NULL;
- return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps);
-}
-
-} // namespace jpgd \ No newline at end of file
+ return m_pFile != nullptr;
+ }
+
+ int jpeg_decoder_file_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag)
+ {
+ if (!m_pFile)
+ return -1;
+
+ if (m_eof_flag)
+ {
+ *pEOF_flag = true;
+ return 0;
+ }
+
+ if (m_error_flag)
+ return -1;
+
+ int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile));
+ if (bytes_read < max_bytes_to_read)
+ {
+ if (ferror(m_pFile))
+ {
+ m_error_flag = true;
+ return -1;
+ }
+
+ m_eof_flag = true;
+ *pEOF_flag = true;
+ }
+
+ return bytes_read;
+ }
+
+ bool jpeg_decoder_mem_stream::open(const uint8* pSrc_data, uint size)
+ {
+ close();
+ m_pSrc_data = pSrc_data;
+ m_ofs = 0;
+ m_size = size;
+ return true;
+ }
+
+ int jpeg_decoder_mem_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag)
+ {
+ *pEOF_flag = false;
+
+ if (!m_pSrc_data)
+ return -1;
+
+ uint bytes_remaining = m_size - m_ofs;
+ if ((uint)max_bytes_to_read > bytes_remaining)
+ {
+ max_bytes_to_read = bytes_remaining;
+ *pEOF_flag = true;
+ }
+
+ memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read);
+ m_ofs += max_bytes_to_read;
+
+ return max_bytes_to_read;
+ }
+
+ unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)
+ {
+ if (!actual_comps)
+ return nullptr;
+ *actual_comps = 0;
+
+ if ((!pStream) || (!width) || (!height) || (!req_comps))
+ return nullptr;
+
+ if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4))
+ return nullptr;
+
+ jpeg_decoder decoder(pStream, flags);
+ if (decoder.get_error_code() != JPGD_SUCCESS)
+ return nullptr;
+
+ const int image_width = decoder.get_width(), image_height = decoder.get_height();
+ *width = image_width;
+ *height = image_height;
+ *actual_comps = decoder.get_num_components();
+
+ if (decoder.begin_decoding() != JPGD_SUCCESS)
+ return nullptr;
+
+ const int dst_bpl = image_width * req_comps;
+
+ uint8* pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height);
+ if (!pImage_data)
+ return nullptr;
+
+ for (int y = 0; y < image_height; y++)
+ {
+ const uint8* pScan_line;
+ uint scan_line_len;
+ if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS)
+ {
+ jpgd_free(pImage_data);
+ return nullptr;
+ }
+
+ uint8* pDst = pImage_data + y * dst_bpl;
+
+ if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3)))
+ memcpy(pDst, pScan_line, dst_bpl);
+ else if (decoder.get_num_components() == 1)
+ {
+ if (req_comps == 3)
+ {
+ for (int x = 0; x < image_width; x++)
+ {
+ uint8 luma = pScan_line[x];
+ pDst[0] = luma;
+ pDst[1] = luma;
+ pDst[2] = luma;
+ pDst += 3;
+ }
+ }
+ else
+ {
+ for (int x = 0; x < image_width; x++)
+ {
+ uint8 luma = pScan_line[x];
+ pDst[0] = luma;
+ pDst[1] = luma;
+ pDst[2] = luma;
+ pDst[3] = 255;
+ pDst += 4;
+ }
+ }
+ }
+ else if (decoder.get_num_components() == 3)
+ {
+ if (req_comps == 1)
+ {
+ const int YR = 19595, YG = 38470, YB = 7471;
+ for (int x = 0; x < image_width; x++)
+ {
+ int r = pScan_line[x * 4 + 0];
+ int g = pScan_line[x * 4 + 1];
+ int b = pScan_line[x * 4 + 2];
+ *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16);
+ }
+ }
+ else
+ {
+ for (int x = 0; x < image_width; x++)
+ {
+ pDst[0] = pScan_line[x * 4 + 0];
+ pDst[1] = pScan_line[x * 4 + 1];
+ pDst[2] = pScan_line[x * 4 + 2];
+ pDst += 3;
+ }
+ }
+ }
+ }
+
+ return pImage_data;
+ }
+
+ unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)
+ {
+ jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size);
+ return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps, flags);
+ }
+
+ unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)
+ {
+ jpgd::jpeg_decoder_file_stream file_stream;
+ if (!file_stream.open(pSrc_filename))
+ return nullptr;
+ return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps, flags);
+ }
+
+} // namespace jpgd
diff --git a/thirdparty/jpeg-compressor/jpgd.h b/thirdparty/jpeg-compressor/jpgd.h
index 150b9a0b26..39136696ba 100644
--- a/thirdparty/jpeg-compressor/jpgd.h
+++ b/thirdparty/jpeg-compressor/jpgd.h
@@ -1,319 +1,351 @@
// jpgd.h - C++ class for JPEG decompression.
-// Public domain, Rich Geldreich <richgel99@gmail.com>
+// Richard Geldreich <richgel99@gmail.com>
+// See jpgd.cpp for license (Public Domain or Apache 2.0).
#ifndef JPEG_DECODER_H
#define JPEG_DECODER_H
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
+#include <assert.h>
+#include <stdint.h>
#ifdef _MSC_VER
- #define JPGD_NORETURN __declspec(noreturn)
+#define JPGD_NORETURN __declspec(noreturn)
#elif defined(__GNUC__)
- #define JPGD_NORETURN __attribute__ ((noreturn))
+#define JPGD_NORETURN __attribute__ ((noreturn))
#else
- #define JPGD_NORETURN
+#define JPGD_NORETURN
#endif
+#define JPGD_HUFF_TREE_MAX_LENGTH 512
+#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256
+
namespace jpgd
{
- typedef unsigned char uint8;
- typedef signed short int16;
- typedef unsigned short uint16;
- typedef unsigned int uint;
- typedef signed int int32;
-
- // Loads a JPEG image from a memory buffer or a file.
- // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA).
- // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB).
- // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly.
- // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp.
- unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps);
- unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps);
-
- // Success/failure error codes.
- enum jpgd_status
- {
- JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1,
- JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE,
- JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS,
- JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH,
- JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER,
- JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS,
- JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE,
- JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, JPGD_ASSERTION_ERROR,
- JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM
- };
-
- // Input stream interface.
- // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available.
- // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set.
- // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer.
- // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding.
- class jpeg_decoder_stream
- {
- public:
- jpeg_decoder_stream() { }
- virtual ~jpeg_decoder_stream() { }
-
- // The read() method is called when the internal input buffer is empty.
- // Parameters:
- // pBuf - input buffer
- // max_bytes_to_read - maximum bytes that can be written to pBuf
- // pEOF_flag - set this to true if at end of stream (no more bytes remaining)
- // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0).
- // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full.
- virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) = 0;
- };
-
- // stdio FILE stream class.
- class jpeg_decoder_file_stream : public jpeg_decoder_stream
- {
- jpeg_decoder_file_stream(const jpeg_decoder_file_stream &);
- jpeg_decoder_file_stream &operator =(const jpeg_decoder_file_stream &);
-
- FILE *m_pFile;
- bool m_eof_flag, m_error_flag;
-
- public:
- jpeg_decoder_file_stream();
- virtual ~jpeg_decoder_file_stream();
-
- bool open(const char *Pfilename);
- void close();
-
- virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag);
- };
-
- // Memory stream class.
- class jpeg_decoder_mem_stream : public jpeg_decoder_stream
- {
- const uint8 *m_pSrc_data;
- uint m_ofs, m_size;
-
- public:
- jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { }
- jpeg_decoder_mem_stream(const uint8 *pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { }
-
- virtual ~jpeg_decoder_mem_stream() { }
-
- bool open(const uint8 *pSrc_data, uint size);
- void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; }
-
- virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag);
- };
-
- // Loads JPEG file from a jpeg_decoder_stream.
- unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps);
-
- enum
- {
- JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4,
- JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384
- };
-
- typedef int16 jpgd_quant_t;
- typedef int16 jpgd_block_t;
-
- class jpeg_decoder
- {
- public:
- // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc.
- // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline.
- jpeg_decoder(jpeg_decoder_stream *pStream);
-
- ~jpeg_decoder();
-
- // Call this method after constructing the object to begin decompression.
- // If JPGD_SUCCESS is returned you may then call decode() on each scanline.
- int begin_decoding();
-
- // Returns the next scan line.
- // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1).
- // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4).
- // Returns JPGD_SUCCESS if a scan line has been returned.
- // Returns JPGD_DONE if all scan lines have been returned.
- // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info.
- int decode(const void** pScan_line, uint* pScan_line_len);
-
- inline jpgd_status get_error_code() const { return m_error_code; }
-
- inline int get_width() const { return m_image_x_size; }
- inline int get_height() const { return m_image_y_size; }
-
- inline int get_num_components() const { return m_comps_in_frame; }
-
- inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; }
- inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); }
-
- // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file).
- inline int get_total_bytes_read() const { return m_total_bytes_read; }
-
- private:
- jpeg_decoder(const jpeg_decoder &);
- jpeg_decoder &operator =(const jpeg_decoder &);
-
- typedef void (*pDecode_block_func)(jpeg_decoder *, int, int, int);
-
- struct huff_tables
- {
- bool ac_table;
- uint look_up[256];
- uint look_up2[256];
- uint8 code_size[256];
- uint tree[512];
- };
-
- struct coeff_buf
- {
- uint8 *pData;
- int block_num_x, block_num_y;
- int block_len_x, block_len_y;
- int block_size;
- };
-
- struct mem_block
- {
- mem_block *m_pNext;
- size_t m_used_count;
- size_t m_size;
- char m_data[1];
- };
-
- jmp_buf m_jmp_state;
- mem_block *m_pMem_blocks;
- int m_image_x_size;
- int m_image_y_size;
- jpeg_decoder_stream *m_pStream;
- int m_progressive_flag;
- uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES];
- uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size
- uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size
- jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables
- int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported)
- int m_comps_in_frame; // # of components in frame
- int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor
- int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor
- int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector
- int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID
- int m_comp_h_blocks[JPGD_MAX_COMPONENTS];
- int m_comp_v_blocks[JPGD_MAX_COMPONENTS];
- int m_comps_in_scan; // # of components in scan
- int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan
- int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector
- int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector
- int m_spectral_start; // spectral selection start
- int m_spectral_end; // spectral selection end
- int m_successive_low; // successive approximation low
- int m_successive_high; // successive approximation high
- int m_max_mcu_x_size; // MCU's max. X size in pixels
- int m_max_mcu_y_size; // MCU's max. Y size in pixels
- int m_blocks_per_mcu;
- int m_max_blocks_per_row;
- int m_mcus_per_row, m_mcus_per_col;
- int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU];
- int m_total_lines_left; // total # lines left in image
- int m_mcu_lines_left; // total # lines left in this MCU
- int m_real_dest_bytes_per_scan_line;
- int m_dest_bytes_per_scan_line; // rounded up
- int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y)
- huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES];
- coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS];
- coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS];
- int m_eob_run;
- int m_block_y_mcu[JPGD_MAX_COMPONENTS];
- uint8* m_pIn_buf_ofs;
- int m_in_buf_left;
- int m_tem_flag;
- bool m_eof_flag;
- uint8 m_in_buf_pad_start[128];
- uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128];
- uint8 m_in_buf_pad_end[128];
- int m_bits_left;
- uint m_bit_buf;
- int m_restart_interval;
- int m_restarts_left;
- int m_next_restart_num;
- int m_max_mcus_per_row;
- int m_max_blocks_per_mcu;
- int m_expanded_blocks_per_mcu;
- int m_expanded_blocks_per_row;
- int m_expanded_blocks_per_component;
- bool m_freq_domain_chroma_upsample;
- int m_max_mcus_per_col;
- uint m_last_dc_val[JPGD_MAX_COMPONENTS];
- jpgd_block_t* m_pMCU_coefficients;
- int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU];
- uint8* m_pSample_buf;
- int m_crr[256];
- int m_cbb[256];
- int m_crg[256];
- int m_cbg[256];
- uint8* m_pScan_line_0;
- uint8* m_pScan_line_1;
- jpgd_status m_error_code;
- bool m_ready_flag;
- int m_total_bytes_read;
-
- void free_all_blocks();
- JPGD_NORETURN void stop_decoding(jpgd_status status);
- void *alloc(size_t n, bool zero = false);
- void word_clear(void *p, uint16 c, uint n);
- void prep_in_buffer();
- void read_dht_marker();
- void read_dqt_marker();
- void read_sof_marker();
- void skip_variable_marker();
- void read_dri_marker();
- void read_sos_marker();
- int next_marker();
- int process_markers();
- void locate_soi_marker();
- void locate_sof_marker();
- int locate_sos_marker();
- void init(jpeg_decoder_stream * pStream);
- void create_look_ups();
- void fix_in_buffer();
- void transform_mcu(int mcu_row);
- void transform_mcu_expand(int mcu_row);
- coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y);
- inline jpgd_block_t *coeff_buf_getp(coeff_buf *cb, int block_x, int block_y);
- void load_next_row();
- void decode_next_row();
- void make_huff_table(int index, huff_tables *pH);
- void check_quant_tables();
- void check_huff_tables();
- void calc_mcu_block_order();
- int init_scan();
- void init_frame();
- void process_restart();
- void decode_scan(pDecode_block_func decode_block_func);
- void init_progressive();
- void init_sequential();
- void decode_start();
- void decode_init(jpeg_decoder_stream * pStream);
- void H2V2Convert();
- void H2V1Convert();
- void H1V2Convert();
- void H1V1Convert();
- void gray_convert();
- void expanded_convert();
- void find_eoi();
- inline uint get_char();
- inline uint get_char(bool *pPadding_flag);
- inline void stuff_char(uint8 q);
- inline uint8 get_octet();
- inline uint get_bits(int num_bits);
- inline uint get_bits_no_markers(int numbits);
- inline int huff_decode(huff_tables *pH);
- inline int huff_decode(huff_tables *pH, int& extrabits);
- static inline uint8 clamp(int i);
- static void decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y);
- static void decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y);
- static void decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y);
- static void decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y);
- };
-
+ typedef unsigned char uint8;
+ typedef signed short int16;
+ typedef unsigned short uint16;
+ typedef unsigned int uint;
+ typedef signed int int32;
+
+ // Loads a JPEG image from a memory buffer or a file.
+ // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA).
+ // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB).
+ // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly.
+ // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp.
+ unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0);
+ unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0);
+
+ // Success/failure error codes.
+ enum jpgd_status
+ {
+ JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1,
+ JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE,
+ JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS,
+ JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH,
+ JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER,
+ JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS,
+ JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE,
+ JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER,
+ JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM, JPGD_TOO_MANY_SCANS
+ };
+
+ // Input stream interface.
+ // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available.
+ // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set.
+ // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer.
+ // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding.
+ class jpeg_decoder_stream
+ {
+ public:
+ jpeg_decoder_stream() { }
+ virtual ~jpeg_decoder_stream() { }
+
+ // The read() method is called when the internal input buffer is empty.
+ // Parameters:
+ // pBuf - input buffer
+ // max_bytes_to_read - maximum bytes that can be written to pBuf
+ // pEOF_flag - set this to true if at end of stream (no more bytes remaining)
+ // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0).
+ // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full.
+ virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) = 0;
+ };
+
+ // stdio FILE stream class.
+ class jpeg_decoder_file_stream : public jpeg_decoder_stream
+ {
+ jpeg_decoder_file_stream(const jpeg_decoder_file_stream&);
+ jpeg_decoder_file_stream& operator =(const jpeg_decoder_file_stream&);
+
+ FILE* m_pFile;
+ bool m_eof_flag, m_error_flag;
+
+ public:
+ jpeg_decoder_file_stream();
+ virtual ~jpeg_decoder_file_stream();
+
+ bool open(const char* Pfilename);
+ void close();
+
+ virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag);
+ };
+
+ // Memory stream class.
+ class jpeg_decoder_mem_stream : public jpeg_decoder_stream
+ {
+ const uint8* m_pSrc_data;
+ uint m_ofs, m_size;
+
+ public:
+ jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { }
+ jpeg_decoder_mem_stream(const uint8* pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { }
+
+ virtual ~jpeg_decoder_mem_stream() { }
+
+ bool open(const uint8* pSrc_data, uint size);
+ void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; }
+
+ virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag);
+ };
+
+ // Loads JPEG file from a jpeg_decoder_stream.
+ unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0);
+
+ enum
+ {
+ JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4,
+ JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 16384, JPGD_MAX_HEIGHT = 32768, JPGD_MAX_WIDTH = 32768
+ };
+
+ typedef int16 jpgd_quant_t;
+ typedef int16 jpgd_block_coeff_t;
+
+ class jpeg_decoder
+ {
+ public:
+ enum
+ {
+ cFlagBoxChromaFiltering = 1,
+ cFlagDisableSIMD = 2
+ };
+
+ // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc.
+ // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline.
+ jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags = 0);
+
+ ~jpeg_decoder();
+
+ // Call this method after constructing the object to begin decompression.
+ // If JPGD_SUCCESS is returned you may then call decode() on each scanline.
+
+ int begin_decoding();
+
+ // Returns the next scan line.
+ // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1).
+ // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4).
+ // Returns JPGD_SUCCESS if a scan line has been returned.
+ // Returns JPGD_DONE if all scan lines have been returned.
+ // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info.
+ int decode(const void** pScan_line, uint* pScan_line_len);
+
+ inline jpgd_status get_error_code() const { return m_error_code; }
+
+ inline int get_width() const { return m_image_x_size; }
+ inline int get_height() const { return m_image_y_size; }
+
+ inline int get_num_components() const { return m_comps_in_frame; }
+
+ inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; }
+ inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); }
+
+ // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file).
+ inline int get_total_bytes_read() const { return m_total_bytes_read; }
+
+ private:
+ jpeg_decoder(const jpeg_decoder&);
+ jpeg_decoder& operator =(const jpeg_decoder&);
+
+ typedef void (*pDecode_block_func)(jpeg_decoder*, int, int, int);
+
+ struct huff_tables
+ {
+ bool ac_table;
+ uint look_up[256];
+ uint look_up2[256];
+ uint8 code_size[JPGD_HUFF_CODE_SIZE_MAX_LENGTH];
+ uint tree[JPGD_HUFF_TREE_MAX_LENGTH];
+ };
+
+ struct coeff_buf
+ {
+ uint8* pData;
+ int block_num_x, block_num_y;
+ int block_len_x, block_len_y;
+ int block_size;
+ };
+
+ struct mem_block
+ {
+ mem_block* m_pNext;
+ size_t m_used_count;
+ size_t m_size;
+ char m_data[1];
+ };
+
+ jmp_buf m_jmp_state;
+ uint32_t m_flags;
+ mem_block* m_pMem_blocks;
+ int m_image_x_size;
+ int m_image_y_size;
+ jpeg_decoder_stream* m_pStream;
+
+ int m_progressive_flag;
+
+ uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES];
+ uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size
+ uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size
+ jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables
+ int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported)
+ int m_comps_in_frame; // # of components in frame
+ int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor
+ int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor
+ int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector
+ int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID
+ int m_comp_h_blocks[JPGD_MAX_COMPONENTS];
+ int m_comp_v_blocks[JPGD_MAX_COMPONENTS];
+ int m_comps_in_scan; // # of components in scan
+ int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan
+ int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector
+ int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector
+ int m_spectral_start; // spectral selection start
+ int m_spectral_end; // spectral selection end
+ int m_successive_low; // successive approximation low
+ int m_successive_high; // successive approximation high
+ int m_max_mcu_x_size; // MCU's max. X size in pixels
+ int m_max_mcu_y_size; // MCU's max. Y size in pixels
+ int m_blocks_per_mcu;
+ int m_max_blocks_per_row;
+ int m_mcus_per_row, m_mcus_per_col;
+ int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU];
+ int m_total_lines_left; // total # lines left in image
+ int m_mcu_lines_left; // total # lines left in this MCU
+ int m_num_buffered_scanlines;
+ int m_real_dest_bytes_per_scan_line;
+ int m_dest_bytes_per_scan_line; // rounded up
+ int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y)
+ huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES];
+ coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS];
+ coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS];
+ int m_eob_run;
+ int m_block_y_mcu[JPGD_MAX_COMPONENTS];
+ uint8* m_pIn_buf_ofs;
+ int m_in_buf_left;
+ int m_tem_flag;
+
+ uint8 m_in_buf_pad_start[64];
+ uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128];
+ uint8 m_in_buf_pad_end[64];
+
+ int m_bits_left;
+ uint m_bit_buf;
+ int m_restart_interval;
+ int m_restarts_left;
+ int m_next_restart_num;
+ int m_max_mcus_per_row;
+ int m_max_blocks_per_mcu;
+
+ int m_max_mcus_per_col;
+ uint m_last_dc_val[JPGD_MAX_COMPONENTS];
+ jpgd_block_coeff_t* m_pMCU_coefficients;
+ int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU];
+ uint8* m_pSample_buf;
+ uint8* m_pSample_buf_prev;
+ int m_crr[256];
+ int m_cbb[256];
+ int m_crg[256];
+ int m_cbg[256];
+ uint8* m_pScan_line_0;
+ uint8* m_pScan_line_1;
+ jpgd_status m_error_code;
+ int m_total_bytes_read;
+
+ bool m_ready_flag;
+ bool m_eof_flag;
+ bool m_sample_buf_prev_valid;
+ bool m_has_sse2;
+
+ inline int check_sample_buf_ofs(int ofs) const { assert(ofs >= 0); assert(ofs < m_max_blocks_per_row * 64); return ofs; }
+ void free_all_blocks();
+ JPGD_NORETURN void stop_decoding(jpgd_status status);
+ void* alloc(size_t n, bool zero = false);
+ void* alloc_aligned(size_t nSize, uint32_t align = 16, bool zero = false);
+ void word_clear(void* p, uint16 c, uint n);
+ void prep_in_buffer();
+ void read_dht_marker();
+ void read_dqt_marker();
+ void read_sof_marker();
+ void skip_variable_marker();
+ void read_dri_marker();
+ void read_sos_marker();
+ int next_marker();
+ int process_markers();
+ void locate_soi_marker();
+ void locate_sof_marker();
+ int locate_sos_marker();
+ void init(jpeg_decoder_stream* pStream, uint32_t flags);
+ void create_look_ups();
+ void fix_in_buffer();
+ void transform_mcu(int mcu_row);
+ coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y);
+ inline jpgd_block_coeff_t* coeff_buf_getp(coeff_buf* cb, int block_x, int block_y);
+ void load_next_row();
+ void decode_next_row();
+ void make_huff_table(int index, huff_tables* pH);
+ void check_quant_tables();
+ void check_huff_tables();
+ bool calc_mcu_block_order();
+ int init_scan();
+ void init_frame();
+ void process_restart();
+ void decode_scan(pDecode_block_func decode_block_func);
+ void init_progressive();
+ void init_sequential();
+ void decode_start();
+ void decode_init(jpeg_decoder_stream* pStream, uint32_t flags);
+ void H2V2Convert();
+ uint32_t H2V2ConvertFiltered();
+ void H2V1Convert();
+ void H2V1ConvertFiltered();
+ void H1V2Convert();
+ void H1V2ConvertFiltered();
+ void H1V1Convert();
+ void gray_convert();
+ void find_eoi();
+ inline uint get_char();
+ inline uint get_char(bool* pPadding_flag);
+ inline void stuff_char(uint8 q);
+ inline uint8 get_octet();
+ inline uint get_bits(int num_bits);
+ inline uint get_bits_no_markers(int numbits);
+ inline int huff_decode(huff_tables* pH);
+ inline int huff_decode(huff_tables* pH, int& extrabits);
+
+ // Clamps a value between 0-255.
+ static inline uint8 clamp(int i)
+ {
+ if (static_cast<uint>(i) > 255)
+ i = (((~i) >> 31) & 0xFF);
+ return static_cast<uint8>(i);
+ }
+ int decode_next_mcu_row();
+
+ static void decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y);
+ static void decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y);
+ static void decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y);
+ static void decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y);
+ };
+
} // namespace jpgd
#endif // JPEG_DECODER_H
diff --git a/thirdparty/jpeg-compressor/jpgd_idct.h b/thirdparty/jpeg-compressor/jpgd_idct.h
new file mode 100644
index 0000000000..876425a959
--- /dev/null
+++ b/thirdparty/jpeg-compressor/jpgd_idct.h
@@ -0,0 +1,462 @@
+// Copyright 2009 Intel Corporation
+// All Rights Reserved
+//
+// Permission is granted to use, copy, distribute and prepare derivative works of this
+// software for any purpose and without fee, provided, that the above copyright notice
+// and this statement appear in all copies. Intel makes no representations about the
+// suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS."
+// INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, AND ALL LIABILITY,
+// INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, FOR THE USE OF THIS SOFTWARE,
+// INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY RIGHTS, AND INCLUDING THE
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Intel does not
+// assume any responsibility for any errors which may appear in this software nor any
+// responsibility to update it.
+//
+// From:
+// https://software.intel.com/sites/default/files/m/d/4/1/d/8/UsingIntelAVXToImplementIDCT-r1_5.pdf
+// https://software.intel.com/file/29048
+//
+// Requires SSE
+//
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+#include <immintrin.h>
+
+#ifdef _MSC_VER
+ #define JPGD_SIMD_ALIGN(type, name) __declspec(align(16)) type name
+#else
+ #define JPGD_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
+#endif
+
+#define BITS_INV_ACC 4
+#define SHIFT_INV_ROW 16 - BITS_INV_ACC
+#define SHIFT_INV_COL 1 + BITS_INV_ACC
+const short IRND_INV_ROW = 1024 * (6 - BITS_INV_ACC); //1 << (SHIFT_INV_ROW-1)
+const short IRND_INV_COL = 16 * (BITS_INV_ACC - 3); // 1 << (SHIFT_INV_COL-1)
+const short IRND_INV_CORR = IRND_INV_COL - 1; // correction -1.0 and round
+
+JPGD_SIMD_ALIGN(short, shortM128_one_corr[8]) = {1, 1, 1, 1, 1, 1, 1, 1};
+JPGD_SIMD_ALIGN(short, shortM128_round_inv_row[8]) = {IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0};
+JPGD_SIMD_ALIGN(short, shortM128_round_inv_col[8]) = {IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL};
+JPGD_SIMD_ALIGN(short, shortM128_round_inv_corr[8])= {IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR};
+JPGD_SIMD_ALIGN(short, shortM128_tg_1_16[8]) = {13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036}; // tg * (2<<16) + 0.5
+JPGD_SIMD_ALIGN(short, shortM128_tg_2_16[8]) = {27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146}; // tg * (2<<16) + 0.5
+JPGD_SIMD_ALIGN(short, shortM128_tg_3_16[8]) = {-21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746}; // tg * (2<<16) + 0.5
+JPGD_SIMD_ALIGN(short, shortM128_cos_4_16[8]) = {-19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195};// cos * (2<<16) + 0.5
+
+//-----------------------------------------------------------------------------
+// Table for rows 0,4 - constants are multiplied on cos_4_16
+// w15 w14 w11 w10 w07 w06 w03 w02
+// w29 w28 w25 w24 w21 w20 w17 w16
+// w31 w30 w27 w26 w23 w22 w19 w18
+//movq -> w05 w04 w01 w00
+JPGD_SIMD_ALIGN(short, shortM128_tab_i_04[]) = {
+ 16384, 21407, 16384, 8867,
+ 16384, -8867, 16384, -21407, // w13 w12 w09 w08
+ 16384, 8867, -16384, -21407, // w07 w06 w03 w02
+ -16384, 21407, 16384, -8867, // w15 w14 w11 w10
+ 22725, 19266, 19266, -4520, // w21 w20 w17 w16
+ 12873, -22725, 4520, -12873, // w29 w28 w25 w24
+ 12873, 4520, -22725, -12873, // w23 w22 w19 w18
+ 4520, 19266, 19266, -22725}; // w31 w30 w27 w26
+
+ // Table for rows 1,7 - constants are multiplied on cos_1_16
+//movq -> w05 w04 w01 w00
+JPGD_SIMD_ALIGN(short, shortM128_tab_i_17[]) = {
+ 22725, 29692, 22725, 12299,
+ 22725, -12299, 22725, -29692, // w13 w12 w09 w08
+ 22725, 12299, -22725, -29692, // w07 w06 w03 w02
+ -22725, 29692, 22725, -12299, // w15 w14 w11 w10
+ 31521, 26722, 26722, -6270, // w21 w20 w17 w16
+ 17855, -31521, 6270, -17855, // w29 w28 w25 w24
+ 17855, 6270, -31521, -17855, // w23 w22 w19 w18
+ 6270, 26722, 26722, -31521}; // w31 w30 w27 w26
+
+// Table for rows 2,6 - constants are multiplied on cos_2_16
+//movq -> w05 w04 w01 w00
+JPGD_SIMD_ALIGN(short, shortM128_tab_i_26[]) = {
+ 21407, 27969, 21407, 11585,
+ 21407, -11585, 21407, -27969, // w13 w12 w09 w08
+ 21407, 11585, -21407, -27969, // w07 w06 w03 w02
+ -21407, 27969, 21407, -11585, // w15 w14 w11 w10
+ 29692, 25172, 25172, -5906, // w21 w20 w17 w16
+ 16819, -29692, 5906, -16819, // w29 w28 w25 w24
+ 16819, 5906, -29692, -16819, // w23 w22 w19 w18
+ 5906, 25172, 25172, -29692}; // w31 w30 w27 w26
+// Table for rows 3,5 - constants are multiplied on cos_3_16
+//movq -> w05 w04 w01 w00
+JPGD_SIMD_ALIGN(short, shortM128_tab_i_35[]) = {
+ 19266, 25172, 19266, 10426,
+ 19266, -10426, 19266, -25172, // w13 w12 w09 w08
+ 19266, 10426, -19266, -25172, // w07 w06 w03 w02
+ -19266, 25172, 19266, -10426, // w15 w14 w11 w10
+ 26722, 22654, 22654, -5315, // w21 w20 w17 w16
+ 15137, -26722, 5315, -15137, // w29 w28 w25 w24
+ 15137, 5315, -26722, -15137, // w23 w22 w19 w18
+ 5315, 22654, 22654, -26722}; // w31 w30 w27 w26
+
+JPGD_SIMD_ALIGN(short, shortM128_128[8]) = { 128, 128, 128, 128, 128, 128, 128, 128 };
+
+void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
+{
+ __m128i r_xmm0, r_xmm4;
+ __m128i r_xmm1, r_xmm2, r_xmm3, r_xmm5, r_xmm6, r_xmm7;
+ __m128i row0, row1, row2, row3, row4, row5, row6, row7;
+ short * pTab_i_04 = shortM128_tab_i_04;
+ short * pTab_i_26 = shortM128_tab_i_26;
+
+ //Get pointers for this input and output
+ pTab_i_04 = shortM128_tab_i_04;
+ pTab_i_26 = shortM128_tab_i_26;
+
+ //Row 1 and Row 3
+ r_xmm0 = _mm_load_si128((__m128i *) pInput);
+ r_xmm4 = _mm_load_si128((__m128i *) (&pInput[2*8]));
+
+ // *** Work on the data in xmm0
+ //low shuffle mask = 0xd8 = 11 01 10 00
+ //get short 2 and short 0 into ls 32-bits
+ r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
+
+ // copy short 2 and short 0 to all locations
+ r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
+
+ // add to those copies
+ r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
+
+ // shuffle mask = 0x55 = 01 01 01 01
+ // copy short 3 and short 1 to all locations
+ r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
+
+ // high shuffle mask = 0xd8 = 11 01 10 00
+ // get short 6 and short 4 into bit positions 64-95
+ // get short 7 and short 5 into bit positions 96-127
+ r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
+
+ // add to short 3 and short 1
+ r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
+
+ // shuffle mask = 0xaa = 10 10 10 10
+ // copy short 6 and short 4 to all locations
+ r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
+
+ // shuffle mask = 0xaa = 11 11 11 11
+ // copy short 7 and short 5 to all locations
+ r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
+
+ // add to short 6 and short 4
+ r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
+
+ // *** Work on the data in xmm4
+ // high shuffle mask = 0xd8 11 01 10 00
+ // get short 6 and short 4 into bit positions 64-95
+ // get short 7 and short 5 into bit positions 96-127
+ r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
+
+ // (xmm0 short 2 and short 0 plus pSi) + some constants
+ r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
+ r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
+ r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
+ r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0]));
+ r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
+ r_xmm2 = r_xmm1;
+ r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
+ r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
+ r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
+ r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
+ r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
+ r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
+ r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24]));
+ r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
+ r_xmm6 = r_xmm5;
+ r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
+ r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b);
+ row0 = _mm_packs_epi32(r_xmm0, r_xmm2);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7);
+ r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5);
+ r_xmm6 = _mm_srai_epi32(r_xmm6, 12);
+ r_xmm4 = _mm_srai_epi32(r_xmm4, 12);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
+ row2 = _mm_packs_epi32(r_xmm4, r_xmm6);
+
+ //Row 5 and row 7
+ r_xmm0 = _mm_load_si128((__m128i *) (&pInput[4*8]));
+ r_xmm4 = _mm_load_si128((__m128i *) (&pInput[6*8]));
+
+ r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
+ r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
+ r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
+ r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
+ r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
+ r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
+ r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
+ r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
+ r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
+ r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
+ r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
+ r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
+ r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
+ r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0]));
+ r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
+ r_xmm2 = r_xmm1;
+ r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
+ r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
+ r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
+ r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
+ r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
+ r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
+ r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24]));
+ r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
+ r_xmm6 = r_xmm5;
+ r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
+ r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b);
+ row4 = _mm_packs_epi32(r_xmm0, r_xmm2);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7);
+ r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5);
+ r_xmm6 = _mm_srai_epi32(r_xmm6, 12);
+ r_xmm4 = _mm_srai_epi32(r_xmm4, 12);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
+ row6 = _mm_packs_epi32(r_xmm4, r_xmm6);
+
+ //Row 4 and row 2
+ pTab_i_04 = shortM128_tab_i_35;
+ pTab_i_26 = shortM128_tab_i_17;
+ r_xmm0 = _mm_load_si128((__m128i *) (&pInput[3*8]));
+ r_xmm4 = _mm_load_si128((__m128i *) (&pInput[1*8]));
+
+ r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
+ r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
+ r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
+ r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
+ r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
+ r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
+ r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
+ r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
+ r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
+ r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
+ r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
+ r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
+ r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
+ r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0]));
+ r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
+ r_xmm2 = r_xmm1;
+ r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
+ r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
+ r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
+ r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
+ r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
+ r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
+ r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24]));
+ r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
+ r_xmm6 = r_xmm5;
+ r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
+ r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b);
+ row3 = _mm_packs_epi32(r_xmm0, r_xmm2);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7);
+ r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5);
+ r_xmm6 = _mm_srai_epi32(r_xmm6, 12);
+ r_xmm4 = _mm_srai_epi32(r_xmm4, 12);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
+ row1 = _mm_packs_epi32(r_xmm4, r_xmm6);
+
+ //Row 6 and row 8
+ r_xmm0 = _mm_load_si128((__m128i *) (&pInput[5*8]));
+ r_xmm4 = _mm_load_si128((__m128i *) (&pInput[7*8]));
+
+ r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
+ r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
+ r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
+ r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
+ r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
+ r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
+ r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
+ r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
+ r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
+ r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
+ r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
+ r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
+ r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
+ r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0]));
+ r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
+ r_xmm2 = r_xmm1;
+ r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
+ r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
+ r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
+ r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
+ r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
+ r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
+ r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24]));
+ r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
+ r_xmm6 = r_xmm5;
+ r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
+ r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b);
+ row5 = _mm_packs_epi32(r_xmm0, r_xmm2);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7);
+ r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5);
+ r_xmm6 = _mm_srai_epi32(r_xmm6, 12);
+ r_xmm4 = _mm_srai_epi32(r_xmm4, 12);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
+ row7 = _mm_packs_epi32(r_xmm4, r_xmm6);
+
+ r_xmm1 = _mm_load_si128((__m128i *) shortM128_tg_3_16);
+ r_xmm2 = row5;
+ r_xmm3 = row3;
+ r_xmm0 = _mm_mulhi_epi16(row5, r_xmm1);
+
+ r_xmm1 = _mm_mulhi_epi16(r_xmm1, r_xmm3);
+ r_xmm5 = _mm_load_si128((__m128i *) shortM128_tg_1_16);
+ r_xmm6 = row7;
+ r_xmm4 = _mm_mulhi_epi16(row7, r_xmm5);
+
+ r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm2);
+ r_xmm5 = _mm_mulhi_epi16(r_xmm5, row1);
+ r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm3);
+ r_xmm7 = row6;
+
+ r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm3);
+ r_xmm3 = _mm_load_si128((__m128i *) shortM128_tg_2_16);
+ r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm1);
+ r_xmm7 = _mm_mulhi_epi16(r_xmm7, r_xmm3);
+ r_xmm1 = r_xmm0;
+ r_xmm3 = _mm_mulhi_epi16(r_xmm3, row2);
+ r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm6);
+ r_xmm4 = _mm_adds_epi16(r_xmm4, row1);
+ r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm4);
+ r_xmm0 = _mm_adds_epi16(r_xmm0, *((__m128i *) shortM128_one_corr));
+ r_xmm4 = _mm_subs_epi16(r_xmm4, r_xmm1);
+ r_xmm6 = r_xmm5;
+ r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm2);
+ r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_one_corr));
+ r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2);
+
+ //Intermediate results, needed later
+ __m128i temp3, temp7;
+ temp7 = r_xmm0;
+
+ r_xmm1 = r_xmm4;
+ r_xmm0 = _mm_load_si128((__m128i *) shortM128_cos_4_16);
+ r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm5);
+ r_xmm2 = _mm_load_si128((__m128i *) shortM128_cos_4_16);
+ r_xmm2 = _mm_mulhi_epi16(r_xmm2, r_xmm4);
+
+ //Intermediate results, needed later
+ temp3 = r_xmm6;
+
+ r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm5);
+ r_xmm7 = _mm_adds_epi16(r_xmm7, row2);
+ r_xmm3 = _mm_subs_epi16(r_xmm3, row6);
+ r_xmm6 = row0;
+ r_xmm0 = _mm_mulhi_epi16(r_xmm0, r_xmm1);
+ r_xmm5 = row4;
+ r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm6);
+ r_xmm6 = _mm_subs_epi16(r_xmm6, row4);
+ r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm2);
+
+ r_xmm4 = _mm_or_si128(r_xmm4, *((__m128i *) shortM128_one_corr));
+ r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm1);
+ r_xmm0 = _mm_or_si128(r_xmm0, *((__m128i *) shortM128_one_corr));
+
+ r_xmm2 = r_xmm5;
+ r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm7);
+ r_xmm1 = r_xmm6;
+ r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_round_inv_col));
+ r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm7);
+ r_xmm7 = temp7;
+ r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm3);
+ r_xmm6 = _mm_adds_epi16(r_xmm6, *((__m128i *) shortM128_round_inv_col));
+ r_xmm7 = _mm_adds_epi16(r_xmm7, r_xmm5);
+ r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL);
+ r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm3);
+ r_xmm1 = _mm_adds_epi16(r_xmm1, *((__m128i *) shortM128_round_inv_corr));
+ r_xmm3 = r_xmm6;
+ r_xmm2 = _mm_adds_epi16(r_xmm2, *((__m128i *) shortM128_round_inv_corr));
+ r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm4);
+
+ //Store results for row 0
+ //_mm_store_si128((__m128i *) pOutput, r_xmm7);
+ __m128i r0 = r_xmm7;
+
+ r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL);
+ r_xmm7 = r_xmm1;
+ r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm0);
+
+ //Store results for row 1
+ //_mm_store_si128((__m128i *) (&pOutput[1*8]), r_xmm6);
+ __m128i r1 = r_xmm6;
+
+ r_xmm1 = _mm_srai_epi16(r_xmm1, SHIFT_INV_COL);
+ r_xmm6 = temp3;
+ r_xmm7 = _mm_subs_epi16(r_xmm7, r_xmm0);
+ r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL);
+
+ //Store results for row 2
+ //_mm_store_si128((__m128i *) (&pOutput[2*8]), r_xmm1);
+ __m128i r2 = r_xmm1;
+
+ r_xmm5 = _mm_subs_epi16(r_xmm5, temp7);
+ r_xmm5 = _mm_srai_epi16(r_xmm5, SHIFT_INV_COL);
+
+ //Store results for row 7
+ //_mm_store_si128((__m128i *) (&pOutput[7*8]), r_xmm5);
+ __m128i r7 = r_xmm5;
+
+ r_xmm3 = _mm_subs_epi16(r_xmm3, r_xmm4);
+ r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2);
+ r_xmm2 = _mm_subs_epi16(r_xmm2, temp3);
+ r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL);
+ r_xmm2 = _mm_srai_epi16(r_xmm2, SHIFT_INV_COL);
+
+ //Store results for row 3
+ //_mm_store_si128((__m128i *) (&pOutput[3*8]), r_xmm6);
+ __m128i r3 = r_xmm6;
+
+ r_xmm3 = _mm_srai_epi16(r_xmm3, SHIFT_INV_COL);
+
+ //Store results for rows 4, 5, and 6
+ //_mm_store_si128((__m128i *) (&pOutput[4*8]), r_xmm2);
+ //_mm_store_si128((__m128i *) (&pOutput[5*8]), r_xmm7);
+ //_mm_store_si128((__m128i *) (&pOutput[6*8]), r_xmm3);
+
+ __m128i r4 = r_xmm2;
+ __m128i r5 = r_xmm7;
+ __m128i r6 = r_xmm3;
+
+ r0 = _mm_add_epi16(*(const __m128i *)shortM128_128, r0);
+ r1 = _mm_add_epi16(*(const __m128i *)shortM128_128, r1);
+ r2 = _mm_add_epi16(*(const __m128i *)shortM128_128, r2);
+ r3 = _mm_add_epi16(*(const __m128i *)shortM128_128, r3);
+ r4 = _mm_add_epi16(*(const __m128i *)shortM128_128, r4);
+ r5 = _mm_add_epi16(*(const __m128i *)shortM128_128, r5);
+ r6 = _mm_add_epi16(*(const __m128i *)shortM128_128, r6);
+ r7 = _mm_add_epi16(*(const __m128i *)shortM128_128, r7);
+
+ ((__m128i *)pOutputUB)[0] = _mm_packus_epi16(r0, r1);
+ ((__m128i *)pOutputUB)[1] = _mm_packus_epi16(r2, r3);
+ ((__m128i *)pOutputUB)[2] = _mm_packus_epi16(r4, r5);
+ ((__m128i *)pOutputUB)[3] = _mm_packus_epi16(r6, r7);
+}
diff --git a/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch b/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch
new file mode 100644
index 0000000000..7b338de084
--- /dev/null
+++ b/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch
@@ -0,0 +1,31 @@
+diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp
+index a0c494db61..257d0b7574 100644
+--- a/thirdparty/jpeg-compressor/jpgd.cpp
++++ b/thirdparty/jpeg-compressor/jpgd.cpp
+@@ -2126,7 +2126,7 @@ namespace jpgd {
+
+ int jpeg_decoder::decode_next_mcu_row()
+ {
+- if (setjmp(m_jmp_state))
++ if (::setjmp(m_jmp_state))
+ return JPGD_FAILED;
+
+ const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));
+@@ -3042,7 +3042,7 @@ namespace jpgd {
+
+ jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags)
+ {
+- if (setjmp(m_jmp_state))
++ if (::setjmp(m_jmp_state))
+ return;
+ decode_init(pStream, flags);
+ }
+@@ -3055,7 +3055,7 @@ namespace jpgd {
+ if (m_error_code)
+ return JPGD_FAILED;
+
+- if (setjmp(m_jmp_state))
++ if (::setjmp(m_jmp_state))
+ return JPGD_FAILED;
+
+ decode_start();
diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h
index d076c2352f..93de091c4d 100644
--- a/thirdparty/mbedtls/include/mbedtls/check_config.h
+++ b/thirdparty/mbedtls/include/mbedtls/check_config.h
@@ -546,6 +546,23 @@
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
+#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
+ !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) )
+#error "One or more versions of the TLS protocol are enabled " \
+ "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -669,6 +686,10 @@
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C)
+#error "MBEDTLS_CERTS_C defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h
index 8e2ce03c32..e0a2e7f6d6 100644
--- a/thirdparty/mbedtls/include/mbedtls/version.h
+++ b/thirdparty/mbedtls/include/mbedtls/version.h
@@ -40,16 +40,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 16
-#define MBEDTLS_VERSION_PATCH 5
+#define MBEDTLS_VERSION_PATCH 6
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x02100500
-#define MBEDTLS_VERSION_STRING "2.16.5"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.5"
+#define MBEDTLS_VERSION_NUMBER 0x02100600
+#define MBEDTLS_VERSION_STRING "2.16.6"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.6"
#if defined(MBEDTLS_VERSION_C)
diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c
index 040c20bd38..725e176df2 100644
--- a/thirdparty/mbedtls/library/ecp.c
+++ b/thirdparty/mbedtls/library/ecp.c
@@ -1938,6 +1938,20 @@ static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp,
final_norm:
#endif
+ /*
+ * Knowledge of the jacobian coordinates may leak the last few bits of the
+ * scalar [1], and since our MPI implementation isn't constant-flow,
+ * inversion (used for coordinate normalization) may leak the full value
+ * of its input via side-channels [2].
+ *
+ * [1] https://eprint.iacr.org/2003/191
+ * [2] https://eprint.iacr.org/2020/055
+ *
+ * Avoid the leak by randomizing coordinates before we normalize them.
+ */
+ if( f_rng != 0 )
+ MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) );
+
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV );
MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
@@ -2308,6 +2322,20 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
}
+ /*
+ * Knowledge of the projective coordinates may leak the last few bits of the
+ * scalar [1], and since our MPI implementation isn't constant-flow,
+ * inversion (used for coordinate normalization) may leak the full value
+ * of its input via side-channels [2].
+ *
+ * [1] https://eprint.iacr.org/2003/191
+ * [2] https://eprint.iacr.org/2020/055
+ *
+ * Avoid the leak by randomizing coordinates before we normalize them.
+ */
+ if( f_rng != NULL )
+ MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
+
MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
cleanup:
diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c
index afced7a99c..c5c3af69df 100644
--- a/thirdparty/mbedtls/library/ssl_cli.c
+++ b/thirdparty/mbedtls/library/ssl_cli.c
@@ -1417,6 +1417,19 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
+ /* Check that there is enough room for:
+ * - 2 bytes of version
+ * - 1 byte of cookie_len
+ */
+ if( mbedtls_ssl_hs_hdr_len( ssl ) + 3 > ssl->in_msglen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "incoming HelloVerifyRequest message is too short" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
/*
* struct {
* ProtocolVersion server_version;
@@ -1445,8 +1458,6 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
}
cookie_len = *p++;
- MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
-
if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
@@ -1455,6 +1466,7 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
+ MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
mbedtls_free( ssl->handshake->verify_cookie );
diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c
index b8f35fec5d..cbec74fe8c 100644
--- a/thirdparty/mbedtls/library/ssl_tls.c
+++ b/thirdparty/mbedtls/library/ssl_tls.c
@@ -1004,8 +1004,6 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_init != NULL )
{
- int ret = 0;
-
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen,
@@ -2885,15 +2883,18 @@ static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
/*
* Swap transform_out and out_ctr with the alternative ones
*/
-static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
+static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_transform *tmp_transform;
unsigned char tmp_out_ctr[8];
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ int ret;
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
if( ssl->transform_out == ssl->handshake->alt_transform_out )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
- return;
+ return( 0 );
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
@@ -2920,7 +2921,9 @@ static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
}
-#endif
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+ return( 0 );
}
/*
@@ -2957,7 +2960,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
ssl->handshake->cur_msg = ssl->handshake->flight;
ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
- ssl_swap_epochs( ssl );
+ if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+ return( ret );
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
}
@@ -2980,7 +2984,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
- ssl_swap_epochs( ssl );
+ if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+ return( ret );
}
ret = ssl_get_remaining_payload_in_datagram( ssl );
@@ -3017,7 +3022,10 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
{
if( is_finished )
- ssl_swap_epochs( ssl );
+ {
+ if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+ return( ret );
+ }
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
return( ret );
@@ -3997,17 +4005,23 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
{
+ int send_ret;
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
+ ssl->out_buf, len );
/* Don't check write errors as we can't do anything here.
* If the error is permanent we'll catch it later,
* if it's not, then hopefully it'll work next time. */
- (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+ send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
+ (void) send_ret;
return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
}
if( ret == 0 )
{
- /* Got a valid cookie, partially reset context */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c
index 2e0b0e8f6c..4d25303206 100644
--- a/thirdparty/mbedtls/library/x509.c
+++ b/thirdparty/mbedtls/library/x509.c
@@ -1063,7 +1063,7 @@ cleanup:
mbedtls_x509_crt_free( &clicert );
#else
((void) verbose);
-#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */
return( ret );
}
diff --git a/thirdparty/vulkan/android/vk_mem_alloc.cpp b/thirdparty/vulkan/android/vk_mem_alloc.cpp
new file mode 100644
index 0000000000..a28454cf6e
--- /dev/null
+++ b/thirdparty/vulkan/android/vk_mem_alloc.cpp
@@ -0,0 +1,8 @@
+#define VMA_IMPLEMENTATION
+#ifdef DEBUG_ENABLED
+#ifndef _DEBUG
+#define _DEBUG
+#endif
+#endif
+// Include memory allocator from Android NDK
+#include <vk_mem_alloc.h>