summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/CODEOWNERS5
-rw-r--r--.github/workflows/runner.yml2
-rw-r--r--SConstruct75
-rw-r--r--core/core_constants.cpp1
-rw-r--r--core/extension/extension_api_dump.cpp1
-rw-r--r--core/extension/make_wrappers.py4
-rw-r--r--core/object/make_virtuals.py30
-rw-r--r--core/object/object.h9
-rw-r--r--core/object/script_language_extension.h132
-rw-r--r--core/variant/variant_call.cpp31
-rw-r--r--doc/classes/@GlobalScope.xml10
-rw-r--r--doc/classes/Array.xml15
-rw-r--r--doc/classes/Dictionary.xml8
-rw-r--r--doc/classes/GraphEdit.xml5
-rw-r--r--doc/classes/ItemList.xml13
-rw-r--r--doc/classes/PackedByteArray.xml7
-rw-r--r--doc/classes/PackedColorArray.xml7
-rw-r--r--doc/classes/PackedFloat32Array.xml7
-rw-r--r--doc/classes/PackedFloat64Array.xml7
-rw-r--r--doc/classes/PackedInt32Array.xml7
-rw-r--r--doc/classes/PackedInt64Array.xml7
-rw-r--r--doc/classes/PackedStringArray.xml7
-rw-r--r--doc/classes/PackedVector2Array.xml7
-rw-r--r--doc/classes/PackedVector3Array.xml7
-rw-r--r--doc/classes/PackedVector4Array.xml7
-rw-r--r--doc/classes/ParticleProcessMaterial.xml3
-rw-r--r--doc/classes/ProjectSettings.xml5
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp3
-rw-r--r--drivers/gles3/shaders/scene.glsl289
-rw-r--r--drivers/gles3/storage/config.cpp2
-rw-r--r--drivers/gles3/storage/material_storage.cpp4
-rw-r--r--editor/editor_file_system.h12
-rw-r--r--editor/editor_script.cpp2
-rw-r--r--editor/editor_script.h2
-rw-r--r--editor/editor_vcs_interface.cpp46
-rw-r--r--editor/editor_vcs_interface.h46
-rw-r--r--editor/export/editor_export_platform_extension.cpp18
-rw-r--r--editor/export/editor_export_platform_extension.h18
-rw-r--r--editor/export/editor_export_plugin.cpp8
-rw-r--r--editor/export/editor_export_plugin.h8
-rw-r--r--editor/plugins/tool_button_editor_plugin.cpp82
-rw-r--r--editor/plugins/tool_button_editor_plugin.h (renamed from modules/squish/image_decompress_squish.cpp)79
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp1
-rw-r--r--editor/project_manager/project_dialog.cpp6
-rw-r--r--editor/register_editor_types.cpp2
-rw-r--r--editor/renames_map_3_to_4.cpp2
-rw-r--r--methods.py21
-rw-r--r--modules/bcdec/SCsub10
-rw-r--r--modules/bcdec/config.py (renamed from modules/squish/config.py)0
-rw-r--r--modules/bcdec/image_decompress_bcdec.cpp181
-rw-r--r--modules/bcdec/image_decompress_bcdec.h (renamed from modules/squish/image_decompress_squish.h)21
-rw-r--r--modules/bcdec/register_types.cpp (renamed from modules/squish/register_types.cpp)9
-rw-r--r--modules/bcdec/register_types.h (renamed from modules/squish/register_types.h)10
-rw-r--r--modules/cvtt/register_types.cpp1
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml35
-rw-r--r--modules/gdscript/gdscript_parser.cpp63
-rw-r--r--modules/gdscript/gdscript_parser.h1
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.gd1
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_variable.gd5
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_variable.out4
-rw-r--r--modules/gdscript/tests/scripts/utils.notest.gd3
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs26
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs46
-rw-r--r--modules/mono/editor/bindings_generator.cpp40
-rw-r--r--modules/squish/SCsub45
-rw-r--r--platform/android/doc_classes/EditorExportPlatformAndroid.xml3
-rw-r--r--platform/android/export/export_plugin.cpp42
-rw-r--r--platform/android/export/export_plugin.h5
-rw-r--r--platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt4
-rw-r--r--platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt2
-rw-r--r--platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml1
-rw-r--r--platform/android/java/lib/res/mipmap/icon_monochrome.pngbin0 -> 5617 bytes
-rw-r--r--platform/linuxbsd/detect.py4
-rw-r--r--scene/3d/mesh_instance_3d.cpp4
-rw-r--r--scene/gui/graph_edit.cpp4
-rw-r--r--scene/resources/material.cpp4
-rw-r--r--scene/resources/material.h4
-rw-r--r--scene/resources/mesh.cpp28
-rw-r--r--scene/resources/mesh.h28
-rw-r--r--scene/resources/style_box.cpp2
-rw-r--r--scene/resources/style_box.h2
-rw-r--r--scene/resources/texture.cpp30
-rw-r--r--scene/resources/texture.h30
-rw-r--r--scene/resources/video_stream.cpp2
-rw-r--r--scene/resources/video_stream.h2
-rw-r--r--scene/scene_string_names.cpp1
-rw-r--r--scene/scene_string_names.h1
-rw-r--r--servers/audio/audio_effect.cpp4
-rw-r--r--servers/audio/audio_effect.h4
-rw-r--r--servers/audio/audio_stream.cpp6
-rw-r--r--servers/audio/audio_stream.h6
-rw-r--r--servers/extensions/physics_server_2d_extension.h44
-rw-r--r--servers/extensions/physics_server_3d_extension.h44
-rw-r--r--servers/movie_writer/movie_writer.cpp14
-rw-r--r--servers/movie_writer/movie_writer.h14
-rw-r--r--servers/physics_server_3d.cpp6
-rw-r--r--servers/physics_server_3d.h6
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp5
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp9
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp5
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp7
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp164
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h43
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl10
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl190
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl326
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_vertex_lights_inc.glsl82
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp97
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h27
-rw-r--r--servers/rendering_server.cpp3
-rw-r--r--servers/text/text_server_extension.cpp160
-rw-r--r--servers/text/text_server_extension.h160
-rw-r--r--thirdparty/README.md23
-rw-r--r--thirdparty/misc/bcdec.h1329
-rw-r--r--thirdparty/openxr/COPYING.adoc4
-rw-r--r--thirdparty/openxr/include/openxr/openxr.h644
-rw-r--r--thirdparty/openxr/include/openxr/openxr_platform.h37
-rw-r--r--thirdparty/openxr/include/openxr/openxr_reflection.h549
-rw-r--r--thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h60
-rw-r--r--thirdparty/openxr/include/openxr/openxr_reflection_structs.h49
-rw-r--r--thirdparty/openxr/src/common/platform_utils.hpp5
-rw-r--r--thirdparty/openxr/src/common/xr_linear.h2
-rw-r--r--thirdparty/openxr/src/loader/android_utilities.cpp54
-rw-r--r--thirdparty/openxr/src/loader/loader_core.cpp16
-rw-r--r--thirdparty/openxr/src/loader/loader_instance.cpp4
-rw-r--r--thirdparty/openxr/src/loader/loader_instance.hpp6
-rw-r--r--thirdparty/openxr/src/loader/manifest_file.cpp27
-rw-r--r--thirdparty/openxr/src/loader/runtime_interface.cpp14
-rw-r--r--thirdparty/openxr/src/loader/runtime_interface.hpp8
-rw-r--r--thirdparty/openxr/src/loader/xr_generated_loader.cpp13
-rw-r--r--thirdparty/openxr/src/loader/xr_generated_loader.hpp4
-rw-r--r--thirdparty/openxr/src/xr_generated_dispatch_table_core.c5
-rw-r--r--thirdparty/openxr/src/xr_generated_dispatch_table_core.h7
-rw-r--r--thirdparty/squish/LICENSE.txt20
-rw-r--r--thirdparty/squish/alpha.cpp350
-rw-r--r--thirdparty/squish/alpha.h41
-rw-r--r--thirdparty/squish/clusterfit.cpp392
-rw-r--r--thirdparty/squish/clusterfit.h61
-rw-r--r--thirdparty/squish/colourblock.cpp247
-rw-r--r--thirdparty/squish/colourblock.h45
-rw-r--r--thirdparty/squish/colourfit.cpp54
-rw-r--r--thirdparty/squish/colourfit.h56
-rw-r--r--thirdparty/squish/colourset.cpp121
-rw-r--r--thirdparty/squish/colourset.h58
-rw-r--r--thirdparty/squish/config.h69
-rw-r--r--thirdparty/squish/maths.cpp259
-rw-r--r--thirdparty/squish/maths.h233
-rw-r--r--thirdparty/squish/patches/config_sse.patch31
-rw-r--r--thirdparty/squish/patches/decompress_bc4_bc5.patch85
-rw-r--r--thirdparty/squish/rangefit.cpp201
-rw-r--r--thirdparty/squish/rangefit.h54
-rw-r--r--thirdparty/squish/simd.h40
-rw-r--r--thirdparty/squish/simd_float.h183
-rw-r--r--thirdparty/squish/simd_sse.h180
-rw-r--r--thirdparty/squish/simd_ve.h166
-rw-r--r--thirdparty/squish/singlecolourfit.cpp172
-rw-r--r--thirdparty/squish/singlecolourfit.h58
-rw-r--r--thirdparty/squish/singlecolourlookup.inl1064
-rw-r--r--thirdparty/squish/squish.cpp411
-rw-r--r--thirdparty/squish/squish.h309
162 files changed, 4926 insertions, 6110 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 7cca1b6f2a..748d787b86 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -169,10 +169,12 @@
/modules/gridmap/icons/ @godotengine/3d-nodes @godotengine/usability
/modules/noise/ @godotengine/core
/modules/noise/doc_classes/ @godotengine/core @godotengine/documentation
+/modules/noise/icons/ @godotengine/core @godotengine/usability
/modules/noise/tests/ @godotengine/core @godotengine/tests
/modules/regex/ @godotengine/core
/modules/regex/doc_classes/ @godotengine/core @godotengine/documentation
-/modules/regex/test/ @godotengine/core @godotengine/tests
+/modules/regex/icons/ @godotengine/core @godotengine/usability
+/modules/regex/tests/ @godotengine/core @godotengine/tests
/modules/zip/ @godotengine/core
/modules/zip/doc_classes/ @godotengine/core @godotengine/documentation
@@ -207,6 +209,7 @@
/scene/resources/text_paragraph.* @godotengine/gui-nodes
/scene/resources/visual_shader*.* @godotengine/shaders
/scene/theme/ @godotengine/gui-nodes
+/scene/theme/icons/ @godotengine/gui-nodes @godotengine/usability
# Servers
diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml
index d2d0e3571f..fd5e74b914 100644
--- a/.github/workflows/runner.yml
+++ b/.github/workflows/runner.yml
@@ -1,5 +1,5 @@
name: 🔗 GHA
-on: [push, pull_request]
+on: [push, pull_request, merge_group]
concurrency:
group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}-runner
diff --git a/SConstruct b/SConstruct
index 5566770148..63cff4fe16 100644
--- a/SConstruct
+++ b/SConstruct
@@ -299,7 +299,6 @@ opts.Add(BoolVariable("builtin_pcre2_with_jit", "Use JIT compiler for the built-
opts.Add(BoolVariable("builtin_recastnavigation", "Use the built-in Recast navigation library", True))
opts.Add(BoolVariable("builtin_rvo2_2d", "Use the built-in RVO2 2D library", True))
opts.Add(BoolVariable("builtin_rvo2_3d", "Use the built-in RVO2 3D library", True))
-opts.Add(BoolVariable("builtin_squish", "Use the built-in squish library", True))
opts.Add(BoolVariable("builtin_xatlas", "Use the built-in xatlas library", True))
opts.Add(BoolVariable("builtin_zlib", "Use the built-in zlib library", True))
opts.Add(BoolVariable("builtin_zstd", "Use the built-in Zstd library", True))
@@ -640,25 +639,18 @@ if env.dev_build:
print("NOTE: Developer build, with debug optimization level and debug symbols (unless overridden).")
# Enforce our minimal compiler version requirements
-cc_version = methods.get_compiler_version(env) or {
- "major": None,
- "minor": None,
- "patch": None,
- "metadata1": None,
- "metadata2": None,
- "date": None,
-}
-cc_version_major = int(cc_version["major"] or -1)
-cc_version_minor = int(cc_version["minor"] or -1)
-cc_version_metadata1 = cc_version["metadata1"] or ""
-
-if methods.using_gcc(env):
- if cc_version_major == -1:
- print_warning(
- "Couldn't detect compiler version, skipping version checks. "
- "Build may fail if the compiler doesn't support C++17 fully."
- )
- elif cc_version_major < 9:
+cc_version = methods.get_compiler_version(env)
+cc_version_major = cc_version["major"]
+cc_version_minor = cc_version["minor"]
+cc_version_metadata1 = cc_version["metadata1"]
+
+if cc_version_major == -1:
+ print_warning(
+ "Couldn't detect compiler version, skipping version checks. "
+ "Build may fail if the compiler doesn't support C++17 fully."
+ )
+elif methods.using_gcc(env):
+ if cc_version_major < 9:
print_error(
"Detected GCC version older than 9, which does not fully support "
"C++17, or has bugs when compiling Godot. Supported versions are 9 "
@@ -678,17 +670,12 @@ if methods.using_gcc(env):
print_warning("GCC < 8 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option.")
env["debug_paths_relative"] = False
elif methods.using_clang(env):
- if cc_version_major == -1:
- print_warning(
- "Couldn't detect compiler version, skipping version checks. "
- "Build may fail if the compiler doesn't support C++17 fully."
- )
# Apple LLVM versions differ from upstream LLVM version \o/, compare
# in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions
- elif env["platform"] == "macos" or env["platform"] == "ios":
+ if env["platform"] == "macos" or env["platform"] == "ios":
vanilla = methods.is_vanilla_clang(env)
if vanilla and cc_version_major < 6:
- print_warning(
+ print_error(
"Detected Clang version older than 6, which does not fully support "
"C++17. Supported versions are Clang 6 and later."
)
@@ -713,6 +700,28 @@ elif methods.using_clang(env):
if env["debug_paths_relative"] and cc_version_major < 10:
print_warning("Clang < 10 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option.")
env["debug_paths_relative"] = False
+elif env.msvc:
+ # Ensure latest minor builds of Visual Studio 2017/2019.
+ # https://github.com/godotengine/godot/pull/94995#issuecomment-2336464574
+ if cc_version_major == 16 and cc_version_minor < 11:
+ print_error(
+ "Detected Visual Studio 2019 version older than 16.11, which has bugs "
+ "when compiling Godot. Use a newer VS2019 version, or VS2022."
+ )
+ Exit(255)
+ if cc_version_major == 15 and cc_version_minor < 9:
+ print_error(
+ "Detected Visual Studio 2017 version older than 15.9, which has bugs "
+ "when compiling Godot. Use a newer VS2017 version, or VS2019/VS2022."
+ )
+ Exit(255)
+ if cc_version_major < 15:
+ print_error(
+ "Detected Visual Studio 2015 or earlier, which is unsupported in Godot. "
+ "Supported versions are Visual Studio 2017 and later."
+ )
+ Exit(255)
+
# Set optimize and debug_symbols flags.
# "custom" means do nothing and let users set their own optimization flags.
@@ -790,13 +799,17 @@ if env["lto"] != "none":
# This needs to come after `configure`, otherwise we don't have env.msvc.
if not env.msvc:
# Specifying GNU extensions support explicitly, which are supported by
- # both GCC and Clang. Both currently default to gnu11 and gnu++14.
+ # both GCC and Clang. Both currently default to gnu11 and gnu++17.
env.Prepend(CFLAGS=["-std=gnu11"])
env.Prepend(CXXFLAGS=["-std=gnu++17"])
else:
- # MSVC doesn't have clear C standard support, /std only covers C++.
- # We apply it to CCFLAGS (both C and C++ code) in case it impacts C features.
- env.Prepend(CCFLAGS=["/std:c++17"])
+ # MSVC started offering C standard support with Visual Studio 2019 16.8, which covers all
+ # of our supported VS2019 & VS2022 versions; VS2017 will only pass the C++ standard.
+ env.Prepend(CXXFLAGS=["/std:c++17"])
+ if cc_version_major < 16:
+ print_warning("Visual Studio 2017 cannot specify a C-Standard.")
+ else:
+ env.Prepend(CFLAGS=["/std:c11"])
# MSVC is non-conforming with the C++ standard by default, so we enable more conformance.
# Note that this is still not complete conformance, as certain Windows-related headers
# don't compile under complete conformance.
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 68af5abf66..25da49fa5c 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -677,6 +677,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_HIDE_QUATERNION_EDIT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PASSWORD);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_TOOL_BUTTON);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE);
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 4042d6b80d..c5f7502c12 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -1017,6 +1017,7 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
d2["name"] = String(method_name);
d2["is_const"] = (F.flags & METHOD_FLAG_CONST) ? true : false;
d2["is_static"] = (F.flags & METHOD_FLAG_STATIC) ? true : false;
+ d2["is_required"] = (F.flags & METHOD_FLAG_VIRTUAL_REQUIRED) ? true : false;
d2["is_vararg"] = false;
d2["is_virtual"] = true;
// virtual functions have no hash since no MethodBind is involved
diff --git a/core/extension/make_wrappers.py b/core/extension/make_wrappers.py
index 54f4fd5579..665b6f0f91 100644
--- a/core/extension/make_wrappers.py
+++ b/core/extension/make_wrappers.py
@@ -55,10 +55,10 @@ def generate_mod_version(argcount, const=False, returns=False):
proto_ex = """
#define EXBIND$VER($RETTYPE m_name$ARG) \\
-GDVIRTUAL$VER($RETTYPE_##m_name$ARG)\\
+GDVIRTUAL$VER_REQUIRED($RETTYPE_##m_name$ARG)\\
virtual $RETVAL m_name($FUNCARGS) $CONST override { \\
$RETPRE\\
- GDVIRTUAL_REQUIRED_CALL(_##m_name$CALLARGS$RETREF);\\
+ GDVIRTUAL_CALL(_##m_name$CALLARGS$RETREF);\\
$RETPOST\\
}
"""
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index 7a85753072..3df26e3b73 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -2,7 +2,6 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
StringName _gdvirtual_##m_name##_sn = #m_name;\\
mutable bool _gdvirtual_##m_name##_initialized = false;\\
mutable void *_gdvirtual_##m_name = nullptr;\\
- template <bool required>\\
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST {\\
ScriptInstance *_script_instance = ((Object *)(this))->get_script_instance();\\
if (_script_instance) {\\
@@ -36,10 +35,8 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
}\\
return true;\\
}\\
- if (required) {\\
- ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");\\
- $RVOID\\
- }\\
+ $REQCHECK\\
+ $RVOID\\
return false;\\
}\\
_FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const {\\
@@ -73,10 +70,11 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
"""
-def generate_version(argcount, const=False, returns=False):
+def generate_version(argcount, const=False, returns=False, required=False):
s = proto
sproto = str(argcount)
method_info = ""
+ method_flags = "METHOD_FLAG_VIRTUAL"
if returns:
sproto += "R"
s = s.replace("$RET", "m_ret,")
@@ -86,17 +84,27 @@ def generate_version(argcount, const=False, returns=False):
method_info += "\t\tmethod_info.return_val_metadata = GetTypeInfo<m_ret>::METADATA;"
else:
s = s.replace("$RET ", "")
- s = s.replace("\t\t\t$RVOID\\\n", "")
+ s = s.replace("\t\t$RVOID\\\n", "")
s = s.replace("\t\t\t$CALLPTRRETDEF\\\n", "")
if const:
sproto += "C"
+ method_flags += " | METHOD_FLAG_CONST"
s = s.replace("$CONST", "const")
- s = s.replace("$METHOD_FLAGS", "METHOD_FLAG_VIRTUAL | METHOD_FLAG_CONST")
else:
s = s.replace("$CONST ", "")
- s = s.replace("$METHOD_FLAGS", "METHOD_FLAG_VIRTUAL")
+ if required:
+ sproto += "_REQUIRED"
+ method_flags += " | METHOD_FLAG_VIRTUAL_REQUIRED"
+ s = s.replace(
+ "$REQCHECK",
+ 'ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");',
+ )
+ else:
+ s = s.replace("\t\t$REQCHECK\\\n", "")
+
+ s = s.replace("$METHOD_FLAGS", method_flags)
s = s.replace("$VER", sproto)
argtext = ""
callargtext = ""
@@ -198,6 +206,10 @@ def run(target, source, env):
txt += generate_version(i, False, True)
txt += generate_version(i, True, False)
txt += generate_version(i, True, True)
+ txt += generate_version(i, False, False, True)
+ txt += generate_version(i, False, True, True)
+ txt += generate_version(i, True, False, True)
+ txt += generate_version(i, True, True, True)
txt += "#endif // GDVIRTUAL_GEN_H\n"
diff --git a/core/object/object.h b/core/object/object.h
index 763e2974b9..110d2790c5 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -87,6 +87,7 @@ enum PropertyHint {
PROPERTY_HINT_PASSWORD,
PROPERTY_HINT_LAYERS_AVOIDANCE,
PROPERTY_HINT_DICTIONARY_TYPE,
+ PROPERTY_HINT_TOOL_BUTTON,
PROPERTY_HINT_MAX,
};
@@ -215,6 +216,7 @@ enum MethodFlags {
METHOD_FLAG_VARARG = 16,
METHOD_FLAG_STATIC = 32,
METHOD_FLAG_OBJECT_CORE = 64,
+ METHOD_FLAG_VIRTUAL_REQUIRED = 128,
METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL,
};
@@ -368,11 +370,8 @@ struct ObjectGDExtension {
#endif
};
-#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__)
-#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<false>(__VA_ARGS__)
-
-#define GDVIRTUAL_REQUIRED_CALL(m_name, ...) _gdvirtual_##m_name##_call<true>(__VA_ARGS__)
-#define GDVIRTUAL_REQUIRED_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<true>(__VA_ARGS__)
+#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__)
+#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call(__VA_ARGS__)
#ifdef DEBUG_METHODS_ENABLED
#define GDVIRTUAL_BIND(m_name, ...) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), true, sarray(__VA_ARGS__));
diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h
index bc773c5ad3..d2dce34d4f 100644
--- a/core/object/script_language_extension.h
+++ b/core/object/script_language_extension.h
@@ -57,16 +57,16 @@ public:
EXBIND1RC(bool, inherits_script, const Ref<Script> &)
EXBIND0RC(StringName, get_instance_base_type)
- GDVIRTUAL1RC(GDExtensionPtr<void>, _instance_create, Object *)
+ GDVIRTUAL1RC_REQUIRED(GDExtensionPtr<void>, _instance_create, Object *)
virtual ScriptInstance *instance_create(Object *p_this) override {
GDExtensionPtr<void> ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_instance_create, p_this, ret);
+ GDVIRTUAL_CALL(_instance_create, p_this, ret);
return reinterpret_cast<ScriptInstance *>(ret.operator void *());
}
- GDVIRTUAL1RC(GDExtensionPtr<void>, _placeholder_instance_create, Object *)
+ GDVIRTUAL1RC_REQUIRED(GDExtensionPtr<void>, _placeholder_instance_create, Object *)
PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override {
GDExtensionPtr<void> ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_placeholder_instance_create, p_this, ret);
+ GDVIRTUAL_CALL(_placeholder_instance_create, p_this, ret);
return reinterpret_cast<PlaceHolderScriptInstance *>(ret.operator void *());
}
@@ -76,12 +76,12 @@ public:
EXBIND1(set_source_code, const String &)
EXBIND1R(Error, reload, bool)
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_documentation)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_documentation)
GDVIRTUAL0RC(String, _get_class_icon_path)
#ifdef TOOLS_ENABLED
virtual Vector<DocData::ClassDoc> get_documentation() const override {
TypedArray<Dictionary> doc;
- GDVIRTUAL_REQUIRED_CALL(_get_documentation, doc);
+ GDVIRTUAL_CALL(_get_documentation, doc);
Vector<DocData::ClassDoc> class_doc;
for (int i = 0; i < doc.size(); i++) {
@@ -114,10 +114,10 @@ public:
return Script::get_script_method_argument_count(p_method, r_is_valid);
}
- GDVIRTUAL1RC(Dictionary, _get_method_info, const StringName &)
+ GDVIRTUAL1RC_REQUIRED(Dictionary, _get_method_info, const StringName &)
virtual MethodInfo get_method_info(const StringName &p_method) const override {
Dictionary mi;
- GDVIRTUAL_REQUIRED_CALL(_get_method_info, p_method, mi);
+ GDVIRTUAL_CALL(_get_method_info, p_method, mi);
return MethodInfo::from_dict(mi);
}
@@ -133,47 +133,47 @@ public:
EXBIND0RC(ScriptLanguage *, get_language)
EXBIND1RC(bool, has_script_signal, const StringName &)
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_signal_list)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_signal_list)
virtual void get_script_signal_list(List<MethodInfo> *r_signals) const override {
TypedArray<Dictionary> sl;
- GDVIRTUAL_REQUIRED_CALL(_get_script_signal_list, sl);
+ GDVIRTUAL_CALL(_get_script_signal_list, sl);
for (int i = 0; i < sl.size(); i++) {
r_signals->push_back(MethodInfo::from_dict(sl[i]));
}
}
- GDVIRTUAL1RC(bool, _has_property_default_value, const StringName &)
- GDVIRTUAL1RC(Variant, _get_property_default_value, const StringName &)
+ GDVIRTUAL1RC_REQUIRED(bool, _has_property_default_value, const StringName &)
+ GDVIRTUAL1RC_REQUIRED(Variant, _get_property_default_value, const StringName &)
virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const override {
bool has_dv = false;
- if (!GDVIRTUAL_REQUIRED_CALL(_has_property_default_value, p_property, has_dv) || !has_dv) {
+ if (!GDVIRTUAL_CALL(_has_property_default_value, p_property, has_dv) || !has_dv) {
return false;
}
Variant ret;
- GDVIRTUAL_REQUIRED_CALL(_get_property_default_value, p_property, ret);
+ GDVIRTUAL_CALL(_get_property_default_value, p_property, ret);
r_value = ret;
return true;
}
EXBIND0(update_exports)
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_method_list)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_method_list)
virtual void get_script_method_list(List<MethodInfo> *r_methods) const override {
TypedArray<Dictionary> sl;
- GDVIRTUAL_REQUIRED_CALL(_get_script_method_list, sl);
+ GDVIRTUAL_CALL(_get_script_method_list, sl);
for (int i = 0; i < sl.size(); i++) {
r_methods->push_back(MethodInfo::from_dict(sl[i]));
}
}
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_property_list)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_property_list)
virtual void get_script_property_list(List<PropertyInfo> *r_propertys) const override {
TypedArray<Dictionary> sl;
- GDVIRTUAL_REQUIRED_CALL(_get_script_property_list, sl);
+ GDVIRTUAL_CALL(_get_script_property_list, sl);
for (int i = 0; i < sl.size(); i++) {
r_propertys->push_back(PropertyInfo::from_dict(sl[i]));
}
@@ -181,21 +181,21 @@ public:
EXBIND1RC(int, get_member_line, const StringName &)
- GDVIRTUAL0RC(Dictionary, _get_constants)
+ GDVIRTUAL0RC_REQUIRED(Dictionary, _get_constants)
virtual void get_constants(HashMap<StringName, Variant> *p_constants) override {
Dictionary constants;
- GDVIRTUAL_REQUIRED_CALL(_get_constants, constants);
+ GDVIRTUAL_CALL(_get_constants, constants);
List<Variant> keys;
constants.get_key_list(&keys);
for (const Variant &K : keys) {
p_constants->insert(K, constants[K]);
}
}
- GDVIRTUAL0RC(TypedArray<StringName>, _get_members)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<StringName>, _get_members)
virtual void get_members(HashSet<StringName> *p_members) override {
TypedArray<StringName> members;
- GDVIRTUAL_REQUIRED_CALL(_get_members, members);
+ GDVIRTUAL_CALL(_get_members, members);
for (int i = 0; i < members.size(); i++) {
p_members->insert(members[i]);
}
@@ -203,11 +203,11 @@ public:
EXBIND0RC(bool, is_placeholder_fallback_enabled)
- GDVIRTUAL0RC(Variant, _get_rpc_config)
+ GDVIRTUAL0RC_REQUIRED(Variant, _get_rpc_config)
virtual Variant get_rpc_config() const override {
Variant ret;
- GDVIRTUAL_REQUIRED_CALL(_get_rpc_config, ret);
+ GDVIRTUAL_CALL(_get_rpc_config, ret);
return ret;
}
@@ -233,22 +233,22 @@ public:
/* EDITOR FUNCTIONS */
- GDVIRTUAL0RC(Vector<String>, _get_reserved_words)
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_reserved_words)
virtual void get_reserved_words(List<String> *p_words) const override {
Vector<String> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_reserved_words, ret);
+ GDVIRTUAL_CALL(_get_reserved_words, ret);
for (int i = 0; i < ret.size(); i++) {
p_words->push_back(ret[i]);
}
}
EXBIND1RC(bool, is_control_flow_keyword, const String &)
- GDVIRTUAL0RC(Vector<String>, _get_comment_delimiters)
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_comment_delimiters)
virtual void get_comment_delimiters(List<String> *p_words) const override {
Vector<String> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_comment_delimiters, ret);
+ GDVIRTUAL_CALL(_get_comment_delimiters, ret);
for (int i = 0; i < ret.size(); i++) {
p_words->push_back(ret[i]);
}
@@ -264,11 +264,11 @@ public:
}
}
- GDVIRTUAL0RC(Vector<String>, _get_string_delimiters)
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_string_delimiters)
virtual void get_string_delimiters(List<String> *p_words) const override {
Vector<String> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_string_delimiters, ret);
+ GDVIRTUAL_CALL(_get_string_delimiters, ret);
for (int i = 0; i < ret.size(); i++) {
p_words->push_back(ret[i]);
}
@@ -276,11 +276,11 @@ public:
EXBIND3RC(Ref<Script>, make_template, const String &, const String &, const String &)
- GDVIRTUAL1RC(TypedArray<Dictionary>, _get_built_in_templates, StringName)
+ GDVIRTUAL1RC_REQUIRED(TypedArray<Dictionary>, _get_built_in_templates, StringName)
virtual Vector<ScriptTemplate> get_built_in_templates(const StringName &p_object) override {
TypedArray<Dictionary> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_built_in_templates, p_object, ret);
+ GDVIRTUAL_CALL(_get_built_in_templates, p_object, ret);
Vector<ScriptTemplate> stret;
for (int i = 0; i < ret.size(); i++) {
Dictionary d = ret[i];
@@ -304,10 +304,10 @@ public:
EXBIND0R(bool, is_using_templates)
- GDVIRTUAL6RC(Dictionary, _validate, const String &, const String &, bool, bool, bool, bool)
+ GDVIRTUAL6RC_REQUIRED(Dictionary, _validate, const String &, const String &, bool, bool, bool, bool)
virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, HashSet<int> *r_safe_lines = nullptr) const override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_validate, p_script, p_path, r_functions != nullptr, r_errors != nullptr, r_warnings != nullptr, r_safe_lines != nullptr, ret);
+ GDVIRTUAL_CALL(_validate, p_script, p_path, r_functions != nullptr, r_errors != nullptr, r_warnings != nullptr, r_safe_lines != nullptr, ret);
if (!ret.has("valid")) {
return false;
}
@@ -371,10 +371,10 @@ public:
}
EXBIND1RC(String, validate_path, const String &)
- GDVIRTUAL0RC(Object *, _create_script)
+ GDVIRTUAL0RC_REQUIRED(Object *, _create_script)
Script *create_script() const override {
Object *ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_create_script, ret);
+ GDVIRTUAL_CALL(_create_script, ret);
return Object::cast_to<Script>(ret);
}
#ifndef DISABLE_DEPRECATED
@@ -400,11 +400,11 @@ public:
return ScriptNameCasing::SCRIPT_NAME_CASING_SNAKE_CASE;
}
- GDVIRTUAL3RC(Dictionary, _complete_code, const String &, const String &, Object *)
+ GDVIRTUAL3RC_REQUIRED(Dictionary, _complete_code, const String &, const String &, Object *)
virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<CodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_complete_code, p_code, p_path, p_owner, ret);
+ GDVIRTUAL_CALL(_complete_code, p_code, p_path, p_owner, ret);
if (!ret.has("result")) {
return ERR_UNAVAILABLE;
}
@@ -449,11 +449,11 @@ public:
return result;
}
- GDVIRTUAL4RC(Dictionary, _lookup_code, const String &, const String &, const String &, Object *)
+ GDVIRTUAL4RC_REQUIRED(Dictionary, _lookup_code, const String &, const String &, const String &, Object *)
virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret);
+ GDVIRTUAL_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret);
if (!ret.has("result")) {
return ERR_UNAVAILABLE;
}
@@ -474,10 +474,10 @@ public:
return result;
}
- GDVIRTUAL3RC(String, _auto_indent_code, const String &, int, int)
+ GDVIRTUAL3RC_REQUIRED(String, _auto_indent_code, const String &, int, int)
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override {
String ret;
- GDVIRTUAL_REQUIRED_CALL(_auto_indent_code, p_code, p_from_line, p_to_line, ret);
+ GDVIRTUAL_CALL(_auto_indent_code, p_code, p_from_line, p_to_line, ret);
p_code = ret;
}
EXBIND2(add_global_constant, const StringName &, const Variant &)
@@ -496,10 +496,10 @@ public:
EXBIND1RC(String, debug_get_stack_level_function, int)
EXBIND1RC(String, debug_get_stack_level_source, int)
- GDVIRTUAL3R(Dictionary, _debug_get_stack_level_locals, int, int, int)
+ GDVIRTUAL3R_REQUIRED(Dictionary, _debug_get_stack_level_locals, int, int, int)
virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_locals, p_level, p_max_subitems, p_max_depth, ret);
+ GDVIRTUAL_CALL(_debug_get_stack_level_locals, p_level, p_max_subitems, p_max_depth, ret);
if (ret.size() == 0) {
return;
}
@@ -516,10 +516,10 @@ public:
}
}
}
- GDVIRTUAL3R(Dictionary, _debug_get_stack_level_members, int, int, int)
+ GDVIRTUAL3R_REQUIRED(Dictionary, _debug_get_stack_level_members, int, int, int)
virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_members, p_level, p_max_subitems, p_max_depth, ret);
+ GDVIRTUAL_CALL(_debug_get_stack_level_members, p_level, p_max_subitems, p_max_depth, ret);
if (ret.size() == 0) {
return;
}
@@ -536,17 +536,17 @@ public:
}
}
}
- GDVIRTUAL1R(GDExtensionPtr<void>, _debug_get_stack_level_instance, int)
+ GDVIRTUAL1R_REQUIRED(GDExtensionPtr<void>, _debug_get_stack_level_instance, int)
virtual ScriptInstance *debug_get_stack_level_instance(int p_level) override {
GDExtensionPtr<void> ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_instance, p_level, ret);
+ GDVIRTUAL_CALL(_debug_get_stack_level_instance, p_level, ret);
return reinterpret_cast<ScriptInstance *>(ret.operator void *());
}
- GDVIRTUAL2R(Dictionary, _debug_get_globals, int, int)
+ GDVIRTUAL2R_REQUIRED(Dictionary, _debug_get_globals, int, int)
virtual void debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_globals, p_max_subitems, p_max_depth, ret);
+ GDVIRTUAL_CALL(_debug_get_globals, p_max_subitems, p_max_depth, ret);
if (ret.size() == 0) {
return;
}
@@ -566,10 +566,10 @@ public:
EXBIND4R(String, debug_parse_stack_level_expression, int, const String &, int, int)
- GDVIRTUAL0R(TypedArray<Dictionary>, _debug_get_current_stack_info)
+ GDVIRTUAL0R_REQUIRED(TypedArray<Dictionary>, _debug_get_current_stack_info)
virtual Vector<StackInfo> debug_get_current_stack_info() override {
TypedArray<Dictionary> ret;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_current_stack_info, ret);
+ GDVIRTUAL_CALL(_debug_get_current_stack_info, ret);
Vector<StackInfo> sret;
for (const Variant &var : ret) {
StackInfo si;
@@ -590,29 +590,29 @@ public:
EXBIND2(reload_tool_script, const Ref<Script> &, bool)
/* LOADER FUNCTIONS */
- GDVIRTUAL0RC(PackedStringArray, _get_recognized_extensions)
+ GDVIRTUAL0RC_REQUIRED(PackedStringArray, _get_recognized_extensions)
virtual void get_recognized_extensions(List<String> *p_extensions) const override {
PackedStringArray ret;
- GDVIRTUAL_REQUIRED_CALL(_get_recognized_extensions, ret);
+ GDVIRTUAL_CALL(_get_recognized_extensions, ret);
for (int i = 0; i < ret.size(); i++) {
p_extensions->push_back(ret[i]);
}
}
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_functions)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_public_functions)
virtual void get_public_functions(List<MethodInfo> *p_functions) const override {
TypedArray<Dictionary> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_public_functions, ret);
+ GDVIRTUAL_CALL(_get_public_functions, ret);
for (const Variant &var : ret) {
MethodInfo mi = MethodInfo::from_dict(var);
p_functions->push_back(mi);
}
}
- GDVIRTUAL0RC(Dictionary, _get_public_constants)
+ GDVIRTUAL0RC_REQUIRED(Dictionary, _get_public_constants)
virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_get_public_constants, ret);
+ GDVIRTUAL_CALL(_get_public_constants, ret);
for (int i = 0; i < ret.size(); i++) {
Dictionary d = ret[i];
ERR_CONTINUE(!d.has("name"));
@@ -620,10 +620,10 @@ public:
p_constants->push_back(Pair<String, Variant>(d["name"], d["value"]));
}
}
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_annotations)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_public_annotations)
virtual void get_public_annotations(List<MethodInfo> *p_annotations) const override {
TypedArray<Dictionary> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_public_annotations, ret);
+ GDVIRTUAL_CALL(_get_public_annotations, ret);
for (const Variant &var : ret) {
MethodInfo mi = MethodInfo::from_dict(var);
p_annotations->push_back(mi);
@@ -634,19 +634,19 @@ public:
EXBIND0(profiling_stop)
EXBIND1(profiling_set_save_native_calls, bool)
- GDVIRTUAL2R(int, _profiling_get_accumulated_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int)
+ GDVIRTUAL2R_REQUIRED(int, _profiling_get_accumulated_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int)
virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_profiling_get_accumulated_data, p_info_arr, p_info_max, ret);
+ GDVIRTUAL_CALL(_profiling_get_accumulated_data, p_info_arr, p_info_max, ret);
return ret;
}
- GDVIRTUAL2R(int, _profiling_get_frame_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int)
+ GDVIRTUAL2R_REQUIRED(int, _profiling_get_frame_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int)
virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_profiling_get_frame_data, p_info_arr, p_info_max, ret);
+ GDVIRTUAL_CALL(_profiling_get_frame_data, p_info_arr, p_info_max, ret);
return ret;
}
@@ -654,11 +654,11 @@ public:
EXBIND1RC(bool, handles_global_class_type, const String &)
- GDVIRTUAL1RC(Dictionary, _get_global_class_name, const String &)
+ GDVIRTUAL1RC_REQUIRED(Dictionary, _get_global_class_name, const String &)
virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_get_global_class_name, p_path, ret);
+ GDVIRTUAL_CALL(_get_global_class_name, p_path, ret);
if (!ret.has("name")) {
return String();
}
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 63fb5e8d94..ab33c9db55 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -657,7 +657,23 @@ static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, c
} \
};
+#define VARCALL_PACKED_GETTER(m_packed_type, m_return_type) \
+ static m_return_type func_##m_packed_type##_get(m_packed_type *p_instance, int64_t p_index) { \
+ return p_instance->get(p_index); \
+ }
+
struct _VariantCall {
+ VARCALL_PACKED_GETTER(PackedByteArray, uint8_t)
+ VARCALL_PACKED_GETTER(PackedColorArray, Color)
+ VARCALL_PACKED_GETTER(PackedFloat32Array, float)
+ VARCALL_PACKED_GETTER(PackedFloat64Array, double)
+ VARCALL_PACKED_GETTER(PackedInt32Array, int32_t)
+ VARCALL_PACKED_GETTER(PackedInt64Array, int64_t)
+ VARCALL_PACKED_GETTER(PackedStringArray, String)
+ VARCALL_PACKED_GETTER(PackedVector2Array, Vector2)
+ VARCALL_PACKED_GETTER(PackedVector3Array, Vector3)
+ VARCALL_PACKED_GETTER(PackedVector4Array, Vector4)
+
static String func_PackedByteArray_get_string_from_ascii(PackedByteArray *p_instance) {
String s;
if (p_instance->size() > 0) {
@@ -2268,6 +2284,7 @@ static void _register_variant_builtin_methods_misc() {
bind_method(Dictionary, duplicate, sarray("deep"), varray(false));
bind_method(Dictionary, get, sarray("key", "default"), varray(Variant()));
bind_method(Dictionary, get_or_add, sarray("key", "default"), varray(Variant()));
+ bind_method(Dictionary, set, sarray("key", "value"), varray());
bind_method(Dictionary, is_typed, sarray(), varray());
bind_method(Dictionary, is_typed_key, sarray(), varray());
bind_method(Dictionary, is_typed_value, sarray(), varray());
@@ -2293,6 +2310,8 @@ static void _register_variant_builtin_methods_array() {
bind_method(Array, clear, sarray(), varray());
bind_method(Array, hash, sarray(), varray());
bind_method(Array, assign, sarray("array"), varray());
+ bind_method(Array, get, sarray("index"), varray());
+ bind_method(Array, set, sarray("index", "value"), varray());
bind_method(Array, push_back, sarray("value"), varray());
bind_method(Array, push_front, sarray("value"), varray());
bind_method(Array, append, sarray("value"), varray());
@@ -2337,6 +2356,18 @@ static void _register_variant_builtin_methods_array() {
bind_method(Array, make_read_only, sarray(), varray());
bind_method(Array, is_read_only, sarray(), varray());
+ /* Packed*Array get (see VARCALL_PACKED_GETTER macro) */
+ bind_function(PackedByteArray, get, _VariantCall::func_PackedByteArray_get, sarray("index"), varray());
+ bind_function(PackedColorArray, get, _VariantCall::func_PackedColorArray_get, sarray("index"), varray());
+ bind_function(PackedFloat32Array, get, _VariantCall::func_PackedFloat32Array_get, sarray("index"), varray());
+ bind_function(PackedFloat64Array, get, _VariantCall::func_PackedFloat64Array_get, sarray("index"), varray());
+ bind_function(PackedInt32Array, get, _VariantCall::func_PackedInt32Array_get, sarray("index"), varray());
+ bind_function(PackedInt64Array, get, _VariantCall::func_PackedInt64Array_get, sarray("index"), varray());
+ bind_function(PackedStringArray, get, _VariantCall::func_PackedStringArray_get, sarray("index"), varray());
+ bind_function(PackedVector2Array, get, _VariantCall::func_PackedVector2Array_get, sarray("index"), varray());
+ bind_function(PackedVector3Array, get, _VariantCall::func_PackedVector3Array_get, sarray("index"), varray());
+ bind_function(PackedVector4Array, get, _VariantCall::func_PackedVector4Array_get, sarray("index"), varray());
+
/* Byte Array */
bind_method(PackedByteArray, size, sarray(), varray());
bind_method(PackedByteArray, is_empty, sarray(), varray());
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index a86f41cd9c..63d20242d6 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2933,7 +2933,15 @@
<constant name="PROPERTY_HINT_PASSWORD" value="36" enum="PropertyHint">
Hints that a string property is a password, and every character is replaced with the secret character.
</constant>
- <constant name="PROPERTY_HINT_MAX" value="39" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_TOOL_BUTTON" value="39" enum="PropertyHint">
+ Hints that a [Callable] property should be displayed as a clickable button. When the button is pressed, the callable is called. The hint string specifies the button text and optionally an icon from the [code]"EditorIcons"[/code] theme type.
+ [codeblock lang=text]
+ "Click me!" - A button with the text "Click me!" and the default "Callable" icon.
+ "Click me!,ColorRect" - A button with the text "Click me!" and the "ColorRect" icon.
+ [/codeblock]
+ [b]Note:[/b] A [Callable] cannot be properly serialized and stored in a file, so it is recommended to use [constant PROPERTY_USAGE_EDITOR] instead of [constant PROPERTY_USAGE_DEFAULT].
+ </constant>
+ <constant name="PROPERTY_HINT_MAX" value="40" enum="PropertyHint">
Represents the size of the [enum PropertyHint] enum.
</constant>
<constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags" is_bitfield="true">
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index adb6be1070..1b7dbf7c41 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -422,6 +422,13 @@
[b]Note:[/b] Unlike with the [code][][/code] operator ([code]array[0][/code]), an error is generated without stopping project execution.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="Variant" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the element at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="get_typed_builtin" qualifiers="const">
<return type="int" />
<description>
@@ -693,6 +700,14 @@
Returns the index of the [b]last[/b] element of the array that causes [param method] to return [code]true[/code], or [code]-1[/code] if there are none. The search's start can be specified with [param from], continuing to the beginning of the array. This method is the reverse of [method find_custom].
</description>
</method>
+ <method name="set">
+ <return type="void" />
+ <param index="0" name="index" type="int" />
+ <param index="1" name="value" type="Variant" />
+ <description>
+ Sets the value of the element at the given [param index] to the given [param value]. This will not change the size of the array, it only changes the value at an index already in the array. This is the same as using the [code][][/code] operator ([code]array[index] = value[/code]).
+ </description>
+ </method>
<method name="shuffle">
<return type="void" />
<description>
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml
index feb2a07e4a..4441c3cb79 100644
--- a/doc/classes/Dictionary.xml
+++ b/doc/classes/Dictionary.xml
@@ -460,6 +460,14 @@
Returns [code]true[/code] if the two dictionaries contain the same keys and values, inner [Dictionary] and [Array] keys and values are compared recursively.
</description>
</method>
+ <method name="set">
+ <return type="bool" />
+ <param index="0" name="key" type="Variant" />
+ <param index="1" name="value" type="Variant" />
+ <description>
+ Sets the value of the element at the given [param key] to the given [param value]. This is the same as using the [code][][/code] operator ([code]array[index] = value[/code]).
+ </description>
+ </method>
<method name="size" qualifiers="const">
<return type="int" />
<description>
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 670df10a89..3451e427f3 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -399,6 +399,11 @@
Emitted when this [GraphEdit] captures a [code]ui_copy[/code] action ([kbd]Ctrl + C[/kbd] by default). In general, this signal indicates that the selected [GraphElement]s should be copied.
</description>
</signal>
+ <signal name="cut_nodes_request">
+ <description>
+ Emitted when this [GraphEdit] captures a [code]ui_cut[/code] action ([kbd]Ctrl + X[/kbd] by default). In general, this signal indicates that the selected [GraphElement]s should be cut.
+ </description>
+ </signal>
<signal name="delete_nodes_request">
<param index="0" name="nodes" type="StringName[]" />
<description>
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index a1e5d9cbd9..c60a2ca887 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -407,13 +407,14 @@
<param index="0" name="at_position" type="Vector2" />
<param index="1" name="mouse_button_index" type="int" />
<description>
- Triggered when any mouse click is issued within the rect of the list but on empty space.
+ Emitted when any mouse click is issued within the rect of the list but on empty space.
+ [param at_position] is the click position in this control's local coordinate system.
</description>
</signal>
<signal name="item_activated">
<param index="0" name="index" type="int" />
<description>
- Triggered when specified list item is activated via double-clicking or by pressing [kbd]Enter[/kbd].
+ Emitted when specified list item is activated via double-clicking or by pressing [kbd]Enter[/kbd].
</description>
</signal>
<signal name="item_clicked">
@@ -421,14 +422,14 @@
<param index="1" name="at_position" type="Vector2" />
<param index="2" name="mouse_button_index" type="int" />
<description>
- Triggered when specified list item has been clicked with any mouse button.
- The click position is also provided to allow appropriate popup of context menus at the correct location.
+ Emitted when specified list item has been clicked with any mouse button.
+ [param at_position] is the click position in this control's local coordinate system.
</description>
</signal>
<signal name="item_selected">
<param index="0" name="index" type="int" />
<description>
- Triggered when specified item has been selected.
+ Emitted when specified item has been selected. Only applicable in single selection mode.
[member allow_reselect] must be enabled to reselect an item.
</description>
</signal>
@@ -436,7 +437,7 @@
<param index="0" name="index" type="int" />
<param index="1" name="selected" type="bool" />
<description>
- Triggered when a multiple selection is altered on a list allowing multiple selection.
+ Emitted when a multiple selection is altered on a list allowing multiple selection.
</description>
</signal>
</signals>
diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml
index e179c111a2..75193ae8ed 100644
--- a/doc/classes/PackedByteArray.xml
+++ b/doc/classes/PackedByteArray.xml
@@ -307,6 +307,13 @@
Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="int" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the byte at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="get_string_from_ascii" qualifiers="const">
<return type="String" />
<description>
diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml
index 57295cb1e3..b9cef0ead6 100644
--- a/doc/classes/PackedColorArray.xml
+++ b/doc/classes/PackedColorArray.xml
@@ -94,6 +94,13 @@
Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="Color" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the [Color] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="Color" />
diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml
index 2db1386fd0..d421993b8f 100644
--- a/doc/classes/PackedFloat32Array.xml
+++ b/doc/classes/PackedFloat32Array.xml
@@ -93,6 +93,13 @@
[b]Note:[/b] [constant @GDScript.NAN] doesn't behave the same as other numbers. Therefore, the results from this method may not be accurate if NaNs are included.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="float" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the 32-bit float at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="float" />
diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml
index 0bcee918ed..4622d63258 100644
--- a/doc/classes/PackedFloat64Array.xml
+++ b/doc/classes/PackedFloat64Array.xml
@@ -94,6 +94,13 @@
[b]Note:[/b] [constant @GDScript.NAN] doesn't behave the same as other numbers. Therefore, the results from this method may not be accurate if NaNs are included.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="float" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the 64-bit float at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="float" />
diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml
index 93b2ae7394..3a3596b2d0 100644
--- a/doc/classes/PackedInt32Array.xml
+++ b/doc/classes/PackedInt32Array.xml
@@ -90,6 +90,13 @@
Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="int" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the 32-bit integer at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="int" />
diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml
index 3d34165915..cfaf012a55 100644
--- a/doc/classes/PackedInt64Array.xml
+++ b/doc/classes/PackedInt64Array.xml
@@ -91,6 +91,13 @@
Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="int" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the 64-bit integer at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="int" />
diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml
index 621831c7a3..511850d645 100644
--- a/doc/classes/PackedStringArray.xml
+++ b/doc/classes/PackedStringArray.xml
@@ -97,6 +97,13 @@
Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="String" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the [String] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="String" />
diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml
index 14a3816353..da41812e0b 100644
--- a/doc/classes/PackedVector2Array.xml
+++ b/doc/classes/PackedVector2Array.xml
@@ -98,6 +98,13 @@
[b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="Vector2" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the [Vector2] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="Vector2" />
diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml
index 49220c6fd6..d47f2f3cd1 100644
--- a/doc/classes/PackedVector3Array.xml
+++ b/doc/classes/PackedVector3Array.xml
@@ -97,6 +97,13 @@
[b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="Vector3" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the [Vector3] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="Vector3" />
diff --git a/doc/classes/PackedVector4Array.xml b/doc/classes/PackedVector4Array.xml
index fd0cfeb74b..6dbfc7413d 100644
--- a/doc/classes/PackedVector4Array.xml
+++ b/doc/classes/PackedVector4Array.xml
@@ -96,6 +96,13 @@
[b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included.
</description>
</method>
+ <method name="get" qualifiers="const">
+ <return type="Vector4" />
+ <param index="0" name="index" type="int" />
+ <description>
+ Returns the [Vector4] at the given [param index] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]).
+ </description>
+ </method>
<method name="has" qualifiers="const">
<return type="bool" />
<param index="0" name="value" type="Vector4" />
diff --git a/doc/classes/ParticleProcessMaterial.xml b/doc/classes/ParticleProcessMaterial.xml
index 28c60194c8..742e0cc44c 100644
--- a/doc/classes/ParticleProcessMaterial.xml
+++ b/doc/classes/ParticleProcessMaterial.xml
@@ -90,6 +90,7 @@
<members>
<member name="alpha_curve" type="Texture2D" setter="set_alpha_curve" getter="get_alpha_curve">
The alpha value of each particle's color will be multiplied by this [CurveTexture] over its lifetime.
+ [b]Note:[/b] [member alpha_curve] multiplies the particle mesh's vertex colors. To have a visible effect on a [BaseMaterial3D], [member BaseMaterial3D.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member alpha_curve] will have no visible effect.
</member>
<member name="angle_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's rotation will be animated along this [CurveTexture].
@@ -193,7 +194,7 @@
</member>
<member name="emission_curve" type="Texture2D" setter="set_emission_curve" getter="get_emission_curve">
Each particle's color will be multiplied by this [CurveTexture] over its lifetime.
- [b]Note:[/b] This property won't have a visible effect unless the render material is marked as unshaded.
+ [b]Note:[/b] [member emission_curve] multiplies the particle mesh's vertex colors. To have a visible effect on a [BaseMaterial3D], [member BaseMaterial3D.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member emission_curve] will have no visible effect.
</member>
<member name="emission_normal_texture" type="Texture2D" setter="set_emission_normal_texture" getter="get_emission_normal_texture">
Particle velocity and rotation will be set by sampling this texture at the same point as the [member emission_point_texture]. Used only in [constant EMISSION_SHAPE_DIRECTED_POINTS]. Can be created automatically from mesh or node by selecting "Create Emission Points from Mesh/Node" under the "Particles" tool in the toolbar.
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 7b6d8d0cd3..af5ec41b60 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -2863,11 +2863,6 @@
</member>
<member name="rendering/shading/overrides/force_vertex_shading" type="bool" setter="" getter="" default="false">
If [code]true[/code], forces vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can be used to optimize performance on low-end mobile devices.
- [b]Note:[/b] This setting currently has no effect, as vertex shading is not implemented yet.
- </member>
- <member name="rendering/shading/overrides/force_vertex_shading.mobile" type="bool" setter="" getter="" default="true">
- Lower-end override for [member rendering/shading/overrides/force_vertex_shading] on mobile devices, due to performance concerns or driver support.
- [b]Note:[/b] This setting currently has no effect, as vertex shading is not implemented yet.
</member>
<member name="rendering/textures/canvas_textures/default_texture_filter" type="int" setter="" getter="" default="1">
The default texture filtering mode to use on [CanvasItem]s.
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 65749323fd..c2d1784958 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -4125,6 +4125,9 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n";
global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "u\n";
global_defines += "\n#define MAX_ROUGHNESS_LOD " + itos(sky_globals.roughness_layers - 1) + ".0\n";
+ if (config->force_vertex_shading) {
+ global_defines += "\n#define USE_VERTEX_LIGHTING\n";
+ }
material_storage->shaders.scene_shader.initialize(global_defines);
scene_globals.shader_default_version = material_storage->shaders.scene_shader.version_create();
material_storage->shaders.scene_shader.version_bind_shader(scene_globals.shader_default_version, SceneShaderGLES3::MODE_COLOR);
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 393ba014c6..9ce10a4488 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -248,6 +248,175 @@ uniform lowp uint directional_shadow_index;
#endif // !(defined(ADDITIVE_OMNI) || defined(ADDITIVE_SPOT))
#endif // USE_ADDITIVE_LIGHTING
+#ifdef USE_VERTEX_LIGHTING
+
+out vec3 diffuse_light_interp;
+out vec3 specular_light_interp;
+
+#ifdef USE_ADDITIVE_LIGHTING
+out vec3 additive_diffuse_light_interp;
+out vec3 additive_specular_light_interp;
+#endif // USE_ADDITIVE_LIGHTING
+
+// Directional light data.
+#if !defined(DISABLE_LIGHT_DIRECTIONAL) || (!defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING))
+
+struct DirectionalLightData {
+ mediump vec3 direction;
+ mediump float energy;
+ mediump vec3 color;
+ mediump float size;
+ lowp uint unused;
+ lowp uint bake_mode;
+ mediump float shadow_opacity;
+ mediump float specular;
+};
+
+layout(std140) uniform DirectionalLights { // ubo:7
+ DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
+};
+#endif // !DISABLE_LIGHT_DIRECTIONAL
+
+// Omni and spot light data.
+#if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) || (defined(ADDITIVE_OMNI) || defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING))
+
+struct LightData { // This structure needs to be as packed as possible.
+ highp vec3 position;
+ highp float inv_radius;
+
+ mediump vec3 direction;
+ highp float size;
+
+ mediump vec3 color;
+ mediump float attenuation;
+
+ mediump float cone_attenuation;
+ mediump float cone_angle;
+ mediump float specular_amount;
+ mediump float shadow_opacity;
+
+ lowp vec3 pad;
+ lowp uint bake_mode;
+};
+
+#if !defined(DISABLE_LIGHT_OMNI) || defined(ADDITIVE_OMNI)
+layout(std140) uniform OmniLightData { // ubo:5
+ LightData omni_lights[MAX_LIGHT_DATA_STRUCTS];
+};
+#ifdef BASE_PASS
+uniform uint omni_light_indices[MAX_FORWARD_LIGHTS];
+uniform uint omni_light_count;
+#endif // BASE_PASS
+#endif // DISABLE_LIGHT_OMNI
+
+#if !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_SPOT)
+layout(std140) uniform SpotLightData { // ubo:6
+ LightData spot_lights[MAX_LIGHT_DATA_STRUCTS];
+};
+#ifdef BASE_PASS
+uniform uint spot_light_indices[MAX_FORWARD_LIGHTS];
+uniform uint spot_light_count;
+#endif // BASE_PASS
+#endif // DISABLE_LIGHT_SPOT
+#endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) || (defined(ADDITIVE_OMNI) || defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING))
+
+#ifdef USE_ADDITIVE_LIGHTING
+#ifdef ADDITIVE_OMNI
+uniform lowp uint omni_light_index;
+#endif
+#ifdef ADDITIVE_SPOT
+uniform lowp uint spot_light_index;
+#endif
+#endif // USE_ADDITIVE_LIGHTING
+
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+
+// Eyeballed approximation of `exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25`.
+// Uses slightly more FMA instructions (2x rate) to avoid special instructions (0.25x rate).
+// Range is reduced to [0.64,4977] from [068,2,221,528] which makes mediump feasible for the rest of the shader.
+mediump float roughness_to_shininess(mediump float roughness) {
+ mediump float r = 1.2 - roughness;
+ mediump float r2 = r * r;
+ return r * r2 * r2 * 2000.0;
+}
+
+void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, bool is_directional, float roughness,
+ inout vec3 diffuse_light, inout vec3 specular_light) {
+ float NdotL = min(dot(N, L), 1.0);
+ float cNdotL = max(NdotL, 0.0); // clamped NdotL
+
+#if defined(DIFFUSE_LAMBERT_WRAP)
+ // Energy conserving lambert wrap shader.
+ // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
+ float diffuse_brdf_NL = max(0.0, (cNdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI);
+#else
+ // lambert
+ float diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
+#endif
+
+ diffuse_light += light_color * diffuse_brdf_NL;
+
+#if !defined(SPECULAR_DISABLED)
+ float specular_brdf_NL = 0.0;
+ // Normalized blinn always unless disabled.
+ vec3 H = normalize(V + L);
+ float cNdotH = clamp(dot(N, H), 0.0, 1.0);
+ float shininess = roughness_to_shininess(roughness);
+ float blinn = pow(cNdotH, shininess);
+ blinn *= (shininess + 2.0) * (1.0 / (8.0 * M_PI)) * cNdotL;
+ specular_brdf_NL = blinn;
+ specular_light += specular_brdf_NL * light_color;
+#endif
+}
+
+float get_omni_spot_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
+#if !defined(DISABLE_LIGHT_OMNI) || (defined(ADDITIVE_OMNI) && defined(USE_ADDITIVE_LIGHTING))
+void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness,
+ inout vec3 diffuse_light, inout vec3 specular_light) {
+ vec3 light_rel_vec = omni_lights[idx].position - vertex;
+ float light_length = length(light_rel_vec);
+ float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation);
+ vec3 color = omni_lights[idx].color * omni_attenuation; // No light shaders here, so combine.
+
+ light_compute(normal, normalize(light_rel_vec), eye_vec, color, false, roughness,
+ diffuse_light,
+ specular_light);
+}
+#endif // !defined(DISABLE_LIGHT_OMNI) || (defined(ADDITIVE_OMNI) && defined(USE_ADDITIVE_LIGHTING))
+
+#if !defined(DISABLE_LIGHT_SPOT) || (defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING))
+void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness,
+ inout vec3 diffuse_light,
+ inout vec3 specular_light) {
+ vec3 light_rel_vec = spot_lights[idx].position - vertex;
+ float light_length = length(light_rel_vec);
+ float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation);
+ vec3 spot_dir = spot_lights[idx].direction;
+ float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle));
+
+ mediump float cone_attenuation = spot_lights[idx].cone_attenuation;
+ spot_attenuation *= 1.0 - pow(spot_rim, cone_attenuation);
+
+ vec3 color = spot_lights[idx].color * spot_attenuation;
+
+ light_compute(normal, normalize(light_rel_vec), eye_vec, color, false, roughness,
+ diffuse_light, specular_light);
+}
+#endif // !defined(DISABLE_LIGHT_SPOT) || (defined(ADDITIVE_SPOT) && defined(USE_ADDITIVE_LIGHTING))
+
+#endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+
+#endif // USE_VERTEX_LIGHTING
+
#ifdef USE_MULTIVIEW
layout(std140) uniform MultiviewData { // ubo:8
highp mat4 projection_matrix_view[MAX_VIEWS];
@@ -540,8 +709,65 @@ void main() {
gl_Position.z = 0.00001;
gl_Position.w = 1.0;
#endif
-}
+#ifdef USE_VERTEX_LIGHTING
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
+#ifdef USE_MULTIVIEW
+ vec3 view = -normalize(vertex_interp - eye_offset);
+#else
+ vec3 view = -normalize(vertex_interp);
+#endif
+ diffuse_light_interp = vec3(0.0);
+ specular_light_interp = vec3(0.0);
+#ifdef BASE_PASS
+#ifndef DISABLE_LIGHT_DIRECTIONAL
+ for (uint i = uint(0); i < scene_data.directional_light_count; i++) {
+ light_compute(normal_interp, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].color * directional_lights[i].energy, true, roughness,
+ diffuse_light_interp.rgb,
+ specular_light_interp.rgb);
+ }
+#endif // !DISABLE_LIGHT_DIRECTIONAL
+
+#ifndef DISABLE_LIGHT_OMNI
+ for (uint i = 0u; i < omni_light_count; i++) {
+ light_process_omni(omni_light_indices[i], vertex_interp, view, normal_interp, roughness,
+ diffuse_light_interp.rgb, specular_light_interp.rgb);
+ }
+#endif // !DISABLE_LIGHT_OMNI
+
+#ifndef DISABLE_LIGHT_SPOT
+ for (uint i = 0u; i < spot_light_count; i++) {
+ light_process_spot(spot_light_indices[i], vertex_interp, view, normal_interp, roughness,
+ diffuse_light_interp.rgb, specular_light_interp.rgb);
+ }
+#endif // !DISABLE_LIGHT_SPOT
+#endif // BASE_PASS
+
+/* ADDITIVE LIGHTING PASS */
+#ifdef USE_ADDITIVE_LIGHTING
+ additive_diffuse_light_interp = vec3(0.0);
+ additive_specular_light_interp = vec3(0.0);
+#if !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT)
+
+ light_compute(normal_interp, normalize(directional_lights[directional_shadow_index].direction), normalize(view), directional_lights[directional_shadow_index].color * directional_lights[directional_shadow_index].energy, true, roughness,
+ additive_diffuse_light_interp.rgb,
+ additive_specular_light_interp.rgb);
+#endif // !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT)
+
+#ifdef ADDITIVE_OMNI
+ light_process_omni(omni_light_index, vertex_interp, view, normal_interp, roughness,
+ additive_diffuse_light_interp.rgb, additive_specular_light_interp.rgb);
+#endif // ADDITIVE_OMNI
+
+#ifdef ADDITIVE_SPOT
+ light_process_spot(spot_light_index, vertex_interp, view, normal_interp, roughness,
+ additive_diffuse_light_interp.rgb, additive_specular_light_interp.rgb);
+#endif // ADDITIVE_SPOT
+
+#endif // USE_ADDITIVE_LIGHTING
+#endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
+#endif // USE_VERTEX_LIGHTING
+}
/* clang-format off */
#[fragment]
@@ -758,6 +984,16 @@ multiview_data;
#define LIGHT_BAKE_DYNAMIC 2u
#ifndef MODE_RENDER_DEPTH
+#ifdef USE_VERTEX_LIGHTING
+in vec3 diffuse_light_interp;
+in vec3 specular_light_interp;
+
+#ifdef USE_ADDITIVE_LIGHTING
+in vec3 additive_diffuse_light_interp;
+in vec3 additive_specular_light_interp;
+#endif // USE_ADDITIVE_LIGHTING
+#endif // USE_VERTEX_LIGHTING
+
// Directional light data.
#if !defined(DISABLE_LIGHT_DIRECTIONAL) || (!defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT))
@@ -809,22 +1045,22 @@ struct LightData { // This structure needs to be as packed as possible.
layout(std140) uniform OmniLightData { // ubo:5
LightData omni_lights[MAX_LIGHT_DATA_STRUCTS];
};
-#ifdef BASE_PASS
+#if defined(BASE_PASS) && !defined(USE_VERTEX_LIGHTING)
uniform uint omni_light_indices[MAX_FORWARD_LIGHTS];
uniform uint omni_light_count;
-#endif // BASE_PASS
-#endif // DISABLE_LIGHT_OMNI
+#endif // defined(BASE_PASS) && !defined(USE_VERTEX_LIGHTING)
+#endif // !defined(DISABLE_LIGHT_OMNI) || defined(ADDITIVE_OMNI)
#if !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_SPOT)
layout(std140) uniform SpotLightData { // ubo:6
LightData spot_lights[MAX_LIGHT_DATA_STRUCTS];
};
-#ifdef BASE_PASS
+#if defined(BASE_PASS) && !defined(USE_VERTEX_LIGHTING)
uniform uint spot_light_indices[MAX_FORWARD_LIGHTS];
uniform uint spot_light_count;
-#endif // BASE_PASS
-#endif // DISABLE_LIGHT_SPOT
-#endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT)
+#endif // defined(BASE_PASS) && !defined(USE_VERTEX_LIGHTING)
+#endif // !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_SPOT)
+#endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_OMNI) || defined(ADDITIVE_SPOT)
#ifdef USE_ADDITIVE_LIGHTING
#ifdef ADDITIVE_OMNI
@@ -985,6 +1221,8 @@ vec3 F0(float metallic, float specular, vec3 albedo) {
return mix(vec3(dielectric), albedo, vec3(metallic));
}
#ifndef MODE_RENDER_DEPTH
+
+#ifndef USE_VERTEX_LIGHTING
#if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) || defined(USE_ADDITIVE_LIGHTING)
float D_GGX(float cos_theta_m, float alpha) {
@@ -1284,6 +1522,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f
#endif // !defined(DISABLE_LIGHT_SPOT) || defined(ADDITIVE_SPOT)
#endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT)
+#endif // !USE_VERTEX_LIGHTING
vec4 fog_process(vec3 vertex) {
vec3 fog_color = scene_data.fog_light_color;
@@ -1859,9 +2098,13 @@ void main() {
specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0);
#endif
}
-
#endif // !AMBIENT_LIGHT_DISABLED
+#ifdef USE_VERTEX_LIGHTING
+ specular_light += specular_light_interp * f0;
+ diffuse_light += diffuse_light_interp;
+#else
+
#ifndef DISABLE_LIGHT_DIRECTIONAL
for (uint i = uint(0); i < scene_data.directional_light_count; i++) {
#if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP)
@@ -1944,6 +2187,7 @@ void main() {
diffuse_light, specular_light);
}
#endif // !DISABLE_LIGHT_SPOT
+#endif // !USE_VERTEX_LIGHTING
#endif // BASE_PASS
#endif // !MODE_UNSHADED
@@ -1993,7 +2237,6 @@ void main() {
#else
diffuse_light *= albedo;
-
diffuse_light *= 1.0 - metallic;
ambient_light *= 1.0 - metallic;
@@ -2024,6 +2267,11 @@ void main() {
diffuse_light = vec3(0.0);
specular_light = vec3(0.0);
+#ifdef USE_VERTEX_LIGHTING
+ diffuse_light = additive_diffuse_light_interp;
+ specular_light = additive_specular_light_interp * f0;
+#endif // USE_VERTEX_LIGHTING
+
#if !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT)
#ifndef SHADOWS_DISABLED
@@ -2137,6 +2385,8 @@ void main() {
#else
float directional_shadow = 1.0f;
#endif // SHADOWS_DISABLED
+
+#ifndef USE_VERTEX_LIGHTING
light_compute(normal, normalize(directional_lights[directional_shadow_index].direction), normalize(view), directional_lights[directional_shadow_index].size, directional_lights[directional_shadow_index].color * directional_lights[directional_shadow_index].energy, true, directional_shadow, f0, roughness, metallic, 1.0, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@@ -2153,6 +2403,11 @@ void main() {
#endif
diffuse_light,
specular_light);
+#else
+ // Just apply shadows to vertex lighting.
+ diffuse_light *= directional_shadow;
+ specular_light *= directional_shadow;
+#endif // !USE_VERTEX_LIGHTING
#endif // !defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT)
#ifdef ADDITIVE_OMNI
@@ -2162,6 +2417,8 @@ void main() {
omni_shadow = texture(omni_shadow_texture, vec4(light_ray, 1.0 - length(light_ray) * omni_lights[omni_light_index].inv_radius));
omni_shadow = mix(1.0, omni_shadow, omni_lights[omni_light_index].shadow_opacity);
#endif // SHADOWS_DISABLED
+
+#ifndef USE_VERTEX_LIGHTING
light_process_omni(omni_light_index, vertex, view, normal, f0, roughness, metallic, omni_shadow, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@@ -2177,6 +2434,11 @@ void main() {
binormal, tangent, anisotropy,
#endif
diffuse_light, specular_light);
+#else
+ // Just apply shadows to vertex lighting.
+ diffuse_light *= omni_shadow;
+ specular_light *= omni_shadow;
+#endif // !USE_VERTEX_LIGHTING
#endif // ADDITIVE_OMNI
#ifdef ADDITIVE_SPOT
@@ -2185,6 +2447,8 @@ void main() {
spot_shadow = sample_shadow(spot_shadow_texture, positional_shadows[positional_shadow_index].shadow_atlas_pixel_size, shadow_coord);
spot_shadow = mix(1.0, spot_shadow, spot_lights[spot_light_index].shadow_opacity);
#endif // SHADOWS_DISABLED
+
+#ifndef USE_VERTEX_LIGHTING
light_process_spot(spot_light_index, vertex, view, normal, f0, roughness, metallic, spot_shadow, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@@ -2201,6 +2465,11 @@ void main() {
binormal, anisotropy,
#endif
diffuse_light, specular_light);
+#else
+ // Just apply shadows to vertex lighting.
+ diffuse_light *= spot_shadow;
+ specular_light *= spot_shadow;
+#endif // !USE_VERTEX_LIGHTING
#endif // ADDITIVE_SPOT
diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp
index 0100719151..209b7dd7d2 100644
--- a/drivers/gles3/storage/config.cpp
+++ b/drivers/gles3/storage/config.cpp
@@ -178,7 +178,7 @@ Config::Config() {
}
#endif
- force_vertex_shading = false; //GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
+ force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading");
use_nearest_mip_filter = GLOBAL_GET("rendering/textures/default_filters/use_nearest_mipmap_filter");
use_depth_prepass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable"));
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index c29c741c2a..5dca149d99 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -1368,6 +1368,10 @@ MaterialStorage::MaterialStorage() {
actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
+ if (!GLES3::Config::get_singleton()->force_vertex_shading) {
+ // If forcing vertex shading, this will be defined already.
+ actions.render_mode_defines["vertex_lighting"] = "#define USE_VERTEX_LIGHTING\n";
+ }
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index 255eaff10d..7aa0137f4e 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -114,9 +114,9 @@ class EditorFileSystemImportFormatSupportQuery : public RefCounted {
GDCLASS(EditorFileSystemImportFormatSupportQuery, RefCounted);
protected:
- GDVIRTUAL0RC(bool, _is_active)
- GDVIRTUAL0RC(Vector<String>, _get_file_extensions)
- GDVIRTUAL0RC(bool, _query)
+ GDVIRTUAL0RC_REQUIRED(bool, _is_active)
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_file_extensions)
+ GDVIRTUAL0RC_REQUIRED(bool, _query)
static void _bind_methods() {
GDVIRTUAL_BIND(_is_active);
GDVIRTUAL_BIND(_get_file_extensions);
@@ -126,17 +126,17 @@ protected:
public:
virtual bool is_active() const {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_is_active, ret);
+ GDVIRTUAL_CALL(_is_active, ret);
return ret;
}
virtual Vector<String> get_file_extensions() const {
Vector<String> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_file_extensions, ret);
+ GDVIRTUAL_CALL(_get_file_extensions, ret);
return ret;
}
virtual bool query() {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_query, ret);
+ GDVIRTUAL_CALL(_query, ret);
return ret;
}
};
diff --git a/editor/editor_script.cpp b/editor/editor_script.cpp
index 30a4b6811c..6968c7f25a 100644
--- a/editor/editor_script.cpp
+++ b/editor/editor_script.cpp
@@ -78,7 +78,7 @@ EditorInterface *EditorScript::get_editor_interface() const {
}
void EditorScript::run() {
- GDVIRTUAL_REQUIRED_CALL(_run);
+ GDVIRTUAL_CALL(_run);
}
void EditorScript::_bind_methods() {
diff --git a/editor/editor_script.h b/editor/editor_script.h
index 72e7641df7..b0724c31c0 100644
--- a/editor/editor_script.h
+++ b/editor/editor_script.h
@@ -44,7 +44,7 @@ class EditorScript : public RefCounted {
protected:
static void _bind_methods();
- GDVIRTUAL0(_run)
+ GDVIRTUAL0_REQUIRED(_run)
public:
void add_root_node(Node *p_node);
diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp
index f4745b8730..6a5d49e41a 100644
--- a/editor/editor_vcs_interface.cpp
+++ b/editor/editor_vcs_interface.cpp
@@ -41,17 +41,17 @@ void EditorVCSInterface::popup_error(const String &p_msg) {
bool EditorVCSInterface::initialize(const String &p_project_path) {
bool result = false;
- GDVIRTUAL_REQUIRED_CALL(_initialize, p_project_path, result);
+ GDVIRTUAL_CALL(_initialize, p_project_path, result);
return result;
}
void EditorVCSInterface::set_credentials(const String &p_username, const String &p_password, const String &p_ssh_public_key, const String &p_ssh_private_key, const String &p_ssh_passphrase) {
- GDVIRTUAL_REQUIRED_CALL(_set_credentials, p_username, p_password, p_ssh_public_key, p_ssh_private_key, p_ssh_passphrase);
+ GDVIRTUAL_CALL(_set_credentials, p_username, p_password, p_ssh_public_key, p_ssh_private_key, p_ssh_passphrase);
}
List<String> EditorVCSInterface::get_remotes() {
TypedArray<String> result;
- if (!GDVIRTUAL_REQUIRED_CALL(_get_remotes, result)) {
+ if (!GDVIRTUAL_CALL(_get_remotes, result)) {
return {};
}
@@ -64,7 +64,7 @@ List<String> EditorVCSInterface::get_remotes() {
List<EditorVCSInterface::StatusFile> EditorVCSInterface::get_modified_files_data() {
TypedArray<Dictionary> result;
- if (!GDVIRTUAL_REQUIRED_CALL(_get_modified_files_data, result)) {
+ if (!GDVIRTUAL_CALL(_get_modified_files_data, result)) {
return {};
}
@@ -76,24 +76,24 @@ List<EditorVCSInterface::StatusFile> EditorVCSInterface::get_modified_files_data
}
void EditorVCSInterface::stage_file(const String &p_file_path) {
- GDVIRTUAL_REQUIRED_CALL(_stage_file, p_file_path);
+ GDVIRTUAL_CALL(_stage_file, p_file_path);
}
void EditorVCSInterface::unstage_file(const String &p_file_path) {
- GDVIRTUAL_REQUIRED_CALL(_unstage_file, p_file_path);
+ GDVIRTUAL_CALL(_unstage_file, p_file_path);
}
void EditorVCSInterface::discard_file(const String &p_file_path) {
- GDVIRTUAL_REQUIRED_CALL(_discard_file, p_file_path);
+ GDVIRTUAL_CALL(_discard_file, p_file_path);
}
void EditorVCSInterface::commit(const String &p_msg) {
- GDVIRTUAL_REQUIRED_CALL(_commit, p_msg);
+ GDVIRTUAL_CALL(_commit, p_msg);
}
List<EditorVCSInterface::DiffFile> EditorVCSInterface::get_diff(const String &p_identifier, TreeArea p_area) {
TypedArray<Dictionary> result;
- if (!GDVIRTUAL_REQUIRED_CALL(_get_diff, p_identifier, int(p_area), result)) {
+ if (!GDVIRTUAL_CALL(_get_diff, p_identifier, int(p_area), result)) {
return {};
}
@@ -106,7 +106,7 @@ List<EditorVCSInterface::DiffFile> EditorVCSInterface::get_diff(const String &p_
List<EditorVCSInterface::Commit> EditorVCSInterface::get_previous_commits(int p_max_commits) {
TypedArray<Dictionary> result;
- if (!GDVIRTUAL_REQUIRED_CALL(_get_previous_commits, p_max_commits, result)) {
+ if (!GDVIRTUAL_CALL(_get_previous_commits, p_max_commits, result)) {
return {};
}
@@ -119,7 +119,7 @@ List<EditorVCSInterface::Commit> EditorVCSInterface::get_previous_commits(int p_
List<String> EditorVCSInterface::get_branch_list() {
TypedArray<String> result;
- if (!GDVIRTUAL_REQUIRED_CALL(_get_branch_list, result)) {
+ if (!GDVIRTUAL_CALL(_get_branch_list, result)) {
return {};
}
@@ -131,48 +131,48 @@ List<String> EditorVCSInterface::get_branch_list() {
}
void EditorVCSInterface::create_branch(const String &p_branch_name) {
- GDVIRTUAL_REQUIRED_CALL(_create_branch, p_branch_name);
+ GDVIRTUAL_CALL(_create_branch, p_branch_name);
}
void EditorVCSInterface::create_remote(const String &p_remote_name, const String &p_remote_url) {
- GDVIRTUAL_REQUIRED_CALL(_create_remote, p_remote_name, p_remote_url);
+ GDVIRTUAL_CALL(_create_remote, p_remote_name, p_remote_url);
}
void EditorVCSInterface::remove_branch(const String &p_branch_name) {
- GDVIRTUAL_REQUIRED_CALL(_remove_branch, p_branch_name);
+ GDVIRTUAL_CALL(_remove_branch, p_branch_name);
}
void EditorVCSInterface::remove_remote(const String &p_remote_name) {
- GDVIRTUAL_REQUIRED_CALL(_remove_remote, p_remote_name);
+ GDVIRTUAL_CALL(_remove_remote, p_remote_name);
}
String EditorVCSInterface::get_current_branch_name() {
String result;
- GDVIRTUAL_REQUIRED_CALL(_get_current_branch_name, result);
+ GDVIRTUAL_CALL(_get_current_branch_name, result);
return result;
}
bool EditorVCSInterface::checkout_branch(const String &p_branch_name) {
bool result = false;
- GDVIRTUAL_REQUIRED_CALL(_checkout_branch, p_branch_name, result);
+ GDVIRTUAL_CALL(_checkout_branch, p_branch_name, result);
return result;
}
void EditorVCSInterface::pull(const String &p_remote) {
- GDVIRTUAL_REQUIRED_CALL(_pull, p_remote);
+ GDVIRTUAL_CALL(_pull, p_remote);
}
void EditorVCSInterface::push(const String &p_remote, bool p_force) {
- GDVIRTUAL_REQUIRED_CALL(_push, p_remote, p_force);
+ GDVIRTUAL_CALL(_push, p_remote, p_force);
}
void EditorVCSInterface::fetch(const String &p_remote) {
- GDVIRTUAL_REQUIRED_CALL(_fetch, p_remote);
+ GDVIRTUAL_CALL(_fetch, p_remote);
}
List<EditorVCSInterface::DiffHunk> EditorVCSInterface::get_line_diff(const String &p_file_path, const String &p_text) {
TypedArray<Dictionary> result;
- if (!GDVIRTUAL_REQUIRED_CALL(_get_line_diff, p_file_path, p_text, result)) {
+ if (!GDVIRTUAL_CALL(_get_line_diff, p_file_path, p_text, result)) {
return {};
}
@@ -185,13 +185,13 @@ List<EditorVCSInterface::DiffHunk> EditorVCSInterface::get_line_diff(const Strin
bool EditorVCSInterface::shut_down() {
bool result = false;
- GDVIRTUAL_REQUIRED_CALL(_shut_down, result);
+ GDVIRTUAL_CALL(_shut_down, result);
return result;
}
String EditorVCSInterface::get_vcs_name() {
String result;
- GDVIRTUAL_REQUIRED_CALL(_get_vcs_name, result);
+ GDVIRTUAL_CALL(_get_vcs_name, result);
return result;
}
diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h
index 8fcd45756a..a425682bed 100644
--- a/editor/editor_vcs_interface.h
+++ b/editor/editor_vcs_interface.h
@@ -106,29 +106,29 @@ protected:
StatusFile _convert_status_file(const Dictionary &p_status_file);
// Proxy endpoints for extensions to implement
- GDVIRTUAL1R(bool, _initialize, String);
- GDVIRTUAL5(_set_credentials, String, String, String, String, String);
- GDVIRTUAL0R(TypedArray<Dictionary>, _get_modified_files_data);
- GDVIRTUAL1(_stage_file, String);
- GDVIRTUAL1(_unstage_file, String);
- GDVIRTUAL1(_discard_file, String);
- GDVIRTUAL1(_commit, String);
- GDVIRTUAL2R(TypedArray<Dictionary>, _get_diff, String, int);
- GDVIRTUAL0R(bool, _shut_down);
- GDVIRTUAL0R(String, _get_vcs_name);
- GDVIRTUAL1R(TypedArray<Dictionary>, _get_previous_commits, int);
- GDVIRTUAL0R(TypedArray<String>, _get_branch_list);
- GDVIRTUAL0R(TypedArray<String>, _get_remotes);
- GDVIRTUAL1(_create_branch, String);
- GDVIRTUAL1(_remove_branch, String);
- GDVIRTUAL2(_create_remote, String, String);
- GDVIRTUAL1(_remove_remote, String);
- GDVIRTUAL0R(String, _get_current_branch_name);
- GDVIRTUAL1R(bool, _checkout_branch, String);
- GDVIRTUAL1(_pull, String);
- GDVIRTUAL2(_push, String, bool);
- GDVIRTUAL1(_fetch, String);
- GDVIRTUAL2R(TypedArray<Dictionary>, _get_line_diff, String, String);
+ GDVIRTUAL1R_REQUIRED(bool, _initialize, String);
+ GDVIRTUAL5_REQUIRED(_set_credentials, String, String, String, String, String);
+ GDVIRTUAL0R_REQUIRED(TypedArray<Dictionary>, _get_modified_files_data);
+ GDVIRTUAL1_REQUIRED(_stage_file, String);
+ GDVIRTUAL1_REQUIRED(_unstage_file, String);
+ GDVIRTUAL1_REQUIRED(_discard_file, String);
+ GDVIRTUAL1_REQUIRED(_commit, String);
+ GDVIRTUAL2R_REQUIRED(TypedArray<Dictionary>, _get_diff, String, int);
+ GDVIRTUAL0R_REQUIRED(bool, _shut_down);
+ GDVIRTUAL0R_REQUIRED(String, _get_vcs_name);
+ GDVIRTUAL1R_REQUIRED(TypedArray<Dictionary>, _get_previous_commits, int);
+ GDVIRTUAL0R_REQUIRED(TypedArray<String>, _get_branch_list);
+ GDVIRTUAL0R_REQUIRED(TypedArray<String>, _get_remotes);
+ GDVIRTUAL1_REQUIRED(_create_branch, String);
+ GDVIRTUAL1_REQUIRED(_remove_branch, String);
+ GDVIRTUAL2_REQUIRED(_create_remote, String, String);
+ GDVIRTUAL1_REQUIRED(_remove_remote, String);
+ GDVIRTUAL0R_REQUIRED(String, _get_current_branch_name);
+ GDVIRTUAL1R_REQUIRED(bool, _checkout_branch, String);
+ GDVIRTUAL1_REQUIRED(_pull, String);
+ GDVIRTUAL2_REQUIRED(_push, String, bool);
+ GDVIRTUAL1_REQUIRED(_fetch, String);
+ GDVIRTUAL2R_REQUIRED(TypedArray<Dictionary>, _get_line_diff, String, String);
public:
static EditorVCSInterface *get_singleton();
diff --git a/editor/export/editor_export_platform_extension.cpp b/editor/export/editor_export_platform_extension.cpp
index 5b75ff19a4..b4f338437f 100644
--- a/editor/export/editor_export_platform_extension.cpp
+++ b/editor/export/editor_export_platform_extension.cpp
@@ -81,7 +81,7 @@ void EditorExportPlatformExtension::_bind_methods() {
void EditorExportPlatformExtension::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
Vector<String> ret;
- if (GDVIRTUAL_REQUIRED_CALL(_get_preset_features, p_preset, ret) && r_features) {
+ if (GDVIRTUAL_CALL(_get_preset_features, p_preset, ret) && r_features) {
for (const String &E : ret) {
r_features->push_back(E);
}
@@ -144,19 +144,19 @@ String EditorExportPlatformExtension::get_export_option_warning(const EditorExpo
String EditorExportPlatformExtension::get_os_name() const {
String ret;
- GDVIRTUAL_REQUIRED_CALL(_get_os_name, ret);
+ GDVIRTUAL_CALL(_get_os_name, ret);
return ret;
}
String EditorExportPlatformExtension::get_name() const {
String ret;
- GDVIRTUAL_REQUIRED_CALL(_get_name, ret);
+ GDVIRTUAL_CALL(_get_name, ret);
return ret;
}
Ref<Texture2D> EditorExportPlatformExtension::get_logo() const {
Ref<Texture2D> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_logo, ret);
+ GDVIRTUAL_CALL(_get_logo, ret);
return ret;
}
@@ -238,7 +238,7 @@ bool EditorExportPlatformExtension::has_valid_export_configuration(const Ref<Edi
bool ret = false;
config_error = r_error;
config_missing_templates = r_missing_templates;
- if (GDVIRTUAL_REQUIRED_CALL(_has_valid_export_configuration, p_preset, p_debug, ret)) {
+ if (GDVIRTUAL_CALL(_has_valid_export_configuration, p_preset, p_debug, ret)) {
r_error = config_error;
r_missing_templates = config_missing_templates;
}
@@ -248,7 +248,7 @@ bool EditorExportPlatformExtension::has_valid_export_configuration(const Ref<Edi
bool EditorExportPlatformExtension::has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const {
bool ret = false;
config_error = r_error;
- if (GDVIRTUAL_REQUIRED_CALL(_has_valid_project_configuration, p_preset, ret)) {
+ if (GDVIRTUAL_CALL(_has_valid_project_configuration, p_preset, ret)) {
r_error = config_error;
}
return ret;
@@ -257,7 +257,7 @@ bool EditorExportPlatformExtension::has_valid_project_configuration(const Ref<Ed
List<String> EditorExportPlatformExtension::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const {
List<String> ret_list;
Vector<String> ret;
- if (GDVIRTUAL_REQUIRED_CALL(_get_binary_extensions, p_preset, ret)) {
+ if (GDVIRTUAL_CALL(_get_binary_extensions, p_preset, ret)) {
for (const String &E : ret) {
ret_list.push_back(E);
}
@@ -269,7 +269,7 @@ Error EditorExportPlatformExtension::export_project(const Ref<EditorExportPreset
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
Error ret = FAILED;
- GDVIRTUAL_REQUIRED_CALL(_export_project, p_preset, p_debug, p_path, p_flags, ret);
+ GDVIRTUAL_CALL(_export_project, p_preset, p_debug, p_path, p_flags, ret);
return ret;
}
@@ -333,7 +333,7 @@ Error EditorExportPlatformExtension::export_zip_patch(const Ref<EditorExportPres
void EditorExportPlatformExtension::get_platform_features(List<String> *r_features) const {
Vector<String> ret;
- if (GDVIRTUAL_REQUIRED_CALL(_get_platform_features, ret) && r_features) {
+ if (GDVIRTUAL_CALL(_get_platform_features, ret) && r_features) {
for (const String &E : ret) {
r_features->push_back(E);
}
diff --git a/editor/export/editor_export_platform_extension.h b/editor/export/editor_export_platform_extension.h
index d1db922698..390aaf4590 100644
--- a/editor/export/editor_export_platform_extension.h
+++ b/editor/export/editor_export_platform_extension.h
@@ -45,7 +45,7 @@ protected:
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override;
- GDVIRTUAL1RC(Vector<String>, _get_preset_features, Ref<EditorExportPreset>);
+ GDVIRTUAL1RC_REQUIRED(Vector<String>, _get_preset_features, Ref<EditorExportPreset>);
virtual bool is_executable(const String &p_path) const override;
GDVIRTUAL1RC(bool, _is_executable, const String &);
@@ -63,13 +63,13 @@ public:
GDVIRTUAL2RC(String, _get_export_option_warning, Ref<EditorExportPreset>, const StringName &);
virtual String get_os_name() const override;
- GDVIRTUAL0RC(String, _get_os_name);
+ GDVIRTUAL0RC_REQUIRED(String, _get_os_name);
virtual String get_name() const override;
- GDVIRTUAL0RC(String, _get_name);
+ GDVIRTUAL0RC_REQUIRED(String, _get_name);
virtual Ref<Texture2D> get_logo() const override;
- GDVIRTUAL0RC(Ref<Texture2D>, _get_logo);
+ GDVIRTUAL0RC_REQUIRED(Ref<Texture2D>, _get_logo);
virtual bool poll_export() override;
GDVIRTUAL0R(bool, _poll_export);
@@ -119,16 +119,16 @@ public:
GDVIRTUAL2RC(bool, _can_export, Ref<EditorExportPreset>, bool);
virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
- GDVIRTUAL2RC(bool, _has_valid_export_configuration, Ref<EditorExportPreset>, bool);
+ GDVIRTUAL2RC_REQUIRED(bool, _has_valid_export_configuration, Ref<EditorExportPreset>, bool);
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override;
- GDVIRTUAL1RC(bool, _has_valid_project_configuration, Ref<EditorExportPreset>);
+ GDVIRTUAL1RC_REQUIRED(bool, _has_valid_project_configuration, Ref<EditorExportPreset>);
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override;
- GDVIRTUAL1RC(Vector<String>, _get_binary_extensions, Ref<EditorExportPreset>);
+ GDVIRTUAL1RC_REQUIRED(Vector<String>, _get_binary_extensions, Ref<EditorExportPreset>);
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
- GDVIRTUAL4R(Error, _export_project, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>);
+ GDVIRTUAL4R_REQUIRED(Error, _export_project, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>);
virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
GDVIRTUAL4R(Error, _export_pack, Ref<EditorExportPreset>, bool, const String &, BitField<EditorExportPlatform::DebugFlags>);
@@ -143,7 +143,7 @@ public:
GDVIRTUAL5R(Error, _export_zip_patch, Ref<EditorExportPreset>, bool, const String &, const Vector<String> &, BitField<EditorExportPlatform::DebugFlags>);
virtual void get_platform_features(List<String> *r_features) const override;
- GDVIRTUAL0RC(Vector<String>, _get_platform_features);
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_platform_features);
virtual String get_debug_protocol() const override;
GDVIRTUAL0RC(String, _get_debug_protocol);
diff --git a/editor/export/editor_export_plugin.cpp b/editor/export/editor_export_plugin.cpp
index 5945c02413..2f57010c2c 100644
--- a/editor/export/editor_export_plugin.cpp
+++ b/editor/export/editor_export_plugin.cpp
@@ -187,7 +187,7 @@ bool EditorExportPlugin::_begin_customize_resources(const Ref<EditorExportPlatfo
Ref<Resource> EditorExportPlugin::_customize_resource(const Ref<Resource> &p_resource, const String &p_path) {
Ref<Resource> ret;
- GDVIRTUAL_REQUIRED_CALL(_customize_resource, p_resource, p_path, ret);
+ GDVIRTUAL_CALL(_customize_resource, p_resource, p_path, ret);
return ret;
}
@@ -199,13 +199,13 @@ bool EditorExportPlugin::_begin_customize_scenes(const Ref<EditorExportPlatform>
Node *EditorExportPlugin::_customize_scene(Node *p_root, const String &p_path) {
Node *ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_customize_scene, p_root, p_path, ret);
+ GDVIRTUAL_CALL(_customize_scene, p_root, p_path, ret);
return ret;
}
uint64_t EditorExportPlugin::_get_customization_configuration_hash() const {
uint64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_customization_configuration_hash, ret);
+ GDVIRTUAL_CALL(_get_customization_configuration_hash, ret);
return ret;
}
@@ -219,7 +219,7 @@ void EditorExportPlugin::_end_customize_resources() {
String EditorExportPlugin::get_name() const {
String ret;
- GDVIRTUAL_REQUIRED_CALL(_get_name, ret);
+ GDVIRTUAL_CALL(_get_name, ret);
return ret;
}
diff --git a/editor/export/editor_export_plugin.h b/editor/export/editor_export_plugin.h
index 4c0107af72..8c744b3108 100644
--- a/editor/export/editor_export_plugin.h
+++ b/editor/export/editor_export_plugin.h
@@ -119,11 +119,11 @@ protected:
GDVIRTUAL0(_export_end)
GDVIRTUAL2RC(bool, _begin_customize_resources, const Ref<EditorExportPlatform> &, const Vector<String> &)
- GDVIRTUAL2R(Ref<Resource>, _customize_resource, const Ref<Resource> &, String)
+ GDVIRTUAL2R_REQUIRED(Ref<Resource>, _customize_resource, const Ref<Resource> &, String)
GDVIRTUAL2RC(bool, _begin_customize_scenes, const Ref<EditorExportPlatform> &, const Vector<String> &)
- GDVIRTUAL2R(Node *, _customize_scene, Node *, String)
- GDVIRTUAL0RC(uint64_t, _get_customization_configuration_hash)
+ GDVIRTUAL2R_REQUIRED(Node *, _customize_scene, Node *, String)
+ GDVIRTUAL0RC_REQUIRED(uint64_t, _get_customization_configuration_hash)
GDVIRTUAL0(_end_customize_scenes)
GDVIRTUAL0(_end_customize_resources)
@@ -134,7 +134,7 @@ protected:
GDVIRTUAL1RC(bool, _should_update_export_options, const Ref<EditorExportPlatform> &);
GDVIRTUAL2RC(String, _get_export_option_warning, const Ref<EditorExportPlatform> &, String);
- GDVIRTUAL0RC(String, _get_name)
+ GDVIRTUAL0RC_REQUIRED(String, _get_name)
GDVIRTUAL1RC(bool, _supports_platform, const Ref<EditorExportPlatform> &);
diff --git a/editor/plugins/tool_button_editor_plugin.cpp b/editor/plugins/tool_button_editor_plugin.cpp
new file mode 100644
index 0000000000..d9852c8694
--- /dev/null
+++ b/editor/plugins/tool_button_editor_plugin.cpp
@@ -0,0 +1,82 @@
+/**************************************************************************/
+/* tool_button_editor_plugin.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "tool_button_editor_plugin.h"
+
+#include "scene/gui/button.h"
+
+void EditorInspectorToolButtonPlugin::_update_action_icon(Button *p_action_button, const String &p_action_icon) {
+ p_action_button->set_icon(p_action_button->get_editor_theme_icon(p_action_icon));
+}
+
+void EditorInspectorToolButtonPlugin::_call_action(const Variant &p_object, const StringName &p_property) {
+ Object *object = p_object.get_validated_object();
+ ERR_FAIL_NULL_MSG(object, vformat(R"(Failed to get property "%s" on a previously freed instance.)", p_property));
+
+ const Variant value = object->get(p_property);
+ ERR_FAIL_COND_MSG(value.get_type() != Variant::CALLABLE, vformat(R"(The value of property "%s" is %s, but Callable was expected.)", p_property, Variant::get_type_name(value.get_type())));
+
+ const Callable callable = value;
+ ERR_FAIL_COND_MSG(!callable.is_valid(), vformat(R"(Tool button action "%s" is an invalid callable.)", callable));
+
+ Variant ret;
+ Callable::CallError ce;
+ callable.callp(nullptr, 0, ret, ce);
+ ERR_FAIL_COND_MSG(ce.error != Callable::CallError::CALL_OK, vformat(R"(Error calling tool button action "%s": %s)", callable, Variant::get_call_error_text(callable.get_method(), nullptr, 0, ce)));
+}
+
+bool EditorInspectorToolButtonPlugin::can_handle(Object *p_object) {
+ return true;
+}
+
+bool EditorInspectorToolButtonPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide) {
+ if (p_type != Variant::CALLABLE || p_hint != PROPERTY_HINT_TOOL_BUTTON || !p_usage.has_flag(PROPERTY_USAGE_EDITOR)) {
+ return false;
+ }
+
+ const PackedStringArray splits = p_hint_text.rsplit(",", true, 1);
+ const String &hint_text = splits[0]; // Safe since `splits` cannot be empty.
+ const String &hint_icon = splits.size() > 1 ? splits[1] : "Callable";
+
+ Button *action_button = EditorInspector::create_inspector_action_button(hint_text);
+ action_button->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED);
+ action_button->set_disabled(p_usage & PROPERTY_USAGE_READ_ONLY);
+ action_button->connect(SceneStringName(theme_changed), callable_mp(this, &EditorInspectorToolButtonPlugin::_update_action_icon).bind(action_button, hint_icon));
+ action_button->connect(SceneStringName(pressed), callable_mp(this, &EditorInspectorToolButtonPlugin::_call_action).bind(p_object, p_path));
+
+ add_custom_control(action_button);
+ return true;
+}
+
+ToolButtonEditorPlugin::ToolButtonEditorPlugin() {
+ Ref<EditorInspectorToolButtonPlugin> plugin;
+ plugin.instantiate();
+ add_inspector_plugin(plugin);
+}
diff --git a/modules/squish/image_decompress_squish.cpp b/editor/plugins/tool_button_editor_plugin.h
index 3841ba8db1..2d185c3a8f 100644
--- a/modules/squish/image_decompress_squish.cpp
+++ b/editor/plugins/tool_button_editor_plugin.h
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* image_decompress_squish.cpp */
+/* tool_button_editor_plugin.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,69 +28,30 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#include "image_decompress_squish.h"
+#ifndef TOOL_BUTTON_EDITOR_PLUGIN_H
+#define TOOL_BUTTON_EDITOR_PLUGIN_H
-#include <squish.h>
+#include "editor/editor_inspector.h"
+#include "editor/plugins/editor_plugin.h"
-void image_decompress_squish(Image *p_image) {
- int w = p_image->get_width();
- int h = p_image->get_height();
+class EditorInspectorToolButtonPlugin : public EditorInspectorPlugin {
+ GDCLASS(EditorInspectorToolButtonPlugin, EditorInspectorPlugin);
- Image::Format source_format = p_image->get_format();
- Image::Format target_format = Image::FORMAT_RGBA8;
+ void _update_action_icon(Button *p_action_button, const String &p_action_icon);
+ void _call_action(const Variant &p_object, const StringName &p_property);
- Vector<uint8_t> data;
- int64_t target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps());
- int mm_count = p_image->get_mipmap_count();
- data.resize(target_size);
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide = false) override;
+};
- const uint8_t *rb = p_image->get_data().ptr();
- uint8_t *wb = data.ptrw();
+class ToolButtonEditorPlugin : public EditorPlugin {
+ GDCLASS(ToolButtonEditorPlugin, EditorPlugin);
- int squish_flags = 0;
+public:
+ virtual String get_name() const override { return "ToolButtonEditorPlugin"; }
- switch (source_format) {
- case Image::FORMAT_DXT1:
- squish_flags = squish::kDxt1;
- break;
+ ToolButtonEditorPlugin();
+};
- case Image::FORMAT_DXT3:
- squish_flags = squish::kDxt3;
- break;
-
- case Image::FORMAT_DXT5:
- case Image::FORMAT_DXT5_RA_AS_RG:
- squish_flags = squish::kDxt5;
- break;
-
- case Image::FORMAT_RGTC_R:
- squish_flags = squish::kBc4;
- break;
-
- case Image::FORMAT_RGTC_RG:
- squish_flags = squish::kBc5;
- break;
-
- default:
- ERR_FAIL_MSG("Squish: Can't decompress unknown format: " + itos(p_image->get_format()) + ".");
- break;
- }
-
- for (int i = 0; i <= mm_count; i++) {
- int64_t src_ofs = 0, mipmap_size = 0;
- int mipmap_w = 0, mipmap_h = 0;
- p_image->get_mipmap_offset_size_and_dimensions(i, src_ofs, mipmap_size, mipmap_w, mipmap_h);
-
- int64_t dst_ofs = Image::get_image_mipmap_offset(p_image->get_width(), p_image->get_height(), target_format, i);
- squish::DecompressImage(&wb[dst_ofs], w, h, &rb[src_ofs], squish_flags);
-
- w >>= 1;
- h >>= 1;
- }
-
- p_image->set_data(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
-
- if (source_format == Image::FORMAT_DXT5_RA_AS_RG) {
- p_image->convert_ra_rgba8_to_rg();
- }
-}
+#endif // TOOL_BUTTON_EDITOR_PLUGIN_H
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index f98a30ebb3..ede8351e41 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -6300,6 +6300,7 @@ VisualShaderEditor::VisualShaderEditor() {
graph->connect("scroll_offset_changed", callable_mp(this, &VisualShaderEditor::_scroll_changed));
graph->connect("duplicate_nodes_request", callable_mp(this, &VisualShaderEditor::_duplicate_nodes));
graph->connect("copy_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes).bind(false));
+ graph->connect("cut_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes).bind(true));
graph->connect("paste_nodes_request", callable_mp(this, &VisualShaderEditor::_paste_nodes).bind(false, Point2()));
graph->connect("delete_nodes_request", callable_mp(this, &VisualShaderEditor::_delete_nodes_request));
graph->connect(SceneStringName(gui_input), callable_mp(this, &VisualShaderEditor::_graph_gui_input));
diff --git a/editor/project_manager/project_dialog.cpp b/editor/project_manager/project_dialog.cpp
index 7acda16890..01868846bf 100644
--- a/editor/project_manager/project_dialog.cpp
+++ b/editor/project_manager/project_dialog.cpp
@@ -1024,8 +1024,14 @@ ProjectDialog::ProjectDialog() {
add_child(fdialog_install);
project_name->connect(SceneStringName(text_changed), callable_mp(this, &ProjectDialog::_project_name_changed).unbind(1));
+ project_name->connect(SceneStringName(text_submitted), callable_mp(this, &ProjectDialog::ok_pressed).unbind(1));
+
project_path->connect(SceneStringName(text_changed), callable_mp(this, &ProjectDialog::_project_path_changed).unbind(1));
+ project_path->connect(SceneStringName(text_submitted), callable_mp(this, &ProjectDialog::ok_pressed).unbind(1));
+
install_path->connect(SceneStringName(text_changed), callable_mp(this, &ProjectDialog::_install_path_changed).unbind(1));
+ install_path->connect(SceneStringName(text_submitted), callable_mp(this, &ProjectDialog::ok_pressed).unbind(1));
+
fdialog_install->connect("dir_selected", callable_mp(this, &ProjectDialog::_install_path_selected));
fdialog_install->connect("file_selected", callable_mp(this, &ProjectDialog::_install_path_selected));
diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp
index 00377a0dd2..19aeeb0612 100644
--- a/editor/register_editor_types.cpp
+++ b/editor/register_editor_types.cpp
@@ -127,6 +127,7 @@
#include "editor/plugins/texture_region_editor_plugin.h"
#include "editor/plugins/theme_editor_plugin.h"
#include "editor/plugins/tiles/tiles_editor_plugin.h"
+#include "editor/plugins/tool_button_editor_plugin.h"
#include "editor/plugins/version_control_editor_plugin.h"
#include "editor/plugins/visual_shader_editor_plugin.h"
#include "editor/plugins/voxel_gi_editor_plugin.h"
@@ -247,6 +248,7 @@ void register_editor_types() {
EditorPlugins::add_by_type<TextureLayeredEditorPlugin>();
EditorPlugins::add_by_type<TextureRegionEditorPlugin>();
EditorPlugins::add_by_type<ThemeEditorPlugin>();
+ EditorPlugins::add_by_type<ToolButtonEditorPlugin>();
EditorPlugins::add_by_type<VoxelGIEditorPlugin>();
// 2D
diff --git a/editor/renames_map_3_to_4.cpp b/editor/renames_map_3_to_4.cpp
index ae7c86a5e5..ca5d3cbf2a 100644
--- a/editor/renames_map_3_to_4.cpp
+++ b/editor/renames_map_3_to_4.cpp
@@ -1354,7 +1354,6 @@ const char *RenamesMap3To4::project_settings_renames[][2] = {
{ "rendering/quality/shading/force_lambert_over_burley", "rendering/shading/overrides/force_lambert_over_burley" },
{ "rendering/quality/shading/force_lambert_over_burley.mobile", "rendering/shading/overrides/force_lambert_over_burley.mobile" },
{ "rendering/quality/shading/force_vertex_shading", "rendering/shading/overrides/force_vertex_shading" },
- { "rendering/quality/shading/force_vertex_shading.mobile", "rendering/shading/overrides/force_vertex_shading.mobile" },
{ "rendering/quality/shadow_atlas/quadrant_0_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_0_subdiv" },
{ "rendering/quality/shadow_atlas/quadrant_1_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_1_subdiv" },
{ "rendering/quality/shadow_atlas/quadrant_2_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_2_subdiv" },
@@ -1400,7 +1399,6 @@ const char *RenamesMap3To4::project_godot_renames[][2] = {
{ "quality/shading/force_lambert_over_burley", "shading/overrides/force_lambert_over_burley" },
{ "quality/shading/force_lambert_over_burley.mobile", "shading/overrides/force_lambert_over_burley.mobile" },
{ "quality/shading/force_vertex_shading", "shading/overrides/force_vertex_shading" },
- { "quality/shading/force_vertex_shading.mobile", "shading/overrides/force_vertex_shading.mobile" },
{ "quality/shadow_atlas/quadrant_0_subdiv", "lights_and_shadows/shadow_atlas/quadrant_0_subdiv" },
{ "quality/shadow_atlas/quadrant_1_subdiv", "lights_and_shadows/shadow_atlas/quadrant_1_subdiv" },
{ "quality/shadow_atlas/quadrant_2_subdiv", "lights_and_shadows/shadow_atlas/quadrant_2_subdiv" },
diff --git a/methods.py b/methods.py
index 3f11d39bd0..411ce59d9e 100644
--- a/methods.py
+++ b/methods.py
@@ -795,9 +795,9 @@ def get_compiler_version(env):
"major": -1,
"minor": -1,
"patch": -1,
- "metadata1": None,
- "metadata2": None,
- "date": None,
+ "metadata1": "",
+ "metadata2": "",
+ "date": "",
"apple_major": -1,
"apple_minor": -1,
"apple_patch1": -1,
@@ -806,7 +806,20 @@ def get_compiler_version(env):
}
if env.msvc and not using_clang(env):
- # TODO: Implement for MSVC
+ try:
+ args = [env["VSWHERE"], "-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"]
+ version = subprocess.check_output(args, encoding="utf-8").strip()
+ for line in version.splitlines():
+ split = line.split(":", 1)
+ if split[0] == "catalog_productDisplayVersion":
+ sem_ver = split[1].split(".")
+ ret["major"] = int(sem_ver[0])
+ ret["minor"] = int(sem_ver[1])
+ ret["patch"] = int(sem_ver[2])
+ if split[0] == "catalog_buildVersion":
+ ret["metadata1"] = split[1]
+ except (subprocess.CalledProcessError, OSError):
+ print_warning("Couldn't find vswhere to determine compiler version.")
return ret
# Not using -dumpversion as some GCC distros only return major, and
diff --git a/modules/bcdec/SCsub b/modules/bcdec/SCsub
new file mode 100644
index 0000000000..32198eff96
--- /dev/null
+++ b/modules/bcdec/SCsub
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+from misc.utility.scons_hints import *
+
+Import("env")
+Import("env_modules")
+
+env_bcdec = env_modules.Clone()
+
+# Godot source files
+env_bcdec.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/squish/config.py b/modules/bcdec/config.py
index d22f9454ed..d22f9454ed 100644
--- a/modules/squish/config.py
+++ b/modules/bcdec/config.py
diff --git a/modules/bcdec/image_decompress_bcdec.cpp b/modules/bcdec/image_decompress_bcdec.cpp
new file mode 100644
index 0000000000..30ca1fccb3
--- /dev/null
+++ b/modules/bcdec/image_decompress_bcdec.cpp
@@ -0,0 +1,181 @@
+/**************************************************************************/
+/* image_decompress_bcdec.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "image_decompress_bcdec.h"
+
+#include "core/os/os.h"
+#include "core/string/print_string.h"
+
+#define BCDEC_IMPLEMENTATION
+#include "thirdparty/misc/bcdec.h"
+
+inline void bcdec_bc6h_half_s(const void *compressedBlock, void *decompressedBlock, int destinationPitch) {
+ bcdec_bc6h_half(compressedBlock, decompressedBlock, destinationPitch, true);
+}
+
+inline void bcdec_bc6h_half_u(const void *compressedBlock, void *decompressedBlock, int destinationPitch) {
+ bcdec_bc6h_half(compressedBlock, decompressedBlock, destinationPitch, false);
+}
+
+static void decompress_image(BCdecFormat format, const void *src, void *dst, const uint64_t width, const uint64_t height) {
+ const uint8_t *src_blocks = reinterpret_cast<const uint8_t *>(src);
+ uint8_t *dec_blocks = reinterpret_cast<uint8_t *>(dst);
+ uint64_t src_pos = 0, dst_pos = 0;
+
+#define DECOMPRESS_LOOP(func, block_size, color_bytesize, color_components) \
+ for (uint64_t y = 0; y < height; y += 4) { \
+ for (uint64_t x = 0; x < width; x += 4) { \
+ func(&src_blocks[src_pos], &dec_blocks[dst_pos], width *color_components); \
+ src_pos += block_size; \
+ dst_pos += 4 * color_bytesize; \
+ } \
+ dst_pos += 3 * width * color_bytesize; \
+ }
+
+ switch (format) {
+ case BCdec_BC1: {
+ DECOMPRESS_LOOP(bcdec_bc1, BCDEC_BC1_BLOCK_SIZE, 4, 4)
+ } break;
+ case BCdec_BC2: {
+ DECOMPRESS_LOOP(bcdec_bc2, BCDEC_BC2_BLOCK_SIZE, 4, 4)
+ } break;
+ case BCdec_BC3: {
+ DECOMPRESS_LOOP(bcdec_bc3, BCDEC_BC3_BLOCK_SIZE, 4, 4)
+ } break;
+ case BCdec_BC4: {
+ DECOMPRESS_LOOP(bcdec_bc4, BCDEC_BC4_BLOCK_SIZE, 1, 1)
+ } break;
+ case BCdec_BC5: {
+ DECOMPRESS_LOOP(bcdec_bc5, BCDEC_BC5_BLOCK_SIZE, 2, 2)
+ } break;
+ case BCdec_BC6U: {
+ DECOMPRESS_LOOP(bcdec_bc6h_half_u, BCDEC_BC6H_BLOCK_SIZE, 6, 3)
+ } break;
+ case BCdec_BC6S: {
+ DECOMPRESS_LOOP(bcdec_bc6h_half_s, BCDEC_BC6H_BLOCK_SIZE, 6, 3)
+ } break;
+ case BCdec_BC7: {
+ DECOMPRESS_LOOP(bcdec_bc7, BCDEC_BC7_BLOCK_SIZE, 4, 4)
+ } break;
+ }
+
+#undef DECOMPRESS_LOOP
+}
+
+void image_decompress_bcdec(Image *p_image) {
+ uint64_t start_time = OS::get_singleton()->get_ticks_msec();
+
+ int w = p_image->get_width();
+ int h = p_image->get_height();
+
+ Image::Format source_format = p_image->get_format();
+ Image::Format target_format = Image::FORMAT_MAX;
+
+ BCdecFormat bcdec_format = BCdec_BC1;
+
+ switch (source_format) {
+ case Image::FORMAT_DXT1:
+ bcdec_format = BCdec_BC1;
+ target_format = Image::FORMAT_RGBA8;
+ break;
+
+ case Image::FORMAT_DXT3:
+ bcdec_format = BCdec_BC2;
+ target_format = Image::FORMAT_RGBA8;
+ break;
+
+ case Image::FORMAT_DXT5:
+ case Image::FORMAT_DXT5_RA_AS_RG:
+ bcdec_format = BCdec_BC3;
+ target_format = Image::FORMAT_RGBA8;
+ break;
+
+ case Image::FORMAT_RGTC_R:
+ bcdec_format = BCdec_BC4;
+ target_format = Image::FORMAT_R8;
+ break;
+
+ case Image::FORMAT_RGTC_RG:
+ bcdec_format = BCdec_BC5;
+ target_format = Image::FORMAT_RG8;
+ break;
+
+ case Image::FORMAT_BPTC_RGBFU:
+ bcdec_format = BCdec_BC6U;
+ target_format = Image::FORMAT_RGBH;
+ break;
+
+ case Image::FORMAT_BPTC_RGBF:
+ bcdec_format = BCdec_BC6S;
+ target_format = Image::FORMAT_RGBH;
+ break;
+
+ case Image::FORMAT_BPTC_RGBA:
+ bcdec_format = BCdec_BC7;
+ target_format = Image::FORMAT_RGBA8;
+ break;
+
+ default:
+ ERR_FAIL_MSG("bcdec: Can't decompress unknown format: " + Image::get_format_name(source_format) + ".");
+ break;
+ }
+
+ int mm_count = p_image->get_mipmap_count();
+ int64_t target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps());
+
+ Vector<uint8_t> data;
+ data.resize(target_size);
+
+ const uint8_t *rb = p_image->get_data().ptr();
+ uint8_t *wb = data.ptrw();
+
+ // Decompress mipmaps.
+ for (int i = 0; i <= mm_count; i++) {
+ int64_t src_ofs = 0, mipmap_size = 0;
+ int mipmap_w = 0, mipmap_h = 0;
+ p_image->get_mipmap_offset_size_and_dimensions(i, src_ofs, mipmap_size, mipmap_w, mipmap_h);
+
+ int64_t dst_ofs = Image::get_image_mipmap_offset(p_image->get_width(), p_image->get_height(), target_format, i);
+ decompress_image(bcdec_format, rb + src_ofs, wb + dst_ofs, mipmap_w, mipmap_h);
+
+ w >>= 1;
+ h >>= 1;
+ }
+
+ p_image->set_data(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
+
+ // Swap channels if necessary.
+ if (source_format == Image::FORMAT_DXT5_RA_AS_RG) {
+ p_image->convert_ra_rgba8_to_rg();
+ }
+
+ print_verbose(vformat("bcdec: Decompression of a %dx%d %s image with %d mipmaps took %d ms.",
+ p_image->get_width(), p_image->get_height(), Image::get_format_name(source_format), p_image->get_mipmap_count(), OS::get_singleton()->get_ticks_msec() - start_time));
+}
diff --git a/modules/squish/image_decompress_squish.h b/modules/bcdec/image_decompress_bcdec.h
index 53c5d344a5..b82ceed9a4 100644
--- a/modules/squish/image_decompress_squish.h
+++ b/modules/bcdec/image_decompress_bcdec.h
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* image_decompress_squish.h */
+/* image_decompress_bcdec.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,22 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#ifndef IMAGE_DECOMPRESS_SQUISH_H
-#define IMAGE_DECOMPRESS_SQUISH_H
+#ifndef IMAGE_DECOMPRESS_BCDEC_H
+#define IMAGE_DECOMPRESS_BCDEC_H
#include "core/io/image.h"
-void image_decompress_squish(Image *p_image);
+enum BCdecFormat {
+ BCdec_BC1,
+ BCdec_BC2,
+ BCdec_BC3,
+ BCdec_BC4,
+ BCdec_BC5,
+ BCdec_BC6S,
+ BCdec_BC6U,
+ BCdec_BC7,
+};
-#endif // IMAGE_DECOMPRESS_SQUISH_H
+void image_decompress_bcdec(Image *p_image);
+
+#endif // IMAGE_DECOMPRESS_BCDEC_H
diff --git a/modules/squish/register_types.cpp b/modules/bcdec/register_types.cpp
index af7cf8f4f1..cbf9c0d383 100644
--- a/modules/squish/register_types.cpp
+++ b/modules/bcdec/register_types.cpp
@@ -30,17 +30,18 @@
#include "register_types.h"
-#include "image_decompress_squish.h"
+#include "image_decompress_bcdec.h"
-void initialize_squish_module(ModuleInitializationLevel p_level) {
+void initialize_bcdec_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
- Image::_image_decompress_bc = image_decompress_squish;
+ Image::_image_decompress_bc = image_decompress_bcdec;
+ Image::_image_decompress_bptc = image_decompress_bcdec;
}
-void uninitialize_squish_module(ModuleInitializationLevel p_level) {
+void uninitialize_bcdec_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
diff --git a/modules/squish/register_types.h b/modules/bcdec/register_types.h
index 1786b28ed3..eb721e3f2a 100644
--- a/modules/squish/register_types.h
+++ b/modules/bcdec/register_types.h
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#ifndef SQUISH_REGISTER_TYPES_H
-#define SQUISH_REGISTER_TYPES_H
+#ifndef BCDEC_REGISTER_TYPES_H
+#define BCDEC_REGISTER_TYPES_H
#include "modules/register_module_types.h"
-void initialize_squish_module(ModuleInitializationLevel p_level);
-void uninitialize_squish_module(ModuleInitializationLevel p_level);
+void initialize_bcdec_module(ModuleInitializationLevel p_level);
+void uninitialize_bcdec_module(ModuleInitializationLevel p_level);
-#endif // SQUISH_REGISTER_TYPES_H
+#endif // BCDEC_REGISTER_TYPES_H
diff --git a/modules/cvtt/register_types.cpp b/modules/cvtt/register_types.cpp
index 211d419349..80e3062d04 100644
--- a/modules/cvtt/register_types.cpp
+++ b/modules/cvtt/register_types.cpp
@@ -40,7 +40,6 @@ void initialize_cvtt_module(ModuleInitializationLevel p_level) {
}
Image::set_compress_bptc_func(image_compress_cvtt);
- Image::_image_decompress_bptc = image_decompress_cvtt;
}
void uninitialize_cvtt_module(ModuleInitializationLevel p_level) {
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index f539f27848..5fe47d69df 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -669,6 +669,41 @@
[b]Note:[/b] Subgroups cannot be nested, they only provide one extra level of depth. Just like the next group ends the previous group, so do the subsequent subgroups.
</description>
</annotation>
+ <annotation name="@export_tool_button">
+ <return type="void" />
+ <param index="0" name="text" type="String" />
+ <param index="1" name="icon" type="String" default="&quot;&quot;" />
+ <description>
+ Export a [Callable] property as a clickable button with the label [param text]. When the button is pressed, the callable is called.
+ If [param icon] is specified, it is used to fetch an icon for the button via [method Control.get_theme_icon], from the [code]"EditorIcons"[/code] theme type. If [param icon] is omitted, the default [code]"Callable"[/code] icon is used instead.
+ Consider using the [EditorUndoRedoManager] to allow the action to be reverted safely.
+ See also [constant PROPERTY_HINT_TOOL_BUTTON].
+ [codeblock]
+ @tool
+ extends Sprite2D
+
+ @export_tool_button("Hello") var hello_action = hello
+ @export_tool_button("Randomize the color!", "ColorRect")
+ var randomize_color_action = randomize_color
+
+ func hello():
+ print("Hello world!")
+
+ func randomize_color():
+ var undo_redo = EditorInterface.get_editor_undo_redo()
+ undo_redo.create_action("Randomized Sprite2D Color")
+ undo_redo.add_do_property(self, &amp;"self_modulate", Color(randf(), randf(), randf()))
+ undo_redo.add_undo_property(self, &amp;"self_modulate", self_modulate)
+ undo_redo.commit_action()
+ [/codeblock]
+ [b]Note:[/b] The property is exported without the [constant PROPERTY_USAGE_STORAGE] flag because a [Callable] cannot be properly serialized and stored in a file.
+ [b]Note:[/b] In an exported project neither [EditorInterface] nor [EditorUndoRedoManager] exist, which may cause some scripts to break. To prevent this, you can use [method Engine.get_singleton] and omit the static type from the variable declaration:
+ [codeblock]
+ var undo_redo = Engine.get_singleton(&amp;"EditorInterface").get_editor_undo_redo()
+ [/codeblock]
+ [b]Note:[/b] Avoid storing lambda callables in member variables of [RefCounted]-based classes (e.g. resources), as this can lead to memory leaks. Use only method callables and optionally [method Callable.bind] or [method Callable.unbind].
+ </description>
+ </annotation>
<annotation name="@icon">
<return type="void" />
<param index="0" name="icon_path" type="String" />
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 65aa150be3..e169566705 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -122,6 +122,7 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@export_flags_avoidance"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_AVOIDANCE, Variant::INT>);
register_annotation(MethodInfo("@export_storage"), AnnotationInfo::VARIABLE, &GDScriptParser::export_storage_annotation);
register_annotation(MethodInfo("@export_custom", PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CLASS_IS_ENUM, "PropertyHint"), PropertyInfo(Variant::STRING, "hint_string"), PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CLASS_IS_BITFIELD, "PropertyUsageFlags")), AnnotationInfo::VARIABLE, &GDScriptParser::export_custom_annotation, varray(PROPERTY_USAGE_DEFAULT));
+ register_annotation(MethodInfo("@export_tool_button", PropertyInfo(Variant::STRING, "text"), PropertyInfo(Variant::STRING, "icon")), AnnotationInfo::VARIABLE, &GDScriptParser::export_tool_button_annotation, varray(""));
// Export grouping annotations.
register_annotation(MethodInfo("@export_category", PropertyInfo(Variant::STRING, "name")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_CATEGORY>);
register_annotation(MethodInfo("@export_group", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_GROUP>, varray(""));
@@ -4618,10 +4619,10 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta
// For `@export_storage` and `@export_custom`, there is no need to check the variable type, argument values,
// or handle array exports in a special way, so they are implemented as separate methods.
-bool GDScriptParser::export_storage_annotation(AnnotationNode *p_annotation, Node *p_node, ClassNode *p_class) {
- ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name));
+bool GDScriptParser::export_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {
+ ERR_FAIL_COND_V_MSG(p_target->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name));
- VariableNode *variable = static_cast<VariableNode *>(p_node);
+ VariableNode *variable = static_cast<VariableNode *>(p_target);
if (variable->is_static) {
push_error(vformat(R"(Annotation "%s" cannot be applied to a static variable.)", p_annotation->name), p_annotation);
return false;
@@ -4640,11 +4641,11 @@ bool GDScriptParser::export_storage_annotation(AnnotationNode *p_annotation, Nod
return true;
}
-bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node *p_node, ClassNode *p_class) {
- ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name));
+bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {
+ ERR_FAIL_COND_V_MSG(p_target->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name));
ERR_FAIL_COND_V_MSG(p_annotation->resolved_arguments.size() < 2, false, R"(Annotation "@export_custom" requires 2 arguments.)");
- VariableNode *variable = static_cast<VariableNode *>(p_node);
+ VariableNode *variable = static_cast<VariableNode *>(p_target);
if (variable->is_static) {
push_error(vformat(R"(Annotation "%s" cannot be applied to a static variable.)", p_annotation->name), p_annotation);
return false;
@@ -4668,12 +4669,56 @@ bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node
return true;
}
-template <PropertyUsageFlags t_usage>
-bool GDScriptParser::export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {
- if (p_annotation->resolved_arguments.is_empty()) {
+bool GDScriptParser::export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_V_MSG(p_target->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name));
+ ERR_FAIL_COND_V(p_annotation->resolved_arguments.is_empty(), false);
+
+ if (!is_tool()) {
+ push_error(R"(Tool buttons can only be used in tool scripts (add "@tool" to the top of the script).)", p_annotation);
+ return false;
+ }
+
+ VariableNode *variable = static_cast<VariableNode *>(p_target);
+
+ if (variable->is_static) {
+ push_error(vformat(R"(Annotation "%s" cannot be applied to a static variable.)", p_annotation->name), p_annotation);
+ return false;
+ }
+ if (variable->exported) {
+ push_error(vformat(R"(Annotation "%s" cannot be used with another "@export" annotation.)", p_annotation->name), p_annotation);
return false;
}
+ const DataType variable_type = variable->get_datatype();
+ if (!variable_type.is_variant() && variable_type.is_hard_type()) {
+ if (variable_type.kind != DataType::BUILTIN || variable_type.builtin_type != Variant::CALLABLE) {
+ push_error(vformat(R"("@export_tool_button" annotation requires a variable of type "Callable", but type "%s" was given instead.)", variable_type.to_string()), p_annotation);
+ return false;
+ }
+ }
+
+ variable->exported = true;
+
+ // Build the hint string (format: `<text>[,<icon>]`).
+ String hint_string = p_annotation->resolved_arguments[0].operator String(); // Button text.
+ if (p_annotation->resolved_arguments.size() > 1) {
+ hint_string += "," + p_annotation->resolved_arguments[1].operator String(); // Button icon.
+ }
+
+ variable->export_info.type = Variant::CALLABLE;
+ variable->export_info.hint = PROPERTY_HINT_TOOL_BUTTON;
+ variable->export_info.hint_string = hint_string;
+ variable->export_info.usage = PROPERTY_USAGE_EDITOR;
+#endif // TOOLS_ENABLED
+
+ return true; // Only available in editor.
+}
+
+template <PropertyUsageFlags t_usage>
+bool GDScriptParser::export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {
+ ERR_FAIL_COND_V(p_annotation->resolved_arguments.is_empty(), false);
+
p_annotation->export_info.name = p_annotation->resolved_arguments[0];
switch (t_usage) {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 7840474a89..7f64ae902b 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -1507,6 +1507,7 @@ private:
bool export_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
bool export_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
bool export_custom_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
+ bool export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
template <PropertyUsageFlags t_usage>
bool export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
bool warning_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
diff --git a/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.gd b/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.gd
new file mode 100644
index 0000000000..48be5b2541
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.gd
@@ -0,0 +1 @@
+@export_tool_button("Click me!") var action
diff --git a/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.out b/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.out
new file mode 100644
index 0000000000..fb148308e4
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/export_tool_button_requires_tool_mode.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Tool buttons can only be used in tool scripts (add "@tool" to the top of the script).
diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.gd b/modules/gdscript/tests/scripts/parser/features/export_variable.gd
index 1e134d0e0e..8aa449f602 100644
--- a/modules/gdscript/tests/scripts/parser/features/export_variable.gd
+++ b/modules/gdscript/tests/scripts/parser/features/export_variable.gd
@@ -1,3 +1,4 @@
+@tool
class_name ExportVariableTest
extends Node
@@ -47,6 +48,10 @@ const PreloadedUnnamedClass = preload("./export_variable_unnamed.notest.gd")
@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_weak_int = 5
@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_hard_int: int = 6
+# `@export_tool_button`.
+@export_tool_button("Click me!") var test_tool_button_1: Callable
+@export_tool_button("Click me!", "ColorRect") var test_tool_button_2: Callable
+
func test():
for property in get_property_list():
if str(property.name).begins_with("test_"):
diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.out b/modules/gdscript/tests/scripts/parser/features/export_variable.out
index d10462bb8d..0d915e00e6 100644
--- a/modules/gdscript/tests/scripts/parser/features/export_variable.out
+++ b/modules/gdscript/tests/scripts/parser/features/export_variable.out
@@ -55,3 +55,7 @@ var test_export_custom_weak_int: int = 5
hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_export_custom_hard_int: int = 6
hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_tool_button_1: Callable = Callable()
+ hint=TOOL_BUTTON hint_string="Click me!" usage=EDITOR|SCRIPT_VARIABLE class_name=&""
+var test_tool_button_2: Callable = Callable()
+ hint=TOOL_BUTTON hint_string="Click me!,ColorRect" usage=EDITOR|SCRIPT_VARIABLE class_name=&""
diff --git a/modules/gdscript/tests/scripts/utils.notest.gd b/modules/gdscript/tests/scripts/utils.notest.gd
index 1e2788f765..fa289e442f 100644
--- a/modules/gdscript/tests/scripts/utils.notest.gd
+++ b/modules/gdscript/tests/scripts/utils.notest.gd
@@ -205,6 +205,9 @@ static func get_property_hint_name(hint: PropertyHint) -> String:
return "PROPERTY_HINT_HIDE_QUATERNION_EDIT"
PROPERTY_HINT_PASSWORD:
return "PROPERTY_HINT_PASSWORD"
+ PROPERTY_HINT_TOOL_BUTTON:
+ return "PROPERTY_HINT_TOOL_BUTTON"
+
printerr("Argument `hint` is invalid. Use `PROPERTY_HINT_*` constants.")
return "<invalid hint>"
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs
index cc45e5746f..188972e6fe 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs
@@ -32,6 +32,10 @@ partial class EventSignals
add => backing_MySignal += value;
remove => backing_MySignal -= value;
}
+ protected void OnMySignal(string str, int num)
+ {
+ EmitSignal(SignalName.MySignal, str, num);
+ }
/// <inheritdoc/>
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void RaiseGodotClassSignalCallbacks(in godot_string_name signal, NativeVariantPtrArgs args)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
index 957d5789df..62fa7b0a36 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
@@ -155,6 +155,32 @@ namespace Godot.SourceGenerators
};
}
+ public static string GetAccessibilityKeyword(this INamedTypeSymbol namedTypeSymbol)
+ {
+ if (namedTypeSymbol.DeclaredAccessibility == Accessibility.NotApplicable)
+ {
+ // Accessibility not specified. Get the default accessibility.
+ return namedTypeSymbol.ContainingSymbol switch
+ {
+ null or INamespaceSymbol => "internal",
+ ITypeSymbol { TypeKind: TypeKind.Class or TypeKind.Struct } => "private",
+ ITypeSymbol { TypeKind: TypeKind.Interface } => "public",
+ _ => "",
+ };
+ }
+
+ return namedTypeSymbol.DeclaredAccessibility switch
+ {
+ Accessibility.Private => "private",
+ Accessibility.Protected => "protected",
+ Accessibility.Internal => "internal",
+ Accessibility.ProtectedAndInternal => "private",
+ Accessibility.ProtectedOrInternal => "private",
+ Accessibility.Public => "public",
+ _ => "",
+ };
+ }
+
public static string NameWithTypeParameters(this INamedTypeSymbol symbol)
{
return symbol.IsGenericType ?
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
index 54f2212339..0dda43ab4c 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
@@ -5,13 +5,6 @@ using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
-// TODO:
-// Determine a proper way to emit the signal.
-// 'Emit(nameof(TheEvent))' creates a StringName every time and has the overhead of string marshaling.
-// I haven't decided on the best option yet. Some possibilities:
-// - Expose the generated StringName fields to the user, for use with 'Emit(...)'.
-// - Generate a 'EmitSignalName' method for each event signal.
-
namespace Godot.SourceGenerators
{
[Generator]
@@ -276,7 +269,7 @@ namespace Godot.SourceGenerators
source.Append(
$" /// <inheritdoc cref=\"{signalDelegate.DelegateSymbol.FullQualifiedNameIncludeGlobal()}\"/>\n");
- source.Append(" public event ")
+ source.Append($" {signalDelegate.DelegateSymbol.GetAccessibilityKeyword()} event ")
.Append(signalDelegate.DelegateSymbol.FullQualifiedNameIncludeGlobal())
.Append(" @")
.Append(signalName)
@@ -288,6 +281,43 @@ namespace Godot.SourceGenerators
.Append(signalName)
.Append(" -= value;\n")
.Append("}\n");
+
+ // Generate On{EventName} method to raise the event
+
+ var invokeMethodSymbol = signalDelegate.InvokeMethodData.Method;
+ int paramCount = invokeMethodSymbol.Parameters.Length;
+
+ string raiseMethodModifiers = signalDelegate.DelegateSymbol.ContainingType.IsSealed ?
+ "private" :
+ "protected";
+
+ source.Append($" {raiseMethodModifiers} void On{signalName}(");
+ for (int i = 0; i < paramCount; i++)
+ {
+ var paramSymbol = invokeMethodSymbol.Parameters[i];
+ source.Append($"{paramSymbol.Type.FullQualifiedNameIncludeGlobal()} {paramSymbol.Name}");
+ if (i < paramCount - 1)
+ {
+ source.Append(", ");
+ }
+ }
+ source.Append(")\n");
+ source.Append(" {\n");
+ source.Append($" EmitSignal(SignalName.{signalName}");
+ foreach (var paramSymbol in invokeMethodSymbol.Parameters)
+ {
+ // Enums must be converted to the underlying type before they can be implicitly converted to Variant
+ if (paramSymbol.Type.TypeKind == TypeKind.Enum)
+ {
+ var underlyingType = ((INamedTypeSymbol)paramSymbol.Type).EnumUnderlyingType;
+ source.Append($", ({underlyingType.FullQualifiedNameIncludeGlobal()}){paramSymbol.Name}");
+ continue;
+ }
+
+ source.Append($", {paramSymbol.Name}");
+ }
+ source.Append(");\n");
+ source.Append(" }\n");
}
// Generate RaiseGodotClassSignalCallbacks
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index a467aae2e9..89655e0b56 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -3227,6 +3227,46 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
}
p_output.append(CLOSE_BLOCK_L1);
+
+ // Generate On{EventName} method to raise the event.
+ if (!p_itype.is_singleton) {
+ p_output.append(MEMBER_BEGIN "protected void ");
+ p_output << "On" << p_isignal.proxy_name;
+ if (is_parameterless) {
+ p_output.append("()\n" OPEN_BLOCK_L1 INDENT2);
+ p_output << "EmitSignal(SignalName." << p_isignal.proxy_name << ");\n";
+ p_output.append(CLOSE_BLOCK_L1);
+ } else {
+ p_output.append("(");
+
+ StringBuilder cs_emitsignal_params;
+
+ int idx = 0;
+ for (const ArgumentInterface &iarg : p_isignal.arguments) {
+ const TypeInterface *arg_type = _get_type_or_null(iarg.type);
+ ERR_FAIL_NULL_V_MSG(arg_type, ERR_BUG, "Argument type '" + iarg.type.cname + "' was not found.");
+
+ if (idx != 0) {
+ p_output << ", ";
+ cs_emitsignal_params << ", ";
+ }
+
+ p_output << arg_type->cs_type << " " << iarg.name;
+
+ if (arg_type->is_enum) {
+ cs_emitsignal_params << "(long)";
+ }
+
+ cs_emitsignal_params << iarg.name;
+
+ idx++;
+ }
+
+ p_output.append(")\n" OPEN_BLOCK_L1 INDENT2);
+ p_output << "EmitSignal(SignalName." << p_isignal.proxy_name << ", " << cs_emitsignal_params << ");\n";
+ p_output.append(CLOSE_BLOCK_L1);
+ }
+ }
}
return OK;
diff --git a/modules/squish/SCsub b/modules/squish/SCsub
deleted file mode 100644
index d8e7fbc142..0000000000
--- a/modules/squish/SCsub
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-from misc.utility.scons_hints import *
-
-Import("env")
-Import("env_modules")
-
-env_squish = env_modules.Clone()
-
-# Thirdparty source files
-
-thirdparty_obj = []
-
-if env["builtin_squish"]:
- thirdparty_dir = "#thirdparty/squish/"
- thirdparty_sources = [
- "alpha.cpp",
- "clusterfit.cpp",
- "colourblock.cpp",
- "colourfit.cpp",
- "colourset.cpp",
- "maths.cpp",
- "rangefit.cpp",
- "singlecolourfit.cpp",
- "squish.cpp",
- ]
-
- thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
-
- env_squish.Prepend(CPPPATH=[thirdparty_dir])
-
- env_thirdparty = env_squish.Clone()
- env_thirdparty.disable_warnings()
- env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
- env.modules_sources += thirdparty_obj
-
-
-# Godot source files
-
-module_obj = []
-
-env_squish.add_source_files(module_obj, "*.cpp")
-env.modules_sources += module_obj
-
-# Needed to force rebuilding the module files when the thirdparty library is updated.
-env.Depends(module_obj, thirdparty_obj)
diff --git a/platform/android/doc_classes/EditorExportPlatformAndroid.xml b/platform/android/doc_classes/EditorExportPlatformAndroid.xml
index 020e432155..2fe5539e56 100644
--- a/platform/android/doc_classes/EditorExportPlatformAndroid.xml
+++ b/platform/android/doc_classes/EditorExportPlatformAndroid.xml
@@ -102,6 +102,9 @@
<member name="launcher_icons/adaptive_foreground_432x432" type="String" setter="" getter="">
Foreground layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url].
</member>
+ <member name="launcher_icons/adaptive_monochrome_432x432" type="String" setter="" getter="">
+ Monochrome layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url].
+ </member>
<member name="launcher_icons/main_192x192" type="String" setter="" getter="">
Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/icon].
</member>
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index e3d9807af7..cfd258cddc 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -222,6 +222,7 @@ static const int icon_densities_count = 6;
static const char *launcher_icon_option = PNAME("launcher_icons/main_192x192");
static const char *launcher_adaptive_icon_foreground_option = PNAME("launcher_icons/adaptive_foreground_432x432");
static const char *launcher_adaptive_icon_background_option = PNAME("launcher_icons/adaptive_background_432x432");
+static const char *launcher_adaptive_icon_monochrome_option = PNAME("launcher_icons/adaptive_monochrome_432x432");
static const LauncherIcon launcher_icons[icon_densities_count] = {
{ "res/mipmap-xxxhdpi-v4/icon.png", 192 },
@@ -250,6 +251,15 @@ static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_coun
{ "res/mipmap/icon_background.png", 432 }
};
+static const LauncherIcon launcher_adaptive_icon_monochromes[icon_densities_count] = {
+ { "res/mipmap-xxxhdpi-v4/icon_monochrome.png", 432 },
+ { "res/mipmap-xxhdpi-v4/icon_monochrome.png", 324 },
+ { "res/mipmap-xhdpi-v4/icon_monochrome.png", 216 },
+ { "res/mipmap-hdpi-v4/icon_monochrome.png", 162 },
+ { "res/mipmap-mdpi-v4/icon_monochrome.png", 108 },
+ { "res/mipmap/icon_monochrome.png", 432 }
+};
+
static const int EXPORT_FORMAT_APK = 0;
static const int EXPORT_FORMAT_AAB = 1;
@@ -1644,12 +1654,13 @@ void EditorExportPlatformAndroid::_process_launcher_icons(const String &p_file_n
}
}
-void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) {
+void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background, Ref<Image> &monochrome) {
String project_icon_path = GLOBAL_GET("application/config/icon");
icon.instantiate();
foreground.instantiate();
background.instantiate();
+ monochrome.instantiate();
// Regular icon: user selection -> project icon -> default.
String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges();
@@ -1677,12 +1688,20 @@ void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &
print_verbose("Loading adaptive background icon from " + path);
ImageLoader::load_image(path, background);
}
+
+ // Adaptive monochrome: user selection -> default.
+ path = static_cast<String>(p_preset->get(launcher_adaptive_icon_monochrome_option)).strip_edges();
+ if (!path.is_empty()) {
+ print_verbose("Loading adaptive monochrome icon from " + path);
+ ImageLoader::load_image(path, background);
+ }
}
void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset,
const Ref<Image> &p_main_image,
const Ref<Image> &p_foreground,
- const Ref<Image> &p_background) {
+ const Ref<Image> &p_background,
+ const Ref<Image> &p_monochrome) {
String gradle_build_dir = ExportTemplateManager::get_android_build_directory(p_preset);
// Prepare images to be resized for the icons. If some image ends up being uninitialized,
@@ -1711,6 +1730,14 @@ void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<Editor
launcher_adaptive_icon_backgrounds[i].dimensions, data);
store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_backgrounds[i].export_path), data);
}
+
+ if (p_monochrome.is_valid() && !p_monochrome->is_empty()) {
+ print_verbose("Processing launcher adaptive icon p_monochrome for dimension " + itos(launcher_adaptive_icon_monochromes[i].dimensions) + " into " + launcher_adaptive_icon_monochromes[i].export_path);
+ Vector<uint8_t> data;
+ _process_launcher_icons(launcher_adaptive_icon_monochromes[i].export_path, p_monochrome,
+ launcher_adaptive_icon_monochromes[i].dimensions, data);
+ store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_monochromes[i].export_path), data);
+ }
}
}
@@ -1875,6 +1902,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_monochrome_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false));
@@ -3035,8 +3063,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
Ref<Image> main_image;
Ref<Image> foreground;
Ref<Image> background;
+ Ref<Image> monochrome;
- load_icon_refs(p_preset, main_image, foreground, background);
+ load_icon_refs(p_preset, main_image, foreground, background, monochrome);
Vector<uint8_t> command_line_flags;
// Write command line flags into the command_line_flags variable.
@@ -3107,7 +3136,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to overwrite res/*.xml files with project name."));
}
// Copies the project icon files into the appropriate Gradle project directory.
- _copy_icons_to_gradle_project(p_preset, main_image, foreground, background);
+ _copy_icons_to_gradle_project(p_preset, main_image, foreground, background, monochrome);
// Write an AndroidManifest.xml file into the Gradle project directory.
_write_tmp_manifest(p_preset, p_give_internet, p_debug);
@@ -3446,6 +3475,11 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
_process_launcher_icons(file, background, launcher_adaptive_icon_backgrounds[i].dimensions, data);
}
}
+ if (monochrome.is_valid() && !monochrome->is_empty()) {
+ if (file == launcher_adaptive_icon_monochromes[i].export_path) {
+ _process_launcher_icons(file, monochrome, launcher_adaptive_icon_monochromes[i].dimensions, data);
+ }
+ }
}
}
diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h
index 708288fbf4..7e1d626486 100644
--- a/platform/android/export/export_plugin.h
+++ b/platform/android/export/export_plugin.h
@@ -167,12 +167,13 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
void _process_launcher_icons(const String &p_file_name, const Ref<Image> &p_source_image, int dimension, Vector<uint8_t> &p_data);
- void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background);
+ void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background, Ref<Image> &monochrome);
void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset,
const Ref<Image> &p_main_image,
const Ref<Image> &p_foreground,
- const Ref<Image> &p_background);
+ const Ref<Image> &p_background,
+ const Ref<Image> &p_monochrome);
static void _create_editor_debug_keystore_if_needed();
diff --git a/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt
index 6cb08ae94b..9dc34f2267 100644
--- a/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt
+++ b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt
@@ -45,14 +45,14 @@ open class GodotEditor : BaseGodotEditor() {
internal val XR_RUN_GAME_INFO = EditorWindowInfo(GodotXRGame::class.java, 1667, ":GodotXRGame")
- internal const val USE_SCENE_PERMISSION = "com.oculus.permission.USE_SCENE"
+ internal val USE_SCENE_PERMISSIONS = listOf("com.oculus.permission.USE_SCENE", "horizonos.permission.USE_SCENE")
}
override fun getExcludedPermissions(): MutableSet<String> {
val excludedPermissions = super.getExcludedPermissions()
// The USE_SCENE permission is requested when the "xr/openxr/enabled" project setting
// is enabled.
- excludedPermissions.add(USE_SCENE_PERMISSION)
+ excludedPermissions.addAll(USE_SCENE_PERMISSIONS)
return excludedPermissions
}
diff --git a/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt
index 5db2879aad..0c82791e89 100644
--- a/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt
+++ b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt
@@ -69,7 +69,7 @@ open class GodotXRGame: GodotGame() {
val automaticPermissionsRequestEnabled = automaticallyRequestPermissionsSetting.isNullOrEmpty() ||
automaticallyRequestPermissionsSetting.toBoolean()
if (automaticPermissionsRequestEnabled) {
- permissionsToEnable.add(USE_SCENE_PERMISSION)
+ permissionsToEnable.addAll(USE_SCENE_PERMISSIONS)
}
}
diff --git a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml
index cfdcca2ab5..bb2ae6bee5 100644
--- a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml
+++ b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml
@@ -2,4 +2,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/icon_background"/>
<foreground android:drawable="@mipmap/icon_foreground"/>
+ <monochrome android:drawable="@mipmap/icon_monochrome"/>
</adaptive-icon>
diff --git a/platform/android/java/lib/res/mipmap/icon_monochrome.png b/platform/android/java/lib/res/mipmap/icon_monochrome.png
new file mode 100644
index 0000000000..28f59ea119
--- /dev/null
+++ b/platform/android/java/lib/res/mipmap/icon_monochrome.png
Binary files differ
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index d1de760f34..a67434527c 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -256,10 +256,6 @@ def configure(env: "SConsEnvironment"):
if not env["builtin_enet"]:
env.ParseConfig("pkg-config libenet --cflags --libs")
- if not env["builtin_squish"]:
- # libsquish doesn't reliably install its .pc file, so some distros lack it.
- env.Append(LIBS=["libsquish"])
-
if not env["builtin_zstd"]:
env.ParseConfig("pkg-config libzstd --cflags --libs")
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index f551cb401c..e8166802f8 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -332,8 +332,8 @@ void MeshInstance3D::create_multiple_convex_collisions(const Ref<MeshConvexDecom
void MeshInstance3D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- _resolve_skeleton_path();
+ case NOTIFICATION_READY: {
+ callable_mp(this, &MeshInstance3D::_resolve_skeleton_path).call_deferred();
} break;
case NOTIFICATION_TRANSLATION_CHANGED: {
if (mesh.is_valid()) {
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 11a6411e65..cf8815679f 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1999,6 +1999,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
} else if (p_ev->is_action("ui_copy", true)) {
emit_signal(SNAME("copy_nodes_request"));
accept_event();
+ } else if (p_ev->is_action("ui_cut", true)) {
+ emit_signal(SNAME("cut_nodes_request"));
+ accept_event();
} else if (p_ev->is_action("ui_paste", true)) {
emit_signal(SNAME("paste_nodes_request"));
accept_event();
@@ -2735,6 +2738,7 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("connection_drag_ended"));
ADD_SIGNAL(MethodInfo("copy_nodes_request"));
+ ADD_SIGNAL(MethodInfo("cut_nodes_request"));
ADD_SIGNAL(MethodInfo("paste_nodes_request"));
ADD_SIGNAL(MethodInfo("duplicate_nodes_request"));
ADD_SIGNAL(MethodInfo("delete_nodes_request", PropertyInfo(Variant::ARRAY, "nodes", PROPERTY_HINT_ARRAY_TYPE, "StringName")));
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 927e76e4b2..ab25aabb81 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -113,12 +113,12 @@ void Material::inspect_native_shader_code() {
RID Material::get_shader_rid() const {
RID ret;
- GDVIRTUAL_REQUIRED_CALL(_get_shader_rid, ret);
+ GDVIRTUAL_CALL(_get_shader_rid, ret);
return ret;
}
Shader::Mode Material::get_shader_mode() const {
Shader::Mode ret = Shader::MODE_MAX;
- GDVIRTUAL_REQUIRED_CALL(_get_shader_mode, ret);
+ GDVIRTUAL_CALL(_get_shader_mode, ret);
return ret;
}
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 50a774e961..25c4450682 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -66,8 +66,8 @@ protected:
void _mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader);
bool _is_initialized() { return init_state == INIT_STATE_READY; }
- GDVIRTUAL0RC(RID, _get_shader_rid)
- GDVIRTUAL0RC(Shader::Mode, _get_shader_mode)
+ GDVIRTUAL0RC_REQUIRED(RID, _get_shader_rid)
+ GDVIRTUAL0RC_REQUIRED(Shader::Mode, _get_shader_mode)
GDVIRTUAL0RC(bool, _can_do_next_pass)
GDVIRTUAL0RC(bool, _can_use_render_priority)
public:
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 22e2e9138f..4d1d733f8b 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -205,81 +205,81 @@ Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr;
int Mesh::get_surface_count() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_surface_count, ret);
+ GDVIRTUAL_CALL(_get_surface_count, ret);
return ret;
}
int Mesh::surface_get_array_len(int p_idx) const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_surface_get_array_len, p_idx, ret);
+ GDVIRTUAL_CALL(_surface_get_array_len, p_idx, ret);
return ret;
}
int Mesh::surface_get_array_index_len(int p_idx) const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_surface_get_array_index_len, p_idx, ret);
+ GDVIRTUAL_CALL(_surface_get_array_index_len, p_idx, ret);
return ret;
}
Array Mesh::surface_get_arrays(int p_surface) const {
Array ret;
- GDVIRTUAL_REQUIRED_CALL(_surface_get_arrays, p_surface, ret);
+ GDVIRTUAL_CALL(_surface_get_arrays, p_surface, ret);
return ret;
}
TypedArray<Array> Mesh::surface_get_blend_shape_arrays(int p_surface) const {
TypedArray<Array> ret;
- GDVIRTUAL_REQUIRED_CALL(_surface_get_blend_shape_arrays, p_surface, ret);
+ GDVIRTUAL_CALL(_surface_get_blend_shape_arrays, p_surface, ret);
return ret;
}
Dictionary Mesh::surface_get_lods(int p_surface) const {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_surface_get_lods, p_surface, ret);
+ GDVIRTUAL_CALL(_surface_get_lods, p_surface, ret);
return ret;
}
BitField<Mesh::ArrayFormat> Mesh::surface_get_format(int p_idx) const {
uint32_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_surface_get_format, p_idx, ret);
+ GDVIRTUAL_CALL(_surface_get_format, p_idx, ret);
return ret;
}
Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const {
uint32_t ret = PRIMITIVE_MAX;
- GDVIRTUAL_REQUIRED_CALL(_surface_get_primitive_type, p_idx, ret);
+ GDVIRTUAL_CALL(_surface_get_primitive_type, p_idx, ret);
return (Mesh::PrimitiveType)ret;
}
void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
- GDVIRTUAL_REQUIRED_CALL(_surface_set_material, p_idx, p_material);
+ GDVIRTUAL_CALL(_surface_set_material, p_idx, p_material);
}
Ref<Material> Mesh::surface_get_material(int p_idx) const {
Ref<Material> ret;
- GDVIRTUAL_REQUIRED_CALL(_surface_get_material, p_idx, ret);
+ GDVIRTUAL_CALL(_surface_get_material, p_idx, ret);
return ret;
}
int Mesh::get_blend_shape_count() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_count, ret);
+ GDVIRTUAL_CALL(_get_blend_shape_count, ret);
return ret;
}
StringName Mesh::get_blend_shape_name(int p_index) const {
StringName ret;
- GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_name, p_index, ret);
+ GDVIRTUAL_CALL(_get_blend_shape_name, p_index, ret);
return ret;
}
void Mesh::set_blend_shape_name(int p_index, const StringName &p_name) {
- GDVIRTUAL_REQUIRED_CALL(_set_blend_shape_name, p_index, p_name);
+ GDVIRTUAL_CALL(_set_blend_shape_name, p_index, p_name);
}
AABB Mesh::get_aabb() const {
AABB ret;
- GDVIRTUAL_REQUIRED_CALL(_get_aabb, ret);
+ GDVIRTUAL_CALL(_get_aabb, ret);
return ret;
}
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 13fd986e81..068bfb6708 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -68,20 +68,20 @@ public:
protected:
static void _bind_methods();
- GDVIRTUAL0RC(int, _get_surface_count)
- GDVIRTUAL1RC(int, _surface_get_array_len, int)
- GDVIRTUAL1RC(int, _surface_get_array_index_len, int)
- GDVIRTUAL1RC(Array, _surface_get_arrays, int)
- GDVIRTUAL1RC(TypedArray<Array>, _surface_get_blend_shape_arrays, int)
- GDVIRTUAL1RC(Dictionary, _surface_get_lods, int)
- GDVIRTUAL1RC(uint32_t, _surface_get_format, int)
- GDVIRTUAL1RC(uint32_t, _surface_get_primitive_type, int)
- GDVIRTUAL2(_surface_set_material, int, Ref<Material>)
- GDVIRTUAL1RC(Ref<Material>, _surface_get_material, int)
- GDVIRTUAL0RC(int, _get_blend_shape_count)
- GDVIRTUAL1RC(StringName, _get_blend_shape_name, int)
- GDVIRTUAL2(_set_blend_shape_name, int, StringName)
- GDVIRTUAL0RC(AABB, _get_aabb)
+ GDVIRTUAL0RC_REQUIRED(int, _get_surface_count)
+ GDVIRTUAL1RC_REQUIRED(int, _surface_get_array_len, int)
+ GDVIRTUAL1RC_REQUIRED(int, _surface_get_array_index_len, int)
+ GDVIRTUAL1RC_REQUIRED(Array, _surface_get_arrays, int)
+ GDVIRTUAL1RC_REQUIRED(TypedArray<Array>, _surface_get_blend_shape_arrays, int)
+ GDVIRTUAL1RC_REQUIRED(Dictionary, _surface_get_lods, int)
+ GDVIRTUAL1RC_REQUIRED(uint32_t, _surface_get_format, int)
+ GDVIRTUAL1RC_REQUIRED(uint32_t, _surface_get_primitive_type, int)
+ GDVIRTUAL2_REQUIRED(_surface_set_material, int, Ref<Material>)
+ GDVIRTUAL1RC_REQUIRED(Ref<Material>, _surface_get_material, int)
+ GDVIRTUAL0RC_REQUIRED(int, _get_blend_shape_count)
+ GDVIRTUAL1RC_REQUIRED(StringName, _get_blend_shape_name, int)
+ GDVIRTUAL2_REQUIRED(_set_blend_shape_name, int, StringName)
+ GDVIRTUAL0RC_REQUIRED(AABB, _get_aabb)
public:
enum {
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index f87bf1ee05..1203c21a1b 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -90,7 +90,7 @@ Point2 StyleBox::get_offset() const {
}
void StyleBox::draw(RID p_canvas_item, const Rect2 &p_rect) const {
- GDVIRTUAL_REQUIRED_CALL(_draw, p_canvas_item, p_rect);
+ GDVIRTUAL_CALL(_draw, p_canvas_item, p_rect);
}
Rect2 StyleBox::get_draw_rect(const Rect2 &p_rect) const {
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 3d3a059d0b..e09b271c47 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -48,7 +48,7 @@ protected:
static void _bind_methods();
virtual float get_style_margin(Side p_side) const { return 0; }
- GDVIRTUAL2C(_draw, RID, Rect2)
+ GDVIRTUAL2C_REQUIRED(_draw, RID, Rect2)
GDVIRTUAL1RC(Rect2, _get_draw_rect, Rect2)
GDVIRTUAL0RC(Size2, _get_minimum_size)
GDVIRTUAL2RC(bool, _test_mask, Point2, Rect2)
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 0efaad61fe..7713181a4b 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -34,13 +34,13 @@
int Texture2D::get_width() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_width, ret);
+ GDVIRTUAL_CALL(_get_width, ret);
return ret;
}
int Texture2D::get_height() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_height, ret);
+ GDVIRTUAL_CALL(_get_height, ret);
return ret;
}
@@ -133,37 +133,37 @@ TypedArray<Image> Texture3D::_get_datai() const {
Image::Format Texture3D::get_format() const {
Image::Format ret = Image::FORMAT_MAX;
- GDVIRTUAL_REQUIRED_CALL(_get_format, ret);
+ GDVIRTUAL_CALL(_get_format, ret);
return ret;
}
int Texture3D::get_width() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_width, ret);
+ GDVIRTUAL_CALL(_get_width, ret);
return ret;
}
int Texture3D::get_height() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_height, ret);
+ GDVIRTUAL_CALL(_get_height, ret);
return ret;
}
int Texture3D::get_depth() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_depth, ret);
+ GDVIRTUAL_CALL(_get_depth, ret);
return ret;
}
bool Texture3D::has_mipmaps() const {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret);
+ GDVIRTUAL_CALL(_has_mipmaps, ret);
return ret;
}
Vector<Ref<Image>> Texture3D::get_data() const {
TypedArray<Image> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_data, ret);
+ GDVIRTUAL_CALL(_get_data, ret);
Vector<Ref<Image>> data;
data.resize(ret.size());
for (int i = 0; i < data.size(); i++) {
@@ -198,43 +198,43 @@ Ref<Resource> Texture3D::create_placeholder() const {
Image::Format TextureLayered::get_format() const {
Image::Format ret = Image::FORMAT_MAX;
- GDVIRTUAL_REQUIRED_CALL(_get_format, ret);
+ GDVIRTUAL_CALL(_get_format, ret);
return ret;
}
TextureLayered::LayeredType TextureLayered::get_layered_type() const {
uint32_t ret = LAYERED_TYPE_2D_ARRAY;
- GDVIRTUAL_REQUIRED_CALL(_get_layered_type, ret);
+ GDVIRTUAL_CALL(_get_layered_type, ret);
return (LayeredType)ret;
}
int TextureLayered::get_width() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_width, ret);
+ GDVIRTUAL_CALL(_get_width, ret);
return ret;
}
int TextureLayered::get_height() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_height, ret);
+ GDVIRTUAL_CALL(_get_height, ret);
return ret;
}
int TextureLayered::get_layers() const {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_layers, ret);
+ GDVIRTUAL_CALL(_get_layers, ret);
return ret;
}
bool TextureLayered::has_mipmaps() const {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret);
+ GDVIRTUAL_CALL(_has_mipmaps, ret);
return ret;
}
Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
Ref<Image> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_layer_data, p_layer, ret);
+ GDVIRTUAL_CALL(_get_layer_data, p_layer, ret);
return ret;
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index e7840804bf..cdad884e71 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -57,8 +57,8 @@ class Texture2D : public Texture {
protected:
static void _bind_methods();
- GDVIRTUAL0RC(int, _get_width)
- GDVIRTUAL0RC(int, _get_height)
+ GDVIRTUAL0RC_REQUIRED(int, _get_width)
+ GDVIRTUAL0RC_REQUIRED(int, _get_height)
GDVIRTUAL2RC(bool, _is_pixel_opaque, int, int)
GDVIRTUAL0RC(bool, _has_alpha)
@@ -93,13 +93,13 @@ class TextureLayered : public Texture {
protected:
static void _bind_methods();
- GDVIRTUAL0RC(Image::Format, _get_format)
- GDVIRTUAL0RC(uint32_t, _get_layered_type)
- GDVIRTUAL0RC(int, _get_width)
- GDVIRTUAL0RC(int, _get_height)
- GDVIRTUAL0RC(int, _get_layers)
- GDVIRTUAL0RC(bool, _has_mipmaps)
- GDVIRTUAL1RC(Ref<Image>, _get_layer_data, int)
+ GDVIRTUAL0RC_REQUIRED(Image::Format, _get_format)
+ GDVIRTUAL0RC_REQUIRED(uint32_t, _get_layered_type)
+ GDVIRTUAL0RC_REQUIRED(int, _get_width)
+ GDVIRTUAL0RC_REQUIRED(int, _get_height)
+ GDVIRTUAL0RC_REQUIRED(int, _get_layers)
+ GDVIRTUAL0RC_REQUIRED(bool, _has_mipmaps)
+ GDVIRTUAL1RC_REQUIRED(Ref<Image>, _get_layer_data, int)
public:
enum LayeredType {
LAYERED_TYPE_2D_ARRAY,
@@ -128,12 +128,12 @@ protected:
TypedArray<Image> _get_datai() const;
- GDVIRTUAL0RC(Image::Format, _get_format)
- GDVIRTUAL0RC(int, _get_width)
- GDVIRTUAL0RC(int, _get_height)
- GDVIRTUAL0RC(int, _get_depth)
- GDVIRTUAL0RC(bool, _has_mipmaps)
- GDVIRTUAL0RC(TypedArray<Image>, _get_data)
+ GDVIRTUAL0RC_REQUIRED(Image::Format, _get_format)
+ GDVIRTUAL0RC_REQUIRED(int, _get_width)
+ GDVIRTUAL0RC_REQUIRED(int, _get_height)
+ GDVIRTUAL0RC_REQUIRED(int, _get_depth)
+ GDVIRTUAL0RC_REQUIRED(bool, _has_mipmaps)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Image>, _get_data)
public:
virtual Image::Format get_format() const;
virtual int get_width() const;
diff --git a/scene/resources/video_stream.cpp b/scene/resources/video_stream.cpp
index 3d31fe0491..1fcc1821dc 100644
--- a/scene/resources/video_stream.cpp
+++ b/scene/resources/video_stream.cpp
@@ -119,7 +119,7 @@ Ref<Texture2D> VideoStreamPlayback::get_texture() const {
}
void VideoStreamPlayback::update(double p_delta) {
- GDVIRTUAL_REQUIRED_CALL(_update, p_delta);
+ GDVIRTUAL_CALL(_update, p_delta);
}
void VideoStreamPlayback::set_mix_callback(AudioMixCallback p_callback, void *p_userdata) {
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index dc54f4b769..3843cc99c4 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -56,7 +56,7 @@ protected:
GDVIRTUAL1(_seek, double);
GDVIRTUAL1(_set_audio_track, int);
GDVIRTUAL0RC(Ref<Texture2D>, _get_texture);
- GDVIRTUAL1(_update, double);
+ GDVIRTUAL1_REQUIRED(_update, double);
GDVIRTUAL0RC(int, _get_channels);
GDVIRTUAL0RC(int, _get_mix_rate);
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index f8a0336b37..140e588291 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -141,5 +141,6 @@ SceneStringNames::SceneStringNames() {
confirmed = StaticCString::create("confirmed");
text_changed = StaticCString::create("text_changed");
+ text_submitted = StaticCString::create("text_submitted");
value_changed = StaticCString::create("value_changed");
}
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index 381a161ad5..fc22be33b2 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -154,6 +154,7 @@ public:
StringName confirmed;
StringName text_changed;
+ StringName text_submitted;
StringName value_changed;
};
diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp
index 28a957cf6f..ac334eb764 100644
--- a/servers/audio/audio_effect.cpp
+++ b/servers/audio/audio_effect.cpp
@@ -31,7 +31,7 @@
#include "audio_effect.h"
void AudioEffectInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
- GDVIRTUAL_REQUIRED_CALL(_process, p_src_frames, p_dst_frames, p_frame_count);
+ GDVIRTUAL_CALL(_process, p_src_frames, p_dst_frames, p_frame_count);
}
bool AudioEffectInstance::process_silence() const {
bool ret = false;
@@ -48,7 +48,7 @@ void AudioEffectInstance::_bind_methods() {
Ref<AudioEffectInstance> AudioEffect::instantiate() {
Ref<AudioEffectInstance> ret;
- GDVIRTUAL_REQUIRED_CALL(_instantiate, ret);
+ GDVIRTUAL_CALL(_instantiate, ret);
return ret;
}
void AudioEffect::_bind_methods() {
diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h
index 9952246c20..cef5bfec5e 100644
--- a/servers/audio/audio_effect.h
+++ b/servers/audio/audio_effect.h
@@ -40,7 +40,7 @@ class AudioEffectInstance : public RefCounted {
GDCLASS(AudioEffectInstance, RefCounted);
protected:
- GDVIRTUAL3(_process, GDExtensionConstPtr<AudioFrame>, GDExtensionPtr<AudioFrame>, int)
+ GDVIRTUAL3_REQUIRED(_process, GDExtensionConstPtr<AudioFrame>, GDExtensionPtr<AudioFrame>, int)
GDVIRTUAL0RC(bool, _process_silence)
static void _bind_methods();
@@ -53,7 +53,7 @@ class AudioEffect : public Resource {
GDCLASS(AudioEffect, Resource);
protected:
- GDVIRTUAL0R(Ref<AudioEffectInstance>, _instantiate)
+ GDVIRTUAL0R_REQUIRED(Ref<AudioEffectInstance>, _instantiate)
static void _bind_methods();
public:
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index ece088a694..1886ebe1ac 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -72,7 +72,7 @@ void AudioStreamPlayback::seek(double p_time) {
int AudioStreamPlayback::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret);
+ GDVIRTUAL_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret);
return ret;
}
@@ -132,12 +132,12 @@ void AudioStreamPlaybackResampled::begin_resample() {
int AudioStreamPlaybackResampled::_mix_internal(AudioFrame *p_buffer, int p_frames) {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_mix_resampled, p_buffer, p_frames, ret);
+ GDVIRTUAL_CALL(_mix_resampled, p_buffer, p_frames, ret);
return ret;
}
float AudioStreamPlaybackResampled::get_stream_sampling_rate() {
float ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_stream_sampling_rate, ret);
+ GDVIRTUAL_CALL(_get_stream_sampling_rate, ret);
return ret;
}
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 7f2b68a796..3feaa53630 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -89,7 +89,7 @@ protected:
GDVIRTUAL0RC(int, _get_loop_count)
GDVIRTUAL0RC(double, _get_playback_position)
GDVIRTUAL1(_seek, double)
- GDVIRTUAL3R(int, _mix, GDExtensionPtr<AudioFrame>, float, int)
+ GDVIRTUAL3R_REQUIRED(int, _mix, GDExtensionPtr<AudioFrame>, float, int)
GDVIRTUAL0(_tag_used_streams)
GDVIRTUAL2(_set_parameter, const StringName &, const Variant &)
GDVIRTUAL1RC(Variant, _get_parameter, const StringName &)
@@ -141,8 +141,8 @@ protected:
virtual int _mix_internal(AudioFrame *p_buffer, int p_frames);
virtual float get_stream_sampling_rate();
- GDVIRTUAL2R(int, _mix_resampled, GDExtensionPtr<AudioFrame>, int)
- GDVIRTUAL0RC(float, _get_stream_sampling_rate)
+ GDVIRTUAL2R_REQUIRED(int, _mix_resampled, GDExtensionPtr<AudioFrame>, int)
+ GDVIRTUAL0RC_REQUIRED(float, _get_stream_sampling_rate)
static void _bind_methods();
diff --git a/servers/extensions/physics_server_2d_extension.h b/servers/extensions/physics_server_2d_extension.h
index 6e0277a7c6..7bbd84ddf4 100644
--- a/servers/extensions/physics_server_2d_extension.h
+++ b/servers/extensions/physics_server_2d_extension.h
@@ -127,53 +127,53 @@ protected:
static void _bind_methods();
bool is_body_excluded_from_query(const RID &p_body) const;
- GDVIRTUAL7R(bool, _intersect_ray, const Vector2 &, const Vector2 &, uint32_t, bool, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionRayResult>)
- GDVIRTUAL7R(int, _intersect_point, const Vector2 &, ObjectID, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int)
- GDVIRTUAL9R(int, _intersect_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int)
- GDVIRTUAL9R(bool, _cast_motion, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>)
- GDVIRTUAL10R(bool, _collide_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>)
- GDVIRTUAL8R(bool, _rest_info, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeRestInfo>)
+ GDVIRTUAL7R_REQUIRED(bool, _intersect_ray, const Vector2 &, const Vector2 &, uint32_t, bool, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionRayResult>)
+ GDVIRTUAL7R_REQUIRED(int, _intersect_point, const Vector2 &, ObjectID, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int)
+ GDVIRTUAL9R_REQUIRED(int, _intersect_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int)
+ GDVIRTUAL9R_REQUIRED(bool, _cast_motion, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>)
+ GDVIRTUAL10R_REQUIRED(bool, _collide_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>)
+ GDVIRTUAL8R_REQUIRED(bool, _rest_info, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeRestInfo>)
public:
virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override {
exclude = &p_parameters.exclude;
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, &r_result, ret);
+ GDVIRTUAL_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, &r_result, ret);
exclude = nullptr;
return ret;
}
virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override {
exclude = &p_parameters.exclude;
int ret = false;
- GDVIRTUAL_REQUIRED_CALL(_intersect_point, p_parameters.position, p_parameters.canvas_instance_id, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret);
+ GDVIRTUAL_CALL(_intersect_point, p_parameters.position, p_parameters.canvas_instance_id, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret);
exclude = nullptr;
return ret;
}
virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override {
exclude = &p_parameters.exclude;
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret);
+ GDVIRTUAL_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret);
exclude = nullptr;
return ret;
}
virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe) override {
exclude = &p_parameters.exclude;
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, ret);
+ GDVIRTUAL_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, ret);
exclude = nullptr;
return ret;
}
virtual bool collide_shape(const ShapeParameters &p_parameters, Vector2 *r_results, int p_result_max, int &r_result_count) override {
exclude = &p_parameters.exclude;
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret);
+ GDVIRTUAL_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret);
exclude = nullptr;
return ret;
}
virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override {
exclude = &p_parameters.exclude;
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret);
+ GDVIRTUAL_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret);
exclude = nullptr;
return ret;
}
@@ -191,9 +191,9 @@ class PhysicsServer2DExtension : public PhysicsServer2D {
protected:
static void _bind_methods();
- GDVIRTUAL9R(bool, _shape_collide, RID, const Transform2D &, const Vector2 &, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>)
+ GDVIRTUAL9R_REQUIRED(bool, _shape_collide, RID, const Transform2D &, const Vector2 &, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>)
- GDVIRTUAL8R(bool, _body_collide_shape, RID, int, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>)
+ GDVIRTUAL8R_REQUIRED(bool, _body_collide_shape, RID, int, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>)
public:
// The warning is valid, but unavoidable. If the function is not overridden it will error anyway.
@@ -218,7 +218,7 @@ public:
virtual bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) override {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_shape_collide, p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, &r_result_count, ret);
+ GDVIRTUAL_CALL(_shape_collide, p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, &r_result_count, ret);
return ret;
}
@@ -354,11 +354,11 @@ public:
EXBIND2(body_add_collision_exception, RID, RID)
EXBIND2(body_remove_collision_exception, RID, RID)
- GDVIRTUAL1RC(TypedArray<RID>, _body_get_collision_exceptions, RID)
+ GDVIRTUAL1RC_REQUIRED(TypedArray<RID>, _body_get_collision_exceptions, RID)
void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override {
TypedArray<RID> ret;
- GDVIRTUAL_REQUIRED_CALL(_body_get_collision_exceptions, p_body, ret);
+ GDVIRTUAL_CALL(_body_get_collision_exceptions, p_body, ret);
for (int i = 0; i < ret.size(); i++) {
p_exceptions->push_back(ret[i]);
}
@@ -378,7 +378,7 @@ public:
virtual bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) override {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_body_collide_shape, p_body, p_body_shape, p_shape, p_shape_xform, p_motion, r_results, p_result_max, &r_result_count, ret);
+ GDVIRTUAL_CALL(_body_collide_shape, p_body, p_body_shape, p_shape, p_shape_xform, p_motion, r_results, p_result_max, &r_result_count, ret);
return ret;
}
@@ -386,7 +386,7 @@ public:
EXBIND1R(PhysicsDirectBodyState2D *, body_get_direct_state, RID)
- GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform2D &, const Vector2 &, real_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionMotionResult>)
+ GDVIRTUAL7RC_REQUIRED(bool, _body_test_motion, RID, const Transform2D &, const Vector2 &, real_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionMotionResult>)
thread_local static const HashSet<RID> *exclude_bodies;
thread_local static const HashSet<ObjectID> *exclude_objects;
@@ -398,7 +398,7 @@ public:
bool ret = false;
exclude_bodies = &p_parameters.exclude_bodies;
exclude_objects = &p_parameters.exclude_objects;
- GDVIRTUAL_REQUIRED_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.collide_separation_ray, p_parameters.recovery_as_collision, r_result, ret);
+ GDVIRTUAL_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.collide_separation_ray, p_parameters.recovery_as_collision, r_result, ret);
exclude_bodies = nullptr;
exclude_objects = nullptr;
return ret;
@@ -432,9 +432,9 @@ public:
/* MISC */
- GDVIRTUAL1(_free_rid, RID)
+ GDVIRTUAL1_REQUIRED(_free_rid, RID)
virtual void free(RID p_rid) override {
- GDVIRTUAL_REQUIRED_CALL(_free_rid, p_rid);
+ GDVIRTUAL_CALL(_free_rid, p_rid);
}
EXBIND1(set_active, bool)
diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h
index eb8b627245..b808b80b93 100644
--- a/servers/extensions/physics_server_3d_extension.h
+++ b/servers/extensions/physics_server_3d_extension.h
@@ -129,61 +129,61 @@ protected:
static void _bind_methods();
bool is_body_excluded_from_query(const RID &p_body) const;
- GDVIRTUAL9R(bool, _intersect_ray, const Vector3 &, const Vector3 &, uint32_t, bool, bool, bool, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionRayResult>)
- GDVIRTUAL6R(int, _intersect_point, const Vector3 &, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int)
- GDVIRTUAL9R(int, _intersect_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int)
- GDVIRTUAL10R(bool, _cast_motion, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>)
- GDVIRTUAL10R(bool, _collide_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector3>, int, GDExtensionPtr<int>)
- GDVIRTUAL8R(bool, _rest_info, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>)
- GDVIRTUAL2RC(Vector3, _get_closest_point_to_object_volume, RID, const Vector3 &)
+ GDVIRTUAL9R_REQUIRED(bool, _intersect_ray, const Vector3 &, const Vector3 &, uint32_t, bool, bool, bool, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionRayResult>)
+ GDVIRTUAL6R_REQUIRED(int, _intersect_point, const Vector3 &, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int)
+ GDVIRTUAL9R_REQUIRED(int, _intersect_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int)
+ GDVIRTUAL10R_REQUIRED(bool, _cast_motion, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>)
+ GDVIRTUAL10R_REQUIRED(bool, _collide_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector3>, int, GDExtensionPtr<int>)
+ GDVIRTUAL8R_REQUIRED(bool, _rest_info, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>)
+ GDVIRTUAL2RC_REQUIRED(Vector3, _get_closest_point_to_object_volume, RID, const Vector3 &)
public:
virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override {
exclude = &p_parameters.exclude;
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, p_parameters.hit_back_faces, p_parameters.pick_ray, &r_result, ret);
+ GDVIRTUAL_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, p_parameters.hit_back_faces, p_parameters.pick_ray, &r_result, ret);
exclude = nullptr;
return ret;
}
virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override {
exclude = &p_parameters.exclude;
int ret = false;
- GDVIRTUAL_REQUIRED_CALL(_intersect_point, p_parameters.position, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret);
+ GDVIRTUAL_CALL(_intersect_point, p_parameters.position, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret);
exclude = nullptr;
return ret;
}
virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override {
exclude = &p_parameters.exclude;
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret);
+ GDVIRTUAL_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret);
exclude = nullptr;
return ret;
}
virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe, ShapeRestInfo *r_info = nullptr) override {
exclude = &p_parameters.exclude;
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, r_info, ret);
+ GDVIRTUAL_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, r_info, ret);
exclude = nullptr;
return ret;
}
virtual bool collide_shape(const ShapeParameters &p_parameters, Vector3 *r_results, int p_result_max, int &r_result_count) override {
exclude = &p_parameters.exclude;
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret);
+ GDVIRTUAL_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret);
exclude = nullptr;
return ret;
}
virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override {
exclude = &p_parameters.exclude;
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret);
+ GDVIRTUAL_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret);
exclude = nullptr;
return ret;
}
virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override {
Vector3 ret;
- GDVIRTUAL_REQUIRED_CALL(_get_closest_point_to_object_volume, p_object, p_point, ret);
+ GDVIRTUAL_CALL(_get_closest_point_to_object_volume, p_object, p_point, ret);
return ret;
}
@@ -359,11 +359,11 @@ public:
EXBIND2(body_add_collision_exception, RID, RID)
EXBIND2(body_remove_collision_exception, RID, RID)
- GDVIRTUAL1RC(TypedArray<RID>, _body_get_collision_exceptions, RID)
+ GDVIRTUAL1RC_REQUIRED(TypedArray<RID>, _body_get_collision_exceptions, RID)
void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override {
TypedArray<RID> ret;
- GDVIRTUAL_REQUIRED_CALL(_body_get_collision_exceptions, p_body, ret);
+ GDVIRTUAL_CALL(_body_get_collision_exceptions, p_body, ret);
for (int i = 0; i < ret.size(); i++) {
p_exceptions->push_back(ret[i]);
}
@@ -383,7 +383,7 @@ public:
EXBIND2(body_set_ray_pickable, RID, bool)
- GDVIRTUAL8RC(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionMotionResult>)
+ GDVIRTUAL8RC_REQUIRED(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionMotionResult>)
thread_local static const HashSet<RID> *exclude_bodies;
thread_local static const HashSet<ObjectID> *exclude_objects;
@@ -395,7 +395,7 @@ public:
bool ret = false;
exclude_bodies = &p_parameters.exclude_bodies;
exclude_objects = &p_parameters.exclude_objects;
- GDVIRTUAL_REQUIRED_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.max_collisions, p_parameters.collide_separation_ray, p_parameters.recovery_as_collision, r_result, ret);
+ GDVIRTUAL_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.max_collisions, p_parameters.collide_separation_ray, p_parameters.recovery_as_collision, r_result, ret);
exclude_bodies = nullptr;
exclude_objects = nullptr;
return ret;
@@ -423,11 +423,11 @@ public:
EXBIND2(soft_body_add_collision_exception, RID, RID)
EXBIND2(soft_body_remove_collision_exception, RID, RID)
- GDVIRTUAL1RC(TypedArray<RID>, _soft_body_get_collision_exceptions, RID)
+ GDVIRTUAL1RC_REQUIRED(TypedArray<RID>, _soft_body_get_collision_exceptions, RID)
void soft_body_get_collision_exceptions(RID p_soft_body, List<RID> *p_exceptions) override {
TypedArray<RID> ret;
- GDVIRTUAL_REQUIRED_CALL(_soft_body_get_collision_exceptions, p_soft_body, ret);
+ GDVIRTUAL_CALL(_soft_body_get_collision_exceptions, p_soft_body, ret);
for (int i = 0; i < ret.size(); i++) {
p_exceptions->push_back(ret[i]);
}
@@ -520,9 +520,9 @@ public:
/* MISC */
- GDVIRTUAL1(_free_rid, RID)
+ GDVIRTUAL1_REQUIRED(_free_rid, RID)
virtual void free(RID p_rid) override {
- GDVIRTUAL_REQUIRED_CALL(_free_rid, p_rid);
+ GDVIRTUAL_CALL(_free_rid, p_rid);
}
EXBIND1(set_active, bool)
diff --git a/servers/movie_writer/movie_writer.cpp b/servers/movie_writer/movie_writer.cpp
index aebed4b432..14e920d8cd 100644
--- a/servers/movie_writer/movie_writer.cpp
+++ b/servers/movie_writer/movie_writer.cpp
@@ -54,40 +54,40 @@ MovieWriter *MovieWriter::find_writer_for_file(const String &p_file) {
uint32_t MovieWriter::get_audio_mix_rate() const {
uint32_t ret = 48000;
- GDVIRTUAL_REQUIRED_CALL(_get_audio_mix_rate, ret);
+ GDVIRTUAL_CALL(_get_audio_mix_rate, ret);
return ret;
}
AudioServer::SpeakerMode MovieWriter::get_audio_speaker_mode() const {
AudioServer::SpeakerMode ret = AudioServer::SPEAKER_MODE_STEREO;
- GDVIRTUAL_REQUIRED_CALL(_get_audio_speaker_mode, ret);
+ GDVIRTUAL_CALL(_get_audio_speaker_mode, ret);
return ret;
}
Error MovieWriter::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) {
Error ret = ERR_UNCONFIGURED;
- GDVIRTUAL_REQUIRED_CALL(_write_begin, p_movie_size, p_fps, p_base_path, ret);
+ GDVIRTUAL_CALL(_write_begin, p_movie_size, p_fps, p_base_path, ret);
return ret;
}
Error MovieWriter::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) {
Error ret = ERR_UNCONFIGURED;
- GDVIRTUAL_REQUIRED_CALL(_write_frame, p_image, p_audio_data, ret);
+ GDVIRTUAL_CALL(_write_frame, p_image, p_audio_data, ret);
return ret;
}
void MovieWriter::write_end() {
- GDVIRTUAL_REQUIRED_CALL(_write_end);
+ GDVIRTUAL_CALL(_write_end);
}
bool MovieWriter::handles_file(const String &p_path) const {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_handles_file, p_path, ret);
+ GDVIRTUAL_CALL(_handles_file, p_path, ret);
return ret;
}
void MovieWriter::get_supported_extensions(List<String> *r_extensions) const {
Vector<String> exts;
- GDVIRTUAL_REQUIRED_CALL(_get_supported_extensions, exts);
+ GDVIRTUAL_CALL(_get_supported_extensions, exts);
for (int i = 0; i < exts.size(); i++) {
r_extensions->push_back(exts[i]);
}
diff --git a/servers/movie_writer/movie_writer.h b/servers/movie_writer/movie_writer.h
index 4757de203c..e1dc8ef8cf 100644
--- a/servers/movie_writer/movie_writer.h
+++ b/servers/movie_writer/movie_writer.h
@@ -63,15 +63,15 @@ protected:
virtual Error write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data);
virtual void write_end();
- GDVIRTUAL0RC(uint32_t, _get_audio_mix_rate)
- GDVIRTUAL0RC(AudioServer::SpeakerMode, _get_audio_speaker_mode)
+ GDVIRTUAL0RC_REQUIRED(uint32_t, _get_audio_mix_rate)
+ GDVIRTUAL0RC_REQUIRED(AudioServer::SpeakerMode, _get_audio_speaker_mode)
- GDVIRTUAL1RC(bool, _handles_file, const String &)
- GDVIRTUAL0RC(Vector<String>, _get_supported_extensions)
+ GDVIRTUAL1RC_REQUIRED(bool, _handles_file, const String &)
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_supported_extensions)
- GDVIRTUAL3R(Error, _write_begin, const Size2i &, uint32_t, const String &)
- GDVIRTUAL2R(Error, _write_frame, const Ref<Image> &, GDExtensionConstPtr<int32_t>)
- GDVIRTUAL0(_write_end)
+ GDVIRTUAL3R_REQUIRED(Error, _write_begin, const Size2i &, uint32_t, const String &)
+ GDVIRTUAL2R_REQUIRED(Error, _write_frame, const Ref<Image> &, GDExtensionConstPtr<int32_t>)
+ GDVIRTUAL0_REQUIRED(_write_end)
static void _bind_methods();
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index ee48151863..312b67ada9 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -37,13 +37,13 @@
#include "core/variant/typed_array.h"
void PhysicsServer3DRenderingServerHandler::set_vertex(int p_vertex_id, const Vector3 &p_vertex) {
- GDVIRTUAL_REQUIRED_CALL(_set_vertex, p_vertex_id, p_vertex);
+ GDVIRTUAL_CALL(_set_vertex, p_vertex_id, p_vertex);
}
void PhysicsServer3DRenderingServerHandler::set_normal(int p_vertex_id, const Vector3 &p_normal) {
- GDVIRTUAL_REQUIRED_CALL(_set_normal, p_vertex_id, p_normal);
+ GDVIRTUAL_CALL(_set_normal, p_vertex_id, p_normal);
}
void PhysicsServer3DRenderingServerHandler::set_aabb(const AABB &p_aabb) {
- GDVIRTUAL_REQUIRED_CALL(_set_aabb, p_aabb);
+ GDVIRTUAL_CALL(_set_aabb, p_aabb);
}
void PhysicsServer3DRenderingServerHandler::_bind_methods() {
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index ea785fa03f..33def7cf8d 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -213,9 +213,9 @@ public:
class PhysicsServer3DRenderingServerHandler : public Object {
GDCLASS(PhysicsServer3DRenderingServerHandler, Object)
protected:
- GDVIRTUAL2(_set_vertex, int, const Vector3 &)
- GDVIRTUAL2(_set_normal, int, const Vector3 &)
- GDVIRTUAL1(_set_aabb, const AABB &)
+ GDVIRTUAL2_REQUIRED(_set_vertex, int, const Vector3 &)
+ GDVIRTUAL2_REQUIRED(_set_normal, int, const Vector3 &)
+ GDVIRTUAL1_REQUIRED(_set_aabb, const AABB &)
static void _bind_methods();
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index aca85ce497..307898232d 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -4261,6 +4261,11 @@ RenderForwardClustered::RenderForwardClustered() {
defines += "\n#define SDFGI_OCT_SIZE " + itos(gi.sdfgi_get_lightprobe_octahedron_size()) + "\n";
defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n";
+ bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading");
+ if (force_vertex_shading) {
+ defines += "\n#define USE_VERTEX_LIGHTING\n";
+ }
+
{
//lightmaps
scene_state.max_lightmaps = MAX_LIGHTMAPS;
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 6846c3f693..ee5b5ef1d8 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -730,13 +730,20 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
+
+ bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading");
+ if (!force_vertex_shading) {
+ // If forcing vertex shading, this will be defined already.
+ actions.render_mode_defines["vertex_lighting"] = "#define USE_VERTEX_LIGHTING\n";
+ }
+
actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
actions.base_texture_binding_index = 1;
actions.texture_layout_set = RenderForwardClustered::MATERIAL_UNIFORM_SET;
actions.base_uniform_string = "material.";
- actions.base_varying_index = 12;
+ actions.base_varying_index = 14;
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 8a02ec0eb5..fa8796fae6 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -2800,6 +2800,11 @@ RenderForwardMobile::RenderForwardMobile() {
// defines += "\n#define SDFGI_OCT_SIZE " + itos(gi.sdfgi_get_lightprobe_octahedron_size()) + "\n";
defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n";
+ bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading");
+ if (force_vertex_shading) {
+ defines += "\n#define USE_VERTEX_LIGHTING\n";
+ }
+
{
//lightmaps
scene_state.max_lightmaps = 2;
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 08982096c5..5dec4d8f21 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -633,6 +633,13 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
+
+ bool force_vertex_shading = GLOBAL_GET("rendering/shading/overrides/force_vertex_shading");
+ if (!force_vertex_shading) {
+ // If forcing vertex shading, this will be defined already.
+ actions.render_mode_defines["vertex_lighting"] = "#define USE_VERTEX_LIGHTING\n";
+ }
+
actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 57497eb207..5441e28be0 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1974,6 +1974,12 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
default_canvas_texture = texture_storage->canvas_texture_allocate();
texture_storage->canvas_texture_initialize(default_canvas_texture);
+ RendererRD::TextureStorage::CanvasTextureInfo info = RendererRD::TextureStorage::get_singleton()->canvas_texture_get_info(default_canvas_texture, default_filter, default_repeat, false, false);
+ default_texture_info.diffuse = info.diffuse;
+ default_texture_info.normal = info.normal;
+ default_texture_info.specular = info.specular;
+ default_texture_info.sampler = info.sampler;
+
state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size");
//create functions for shader and material
@@ -2219,7 +2225,7 @@ void RendererCanvasRenderRD::_render_batch_items(RenderTarget p_to_render_target
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.default_transforms_uniform_set, TRANSFORMS_UNIFORM_SET);
Item *current_clip = nullptr;
- state.current_tex_uniform_set = RID();
+ state.current_batch_uniform_set = RID();
for (uint32_t i = 0; i <= state.current_batch_index; i++) {
Batch *current_batch = &state.canvas_instance_batches[i];
@@ -2337,11 +2343,11 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
instance_data->world[i] = world[i];
}
- instance_data->flags = base_flags | r_current_batch->tex_flags; // Reset on each command for safety, keep canvas texture binding config.
+ instance_data->flags = base_flags | r_current_batch->tex_info.flags; // Reset on each command for safety, keep canvas texture binding config.
- instance_data->color_texture_pixel_size[0] = r_current_batch->tex_texpixel_size.width;
- instance_data->color_texture_pixel_size[1] = r_current_batch->tex_texpixel_size.height;
- instance_data->specular_shininess = r_current_batch->tex_specular_shininess;
+ instance_data->color_texture_pixel_size[0] = r_current_batch->tex_info.texpixel_size.width;
+ instance_data->color_texture_pixel_size[1] = r_current_batch->tex_info.texpixel_size.height;
+ instance_data->specular_shininess = r_current_batch->tex_info.specular_shininess;
return instance_data;
};
@@ -2373,10 +2379,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
bool has_msdf = bool(rect->flags & CANVAS_RECT_MSDF);
TextureState tex_state(rect->texture, texture_filter, texture_repeat, has_msdf, use_linear_colors);
- if (tex_state != r_current_batch->tex_state) {
+ if (tex_state != r_current_batch->tex_info.state) {
r_current_batch = _new_batch(r_batch_broken);
- r_current_batch->set_tex_state(tex_state);
- _prepare_batch_texture(r_current_batch, rect->texture);
+ r_current_batch->tex_info.state = tex_state;
+ _prepare_batch_texture_info(r_current_batch, rect->texture);
}
Color modulated = rect->modulate * base_color;
@@ -2399,7 +2405,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
Rect2 dst_rect;
if (rect->texture.is_valid()) {
- src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * r_current_batch->tex_texpixel_size, rect->source.size * r_current_batch->tex_texpixel_size) : Rect2(0, 0, 1, 1);
+ src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * r_current_batch->tex_info.texpixel_size, rect->source.size * r_current_batch->tex_info.texpixel_size) : Rect2(0, 0, 1, 1);
dst_rect = Rect2(rect->rect.position, rect->rect.size);
if (dst_rect.size.width < 0) {
@@ -2484,10 +2490,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
}
TextureState tex_state(np->texture, texture_filter, texture_repeat, false, use_linear_colors);
- if (tex_state != r_current_batch->tex_state) {
+ if (tex_state != r_current_batch->tex_info.state) {
r_current_batch = _new_batch(r_batch_broken);
- r_current_batch->set_tex_state(tex_state);
- _prepare_batch_texture(r_current_batch, np->texture);
+ r_current_batch->tex_info.state = tex_state;
+ _prepare_batch_texture_info(r_current_batch, np->texture);
}
InstanceData *instance_data = new_instance_data();
@@ -2499,7 +2505,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
src_rect = Rect2(0, 0, 1, 1);
} else {
if (np->source != Rect2()) {
- src_rect = Rect2(np->source.position.x * r_current_batch->tex_texpixel_size.width, np->source.position.y * r_current_batch->tex_texpixel_size.height, np->source.size.x * r_current_batch->tex_texpixel_size.width, np->source.size.y * r_current_batch->tex_texpixel_size.height);
+ src_rect = Rect2(np->source.position.x * r_current_batch->tex_info.texpixel_size.width, np->source.position.y * r_current_batch->tex_info.texpixel_size.height, np->source.size.x * r_current_batch->tex_info.texpixel_size.width, np->source.size.y * r_current_batch->tex_info.texpixel_size.height);
instance_data->color_texture_pixel_size[0] = 1.0 / np->source.size.width;
instance_data->color_texture_pixel_size[1] = 1.0 / np->source.size.height;
} else {
@@ -2553,10 +2559,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
r_current_batch->command = c;
TextureState tex_state(polygon->texture, texture_filter, texture_repeat, false, use_linear_colors);
- if (tex_state != r_current_batch->tex_state) {
+ if (tex_state != r_current_batch->tex_info.state) {
r_current_batch = _new_batch(r_batch_broken);
- r_current_batch->set_tex_state(tex_state);
- _prepare_batch_texture(r_current_batch, polygon->texture);
+ r_current_batch->tex_info.state = tex_state;
+ _prepare_batch_texture_info(r_current_batch, polygon->texture);
}
// pipeline variant
@@ -2596,10 +2602,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
r_current_batch->pipeline_variant = variant[primitive->point_count - 1];
TextureState tex_state(primitive->texture, texture_filter, texture_repeat, false, use_linear_colors);
- if (tex_state != r_current_batch->tex_state) {
+ if (tex_state != r_current_batch->tex_info.state) {
r_current_batch = _new_batch(r_batch_broken);
- r_current_batch->set_tex_state(tex_state);
- _prepare_batch_texture(r_current_batch, primitive->texture);
+ r_current_batch->tex_info.state = tex_state;
+ _prepare_batch_texture_info(r_current_batch, primitive->texture);
}
}
@@ -2657,8 +2663,8 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
if (c->type == Item::Command::TYPE_MESH) {
const Item::CommandMesh *m = static_cast<const Item::CommandMesh *>(c);
TextureState tex_state(m->texture, texture_filter, texture_repeat, false, use_linear_colors);
- r_current_batch->set_tex_state(tex_state);
- _prepare_batch_texture(r_current_batch, m->texture);
+ r_current_batch->tex_info.state = tex_state;
+ _prepare_batch_texture_info(r_current_batch, m->texture);
instance_data = new_instance_data();
r_current_batch->mesh_instance_count = 1;
@@ -2680,8 +2686,8 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
}
TextureState tex_state(mm->texture, texture_filter, texture_repeat, false, use_linear_colors);
- r_current_batch->set_tex_state(tex_state);
- _prepare_batch_texture(r_current_batch, mm->texture);
+ r_current_batch->tex_info.state = tex_state;
+ _prepare_batch_texture_info(r_current_batch, mm->texture);
instance_data = new_instance_data();
instance_data->flags |= 1; // multimesh, trails disabled
@@ -2698,8 +2704,8 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
const Item::CommandParticles *pt = static_cast<const Item::CommandParticles *>(c);
TextureState tex_state(pt->texture, texture_filter, texture_repeat, false, use_linear_colors);
- r_current_batch->set_tex_state(tex_state);
- _prepare_batch_texture(r_current_batch, pt->texture);
+ r_current_batch->tex_info.state = tex_state;
+ _prepare_batch_texture_info(r_current_batch, pt->texture);
instance_data = new_instance_data();
@@ -2795,7 +2801,20 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV
ERR_FAIL_NULL(p_batch->command);
- _bind_canvas_texture(p_draw_list, p_batch->tex_uniform_set);
+ {
+ RD::Uniform u_diffuse(RD::UNIFORM_TYPE_TEXTURE, 0, p_batch->tex_info.diffuse);
+ RD::Uniform u_normal(RD::UNIFORM_TYPE_TEXTURE, 1, p_batch->tex_info.normal);
+ RD::Uniform u_specular(RD::UNIFORM_TYPE_TEXTURE, 2, p_batch->tex_info.specular);
+ RD::Uniform u_sampler(RD::UNIFORM_TYPE_SAMPLER, 3, p_batch->tex_info.sampler);
+ RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 4, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]);
+
+ RID uniform_set = uniform_set_cache->get_cache(shader.default_version_rd_shader, BATCH_UNIFORM_SET, u_diffuse, u_normal, u_specular, u_sampler, u_instance_data);
+
+ if (state.current_batch_uniform_set != uniform_set) {
+ state.current_batch_uniform_set = uniform_set;
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, uniform_set, BATCH_UNIFORM_SET);
+ }
+ }
switch (p_batch->command_type) {
case Item::Command::TYPE_RECT:
@@ -2810,13 +2829,6 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV
PushConstant push_constant;
push_constant.base_instance_index = p_batch->start;
RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant));
-
- RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 0, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]);
- RD::get_singleton()->draw_list_bind_uniform_set(
- p_draw_list,
- uniform_set_cache->get_cache(shader.default_version_rd_shader, INSTANCE_DATA_UNIFORM_SET, u_instance_data),
- INSTANCE_DATA_UNIFORM_SET);
-
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array);
RD::get_singleton()->draw_list_draw(p_draw_list, true, p_batch->instance_count);
@@ -2839,13 +2851,6 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV
PushConstant push_constant;
push_constant.base_instance_index = p_batch->start;
RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant));
-
- RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 0, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]);
- RD::get_singleton()->draw_list_bind_uniform_set(
- p_draw_list,
- uniform_set_cache->get_cache(shader.default_version_rd_shader, INSTANCE_DATA_UNIFORM_SET, u_instance_data),
- INSTANCE_DATA_UNIFORM_SET);
-
RD::get_singleton()->draw_list_bind_vertex_array(p_draw_list, pb->vertex_array);
if (pb->indices.is_valid()) {
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, pb->indices);
@@ -2868,13 +2873,6 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV
PushConstant push_constant;
push_constant.base_instance_index = p_batch->start;
RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant));
-
- RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 0, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]);
- RD::get_singleton()->draw_list_bind_uniform_set(
- p_draw_list,
- uniform_set_cache->get_cache(shader.default_version_rd_shader, INSTANCE_DATA_UNIFORM_SET, u_instance_data),
- INSTANCE_DATA_UNIFORM_SET);
-
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3u, primitive->point_count) - 1]);
uint32_t instance_count = p_batch->instance_count;
RD::get_singleton()->draw_list_draw(p_draw_list, true, instance_count);
@@ -2934,12 +2932,6 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV
break;
}
- RD::Uniform u_instance_data(RD::UNIFORM_TYPE_STORAGE_BUFFER, 0, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[p_batch->instance_buffer_index]);
- RD::get_singleton()->draw_list_bind_uniform_set(
- p_draw_list,
- uniform_set_cache->get_cache(shader.default_version_rd_shader, INSTANCE_DATA_UNIFORM_SET, u_instance_data),
- INSTANCE_DATA_UNIFORM_SET);
-
uint32_t surf_count = mesh_storage->mesh_get_surface_count(mesh);
static const PipelineVariant variant[RS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_LINES_STRIP, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLE_STRIP };
@@ -3046,60 +3038,46 @@ void RendererCanvasRenderRD::_allocate_instance_buffer() {
state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.push_back(buf);
}
-void RendererCanvasRenderRD::_prepare_batch_texture(Batch *p_current_batch, RID p_texture) const {
+void RendererCanvasRenderRD::_prepare_batch_texture_info(Batch *p_current_batch, RID p_texture) const {
if (p_texture.is_null()) {
p_texture = default_canvas_texture;
}
- Color specular_shininess;
- bool use_normal;
- bool use_specular;
- Size2i size;
- bool success = RendererRD::TextureStorage::get_singleton()->canvas_texture_get_uniform_set(
- p_texture,
- p_current_batch->tex_state.texture_filter(),
- p_current_batch->tex_state.texture_repeat(),
- shader.default_version_rd_shader,
- CANVAS_TEXTURE_UNIFORM_SET,
- p_current_batch->tex_state.linear_colors(),
- p_current_batch->tex_uniform_set,
- size,
- specular_shininess,
- use_normal,
- use_specular,
- p_current_batch->tex_state.texture_is_data());
+ RendererRD::TextureStorage::CanvasTextureInfo info =
+ RendererRD::TextureStorage::get_singleton()->canvas_texture_get_info(
+ p_texture,
+ p_current_batch->tex_info.state.texture_filter(),
+ p_current_batch->tex_info.state.texture_repeat(),
+ p_current_batch->tex_info.state.linear_colors(),
+ p_current_batch->tex_info.state.texture_is_data());
+
// something odd happened
- if (!success) {
- _prepare_batch_texture(p_current_batch, default_canvas_texture);
+ if (info.is_null()) {
+ _prepare_batch_texture_info(p_current_batch, default_canvas_texture);
return;
}
- // cache values to be copied to instance data
- if (specular_shininess.a < 0.999) {
- p_current_batch->tex_flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
- }
+ p_current_batch->tex_info.diffuse = info.diffuse;
+ p_current_batch->tex_info.normal = info.normal;
+ p_current_batch->tex_info.specular = info.specular;
+ p_current_batch->tex_info.sampler = info.sampler;
- if (use_normal) {
- p_current_batch->tex_flags |= FLAGS_DEFAULT_NORMAL_MAP_USED;
+ // cache values to be copied to instance data
+ if (info.specular_color.a < 0.999) {
+ p_current_batch->tex_info.flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
}
- uint8_t a = uint8_t(CLAMP(specular_shininess.a * 255.0, 0.0, 255.0));
- uint8_t b = uint8_t(CLAMP(specular_shininess.b * 255.0, 0.0, 255.0));
- uint8_t g = uint8_t(CLAMP(specular_shininess.g * 255.0, 0.0, 255.0));
- uint8_t r = uint8_t(CLAMP(specular_shininess.r * 255.0, 0.0, 255.0));
- p_current_batch->tex_specular_shininess = uint32_t(a) << 24 | uint32_t(b) << 16 | uint32_t(g) << 8 | uint32_t(r);
-
- p_current_batch->tex_texpixel_size = Vector2(1.0 / float(size.width), 1.0 / float(size.height));
-}
-
-void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RID p_uniform_set) {
- if (state.current_tex_uniform_set == p_uniform_set) {
- return;
+ if (info.use_normal) {
+ p_current_batch->tex_info.flags |= FLAGS_DEFAULT_NORMAL_MAP_USED;
}
- state.current_tex_uniform_set = p_uniform_set;
+ uint8_t a = uint8_t(CLAMP(info.specular_color.a * 255.0, 0.0, 255.0));
+ uint8_t b = uint8_t(CLAMP(info.specular_color.b * 255.0, 0.0, 255.0));
+ uint8_t g = uint8_t(CLAMP(info.specular_color.g * 255.0, 0.0, 255.0));
+ uint8_t r = uint8_t(CLAMP(info.specular_color.r * 255.0, 0.0, 255.0));
+ p_current_batch->tex_info.specular_shininess = uint32_t(a) << 24 | uint32_t(b) << 16 | uint32_t(g) << 8 | uint32_t(r);
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, p_uniform_set, CANVAS_TEXTURE_UNIFORM_SET);
+ p_current_batch->tex_info.texpixel_size = Vector2(1.0 / float(info.size.width), 1.0 / float(info.size.height));
}
RendererCanvasRenderRD::~RendererCanvasRenderRD() {
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 8d90cd23ce..b0f4a4595a 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -45,8 +45,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
BASE_UNIFORM_SET = 0,
MATERIAL_UNIFORM_SET = 1,
TRANSFORMS_UNIFORM_SET = 2,
- CANVAS_TEXTURE_UNIFORM_SET = 3,
- INSTANCE_DATA_UNIFORM_SET = 4,
+ BATCH_UNIFORM_SET = 3,
};
const int SAMPLERS_BINDING_FIRST_INDEX = 10;
@@ -423,24 +422,25 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
}
};
+ struct TextureInfo {
+ TextureState state;
+ uint32_t specular_shininess = 0;
+ uint32_t flags = 0;
+ Vector2 texpixel_size;
+
+ RID diffuse;
+ RID normal;
+ RID specular;
+ RID sampler;
+ };
+
struct Batch {
// Position in the UBO measured in bytes
uint32_t start = 0;
uint32_t instance_count = 0;
uint32_t instance_buffer_index = 0;
- TextureState tex_state;
- RID tex_uniform_set;
-
- // The following tex_ prefixed fields are used to cache the texture data for the current batch.
- // These values are applied to new InstanceData for the batch
-
- // The cached specular shininess derived from the current texture.
- uint32_t tex_specular_shininess = 0;
- // The cached texture flags, such as FLAGS_DEFAULT_SPECULAR_MAP_USED and FLAGS_DEFAULT_NORMAL_MAP_USED
- uint32_t tex_flags = 0;
- // The cached texture pixel size.
- Vector2 tex_texpixel_size;
+ TextureInfo tex_info;
Color modulate = Color(1.0, 1.0, 1.0, 1.0);
@@ -462,14 +462,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
uint32_t mesh_instance_count;
};
bool has_blend = false;
-
- void set_tex_state(TextureState &p_tex_state) {
- tex_state = p_tex_state;
- tex_uniform_set = RID();
- tex_texpixel_size = Size2();
- tex_specular_shininess = 0;
- tex_flags = 0;
- }
};
struct DataBuffer {
@@ -509,7 +501,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
uint32_t max_instances_per_buffer = 16384;
uint32_t max_instance_buffer_size = 16384 * sizeof(InstanceData);
- RID current_tex_uniform_set;
+ RID current_batch_uniform_set;
LightUniform *light_uniforms = nullptr;
@@ -532,6 +524,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
Item *items[MAX_RENDER_ITEMS];
+ TextureInfo default_texture_info;
+
bool using_directional_lights = false;
RID default_canvas_texture;
@@ -561,8 +555,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
void _render_batch_items(RenderTarget p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false, RenderingMethod::RenderInfo *r_render_info = nullptr);
void _record_item_commands(const Item *p_item, RenderTarget p_render_target, const Transform2D &p_base_transform, Item *&r_current_clip, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used, Batch *&r_current_batch);
void _render_batch(RD::DrawListID p_draw_list, PipelineVariants *p_pipeline_variants, RenderingDevice::FramebufferFormatID p_framebuffer_format, Light *p_lights, Batch const *p_batch, RenderingMethod::RenderInfo *r_render_info = nullptr);
- void _prepare_batch_texture(Batch *p_current_batch, RID p_texture) const;
- void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_uniform_set);
+ void _prepare_batch_texture_info(Batch *p_current_batch, RID p_texture) const;
[[nodiscard]] Batch *_new_batch(bool &r_batch_broken);
void _add_to_batch(uint32_t &r_index, bool &r_batch_broken, Batch *&r_current_batch);
void _allocate_instance_buffer();
diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
index 7cf5b4576e..fc9b727581 100644
--- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
@@ -54,11 +54,6 @@ struct InstanceData {
uint lights[4];
};
-layout(set = 4, binding = 0, std430) restrict readonly buffer DrawData {
- InstanceData data[];
-}
-instances;
-
layout(push_constant, std430) uniform Params {
uint base_instance_index; // base index to instance data
uint pad1;
@@ -163,3 +158,8 @@ layout(set = 3, binding = 0) uniform texture2D color_texture;
layout(set = 3, binding = 1) uniform texture2D normal_texture;
layout(set = 3, binding = 2) uniform texture2D specular_texture;
layout(set = 3, binding = 3) uniform sampler texture_sampler;
+
+layout(set = 3, binding = 4, std430) restrict readonly buffer DrawData {
+ InstanceData data[];
+}
+instances;
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
index 400451ec36..3cbe1427b6 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
@@ -156,8 +156,30 @@ vec2 multiview_uv(vec2 uv) {
ivec2 multiview_uv(ivec2 uv) {
return uv;
}
+
#endif //USE_MULTIVIEW
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+layout(location = 12) highp out vec4 diffuse_light_interp;
+layout(location = 13) highp out vec4 specular_light_interp;
+
+#include "../scene_forward_vertex_lights_inc.glsl"
+
+void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) {
+ uint item_min_max = cluster_buffer.data[p_offset];
+ item_min = item_min_max & 0xFFFFu;
+ item_max = item_min_max >> 16;
+
+ item_from = item_min >> 5;
+ item_to = (item_max == 0) ? 0 : ((item_max - 1) >> 5) + 1; //side effect of how it is stored, as item_max 0 means no elements
+}
+
+uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) {
+ int local_min = clamp(int(z_min) - int(i) * 32, 0, 31);
+ int mask_width = min(int(z_max) - int(z_min), 32 - local_min);
+ return bitfieldInsert(uint(0), uint(0xFFFFFFFF), local_min, mask_width);
+}
+#endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
invariant gl_Position;
#GLOBALS
@@ -488,6 +510,145 @@ void vertex_shader(vec3 vertex_input,
screen_pos = gl_Position;
#endif
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+ diffuse_light_interp = vec4(0.0);
+ specular_light_interp = vec4(0.0);
+
+#ifdef USE_MULTIVIEW
+ vec3 view = -normalize(vertex_interp - eye_offset);
+ vec2 clip_pos = clamp((combined_projected.xy / combined_projected.w) * 0.5 + 0.5, 0.0, 1.0);
+#else
+ vec3 view = -normalize(vertex_interp);
+ vec2 clip_pos = clamp((gl_Position.xy / gl_Position.w) * 0.5 + 0.5, 0.0, 1.0);
+#endif
+
+ uvec2 cluster_pos = uvec2(clip_pos / scene_data.screen_pixel_size) >> implementation_data.cluster_shift;
+ uint cluster_offset = (implementation_data.cluster_width * cluster_pos.y + cluster_pos.x) * (implementation_data.max_cluster_element_count_div_32 + 32);
+ uint cluster_z = uint(clamp((-vertex_interp.z / scene_data.z_far) * 32.0, 0.0, 31.0));
+
+ { //omni lights
+
+ uint cluster_omni_offset = cluster_offset;
+
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
+
+ cluster_get_item_range(cluster_omni_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_omni_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+ uint merged_mask = mask;
+
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1u << bit);
+ uint light_index = 32 * i + bit;
+
+ if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
+
+ if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+ continue; // Statically baked light and object uses lightmap, skip
+ }
+
+ light_process_omni_vertex(light_index, vertex, view, normal, roughness,
+ diffuse_light_interp.rgb, specular_light_interp.rgb);
+ }
+ }
+ }
+
+ { //spot lights
+ uint cluster_spot_offset = cluster_offset + implementation_data.cluster_type_size;
+
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
+
+ cluster_get_item_range(cluster_spot_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_spot_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+ uint merged_mask = mask;
+
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1u << bit);
+
+ uint light_index = 32 * i + bit;
+
+ if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
+
+ if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+ continue; // Statically baked light and object uses lightmap, skip
+ }
+
+ light_process_spot_vertex(light_index, vertex, view, normal, roughness,
+ diffuse_light_interp.rgb, specular_light_interp.rgb);
+ }
+ }
+ }
+
+ { // Directional light.
+
+ // We process the first directional light separately as it may have shadows.
+ vec3 directional_diffuse = vec3(0.0);
+ vec3 directional_specular = vec3(0.0);
+
+ for (uint i = 0; i < scene_data.directional_light_count; i++) {
+ if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
+ continue; // Not masked, skip.
+ }
+
+ if (directional_lights.data[i].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+ continue; // Statically baked light and object uses lightmap, skip.
+ }
+ if (i == 0) {
+ light_compute_vertex(normal, directional_lights.data[0].direction, view,
+ directional_lights.data[0].color * directional_lights.data[0].energy,
+ true, roughness,
+ directional_diffuse,
+ directional_specular);
+ } else {
+ light_compute_vertex(normal, directional_lights.data[i].direction, view,
+ directional_lights.data[i].color * directional_lights.data[i].energy,
+ true, roughness,
+ diffuse_light_interp.rgb,
+ specular_light_interp.rgb);
+ }
+ }
+
+ // Calculate the contribution from the shadowed light so we can scale the shadows accordingly.
+ float diff_avg = dot(diffuse_light_interp.rgb, vec3(0.33333));
+ float diff_dir_avg = dot(directional_diffuse, vec3(0.33333));
+ if (diff_avg > 0.0) {
+ diffuse_light_interp.a = diff_dir_avg / (diff_avg + diff_dir_avg);
+ } else {
+ diffuse_light_interp.a = 1.0;
+ }
+
+ diffuse_light_interp.rgb += directional_diffuse;
+
+ float spec_avg = dot(specular_light_interp.rgb, vec3(0.33333));
+ float spec_dir_avg = dot(directional_specular, vec3(0.33333));
+ if (spec_avg > 0.0) {
+ specular_light_interp.a = spec_dir_avg / (spec_avg + spec_dir_avg);
+ } else {
+ specular_light_interp.a = 1.0;
+ }
+
+ specular_light_interp.rgb += directional_specular;
+ }
+
+#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+
#ifdef MODE_RENDER_DEPTH
if (scene_data.pancake_shadows) {
if (gl_Position.z >= 0.9999) {
@@ -791,7 +952,10 @@ ivec2 multiview_uv(ivec2 uv) {
return uv;
}
#endif //USE_MULTIVIEW
-
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+layout(location = 12) highp in vec4 diffuse_light_interp;
+layout(location = 13) highp in vec4 specular_light_interp;
+#endif
//defines to keep compatibility with vertex
#ifdef USE_MULTIVIEW
@@ -1375,7 +1539,6 @@ void fragment_shader(in SceneData scene_data) {
vec3 specular_light = vec3(0.0, 0.0, 0.0);
vec3 diffuse_light = vec3(0.0, 0.0, 0.0);
vec3 ambient_light = vec3(0.0, 0.0, 0.0);
-
#ifndef MODE_UNSHADED
// Used in regular draw pass and when drawing SDFs for SDFGI and materials for VoxelGI.
emission *= scene_data.emissive_exposure_normalization;
@@ -1836,6 +1999,11 @@ void fragment_shader(in SceneData scene_data) {
// LIGHTING
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
+#ifdef USE_VERTEX_LIGHTING
+ diffuse_light += diffuse_light_interp.rgb;
+ specular_light += specular_light_interp.rgb * f0;
+#endif
+
{ // Directional light.
// Do shadow and lighting in two passes to reduce register pressure.
@@ -1843,10 +2011,15 @@ void fragment_shader(in SceneData scene_data) {
uint shadow0 = 0;
uint shadow1 = 0;
+#ifdef USE_VERTEX_LIGHTING
+ // Only process the first light's shadow for vertex lighting.
+ for (uint i = 0; i < 1; i++) {
+#else
for (uint i = 0; i < 8; i++) {
if (i >= scene_data.directional_light_count) {
break;
}
+#endif
if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) {
continue; //not masked
@@ -2044,6 +2217,11 @@ void fragment_shader(in SceneData scene_data) {
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
+#ifdef USE_VERTEX_LIGHTING
+ diffuse_light *= mix(1.0, shadow, diffuse_light_interp.a);
+ specular_light *= mix(1.0, shadow, specular_light_interp.a);
+#endif
+
#undef BIAS_FUNC
} // shadows
@@ -2055,6 +2233,8 @@ void fragment_shader(in SceneData scene_data) {
}
#endif // SHADOWS_DISABLED
+#ifndef USE_VERTEX_LIGHTING
+
for (uint i = 0; i < 8; i++) {
if (i >= scene_data.directional_light_count) {
break;
@@ -2175,8 +2355,10 @@ void fragment_shader(in SceneData scene_data) {
diffuse_light,
specular_light);
}
+#endif // USE_VERTEX_LIGHTING
}
+#ifndef USE_VERTEX_LIGHTING
{ //omni lights
uint cluster_omni_offset = cluster_offset;
@@ -2320,6 +2502,8 @@ void fragment_shader(in SceneData scene_data) {
}
}
}
+#endif // !USE_VERTEX_LIGHTING
+#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
#ifdef USE_SHADOW_TO_OPACITY
#ifndef MODE_RENDER_DEPTH
@@ -2334,8 +2518,6 @@ void fragment_shader(in SceneData scene_data) {
#endif // !MODE_RENDER_DEPTH
#endif // USE_SHADOW_TO_OPACITY
-#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
-
#ifdef MODE_RENDER_DEPTH
#ifdef MODE_RENDER_SDF
diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
index 17c7b756c3..e7ce44bce2 100644
--- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
@@ -105,7 +105,16 @@ layout(location = 4) mediump out vec2 uv2_interp;
layout(location = 5) mediump out vec3 tangent_interp;
layout(location = 6) mediump out vec3 binormal_interp;
#endif
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+layout(location = 7) highp out vec4 diffuse_light_interp;
+layout(location = 8) highp out vec4 specular_light_interp;
+layout(constant_id = 9) const bool sc_disable_omni_lights = false;
+layout(constant_id = 10) const bool sc_disable_spot_lights = false;
+layout(constant_id = 12) const bool sc_disable_directional_lights = false;
+
+#include "../scene_forward_vertex_lights_inc.glsl"
+#endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
#ifdef MATERIAL_UNIFORMS_USED
/* clang-format off */
layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms {
@@ -185,6 +194,7 @@ void main() {
mat4 model_matrix = instances.data[draw_call.instance_index].transform;
mat4 inv_view_matrix = scene_data.inv_view_matrix;
+
#ifdef USE_DOUBLE_PRECISION
vec3 model_precision = vec3(model_matrix[0][3], model_matrix[1][3], model_matrix[2][3]);
model_matrix[0][3] = 0.0;
@@ -448,6 +458,107 @@ void main() {
binormal_interp = binormal;
#endif
+// VERTEX LIGHTING
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+#ifdef USE_MULTIVIEW
+ vec3 view = -normalize(vertex_interp - eye_offset);
+#else
+ vec3 view = -normalize(vertex_interp);
+#endif
+
+ diffuse_light_interp = vec4(0.0);
+ specular_light_interp = vec4(0.0);
+
+ if (!sc_disable_omni_lights) {
+ uint light_indices = instances.data[draw_call.instance_index].omni_lights.x;
+ for (uint i = 0; i < 8; i++) {
+ uint light_index = light_indices & 0xFF;
+ if (i == 3) {
+ light_indices = instances.data[draw_call.instance_index].omni_lights.y;
+ } else {
+ light_indices = light_indices >> 8;
+ }
+
+ if (light_index == 0xFF) {
+ break;
+ }
+
+ light_process_omni_vertex(light_index, vertex, view, normal, roughness,
+ diffuse_light_interp.rgb, specular_light_interp.rgb);
+ }
+ }
+
+ if (!sc_disable_spot_lights) {
+ uint light_indices = instances.data[draw_call.instance_index].spot_lights.x;
+ for (uint i = 0; i < 8; i++) {
+ uint light_index = light_indices & 0xFF;
+ if (i == 3) {
+ light_indices = instances.data[draw_call.instance_index].spot_lights.y;
+ } else {
+ light_indices = light_indices >> 8;
+ }
+
+ if (light_index == 0xFF) {
+ break;
+ }
+
+ light_process_spot_vertex(light_index, vertex, view, normal, roughness,
+ diffuse_light_interp.rgb, specular_light_interp.rgb);
+ }
+ }
+
+ if (!sc_disable_directional_lights) {
+ // We process the first directional light separately as it may have shadows.
+ vec3 directional_diffuse = vec3(0.0);
+ vec3 directional_specular = vec3(0.0);
+
+ for (uint i = 0; i < scene_data.directional_light_count; i++) {
+ if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
+ continue; // Not masked, skip.
+ }
+
+ if (directional_lights.data[i].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+ continue; // Statically baked light and object uses lightmap, skip.
+ }
+ if (i == 0) {
+ light_compute_vertex(normal, directional_lights.data[0].direction, view,
+ directional_lights.data[0].color * directional_lights.data[0].energy,
+ true, roughness,
+ directional_diffuse,
+ directional_specular);
+ } else {
+ light_compute_vertex(normal, directional_lights.data[i].direction, view,
+ directional_lights.data[i].color * directional_lights.data[i].energy,
+ true, roughness,
+ diffuse_light_interp.rgb,
+ specular_light_interp.rgb);
+ }
+ }
+
+ // Calculate the contribution from the shadowed light so we can scale the shadows accordingly.
+ float diff_avg = dot(diffuse_light_interp.rgb, vec3(0.33333));
+ float diff_dir_avg = dot(directional_diffuse, vec3(0.33333));
+ if (diff_avg > 0.0) {
+ diffuse_light_interp.a = diff_dir_avg / (diff_avg + diff_dir_avg);
+ } else {
+ diffuse_light_interp.a = 1.0;
+ }
+
+ diffuse_light_interp.rgb += directional_diffuse;
+
+ float spec_avg = dot(specular_light_interp.rgb, vec3(0.33333));
+ float spec_dir_avg = dot(directional_specular, vec3(0.33333));
+ if (spec_avg > 0.0) {
+ specular_light_interp.a = spec_dir_avg / (spec_avg + spec_dir_avg);
+ } else {
+ specular_light_interp.a = 1.0;
+ }
+
+ specular_light_interp.rgb += directional_specular;
+ }
+
+#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+
#ifdef MODE_RENDER_DEPTH
#ifdef MODE_DUAL_PARABOLOID
@@ -564,6 +675,11 @@ layout(location = 5) mediump in vec3 tangent_interp;
layout(location = 6) mediump in vec3 binormal_interp;
#endif
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
+layout(location = 7) highp in vec4 diffuse_light_interp;
+layout(location = 8) highp in vec4 specular_light_interp;
+#endif
+
#ifdef MODE_DUAL_PARABOLOID
layout(location = 9) highp in float dp_clip;
@@ -709,7 +825,7 @@ layout(location = 0) out mediump vec4 frag_color;
#include "../scene_forward_aa_inc.glsl"
-#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) // && !defined(USE_VERTEX_LIGHTING)
// Default to SPECULAR_SCHLICK_GGX.
#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON)
@@ -718,7 +834,7 @@ layout(location = 0) out mediump vec4 frag_color;
#include "../scene_forward_lights_inc.glsl"
-#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
+#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && !defined(USE_VERTEX_LIGHTING)
#ifndef MODE_RENDER_DEPTH
@@ -1401,6 +1517,10 @@ void main() {
// LIGHTING
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
+#ifdef USE_VERTEX_LIGHTING
+ diffuse_light += diffuse_light_interp.rgb;
+ specular_light += specular_light_interp.rgb * f0;
+#endif
if (!sc_disable_directional_lights) { //directional light
#ifndef SHADOWS_DISABLED
@@ -1408,10 +1528,12 @@ void main() {
uint shadow0 = 0;
uint shadow1 = 0;
- for (uint i = 0; i < 8; i++) {
- if (i >= scene_data.directional_light_count) {
- break;
- }
+#ifdef USE_VERTEX_LIGHTING
+ // Only process the first light's shadow for vertex lighting.
+ for (uint i = 0; i < 1; i++) {
+#else
+ for (uint i = 0; i < scene_data.directional_light_count; i++) {
+#endif
if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
continue; //not masked
@@ -1419,164 +1541,6 @@ void main() {
float shadow = 1.0;
- // Directional light shadow code is basically the same as forward clustered at this point in time minus `LIGHT_TRANSMITTANCE_USED` support.
- // Not sure if there is a reason to change this seeing directional lights are part of our global data
- // Should think about whether we may want to move this code into an include file or function??
-
-#ifdef USE_SOFT_SHADOWS
- //version with soft shadows, more expensive
- if (directional_lights.data[i].shadow_opacity > 0.001) {
- float depth_z = -vertex.z;
-
- vec4 pssm_coord;
- 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;
-
- if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
- 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, scene_data.taa_frame_count);
- } else {
- shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count);
- }
- } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
- 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, scene_data.taa_frame_count);
- } else {
- shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count);
- }
- } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
- 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, scene_data.taa_frame_count);
- } else {
- shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count);
- }
- } else {
- 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;
- shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count);
- } else {
- shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count);
- }
- }
-
- if (directional_lights.data[i].blend_splits) {
- float pssm_blend;
- float shadow2;
-
- if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
- 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, scene_data.taa_frame_count);
- } else {
- shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count);
- }
-
- pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z);
- } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
- 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, scene_data.taa_frame_count);
- } else {
- shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count);
- }
-
- pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z);
- } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
- 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, scene_data.taa_frame_count);
- } else {
- shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count);
- }
-
- pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z);
- } 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_blend = sqrt(pssm_blend);
-
- shadow = mix(shadow, shadow2, 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
-
-#undef BIAS_FUNC
- }
-#else
- // Soft shadow disabled version
-
if (directional_lights.data[i].shadow_opacity > 0.001) {
float depth_z = -vertex.z;
@@ -1667,6 +1631,10 @@ void main() {
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
+#ifdef USE_VERTEX_LIGHTING
+ diffuse_light *= mix(1.0, shadow, diffuse_light_interp.a);
+ specular_light *= mix(1.0, shadow, specular_light_interp.a);
+#endif
#undef BIAS_FUNC
}
#endif
@@ -1678,13 +1646,8 @@ void main() {
}
}
-#endif // SHADOWS_DISABLED
-
- for (uint i = 0; i < 8; i++) {
- if (i >= scene_data.directional_light_count) {
- break;
- }
-
+#ifndef USE_VERTEX_LIGHTING
+ for (uint i = 0; i < scene_data.directional_light_count; i++) {
if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
continue; //not masked
}
@@ -1703,8 +1666,8 @@ void main() {
#endif
blur_shadow(shadow);
-#ifdef DEBUG_DRAW_PSSM_SPLITS
vec3 tint = vec3(1.0);
+#ifdef DEBUG_DRAW_PSSM_SPLITS
if (-vertex.z < directional_lights.data[i].shadow_split_offsets.x) {
tint = vec3(1.0, 0.0, 0.0);
} else if (-vertex.z < directional_lights.data[i].shadow_split_offsets.y) {
@@ -1718,12 +1681,10 @@ void main() {
shadow = 1.0;
#endif
- light_compute(normal, directional_lights.data[i].direction, normalize(view), 0.0,
-#ifndef DEBUG_DRAW_PSSM_SPLITS
- directional_lights.data[i].color * directional_lights.data[i].energy,
-#else
+ float size_A = sc_use_light_soft_shadows ? directional_lights.data[i].size : 0.0;
+
+ light_compute(normal, directional_lights.data[i].direction, view, size_A,
directional_lights.data[i].color * directional_lights.data[i].energy * tint,
-#endif
true, shadow, f0, orms, 1.0, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@@ -1745,14 +1706,13 @@ void main() {
#ifdef LIGHT_ANISOTROPY_USED
binormal, tangent, anisotropy,
#endif
-#ifdef USE_SOFT_SHADOW
- directional_lights.data[i].size,
-#endif
diffuse_light,
specular_light);
}
+#endif // USE_VERTEX_LIGHTING
} //directional light
+#ifndef USE_VERTEX_LIGHTING
if (!sc_disable_omni_lights) { //omni lights
uint light_indices = instances.data[draw_call.instance_index].omni_lights.x;
for (uint i = 0; i < 8; i++) {
@@ -1771,6 +1731,7 @@ void main() {
shadow = blur_shadow(shadow);
+ // Fragment lighting
light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@@ -1841,6 +1802,9 @@ void main() {
diffuse_light, specular_light);
}
} //spot lights
+#endif // !VERTEX_LIGHTING
+
+#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
#ifdef USE_SHADOW_TO_OPACITY
#ifndef MODE_RENDER_DEPTH
@@ -1855,8 +1819,6 @@ void main() {
#endif // !MODE_RENDER_DEPTH
#endif // USE_SHADOW_TO_OPACITY
-#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
-
#ifdef MODE_RENDER_DEPTH
#ifdef MODE_RENDER_MATERIAL
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_vertex_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_vertex_lights_inc.glsl
new file mode 100644
index 0000000000..e962c8f7f3
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_vertex_lights_inc.glsl
@@ -0,0 +1,82 @@
+// Simplified versions of light functions intended for the vertex shader.
+
+// Eyeballed approximation of `exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25`.
+// Uses slightly more FMA instructions (2x rate) to avoid special instructions (0.25x rate).
+// Range is reduced to [0.64,4977] from [068,2,221,528] which makes mediump feasible for the rest of the shader.
+mediump float roughness_to_shininess(mediump float roughness) {
+ mediump float r = 1.2 - roughness;
+ mediump float r2 = r * r;
+ return r * r2 * r2 * 2000.0;
+}
+
+void light_compute_vertex(vec3 N, vec3 L, vec3 V, vec3 light_color, bool is_directional, float roughness,
+ inout vec3 diffuse_light, inout vec3 specular_light) {
+ float NdotL = min(dot(N, L), 1.0);
+ float cNdotL = max(NdotL, 0.0); // clamped NdotL
+
+#if defined(DIFFUSE_LAMBERT_WRAP)
+ // Energy conserving lambert wrap shader.
+ // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
+ float diffuse_brdf_NL = max(0.0, (cNdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI);
+#else
+ // lambert
+ float diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
+#endif
+
+ diffuse_light += light_color * diffuse_brdf_NL;
+
+#if !defined(SPECULAR_DISABLED)
+ float specular_brdf_NL = 0.0;
+ // Normalized blinn always unless disabled.
+ vec3 H = normalize(V + L);
+ float cNdotH = clamp(dot(N, H), 0.0, 1.0);
+ float shininess = roughness_to_shininess(roughness);
+ float blinn = pow(cNdotH, shininess);
+ blinn *= (shininess + 2.0) * (1.0 / (8.0 * M_PI)) * cNdotL;
+ specular_brdf_NL = blinn;
+ specular_light += specular_brdf_NL * light_color;
+#endif
+}
+
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
+void light_process_omni_vertex(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness,
+ inout vec3 diffuse_light, inout vec3 specular_light) {
+ vec3 light_rel_vec = omni_lights.data[idx].position - vertex;
+ float light_length = length(light_rel_vec);
+ float omni_attenuation = get_omni_attenuation(light_length, omni_lights.data[idx].inv_radius, omni_lights.data[idx].attenuation);
+ vec3 color = omni_lights.data[idx].color * omni_attenuation;
+
+ light_compute_vertex(normal, normalize(light_rel_vec), eye_vec, color, false, roughness,
+ diffuse_light,
+ specular_light);
+}
+
+void light_process_spot_vertex(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness,
+ inout vec3 diffuse_light,
+ inout vec3 specular_light) {
+ vec3 light_rel_vec = spot_lights.data[idx].position - vertex;
+ float light_length = length(light_rel_vec);
+ float spot_attenuation = get_omni_attenuation(light_length, spot_lights.data[idx].inv_radius, spot_lights.data[idx].attenuation);
+ vec3 spot_dir = spot_lights.data[idx].direction;
+
+ // This conversion to a highp float is crucial to prevent light leaking
+ // due to precision errors in the following calculations (cone angle is mediump).
+ highp float cone_angle = spot_lights.data[idx].cone_angle;
+ float scos = max(dot(-normalize(light_rel_vec), spot_dir), cone_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cone_angle));
+
+ spot_attenuation *= 1.0 - pow(spot_rim, spot_lights.data[idx].cone_attenuation);
+ vec3 color = spot_lights.data[idx].color * spot_attenuation;
+ float specular_amount = spot_lights.data[idx].specular_amount;
+
+ light_compute_vertex(normal, normalize(light_rel_vec), eye_vec, color, false, roughness,
+ diffuse_light, specular_light);
+}
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index e5a8dbb9b2..84e8d1d671 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -40,25 +40,12 @@ using namespace RendererRD;
///////////////////////////////////////////////////////////////////////////
// TextureStorage::CanvasTexture
-void TextureStorage::CanvasTexture::clear_sets() {
- if (cleared_cache) {
- return;
- }
- for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
- for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
- for (int k = 0; k < 2; k++) {
- if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j][k])) {
- RD::get_singleton()->free(uniform_sets[i][j][k]);
- uniform_sets[i][j][k] = RID();
- }
- }
- }
- }
- cleared_cache = true;
+void TextureStorage::CanvasTexture::clear_cache() {
+ info_cache[0] = CanvasTextureCache();
+ info_cache[1] = CanvasTextureCache();
}
TextureStorage::CanvasTexture::~CanvasTexture() {
- clear_sets();
}
///////////////////////////////////////////////////////////////////////////
@@ -612,8 +599,7 @@ void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::Canvas
ct->specular = p_texture;
} break;
}
-
- ct->clear_sets();
+ ct->clear_cache();
}
void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
@@ -624,7 +610,6 @@ void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture,
ct->specular_color.g = p_specular_color.g;
ct->specular_color.b = p_specular_color.b;
ct->specular_color.a = p_shininess;
- ct->clear_sets();
}
void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
@@ -632,7 +617,6 @@ void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS:
ERR_FAIL_NULL(ct);
ct->texture_filter = p_filter;
- ct->clear_sets();
}
void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
@@ -640,17 +624,14 @@ void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS:
ERR_FAIL_NULL(ct);
ct->texture_repeat = p_repeat;
- ct->clear_sets();
}
-bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, bool p_use_srgb, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular, bool p_texture_is_data) {
+TextureStorage::CanvasTextureInfo TextureStorage::canvas_texture_get_info(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, bool p_use_srgb, bool p_texture_is_data) {
MaterialStorage *material_storage = MaterialStorage::get_singleton();
CanvasTexture *ct = nullptr;
Texture *t = get_texture(p_texture);
- // TODO once we have our texture storage split off we'll look into moving this code into canvas_texture
-
if (t) {
//regular texture
if (!t->canvas_texture) {
@@ -667,93 +648,71 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
}
if (!ct) {
- return false; //invalid texture RID
+ return CanvasTextureInfo(); //invalid texture RID
}
RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter;
- ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false);
+ ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasTextureInfo());
RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat;
- ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false);
+ ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, CanvasTextureInfo());
- RID uniform_set = ct->uniform_sets[filter][repeat][int(p_use_srgb)];
- if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //create and update
- Vector<RD::Uniform> uniforms;
+ CanvasTextureCache &ctc = ct->info_cache[int(p_use_srgb)];
+ if (!RD::get_singleton()->texture_is_valid(ctc.diffuse) ||
+ !RD::get_singleton()->texture_is_valid(ctc.normal) ||
+ !RD::get_singleton()->texture_is_valid(ctc.specular)) {
{ //diffuse
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 0;
-
t = get_texture(ct->diffuse);
if (!t) {
- u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
+ ctc.diffuse = texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE);
ct->size_cache = Size2i(1, 1);
} else {
- u.append_id(t->rd_texture_srgb.is_valid() && p_use_srgb && !p_texture_is_data ? t->rd_texture_srgb : t->rd_texture);
+ ctc.diffuse = t->rd_texture_srgb.is_valid() && p_use_srgb && !p_texture_is_data ? t->rd_texture_srgb : t->rd_texture;
ct->size_cache = Size2i(t->width_2d, t->height_2d);
if (t->render_target) {
t->render_target->was_used = true;
}
}
- uniforms.push_back(u);
}
{ //normal
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1;
-
t = get_texture(ct->normal_map);
if (!t) {
- u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL));
+ ctc.normal = texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL);
ct->use_normal_cache = false;
} else {
- u.append_id(t->rd_texture);
+ ctc.normal = t->rd_texture;
ct->use_normal_cache = true;
if (t->render_target) {
t->render_target->was_used = true;
}
}
- uniforms.push_back(u);
}
{ //specular
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 2;
-
t = get_texture(ct->specular);
if (!t) {
- u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
+ ctc.specular = texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE);
ct->use_specular_cache = false;
} else {
- u.append_id(t->rd_texture);
+ ctc.specular = t->rd_texture;
ct->use_specular_cache = true;
if (t->render_target) {
t->render_target->was_used = true;
}
}
- uniforms.push_back(u);
}
- { //sampler
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 3;
- u.append_id(material_storage->sampler_rd_get_default(filter, repeat));
- uniforms.push_back(u);
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set);
- ct->uniform_sets[filter][repeat][int(p_use_srgb)] = uniform_set;
- ct->cleared_cache = false;
}
- r_uniform_set = uniform_set;
- r_size = ct->size_cache;
- r_specular_shininess = ct->specular_color;
- r_use_normal = ct->use_normal_cache;
- r_use_specular = ct->use_specular_cache;
+ CanvasTextureInfo res;
+ res.diffuse = ctc.diffuse;
+ res.normal = ctc.normal;
+ res.specular = ctc.specular;
+ res.sampler = material_storage->sampler_rd_get_default(filter, repeat);
+ res.size = ct->size_cache;
+ res.specular_color = ct->specular_color;
+ res.use_normal = ct->use_normal_cache;
+ res.use_specular = ct->use_specular_cache;
- return true;
+ return res;
}
/* Texture API */
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 9de4ff7b6b..8aecc78f07 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -76,6 +76,21 @@ public:
TYPE_3D
};
+ struct CanvasTextureInfo {
+ RID diffuse;
+ RID normal;
+ RID specular;
+ RID sampler;
+ Size2i size;
+ Color specular_color;
+
+ bool use_normal = false;
+ bool use_specular = false;
+
+ _FORCE_INLINE_ bool is_valid() const { return diffuse.is_valid(); }
+ _FORCE_INLINE_ bool is_null() const { return diffuse.is_null(); }
+ };
+
private:
friend class LightStorage;
friend class MaterialStorage;
@@ -86,6 +101,12 @@ private:
/* Canvas Texture API */
+ struct CanvasTextureCache {
+ RID diffuse = RID();
+ RID normal = RID();
+ RID specular = RID();
+ };
+
class CanvasTexture {
public:
RID diffuse;
@@ -96,14 +117,14 @@ private:
RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
- RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX][2];
+ CanvasTextureCache info_cache[2];
Size2i size_cache = Size2i(1, 1);
bool use_normal_cache = false;
bool use_specular_cache = false;
bool cleared_cache = true;
- void clear_sets();
+ void clear_cache();
~CanvasTexture();
};
@@ -477,7 +498,7 @@ public:
virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override;
virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override;
- bool canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, bool p_use_srgb, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular, bool p_texture_is_data);
+ CanvasTextureInfo canvas_texture_get_info(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, bool p_use_srgb, bool p_texture_is_data);
/* Texture API */
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 0ad56961c0..5c85080298 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -3580,8 +3580,7 @@ void RenderingServer::init() {
GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/global_illumination/voxel_gi/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)"), 0);
- GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading", false);
- GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading.mobile", true);
+ GLOBAL_DEF_RST("rendering/shading/overrides/force_vertex_shading", false);
GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley", false);
GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true);
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index d387c8ff7e..1c0d518e75 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -352,29 +352,29 @@ void TextServerExtension::_bind_methods() {
bool TextServerExtension::has_feature(Feature p_feature) const {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_has_feature, p_feature, ret);
+ GDVIRTUAL_CALL(_has_feature, p_feature, ret);
return ret;
}
String TextServerExtension::get_name() const {
String ret = "Unknown";
- GDVIRTUAL_REQUIRED_CALL(_get_name, ret);
+ GDVIRTUAL_CALL(_get_name, ret);
return ret;
}
int64_t TextServerExtension::get_features() const {
int64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_features, ret);
+ GDVIRTUAL_CALL(_get_features, ret);
return ret;
}
void TextServerExtension::free_rid(const RID &p_rid) {
- GDVIRTUAL_REQUIRED_CALL(_free_rid, p_rid);
+ GDVIRTUAL_CALL(_free_rid, p_rid);
}
bool TextServerExtension::has(const RID &p_rid) {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_has, p_rid, ret);
+ GDVIRTUAL_CALL(_has, p_rid, ret);
return ret;
}
@@ -430,7 +430,7 @@ String TextServerExtension::tag_to_name(int64_t p_tag) const {
RID TextServerExtension::create_font() {
RID ret;
- GDVIRTUAL_REQUIRED_CALL(_create_font, ret);
+ GDVIRTUAL_CALL(_create_font, ret);
return ret;
}
@@ -581,22 +581,22 @@ int64_t TextServerExtension::font_get_msdf_size(const RID &p_font_rid) const {
}
void TextServerExtension::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_fixed_size, p_font_rid, p_fixed_size);
+ GDVIRTUAL_CALL(_font_set_fixed_size, p_font_rid, p_fixed_size);
}
int64_t TextServerExtension::font_get_fixed_size(const RID &p_font_rid) const {
int64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_fixed_size, p_font_rid, ret);
+ GDVIRTUAL_CALL(_font_get_fixed_size, p_font_rid, ret);
return ret;
}
void TextServerExtension::font_set_fixed_size_scale_mode(const RID &p_font_rid, TextServer::FixedSizeScaleMode p_fixed_size_scale_mode) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_fixed_size_scale_mode, p_font_rid, p_fixed_size_scale_mode);
+ GDVIRTUAL_CALL(_font_set_fixed_size_scale_mode, p_font_rid, p_fixed_size_scale_mode);
}
TextServer::FixedSizeScaleMode TextServerExtension::font_get_fixed_size_scale_mode(const RID &p_font_rid) const {
FixedSizeScaleMode ret = FIXED_SIZE_SCALE_DISABLE;
- GDVIRTUAL_REQUIRED_CALL(_font_get_fixed_size_scale_mode, p_font_rid, ret);
+ GDVIRTUAL_CALL(_font_get_fixed_size_scale_mode, p_font_rid, ret);
return ret;
}
@@ -702,89 +702,89 @@ double TextServerExtension::font_get_oversampling(const RID &p_font_rid) const {
TypedArray<Vector2i> TextServerExtension::font_get_size_cache_list(const RID &p_font_rid) const {
TypedArray<Vector2i> ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_size_cache_list, p_font_rid, ret);
+ GDVIRTUAL_CALL(_font_get_size_cache_list, p_font_rid, ret);
return ret;
}
void TextServerExtension::font_clear_size_cache(const RID &p_font_rid) {
- GDVIRTUAL_REQUIRED_CALL(_font_clear_size_cache, p_font_rid);
+ GDVIRTUAL_CALL(_font_clear_size_cache, p_font_rid);
}
void TextServerExtension::font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
- GDVIRTUAL_REQUIRED_CALL(_font_remove_size_cache, p_font_rid, p_size);
+ GDVIRTUAL_CALL(_font_remove_size_cache, p_font_rid, p_size);
}
void TextServerExtension::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_ascent, p_font_rid, p_size, p_ascent);
+ GDVIRTUAL_CALL(_font_set_ascent, p_font_rid, p_size, p_ascent);
}
double TextServerExtension::font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_ascent, p_font_rid, p_size, ret);
+ GDVIRTUAL_CALL(_font_get_ascent, p_font_rid, p_size, ret);
return ret;
}
void TextServerExtension::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_descent, p_font_rid, p_size, p_descent);
+ GDVIRTUAL_CALL(_font_set_descent, p_font_rid, p_size, p_descent);
}
double TextServerExtension::font_get_descent(const RID &p_font_rid, int64_t p_size) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_descent, p_font_rid, p_size, ret);
+ GDVIRTUAL_CALL(_font_get_descent, p_font_rid, p_size, ret);
return ret;
}
void TextServerExtension::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_underline_position, p_font_rid, p_size, p_underline_position);
+ GDVIRTUAL_CALL(_font_set_underline_position, p_font_rid, p_size, p_underline_position);
}
double TextServerExtension::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_underline_position, p_font_rid, p_size, ret);
+ GDVIRTUAL_CALL(_font_get_underline_position, p_font_rid, p_size, ret);
return ret;
}
void TextServerExtension::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_underline_thickness, p_font_rid, p_size, p_underline_thickness);
+ GDVIRTUAL_CALL(_font_set_underline_thickness, p_font_rid, p_size, p_underline_thickness);
}
double TextServerExtension::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret);
+ GDVIRTUAL_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret);
return ret;
}
void TextServerExtension::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_scale, p_font_rid, p_size, p_scale);
+ GDVIRTUAL_CALL(_font_set_scale, p_font_rid, p_size, p_scale);
}
double TextServerExtension::font_get_scale(const RID &p_font_rid, int64_t p_size) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_scale, p_font_rid, p_size, ret);
+ GDVIRTUAL_CALL(_font_get_scale, p_font_rid, p_size, ret);
return ret;
}
int64_t TextServerExtension::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
int64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_texture_count, p_font_rid, p_size, ret);
+ GDVIRTUAL_CALL(_font_get_texture_count, p_font_rid, p_size, ret);
return ret;
}
void TextServerExtension::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
- GDVIRTUAL_REQUIRED_CALL(_font_clear_textures, p_font_rid, p_size);
+ GDVIRTUAL_CALL(_font_clear_textures, p_font_rid, p_size);
}
void TextServerExtension::font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
- GDVIRTUAL_REQUIRED_CALL(_font_remove_texture, p_font_rid, p_size, p_texture_index);
+ GDVIRTUAL_CALL(_font_remove_texture, p_font_rid, p_size, p_texture_index);
}
void TextServerExtension::font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_texture_image, p_font_rid, p_size, p_texture_index, p_image);
+ GDVIRTUAL_CALL(_font_set_texture_image, p_font_rid, p_size, p_texture_index, p_image);
}
Ref<Image> TextServerExtension::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
Ref<Image> ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret);
+ GDVIRTUAL_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret);
return ret;
}
@@ -800,77 +800,77 @@ PackedInt32Array TextServerExtension::font_get_texture_offsets(const RID &p_font
PackedInt32Array TextServerExtension::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
PackedInt32Array ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_list, p_font_rid, p_size, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_list, p_font_rid, p_size, ret);
return ret;
}
void TextServerExtension::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
- GDVIRTUAL_REQUIRED_CALL(_font_clear_glyphs, p_font_rid, p_size);
+ GDVIRTUAL_CALL(_font_clear_glyphs, p_font_rid, p_size);
}
void TextServerExtension::font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
- GDVIRTUAL_REQUIRED_CALL(_font_remove_glyph, p_font_rid, p_size, p_glyph);
+ GDVIRTUAL_CALL(_font_remove_glyph, p_font_rid, p_size, p_glyph);
}
Vector2 TextServerExtension::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
Vector2 ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret);
return ret;
}
void TextServerExtension::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_advance, p_font_rid, p_size, p_glyph, p_advance);
+ GDVIRTUAL_CALL(_font_set_glyph_advance, p_font_rid, p_size, p_glyph, p_advance);
}
Vector2 TextServerExtension::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
Vector2 ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret);
return ret;
}
void TextServerExtension::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_offset, p_font_rid, p_size, p_glyph, p_offset);
+ GDVIRTUAL_CALL(_font_set_glyph_offset, p_font_rid, p_size, p_glyph, p_offset);
}
Vector2 TextServerExtension::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
Vector2 ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret);
return ret;
}
void TextServerExtension::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_size, p_font_rid, p_size, p_glyph, p_gl_size);
+ GDVIRTUAL_CALL(_font_set_glyph_size, p_font_rid, p_size, p_glyph, p_gl_size);
}
Rect2 TextServerExtension::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
Rect2 ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret);
return ret;
}
void TextServerExtension::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_uv_rect, p_font_rid, p_size, p_glyph, p_uv_rect);
+ GDVIRTUAL_CALL(_font_set_glyph_uv_rect, p_font_rid, p_size, p_glyph, p_uv_rect);
}
int64_t TextServerExtension::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
int64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret);
return ret;
}
void TextServerExtension::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
- GDVIRTUAL_REQUIRED_CALL(_font_set_glyph_texture_idx, p_font_rid, p_size, p_glyph, p_texture_idx);
+ GDVIRTUAL_CALL(_font_set_glyph_texture_idx, p_font_rid, p_size, p_glyph, p_texture_idx);
}
RID TextServerExtension::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
RID ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_texture_rid, p_font_rid, p_size, p_glyph, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_texture_rid, p_font_rid, p_size, p_glyph, ret);
return ret;
}
Size2 TextServerExtension::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
Size2 ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_texture_size, p_font_rid, p_size, p_glyph, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_texture_size, p_font_rid, p_size, p_glyph, ret);
return ret;
}
@@ -906,31 +906,31 @@ Vector2 TextServerExtension::font_get_kerning(const RID &p_font_rid, int64_t p_s
int64_t TextServerExtension::font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const {
int64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret);
+ GDVIRTUAL_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret);
return ret;
}
int64_t TextServerExtension::font_get_char_from_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_glyph_index) const {
int64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_font_get_char_from_glyph_index, p_font_rid, p_size, p_glyph_index, ret);
+ GDVIRTUAL_CALL(_font_get_char_from_glyph_index, p_font_rid, p_size, p_glyph_index, ret);
return ret;
}
bool TextServerExtension::font_has_char(const RID &p_font_rid, int64_t p_char) const {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_font_has_char, p_font_rid, p_char, ret);
+ GDVIRTUAL_CALL(_font_has_char, p_font_rid, p_char, ret);
return ret;
}
String TextServerExtension::font_get_supported_chars(const RID &p_font_rid) const {
String ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_supported_chars, p_font_rid, ret);
+ GDVIRTUAL_CALL(_font_get_supported_chars, p_font_rid, ret);
return ret;
}
PackedInt32Array TextServerExtension::font_get_supported_glyphs(const RID &p_font_rid) const {
PackedInt32Array ret;
- GDVIRTUAL_REQUIRED_CALL(_font_get_supported_glyphs, p_font_rid, ret);
+ GDVIRTUAL_CALL(_font_get_supported_glyphs, p_font_rid, ret);
return ret;
}
@@ -943,11 +943,11 @@ void TextServerExtension::font_render_glyph(const RID &p_font_rid, const Vector2
}
void TextServerExtension::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
- GDVIRTUAL_REQUIRED_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color);
+ GDVIRTUAL_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color);
}
void TextServerExtension::font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
- GDVIRTUAL_REQUIRED_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
+ GDVIRTUAL_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
}
bool TextServerExtension::font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
@@ -1054,12 +1054,12 @@ void TextServerExtension::draw_hex_code_box(const RID &p_canvas, int64_t p_size,
RID TextServerExtension::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
RID ret;
- GDVIRTUAL_REQUIRED_CALL(_create_shaped_text, p_direction, p_orientation, ret);
+ GDVIRTUAL_CALL(_create_shaped_text, p_direction, p_orientation, ret);
return ret;
}
void TextServerExtension::shaped_text_clear(const RID &p_shaped) {
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_clear, p_shaped);
+ GDVIRTUAL_CALL(_shaped_text_clear, p_shaped);
}
void TextServerExtension::shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
@@ -1144,47 +1144,47 @@ int64_t TextServerExtension::shaped_text_get_spacing(const RID &p_shaped, TextSe
bool TextServerExtension::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret);
+ GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret);
return ret;
}
bool TextServerExtension::shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length, double p_baseline) {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, p_baseline, ret);
+ GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, p_baseline, ret);
return ret;
}
bool TextServerExtension::shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, double p_baseline) {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, p_baseline, ret);
+ GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, p_baseline, ret);
return ret;
}
int64_t TextServerExtension::shaped_get_span_count(const RID &p_shaped) const {
int64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_shaped_get_span_count, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_get_span_count, p_shaped, ret);
return ret;
}
Variant TextServerExtension::shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const {
Variant ret = false;
- GDVIRTUAL_REQUIRED_CALL(_shaped_get_span_meta, p_shaped, p_index, ret);
+ GDVIRTUAL_CALL(_shaped_get_span_meta, p_shaped, p_index, ret);
return ret;
}
void TextServerExtension::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) {
- GDVIRTUAL_REQUIRED_CALL(_shaped_set_span_update_font, p_shaped, p_index, p_fonts, p_size, p_opentype_features);
+ GDVIRTUAL_CALL(_shaped_set_span_update_font, p_shaped, p_index, p_fonts, p_size, p_opentype_features);
}
RID TextServerExtension::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
RID ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret);
+ GDVIRTUAL_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret);
return ret;
}
RID TextServerExtension::shaped_text_get_parent(const RID &p_shaped) const {
RID ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_parent, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_parent, p_shaped, ret);
return ret;
}
@@ -1202,7 +1202,7 @@ double TextServerExtension::shaped_text_tab_align(const RID &p_shaped, const Pac
bool TextServerExtension::shaped_text_shape(const RID &p_shaped) {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_shape, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_shape, p_shaped, ret);
return ret;
}
@@ -1220,31 +1220,31 @@ bool TextServerExtension::shaped_text_update_justification_ops(const RID &p_shap
bool TextServerExtension::shaped_text_is_ready(const RID &p_shaped) const {
bool ret = false;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_is_ready, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_is_ready, p_shaped, ret);
return ret;
}
const Glyph *TextServerExtension::shaped_text_get_glyphs(const RID &p_shaped) const {
GDExtensionConstPtr<const Glyph> ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_glyphs, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, ret);
return ret;
}
const Glyph *TextServerExtension::shaped_text_sort_logical(const RID &p_shaped) {
GDExtensionConstPtr<const Glyph> ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_sort_logical, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, ret);
return ret;
}
int64_t TextServerExtension::shaped_text_get_glyph_count(const RID &p_shaped) const {
int64_t ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_glyph_count, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_glyph_count, p_shaped, ret);
return ret;
}
Vector2i TextServerExtension::shaped_text_get_range(const RID &p_shaped) const {
Vector2i ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_range, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_range, p_shaped, ret);
return ret;
}
@@ -1274,25 +1274,25 @@ PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(const RID &p_s
int64_t TextServerExtension::shaped_text_get_trim_pos(const RID &p_shaped) const {
int64_t ret = -1;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_trim_pos, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_trim_pos, p_shaped, ret);
return ret;
}
int64_t TextServerExtension::shaped_text_get_ellipsis_pos(const RID &p_shaped) const {
int64_t ret = -1;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret);
return ret;
}
const Glyph *TextServerExtension::shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const {
GDExtensionConstPtr<const Glyph> ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, ret);
return ret;
}
int64_t TextServerExtension::shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const {
int64_t ret = -1;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret);
return ret;
}
@@ -1302,61 +1302,61 @@ void TextServerExtension::shaped_text_overrun_trim_to_width(const RID &p_shaped_
Array TextServerExtension::shaped_text_get_objects(const RID &p_shaped) const {
Array ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_objects, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_objects, p_shaped, ret);
return ret;
}
Rect2 TextServerExtension::shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const {
Rect2 ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret);
return ret;
}
Vector2i TextServerExtension::shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const {
Vector2i ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_object_range, p_shaped, p_key, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_object_range, p_shaped, p_key, ret);
return ret;
}
int64_t TextServerExtension::shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const {
int64_t ret = -1;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_object_glyph, p_shaped, p_key, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_object_glyph, p_shaped, p_key, ret);
return ret;
}
Size2 TextServerExtension::shaped_text_get_size(const RID &p_shaped) const {
Size2 ret;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_size, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_size, p_shaped, ret);
return ret;
}
double TextServerExtension::shaped_text_get_ascent(const RID &p_shaped) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_ascent, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_ascent, p_shaped, ret);
return ret;
}
double TextServerExtension::shaped_text_get_descent(const RID &p_shaped) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_descent, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_descent, p_shaped, ret);
return ret;
}
double TextServerExtension::shaped_text_get_width(const RID &p_shaped) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_width, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_width, p_shaped, ret);
return ret;
}
double TextServerExtension::shaped_text_get_underline_position(const RID &p_shaped) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_underline_position, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_underline_position, p_shaped, ret);
return ret;
}
double TextServerExtension::shaped_text_get_underline_thickness(const RID &p_shaped) const {
double ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_shaped_text_get_underline_thickness, p_shaped, ret);
+ GDVIRTUAL_CALL(_shaped_text_get_underline_thickness, p_shaped, ret);
return ret;
}
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index 52654c010c..bd803be8aa 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -49,15 +49,15 @@ public:
virtual bool has_feature(Feature p_feature) const override;
virtual String get_name() const override;
virtual int64_t get_features() const override;
- GDVIRTUAL1RC(bool, _has_feature, Feature);
- GDVIRTUAL0RC(String, _get_name);
- GDVIRTUAL0RC(int64_t, _get_features);
+ GDVIRTUAL1RC_REQUIRED(bool, _has_feature, Feature);
+ GDVIRTUAL0RC_REQUIRED(String, _get_name);
+ GDVIRTUAL0RC_REQUIRED(int64_t, _get_features);
virtual void free_rid(const RID &p_rid) override;
virtual bool has(const RID &p_rid) override;
virtual bool load_support_data(const String &p_filename) override;
- GDVIRTUAL1(_free_rid, RID);
- GDVIRTUAL1R(bool, _has, RID);
+ GDVIRTUAL1_REQUIRED(_free_rid, RID);
+ GDVIRTUAL1R_REQUIRED(bool, _has, RID);
GDVIRTUAL1R(bool, _load_support_data, const String &);
virtual String get_support_data_filename() const override;
@@ -78,7 +78,7 @@ public:
/* Font interface */
virtual RID create_font() override;
- GDVIRTUAL0R(RID, _create_font);
+ GDVIRTUAL0R_REQUIRED(RID, _create_font);
virtual RID create_font_linked_variation(const RID &p_font_rid) override;
GDVIRTUAL1R(RID, _create_font_linked_variation, RID);
@@ -155,13 +155,13 @@ public:
virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) override;
virtual int64_t font_get_fixed_size(const RID &p_font_rid) const override;
- GDVIRTUAL2(_font_set_fixed_size, RID, int64_t);
- GDVIRTUAL1RC(int64_t, _font_get_fixed_size, RID);
+ GDVIRTUAL2_REQUIRED(_font_set_fixed_size, RID, int64_t);
+ GDVIRTUAL1RC_REQUIRED(int64_t, _font_get_fixed_size, RID);
virtual void font_set_fixed_size_scale_mode(const RID &p_font_rid, FixedSizeScaleMode p_fixed_size_scale) override;
virtual FixedSizeScaleMode font_get_fixed_size_scale_mode(const RID &p_font_rid) const override;
- GDVIRTUAL2(_font_set_fixed_size_scale_mode, RID, FixedSizeScaleMode);
- GDVIRTUAL1RC(FixedSizeScaleMode, _font_get_fixed_size_scale_mode, RID);
+ GDVIRTUAL2_REQUIRED(_font_set_fixed_size_scale_mode, RID, FixedSizeScaleMode);
+ GDVIRTUAL1RC_REQUIRED(FixedSizeScaleMode, _font_get_fixed_size_scale_mode, RID);
virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) override;
virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const override;
@@ -216,46 +216,46 @@ public:
virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const override;
virtual void font_clear_size_cache(const RID &p_font_rid) override;
virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override;
- GDVIRTUAL1RC(TypedArray<Vector2i>, _font_get_size_cache_list, RID);
- GDVIRTUAL1(_font_clear_size_cache, RID);
- GDVIRTUAL2(_font_remove_size_cache, RID, const Vector2i &);
+ GDVIRTUAL1RC_REQUIRED(TypedArray<Vector2i>, _font_get_size_cache_list, RID);
+ GDVIRTUAL1_REQUIRED(_font_clear_size_cache, RID);
+ GDVIRTUAL2_REQUIRED(_font_remove_size_cache, RID, const Vector2i &);
virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) override;
virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const override;
- GDVIRTUAL3(_font_set_ascent, RID, int64_t, double);
- GDVIRTUAL2RC(double, _font_get_ascent, RID, int64_t);
+ GDVIRTUAL3_REQUIRED(_font_set_ascent, RID, int64_t, double);
+ GDVIRTUAL2RC_REQUIRED(double, _font_get_ascent, RID, int64_t);
virtual void font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) override;
virtual double font_get_descent(const RID &p_font_rid, int64_t p_size) const override;
- GDVIRTUAL3(_font_set_descent, RID, int64_t, double);
- GDVIRTUAL2RC(double, _font_get_descent, RID, int64_t);
+ GDVIRTUAL3_REQUIRED(_font_set_descent, RID, int64_t, double);
+ GDVIRTUAL2RC_REQUIRED(double, _font_get_descent, RID, int64_t);
virtual void font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) override;
virtual double font_get_underline_position(const RID &p_font_rid, int64_t p_size) const override;
- GDVIRTUAL3(_font_set_underline_position, RID, int64_t, double);
- GDVIRTUAL2RC(double, _font_get_underline_position, RID, int64_t);
+ GDVIRTUAL3_REQUIRED(_font_set_underline_position, RID, int64_t, double);
+ GDVIRTUAL2RC_REQUIRED(double, _font_get_underline_position, RID, int64_t);
virtual void font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) override;
virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const override;
- GDVIRTUAL3(_font_set_underline_thickness, RID, int64_t, double);
- GDVIRTUAL2RC(double, _font_get_underline_thickness, RID, int64_t);
+ GDVIRTUAL3_REQUIRED(_font_set_underline_thickness, RID, int64_t, double);
+ GDVIRTUAL2RC_REQUIRED(double, _font_get_underline_thickness, RID, int64_t);
virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override;
virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override;
- GDVIRTUAL3(_font_set_scale, RID, int64_t, double);
- GDVIRTUAL2RC(double, _font_get_scale, RID, int64_t);
+ GDVIRTUAL3_REQUIRED(_font_set_scale, RID, int64_t, double);
+ GDVIRTUAL2RC_REQUIRED(double, _font_get_scale, RID, int64_t);
virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
- GDVIRTUAL2RC(int64_t, _font_get_texture_count, RID, const Vector2i &);
- GDVIRTUAL2(_font_clear_textures, RID, const Vector2i &);
- GDVIRTUAL3(_font_remove_texture, RID, const Vector2i &, int64_t);
+ GDVIRTUAL2RC_REQUIRED(int64_t, _font_get_texture_count, RID, const Vector2i &);
+ GDVIRTUAL2_REQUIRED(_font_clear_textures, RID, const Vector2i &);
+ GDVIRTUAL3_REQUIRED(_font_remove_texture, RID, const Vector2i &, int64_t);
virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) override;
virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
- GDVIRTUAL4(_font_set_texture_image, RID, const Vector2i &, int64_t, const Ref<Image> &);
- GDVIRTUAL3RC(Ref<Image>, _font_get_texture_image, RID, const Vector2i &, int64_t);
+ GDVIRTUAL4_REQUIRED(_font_set_texture_image, RID, const Vector2i &, int64_t, const Ref<Image> &);
+ GDVIRTUAL3RC_REQUIRED(Ref<Image>, _font_get_texture_image, RID, const Vector2i &, int64_t);
virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override;
virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
@@ -265,40 +265,40 @@ public:
virtual PackedInt32Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override;
- GDVIRTUAL2RC(PackedInt32Array, _font_get_glyph_list, RID, const Vector2i &);
- GDVIRTUAL2(_font_clear_glyphs, RID, const Vector2i &);
- GDVIRTUAL3(_font_remove_glyph, RID, const Vector2i &, int64_t);
+ GDVIRTUAL2RC_REQUIRED(PackedInt32Array, _font_get_glyph_list, RID, const Vector2i &);
+ GDVIRTUAL2_REQUIRED(_font_clear_glyphs, RID, const Vector2i &);
+ GDVIRTUAL3_REQUIRED(_font_remove_glyph, RID, const Vector2i &, int64_t);
virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const override;
virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) override;
- GDVIRTUAL3RC(Vector2, _font_get_glyph_advance, RID, int64_t, int64_t);
- GDVIRTUAL4(_font_set_glyph_advance, RID, int64_t, int64_t, const Vector2 &);
+ GDVIRTUAL3RC_REQUIRED(Vector2, _font_get_glyph_advance, RID, int64_t, int64_t);
+ GDVIRTUAL4_REQUIRED(_font_set_glyph_advance, RID, int64_t, int64_t, const Vector2 &);
virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) override;
- GDVIRTUAL3RC(Vector2, _font_get_glyph_offset, RID, const Vector2i &, int64_t);
- GDVIRTUAL4(_font_set_glyph_offset, RID, const Vector2i &, int64_t, const Vector2 &);
+ GDVIRTUAL3RC_REQUIRED(Vector2, _font_get_glyph_offset, RID, const Vector2i &, int64_t);
+ GDVIRTUAL4_REQUIRED(_font_set_glyph_offset, RID, const Vector2i &, int64_t, const Vector2 &);
virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) override;
- GDVIRTUAL3RC(Vector2, _font_get_glyph_size, RID, const Vector2i &, int64_t);
- GDVIRTUAL4(_font_set_glyph_size, RID, const Vector2i &, int64_t, const Vector2 &);
+ GDVIRTUAL3RC_REQUIRED(Vector2, _font_get_glyph_size, RID, const Vector2i &, int64_t);
+ GDVIRTUAL4_REQUIRED(_font_set_glyph_size, RID, const Vector2i &, int64_t, const Vector2 &);
virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) override;
- GDVIRTUAL3RC(Rect2, _font_get_glyph_uv_rect, RID, const Vector2i &, int64_t);
- GDVIRTUAL4(_font_set_glyph_uv_rect, RID, const Vector2i &, int64_t, const Rect2 &);
+ GDVIRTUAL3RC_REQUIRED(Rect2, _font_get_glyph_uv_rect, RID, const Vector2i &, int64_t);
+ GDVIRTUAL4_REQUIRED(_font_set_glyph_uv_rect, RID, const Vector2i &, int64_t, const Rect2 &);
virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override;
- GDVIRTUAL3RC(int64_t, _font_get_glyph_texture_idx, RID, const Vector2i &, int64_t);
- GDVIRTUAL4(_font_set_glyph_texture_idx, RID, const Vector2i &, int64_t, int64_t);
+ GDVIRTUAL3RC_REQUIRED(int64_t, _font_get_glyph_texture_idx, RID, const Vector2i &, int64_t);
+ GDVIRTUAL4_REQUIRED(_font_set_glyph_texture_idx, RID, const Vector2i &, int64_t, int64_t);
virtual RID font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- GDVIRTUAL3RC(RID, _font_get_glyph_texture_rid, RID, const Vector2i &, int64_t);
+ GDVIRTUAL3RC_REQUIRED(RID, _font_get_glyph_texture_rid, RID, const Vector2i &, int64_t);
virtual Size2 font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- GDVIRTUAL3RC(Size2, _font_get_glyph_texture_size, RID, const Vector2i &, int64_t);
+ GDVIRTUAL3RC_REQUIRED(Size2, _font_get_glyph_texture_size, RID, const Vector2i &, int64_t);
virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override;
GDVIRTUAL3RC(Dictionary, _font_get_glyph_contours, RID, int64_t, int64_t);
@@ -316,17 +316,17 @@ public:
GDVIRTUAL3RC(Vector2, _font_get_kerning, RID, int64_t, const Vector2i &);
virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector = 0) const override;
- GDVIRTUAL4RC(int64_t, _font_get_glyph_index, RID, int64_t, int64_t, int64_t);
+ GDVIRTUAL4RC_REQUIRED(int64_t, _font_get_glyph_index, RID, int64_t, int64_t, int64_t);
virtual int64_t font_get_char_from_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_glyph_index) const override;
- GDVIRTUAL3RC(int64_t, _font_get_char_from_glyph_index, RID, int64_t, int64_t);
+ GDVIRTUAL3RC_REQUIRED(int64_t, _font_get_char_from_glyph_index, RID, int64_t, int64_t);
virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override;
virtual String font_get_supported_chars(const RID &p_font_rid) const override;
virtual PackedInt32Array font_get_supported_glyphs(const RID &p_font_rid) const override;
- GDVIRTUAL2RC(bool, _font_has_char, RID, int64_t);
- GDVIRTUAL1RC(String, _font_get_supported_chars, RID);
- GDVIRTUAL1RC(PackedInt32Array, _font_get_supported_glyphs, RID);
+ GDVIRTUAL2RC_REQUIRED(bool, _font_has_char, RID, int64_t);
+ GDVIRTUAL1RC_REQUIRED(String, _font_get_supported_chars, RID);
+ GDVIRTUAL1RC_REQUIRED(PackedInt32Array, _font_get_supported_glyphs, RID);
virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) override;
virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) override;
@@ -335,8 +335,8 @@ public:
virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
- GDVIRTUAL6C(_font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &);
- GDVIRTUAL7C(_font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &);
+ GDVIRTUAL6C_REQUIRED(_font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &);
+ GDVIRTUAL7C_REQUIRED(_font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &);
virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const override;
virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) override;
@@ -383,10 +383,10 @@ public:
/* Shaped text buffer interface */
virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
- GDVIRTUAL2R(RID, _create_shaped_text, Direction, Orientation);
+ GDVIRTUAL2R_REQUIRED(RID, _create_shaped_text, Direction, Orientation);
virtual void shaped_text_clear(const RID &p_shaped) override;
- GDVIRTUAL1(_shaped_text_clear, RID);
+ GDVIRTUAL1_REQUIRED(_shaped_text_clear, RID);
virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) override;
virtual Direction shaped_text_get_direction(const RID &p_shaped) const override;
@@ -431,21 +431,21 @@ public:
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1, double p_baseline = 0.0) override;
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, double p_baseline = 0.0) override;
- GDVIRTUAL7R(bool, _shaped_text_add_string, RID, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &);
- GDVIRTUAL6R(bool, _shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t, double);
- GDVIRTUAL5R(bool, _shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment, double);
+ GDVIRTUAL7R_REQUIRED(bool, _shaped_text_add_string, RID, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &);
+ GDVIRTUAL6R_REQUIRED(bool, _shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t, double);
+ GDVIRTUAL5R_REQUIRED(bool, _shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment, double);
virtual int64_t shaped_get_span_count(const RID &p_shaped) const override;
virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override;
virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override;
- GDVIRTUAL1RC(int64_t, _shaped_get_span_count, RID);
- GDVIRTUAL2RC(Variant, _shaped_get_span_meta, RID, int64_t);
- GDVIRTUAL5(_shaped_set_span_update_font, RID, int64_t, const TypedArray<RID> &, int64_t, const Dictionary &);
+ GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_get_span_count, RID);
+ GDVIRTUAL2RC_REQUIRED(Variant, _shaped_get_span_meta, RID, int64_t);
+ GDVIRTUAL5_REQUIRED(_shaped_set_span_update_font, RID, int64_t, const TypedArray<RID> &, int64_t, const Dictionary &);
virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override;
virtual RID shaped_text_get_parent(const RID &p_shaped) const override;
- GDVIRTUAL3RC(RID, _shaped_text_substr, RID, int64_t, int64_t);
- GDVIRTUAL1RC(RID, _shaped_text_get_parent, RID);
+ GDVIRTUAL3RC_REQUIRED(RID, _shaped_text_substr, RID, int64_t, int64_t);
+ GDVIRTUAL1RC_REQUIRED(RID, _shaped_text_get_parent, RID);
virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override;
@@ -455,22 +455,22 @@ public:
virtual bool shaped_text_shape(const RID &p_shaped) override;
virtual bool shaped_text_update_breaks(const RID &p_shaped) override;
virtual bool shaped_text_update_justification_ops(const RID &p_shaped) override;
- GDVIRTUAL1R(bool, _shaped_text_shape, RID);
+ GDVIRTUAL1R_REQUIRED(bool, _shaped_text_shape, RID);
GDVIRTUAL1R(bool, _shaped_text_update_breaks, RID);
GDVIRTUAL1R(bool, _shaped_text_update_justification_ops, RID);
virtual bool shaped_text_is_ready(const RID &p_shaped) const override;
- GDVIRTUAL1RC(bool, _shaped_text_is_ready, RID);
+ GDVIRTUAL1RC_REQUIRED(bool, _shaped_text_is_ready, RID);
virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const override;
virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) override;
virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const override;
- GDVIRTUAL1RC(GDExtensionConstPtr<const Glyph>, _shaped_text_get_glyphs, RID);
- GDVIRTUAL1R(GDExtensionConstPtr<const Glyph>, _shaped_text_sort_logical, RID);
- GDVIRTUAL1RC(int64_t, _shaped_text_get_glyph_count, RID);
+ GDVIRTUAL1RC_REQUIRED(GDExtensionConstPtr<const Glyph>, _shaped_text_get_glyphs, RID);
+ GDVIRTUAL1R_REQUIRED(GDExtensionConstPtr<const Glyph>, _shaped_text_sort_logical, RID);
+ GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_text_get_glyph_count, RID);
virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override;
- GDVIRTUAL1RC(Vector2i, _shaped_text_get_range, RID);
+ GDVIRTUAL1RC_REQUIRED(Vector2i, _shaped_text_get_range, RID);
virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, BitField<TextServer::LineBreakFlag> p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, BitField<TextServer::LineBreakFlag> p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
@@ -483,10 +483,10 @@ public:
virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override;
virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override;
virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override;
- GDVIRTUAL1RC(int64_t, _shaped_text_get_trim_pos, RID);
- GDVIRTUAL1RC(int64_t, _shaped_text_get_ellipsis_pos, RID);
- GDVIRTUAL1RC(GDExtensionConstPtr<const Glyph>, _shaped_text_get_ellipsis_glyphs, RID);
- GDVIRTUAL1RC(int64_t, _shaped_text_get_ellipsis_glyph_count, RID);
+ GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_text_get_trim_pos, RID);
+ GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_text_get_ellipsis_pos, RID);
+ GDVIRTUAL1RC_REQUIRED(GDExtensionConstPtr<const Glyph>, _shaped_text_get_ellipsis_glyphs, RID);
+ GDVIRTUAL1RC_REQUIRED(int64_t, _shaped_text_get_ellipsis_glyph_count, RID);
virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override;
GDVIRTUAL3(_shaped_text_overrun_trim_to_width, RID, double, BitField<TextServer::TextOverrunFlag>);
@@ -495,10 +495,10 @@ public:
virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override;
virtual Vector2i shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const override;
virtual int64_t shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const override;
- GDVIRTUAL1RC(Array, _shaped_text_get_objects, RID);
- GDVIRTUAL2RC(Rect2, _shaped_text_get_object_rect, RID, const Variant &);
- GDVIRTUAL2RC(Vector2i, _shaped_text_get_object_range, RID, const Variant &);
- GDVIRTUAL2RC(int64_t, _shaped_text_get_object_glyph, RID, const Variant &);
+ GDVIRTUAL1RC_REQUIRED(Array, _shaped_text_get_objects, RID);
+ GDVIRTUAL2RC_REQUIRED(Rect2, _shaped_text_get_object_rect, RID, const Variant &);
+ GDVIRTUAL2RC_REQUIRED(Vector2i, _shaped_text_get_object_range, RID, const Variant &);
+ GDVIRTUAL2RC_REQUIRED(int64_t, _shaped_text_get_object_glyph, RID, const Variant &);
virtual Size2 shaped_text_get_size(const RID &p_shaped) const override;
virtual double shaped_text_get_ascent(const RID &p_shaped) const override;
@@ -506,12 +506,12 @@ public:
virtual double shaped_text_get_width(const RID &p_shaped) const override;
virtual double shaped_text_get_underline_position(const RID &p_shaped) const override;
virtual double shaped_text_get_underline_thickness(const RID &p_shaped) const override;
- GDVIRTUAL1RC(Size2, _shaped_text_get_size, RID);
- GDVIRTUAL1RC(double, _shaped_text_get_ascent, RID);
- GDVIRTUAL1RC(double, _shaped_text_get_descent, RID);
- GDVIRTUAL1RC(double, _shaped_text_get_width, RID);
- GDVIRTUAL1RC(double, _shaped_text_get_underline_position, RID);
- GDVIRTUAL1RC(double, _shaped_text_get_underline_thickness, RID);
+ GDVIRTUAL1RC_REQUIRED(Size2, _shaped_text_get_size, RID);
+ GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_ascent, RID);
+ GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_descent, RID);
+ GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_width, RID);
+ GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_underline_position, RID);
+ GDVIRTUAL1RC_REQUIRED(double, _shaped_text_get_underline_thickness, RID);
virtual Direction shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const override;
GDVIRTUAL3RC(int64_t, _shaped_text_get_dominant_direction_in_range, RID, int64_t, int64_t);
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 4c47b91c8c..a219839afc 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -650,6 +650,10 @@ comments and a patch is provided in the `patches` folder.
Collection of single-file libraries used in Godot components.
+- `bcdec.h`
+ * Upstream: https://github.com/iOrange/bcdec
+ * Version: git (026acf98ea271045cb10713daa96ba98528badb7, 2022)
+ * License: MIT
- `clipper.{cpp,hpp}`
* Upstream: https://sourceforge.net/projects/polyclipping
* Version: 6.4.2 (2017) + Godot changes (added optional exceptions handling)
@@ -757,7 +761,7 @@ with the provided patch.
## openxr
- Upstream: https://github.com/KhronosGroup/OpenXR-SDK
-- Version: 1.1.38 (f90488c4fb1537f4256d09d4a4d3ad5543ebaf24, 2024)
+- Version: 1.1.41 (7d1c0961351bac61fd7bb72d402649d5ac3f2935, 2024)
- License: Apache 2.0
Files extracted from upstream source:
@@ -873,23 +877,6 @@ They can be reapplied using the patches included in the `patches`
folder, in order.
-## squish
-
-- Upstream: https://sourceforge.net/projects/libsquish
-- Version: 1.15 (r104, 2017)
-- License: MIT
-
-Files extracted from upstream source:
-
-- `LICENSE.txt`
-- All `.cpp`, `.h` and `.inl` files
-
-Some downstream changes have been made and are identified by
-`// -- GODOT begin --` and `// -- GODOT end --` comments.
-They can be reapplied using the patches included in the `patches`
-folder.
-
-
## tinyexr
- Upstream: https://github.com/syoyo/tinyexr
diff --git a/thirdparty/misc/bcdec.h b/thirdparty/misc/bcdec.h
new file mode 100644
index 0000000000..78074a0c90
--- /dev/null
+++ b/thirdparty/misc/bcdec.h
@@ -0,0 +1,1329 @@
+/* bcdec.h - v0.96
+ provides functions to decompress blocks of BC compressed images
+ written by Sergii "iOrange" Kudlai in 2022
+
+ This library does not allocate memory and is trying to use as less stack as possible
+
+ The library was never optimized specifically for speed but for the overall size
+ it has zero external dependencies and is not using any runtime functions
+
+ Supported BC formats:
+ BC1 (also known as DXT1) + it's "binary alpha" variant BC1A (DXT1A)
+ BC2 (also known as DXT3)
+ BC3 (also known as DXT5)
+ BC4 (also known as ATI1N)
+ BC5 (also known as ATI2N)
+ BC6H (HDR format)
+ BC7
+
+ BC1/BC2/BC3/BC7 are expected to decompress into 4*4 RGBA blocks 8bit per component (32bit pixel)
+ BC4/BC5 are expected to decompress into 4*4 R/RG blocks 8bit per component (8bit and 16bit pixel)
+ BC6H is expected to decompress into 4*4 RGB blocks of either 32bit float or 16bit "half" per
+ component (96bit or 48bit pixel)
+
+ For more info, issues and suggestions please visit https://github.com/iOrange/bcdec
+
+ CREDITS:
+ Aras Pranckevicius (@aras-p) - BC1/BC3 decoders optimizations (up to 3x the speed)
+ - BC6H/BC7 bits pulling routines optimizations
+ - optimized BC6H by moving unquantize out of the loop
+ - Split BC6H decompression function into 'half' and
+ 'float' variants
+
+ bugfixes:
+ @linkmauve
+
+ LICENSE: See end of file for license information.
+*/
+
+#ifndef BCDEC_HEADER_INCLUDED
+#define BCDEC_HEADER_INCLUDED
+
+/* if BCDEC_STATIC causes problems, try defining BCDECDEF to 'inline' or 'static inline' */
+#ifndef BCDECDEF
+#ifdef BCDEC_STATIC
+#define BCDECDEF static
+#else
+#ifdef __cplusplus
+#define BCDECDEF extern "C"
+#else
+#define BCDECDEF extern
+#endif
+#endif
+#endif
+
+/* Used information sources:
+ https://docs.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression
+ https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc6h-format
+ https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc7-format
+ https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc7-format-mode-reference
+
+ ! WARNING ! Khronos's BPTC partitions tables contain mistakes, do not use them!
+ https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.html#BPTC
+
+ ! Use tables from here instead !
+ https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_bptc.txt
+
+ Leaving it here as it's a nice read
+ https://fgiesen.wordpress.com/2021/10/04/gpu-bcn-decoding/
+
+ Fast half to float function from here
+ https://gist.github.com/rygorous/2144712
+*/
+
+#define BCDEC_BC1_BLOCK_SIZE 8
+#define BCDEC_BC2_BLOCK_SIZE 16
+#define BCDEC_BC3_BLOCK_SIZE 16
+#define BCDEC_BC4_BLOCK_SIZE 8
+#define BCDEC_BC5_BLOCK_SIZE 16
+#define BCDEC_BC6H_BLOCK_SIZE 16
+#define BCDEC_BC7_BLOCK_SIZE 16
+
+#define BCDEC_BC1_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC1_BLOCK_SIZE)
+#define BCDEC_BC2_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC2_BLOCK_SIZE)
+#define BCDEC_BC3_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC3_BLOCK_SIZE)
+#define BCDEC_BC4_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC4_BLOCK_SIZE)
+#define BCDEC_BC5_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC5_BLOCK_SIZE)
+#define BCDEC_BC6H_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC6H_BLOCK_SIZE)
+#define BCDEC_BC7_COMPRESSED_SIZE(w, h) ((((w)>>2)*((h)>>2))*BCDEC_BC7_BLOCK_SIZE)
+
+BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
+BCDECDEF void bcdec_bc2(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
+BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
+BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
+BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
+BCDECDEF void bcdec_bc6h_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
+BCDECDEF void bcdec_bc6h_half(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
+BCDECDEF void bcdec_bc7(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
+
+
+#ifdef BCDEC_IMPLEMENTATION
+
+static void bcdec__color_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int onlyOpaqueMode) {
+ unsigned short c0, c1;
+ unsigned int refColors[4]; /* 0xAABBGGRR */
+ unsigned char* dstColors;
+ unsigned int colorIndices;
+ int i, j, idx;
+ unsigned int r0, g0, b0, r1, g1, b1, r, g, b;
+
+ c0 = ((unsigned short*)compressedBlock)[0];
+ c1 = ((unsigned short*)compressedBlock)[1];
+
+ /* Expand 565 ref colors to 888 */
+ r0 = (((c0 >> 11) & 0x1F) * 527 + 23) >> 6;
+ g0 = (((c0 >> 5) & 0x3F) * 259 + 33) >> 6;
+ b0 = ((c0 & 0x1F) * 527 + 23) >> 6;
+ refColors[0] = 0xFF000000 | (b0 << 16) | (g0 << 8) | r0;
+
+ r1 = (((c1 >> 11) & 0x1F) * 527 + 23) >> 6;
+ g1 = (((c1 >> 5) & 0x3F) * 259 + 33) >> 6;
+ b1 = ((c1 & 0x1F) * 527 + 23) >> 6;
+ refColors[1] = 0xFF000000 | (b1 << 16) | (g1 << 8) | r1;
+
+ if (c0 > c1 || onlyOpaqueMode) { /* Standard BC1 mode (also BC3 color block uses ONLY this mode) */
+ /* color_2 = 2/3*color_0 + 1/3*color_1
+ color_3 = 1/3*color_0 + 2/3*color_1 */
+ r = (2 * r0 + r1 + 1) / 3;
+ g = (2 * g0 + g1 + 1) / 3;
+ b = (2 * b0 + b1 + 1) / 3;
+ refColors[2] = 0xFF000000 | (b << 16) | (g << 8) | r;
+
+ r = (r0 + 2 * r1 + 1) / 3;
+ g = (g0 + 2 * g1 + 1) / 3;
+ b = (b0 + 2 * b1 + 1) / 3;
+ refColors[3] = 0xFF000000 | (b << 16) | (g << 8) | r;
+ } else { /* Quite rare BC1A mode */
+ /* color_2 = 1/2*color_0 + 1/2*color_1;
+ color_3 = 0; */
+ r = (r0 + r1 + 1) >> 1;
+ g = (g0 + g1 + 1) >> 1;
+ b = (b0 + b1 + 1) >> 1;
+ refColors[2] = 0xFF000000 | (b << 16) | (g << 8) | r;
+
+ refColors[3] = 0x00000000;
+ }
+
+ colorIndices = ((unsigned int*)compressedBlock)[1];
+
+ /* Fill out the decompressed color block */
+ dstColors = (unsigned char*)decompressedBlock;
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ idx = colorIndices & 0x03;
+ ((unsigned int*)dstColors)[j] = refColors[idx];
+ colorIndices >>= 2;
+ }
+
+ dstColors += destinationPitch;
+ }
+}
+
+static void bcdec__sharp_alpha_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
+ unsigned short* alpha;
+ unsigned char* decompressed;
+ int i, j;
+
+ alpha = (unsigned short*)compressedBlock;
+ decompressed = (unsigned char*)decompressedBlock;
+
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ decompressed[j * 4] = ((alpha[i] >> (4 * j)) & 0x0F) * 17;
+ }
+
+ decompressed += destinationPitch;
+ }
+}
+
+static void bcdec__smooth_alpha_block(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int pixelSize) {
+ unsigned char* decompressed;
+ unsigned char alpha[8];
+ int i, j;
+ unsigned long long block, indices;
+
+ block = *(unsigned long long*)compressedBlock;
+ decompressed = (unsigned char*)decompressedBlock;
+
+ alpha[0] = block & 0xFF;
+ alpha[1] = (block >> 8) & 0xFF;
+
+ if (alpha[0] > alpha[1]) {
+ /* 6 interpolated alpha values. */
+ alpha[2] = (6 * alpha[0] + alpha[1] + 1) / 7; /* 6/7*alpha_0 + 1/7*alpha_1 */
+ alpha[3] = (5 * alpha[0] + 2 * alpha[1] + 1) / 7; /* 5/7*alpha_0 + 2/7*alpha_1 */
+ alpha[4] = (4 * alpha[0] + 3 * alpha[1] + 1) / 7; /* 4/7*alpha_0 + 3/7*alpha_1 */
+ alpha[5] = (3 * alpha[0] + 4 * alpha[1] + 1) / 7; /* 3/7*alpha_0 + 4/7*alpha_1 */
+ alpha[6] = (2 * alpha[0] + 5 * alpha[1] + 1) / 7; /* 2/7*alpha_0 + 5/7*alpha_1 */
+ alpha[7] = ( alpha[0] + 6 * alpha[1] + 1) / 7; /* 1/7*alpha_0 + 6/7*alpha_1 */
+ }
+ else {
+ /* 4 interpolated alpha values. */
+ alpha[2] = (4 * alpha[0] + alpha[1] + 1) / 5; /* 4/5*alpha_0 + 1/5*alpha_1 */
+ alpha[3] = (3 * alpha[0] + 2 * alpha[1] + 1) / 5; /* 3/5*alpha_0 + 2/5*alpha_1 */
+ alpha[4] = (2 * alpha[0] + 3 * alpha[1] + 1) / 5; /* 2/5*alpha_0 + 3/5*alpha_1 */
+ alpha[5] = ( alpha[0] + 4 * alpha[1] + 1) / 5; /* 1/5*alpha_0 + 4/5*alpha_1 */
+ alpha[6] = 0x00;
+ alpha[7] = 0xFF;
+ }
+
+ indices = block >> 16;
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ decompressed[j * pixelSize] = alpha[indices & 0x07];
+ indices >>= 3;
+ }
+
+ decompressed += destinationPitch;
+ }
+}
+
+typedef struct bcdec__bitstream {
+ unsigned long long low;
+ unsigned long long high;
+} bcdec__bitstream_t;
+
+static int bcdec__bitstream_read_bits(bcdec__bitstream_t* bstream, int numBits) {
+ unsigned int mask = (1 << numBits) - 1;
+ /* Read the low N bits */
+ unsigned int bits = (bstream->low & mask);
+
+ bstream->low >>= numBits;
+ /* Put the low N bits of "high" into the high 64-N bits of "low". */
+ bstream->low |= (bstream->high & mask) << (sizeof(bstream->high) * 8 - numBits);
+ bstream->high >>= numBits;
+
+ return bits;
+}
+
+static int bcdec__bitstream_read_bit(bcdec__bitstream_t* bstream) {
+ return bcdec__bitstream_read_bits(bstream, 1);
+}
+
+/* reversed bits pulling, used in BC6H decoding
+ why ?? just why ??? */
+static int bcdec__bitstream_read_bits_r(bcdec__bitstream_t* bstream, int numBits) {
+ int bits = bcdec__bitstream_read_bits(bstream, numBits);
+ /* Reverse the bits. */
+ int result = 0;
+ while (numBits--) {
+ result <<= 1;
+ result |= (bits & 1);
+ bits >>= 1;
+ }
+ return result;
+}
+
+
+
+BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
+ bcdec__color_block(compressedBlock, decompressedBlock, destinationPitch, 0);
+}
+
+BCDECDEF void bcdec_bc2(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
+ bcdec__color_block(((char*)compressedBlock) + 8, decompressedBlock, destinationPitch, 1);
+ bcdec__sharp_alpha_block(compressedBlock, ((char*)decompressedBlock) + 3, destinationPitch);
+}
+
+BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
+ bcdec__color_block(((char*)compressedBlock) + 8, decompressedBlock, destinationPitch, 1);
+ bcdec__smooth_alpha_block(compressedBlock, ((char*)decompressedBlock) + 3, destinationPitch, 4);
+}
+
+BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
+ bcdec__smooth_alpha_block(compressedBlock, decompressedBlock, destinationPitch, 1);
+}
+
+BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
+ bcdec__smooth_alpha_block(compressedBlock, decompressedBlock, destinationPitch, 2);
+ bcdec__smooth_alpha_block(((char*)compressedBlock) + 8, ((char*)decompressedBlock) + 1, destinationPitch, 2);
+}
+
+/* http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend */
+static int bcdec__extend_sign(int val, int bits) {
+ return (val << (32 - bits)) >> (32 - bits);
+}
+
+static int bcdec__transform_inverse(int val, int a0, int bits, int isSigned) {
+ /* If the precision of A0 is "p" bits, then the transform algorithm is:
+ B0 = (B0 + A0) & ((1 << p) - 1) */
+ val = (val + a0) & ((1 << bits) - 1);
+ if (isSigned) {
+ val = bcdec__extend_sign(val, bits);
+ }
+ return val;
+}
+
+/* pretty much copy-paste from documentation */
+static int bcdec__unquantize(int val, int bits, int isSigned) {
+ int unq, s = 0;
+
+ if (!isSigned) {
+ if (bits >= 15) {
+ unq = val;
+ } else if (!val) {
+ unq = 0;
+ } else if (val == ((1 << bits) - 1)) {
+ unq = 0xFFFF;
+ } else {
+ unq = ((val << 16) + 0x8000) >> bits;
+ }
+ } else {
+ if (bits >= 16) {
+ unq = val;
+ } else {
+ if (val < 0) {
+ s = 1;
+ val = -val;
+ }
+
+ if (val == 0) {
+ unq = 0;
+ } else if (val >= ((1 << (bits - 1)) - 1)) {
+ unq = 0x7FFF;
+ } else {
+ unq = ((val << 15) + 0x4000) >> (bits - 1);
+ }
+
+ if (s) {
+ unq = -unq;
+ }
+ }
+ }
+ return unq;
+}
+
+static int bcdec__interpolate(int a, int b, int* weights, int index) {
+ return (a * (64 - weights[index]) + b * weights[index] + 32) >> 6;
+}
+
+static unsigned short bcdec__finish_unquantize(int val, int isSigned) {
+ int s;
+
+ if (!isSigned) {
+ return (unsigned short)((val * 31) >> 6); /* scale the magnitude by 31 / 64 */
+ } else {
+ val = (val < 0) ? -(((-val) * 31) >> 5) : (val * 31) >> 5; /* scale the magnitude by 31 / 32 */
+ s = 0;
+ if (val < 0) {
+ s = 0x8000;
+ val = -val;
+ }
+ return (unsigned short)(s | val);
+ }
+}
+
+/* modified half_to_float_fast4 from https://gist.github.com/rygorous/2144712 */
+static float bcdec__half_to_float_quick(unsigned short half) {
+ typedef union {
+ unsigned int u;
+ float f;
+ } FP32;
+
+ static const FP32 magic = { 113 << 23 };
+ static const unsigned int shifted_exp = 0x7c00 << 13; /* exponent mask after shift */
+ FP32 o;
+ unsigned int exp;
+
+ o.u = (half & 0x7fff) << 13; /* exponent/mantissa bits */
+ exp = shifted_exp & o.u; /* just the exponent */
+ o.u += (127 - 15) << 23; /* exponent adjust */
+
+ /* handle exponent special cases */
+ if (exp == shifted_exp) { /* Inf/NaN? */
+ o.u += (128 - 16) << 23; /* extra exp adjust */
+ } else if (exp == 0) { /* Zero/Denormal? */
+ o.u += 1 << 23; /* extra exp adjust */
+ o.f -= magic.f; /* renormalize */
+ }
+
+ o.u |= (half & 0x8000) << 16; /* sign bit */
+ return o.f;
+}
+
+BCDECDEF void bcdec_bc6h_half(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) {
+ static char actual_bits_count[4][14] = {
+ { 10, 7, 11, 11, 11, 9, 8, 8, 8, 6, 10, 11, 12, 16 }, /* W */
+ { 5, 6, 5, 4, 4, 5, 6, 5, 5, 6, 10, 9, 8, 4 }, /* dR */
+ { 5, 6, 4, 5, 4, 5, 5, 6, 5, 6, 10, 9, 8, 4 }, /* dG */
+ { 5, 6, 4, 4, 5, 5, 5, 5, 6, 6, 10, 9, 8, 4 } /* dB */
+ };
+
+ /* There are 32 possible partition sets for a two-region tile.
+ Each 4x4 block represents a single shape.
+ Here also every fix-up index has MSB bit set. */
+ static unsigned char partition_sets[32][4][4] = {
+ { {128, 0, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 0 */
+ { {128, 0, 0, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 129} }, /* 1 */
+ { {128, 1, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {0, 1, 1, 129} }, /* 2 */
+ { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 3 */
+ { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 4 */
+ { {128, 0, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 5 */
+ { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 6 */
+ { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 7 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 8 */
+ { {128, 0, 1, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 9 */
+ { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 10 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 1, 1, 129} }, /* 11 */
+ { {128, 0, 0, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 12 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 13 */
+ { {128, 0, 0, 0}, {1, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 14 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 15 */
+ { {128, 0, 0, 0}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {1, 1, 1, 129} }, /* 16 */
+ { {128, 1, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 17 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 1, 0} }, /* 18 */
+ { {128, 1, 129, 1}, {0, 0, 1, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 19 */
+ { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 20 */
+ { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 1, 0, 0}, {1, 1, 1, 0} }, /* 21 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 22 */
+ { {128, 1, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 0, 129} }, /* 23 */
+ { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 24 */
+ { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 25 */
+ { {128, 1, 129, 0}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {0, 1, 1, 0} }, /* 26 */
+ { {128, 0, 129, 1}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {1, 1, 0, 0} }, /* 27 */
+ { {128, 0, 0, 1}, {0, 1, 1, 1}, {129, 1, 1, 0}, {1, 0, 0, 0} }, /* 28 */
+ { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, {0, 0, 0, 0} }, /* 29 */
+ { {128, 1, 129, 1}, {0, 0, 0, 1}, { 1, 0, 0, 0}, {1, 1, 1, 0} }, /* 30 */
+ { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} } /* 31 */
+ };
+
+ static int aWeight3[8] = { 0, 9, 18, 27, 37, 46, 55, 64 };
+ static int aWeight4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 };
+
+ bcdec__bitstream_t bstream;
+ int mode, partition, numPartitions, i, j, partitionSet, indexBits, index, ep_i, actualBits0Mode;
+ int r[4], g[4], b[4]; /* wxyz */
+ unsigned short* decompressed;
+ int* weights;
+
+ decompressed = (unsigned short*)decompressedBlock;
+
+ bstream.low = ((unsigned long long*)compressedBlock)[0];
+ bstream.high = ((unsigned long long*)compressedBlock)[1];
+
+ r[0] = r[1] = r[2] = r[3] = 0;
+ g[0] = g[1] = g[2] = g[3] = 0;
+ b[0] = b[1] = b[2] = b[3] = 0;
+
+ mode = bcdec__bitstream_read_bits(&bstream, 2);
+ if (mode > 1) {
+ mode |= (bcdec__bitstream_read_bits(&bstream, 3) << 2);
+ }
+
+ /* modes >= 11 (10 in my code) are using 0 one, others will read it from the bitstream */
+ partition = 0;
+
+ switch (mode) {
+ /* mode 1 */
+ case 0b00: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 75 bits (10.555, 10.555, 10.555) */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 0;
+ } break;
+
+ /* mode 2 */
+ case 0b01: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 75 bits (7666, 7666, 7666) */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* rw[6:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* gw[6:0] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 7); /* bw[6:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 1;
+ } break;
+
+ /* mode 3 */
+ case 0b00010: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 72 bits (11.555, 11.444, 11.444) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */
+ r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */
+ g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */
+ b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 2;
+ } break;
+
+ /* mode 4 */
+ case 0b00110: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 72 bits (11.444, 11.555, 11.444) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */
+ r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */
+ g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */
+ b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* ry[3:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* rz[3:0] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 3;
+ } break;
+
+ /* mode 5 */
+ case 0b01010: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 72 bits (11.444, 11.444, 11.555) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */
+ r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */
+ g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */
+ b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* ry[3:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* rz[3:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 4;
+ } break;
+
+ /* mode 6 */
+ case 0b01110: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 72 bits (9555, 9555, 9555) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* rw[8:0] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* gw[8:0] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 9); /* bw[8:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 5;
+ } break;
+
+ /* mode 7 */
+ case 0b10010: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 72 bits (8666, 8555, 8555) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 6;
+ } break;
+
+ /* mode 8 */
+ case 0b10110: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 72 bits (8555, 8666, 8555) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* rx[4:0] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* zx[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bx[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 7;
+ } break;
+
+ /* mode 9 */
+ case 0b11010: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 72 bits (8555, 8555, 8666) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* rw[7:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* gw[7:0] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 8); /* bw[7:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* bw[4:0] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 5); /* gx[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 5); /* ry[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 5); /* rz[4:0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 8;
+ } break;
+
+ /* mode 10 */
+ case 0b11110: {
+ /* Partitition indices: 46 bits
+ Partition: 5 bits
+ Color Endpoints: 72 bits (6666, 6666, 6666) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* rw[5:0] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gz[4] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream); /* bz[0] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 1; /* bz[1] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* by[4] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* gw[5:0] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gy[5] */
+ b[2] |= bcdec__bitstream_read_bit(&bstream) << 5; /* by[5] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 2; /* bz[2] */
+ g[2] |= bcdec__bitstream_read_bit(&bstream) << 4; /* gy[4] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 6); /* bw[5:0] */
+ g[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* gz[5] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 3; /* bz[3] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 5; /* bz[5] */
+ b[3] |= bcdec__bitstream_read_bit(&bstream) << 4; /* bz[4] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* rx[5:0] */
+ g[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* gy[3:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* gx[5:0] */
+ g[3] |= bcdec__bitstream_read_bits(&bstream, 4); /* gz[3:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 6); /* bx[5:0] */
+ b[2] |= bcdec__bitstream_read_bits(&bstream, 4); /* by[3:0] */
+ r[2] |= bcdec__bitstream_read_bits(&bstream, 6); /* ry[5:0] */
+ r[3] |= bcdec__bitstream_read_bits(&bstream, 6); /* rz[5:0] */
+ partition = bcdec__bitstream_read_bits(&bstream, 5); /* d[4:0] */
+ mode = 9;
+ } break;
+
+ /* mode 11 */
+ case 0b00011: {
+ /* Partitition indices: 63 bits
+ Partition: 0 bits
+ Color Endpoints: 60 bits (10.10, 10.10, 10.10) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* rx[9:0] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* gx[9:0] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 10); /* bx[9:0] */
+ mode = 10;
+ } break;
+
+ /* mode 12 */
+ case 0b00111: {
+ /* Partitition indices: 63 bits
+ Partition: 0 bits
+ Color Endpoints: 60 bits (11.9, 11.9, 11.9) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* rx[8:0] */
+ r[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* rw[10] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* gx[8:0] */
+ g[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* gw[10] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 9); /* bx[8:0] */
+ b[0] |= bcdec__bitstream_read_bit(&bstream) << 10; /* bw[10] */
+ mode = 11;
+ } break;
+
+ /* mode 13 */
+ case 0b01011: {
+ /* Partitition indices: 63 bits
+ Partition: 0 bits
+ Color Endpoints: 60 bits (12.8, 12.8, 12.8) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* rx[7:0] */
+ r[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* rx[10:11] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* gx[7:0] */
+ g[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* gx[10:11] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 8); /* bx[7:0] */
+ b[0] |= bcdec__bitstream_read_bits_r(&bstream, 2) << 10;/* bx[10:11] */
+ mode = 12;
+ } break;
+
+ /* mode 14 */
+ case 0b01111: {
+ /* Partitition indices: 63 bits
+ Partition: 0 bits
+ Color Endpoints: 60 bits (16.4, 16.4, 16.4) */
+ r[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* rw[9:0] */
+ g[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* gw[9:0] */
+ b[0] |= bcdec__bitstream_read_bits(&bstream, 10); /* bw[9:0] */
+ r[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* rx[3:0] */
+ r[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* rw[10:15] */
+ g[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* gx[3:0] */
+ g[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* gw[10:15] */
+ b[1] |= bcdec__bitstream_read_bits(&bstream, 4); /* bx[3:0] */
+ b[0] |= bcdec__bitstream_read_bits_r(&bstream, 6) << 10;/* bw[10:15] */
+ mode = 13;
+ } break;
+
+ default: {
+ /* Modes 10011, 10111, 11011, and 11111 (not shown) are reserved.
+ Do not use these in your encoder. If the hardware is passed blocks
+ with one of these modes specified, the resulting decompressed block
+ must contain all zeroes in all channels except for the alpha channel. */
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ decompressed[j * 3 + 0] = 0;
+ decompressed[j * 3 + 1] = 0;
+ decompressed[j * 3 + 2] = 0;
+ }
+ decompressed += destinationPitch;
+ }
+
+ return;
+ }
+ }
+
+ numPartitions = (mode >= 10) ? 0 : 1;
+
+ actualBits0Mode = actual_bits_count[0][mode];
+ if (isSigned) {
+ r[0] = bcdec__extend_sign(r[0], actualBits0Mode);
+ g[0] = bcdec__extend_sign(g[0], actualBits0Mode);
+ b[0] = bcdec__extend_sign(b[0], actualBits0Mode);
+ }
+
+ /* Mode 11 (like Mode 10) does not use delta compression,
+ and instead stores both color endpoints explicitly. */
+ if ((mode != 9 && mode != 10) || isSigned) {
+ for (i = 1; i < (numPartitions + 1) * 2; ++i) {
+ r[i] = bcdec__extend_sign(r[i], actual_bits_count[1][mode]);
+ g[i] = bcdec__extend_sign(g[i], actual_bits_count[2][mode]);
+ b[i] = bcdec__extend_sign(b[i], actual_bits_count[3][mode]);
+ }
+ }
+
+ if (mode != 9 && mode != 10) {
+ for (i = 1; i < (numPartitions + 1) * 2; ++i) {
+ r[i] = bcdec__transform_inverse(r[i], r[0], actualBits0Mode, isSigned);
+ g[i] = bcdec__transform_inverse(g[i], g[0], actualBits0Mode, isSigned);
+ b[i] = bcdec__transform_inverse(b[i], b[0], actualBits0Mode, isSigned);
+ }
+ }
+
+ for (i = 0; i < (numPartitions + 1) * 2; ++i) {
+ r[i] = bcdec__unquantize(r[i], actualBits0Mode, isSigned);
+ g[i] = bcdec__unquantize(g[i], actualBits0Mode, isSigned);
+ b[i] = bcdec__unquantize(b[i], actualBits0Mode, isSigned);
+ }
+
+ weights = (mode >= 10) ? aWeight4 : aWeight3;
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ partitionSet = (mode >= 10) ? ((i|j) ? 0 : 128) : partition_sets[partition][i][j];
+
+ indexBits = (mode >= 10) ? 4 : 3;
+ /* fix-up index is specified with one less bit */
+ /* The fix-up index for subset 0 is always index 0 */
+ if (partitionSet & 0x80) {
+ indexBits--;
+ }
+ partitionSet &= 0x01;
+
+ index = bcdec__bitstream_read_bits(&bstream, indexBits);
+
+ ep_i = partitionSet * 2;
+ decompressed[j * 3 + 0] = bcdec__finish_unquantize(
+ bcdec__interpolate(r[ep_i], r[ep_i+1], weights, index), isSigned);
+ decompressed[j * 3 + 1] = bcdec__finish_unquantize(
+ bcdec__interpolate(g[ep_i], g[ep_i+1], weights, index), isSigned);
+ decompressed[j * 3 + 2] = bcdec__finish_unquantize(
+ bcdec__interpolate(b[ep_i], b[ep_i+1], weights, index), isSigned);
+ }
+
+ decompressed += destinationPitch;
+ }
+}
+
+BCDECDEF void bcdec_bc6h_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned) {
+ unsigned short block[16*3];
+ float* decompressed;
+ const unsigned short* b;
+ int i, j;
+
+ bcdec_bc6h_half(compressedBlock, block, 4*3, isSigned);
+ b = block;
+ decompressed = (float*)decompressedBlock;
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ decompressed[j * 3 + 0] = bcdec__half_to_float_quick(*b++);
+ decompressed[j * 3 + 1] = bcdec__half_to_float_quick(*b++);
+ decompressed[j * 3 + 2] = bcdec__half_to_float_quick(*b++);
+ }
+ decompressed += destinationPitch;
+ }
+}
+
+static void bcdec__swap_values(int* a, int* b) {
+ a[0] ^= b[0], b[0] ^= a[0], a[0] ^= b[0];
+}
+
+BCDECDEF void bcdec_bc7(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
+ static char actual_bits_count[2][8] = {
+ { 4, 6, 5, 7, 5, 7, 7, 5 }, /* RGBA */
+ { 0, 0, 0, 0, 6, 8, 7, 5 }, /* Alpha */
+ };
+
+ /* There are 64 possible partition sets for a two-region tile.
+ Each 4x4 block represents a single shape.
+ Here also every fix-up index has MSB bit set. */
+ static unsigned char partition_sets[2][64][4][4] = {
+ { /* Partition table for 2-subset BPTC */
+ { {128, 0, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 0 */
+ { {128, 0, 0, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 129} }, /* 1 */
+ { {128, 1, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {0, 1, 1, 129} }, /* 2 */
+ { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 3 */
+ { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 4 */
+ { {128, 0, 1, 1}, {0, 1, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 5 */
+ { {128, 0, 0, 1}, {0, 0, 1, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 6 */
+ { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 0, 1, 1}, {0, 1, 1, 129} }, /* 7 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 0, 1, 129} }, /* 8 */
+ { {128, 0, 1, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 9 */
+ { {128, 0, 0, 0}, {0, 0, 0, 1}, { 0, 1, 1, 1}, {1, 1, 1, 129} }, /* 10 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 1}, {0, 1, 1, 129} }, /* 11 */
+ { {128, 0, 0, 1}, {0, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 12 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 13 */
+ { {128, 0, 0, 0}, {1, 1, 1, 1}, { 1, 1, 1, 1}, {1, 1, 1, 129} }, /* 14 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 15 */
+ { {128, 0, 0, 0}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {1, 1, 1, 129} }, /* 16 */
+ { {128, 1, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 17 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 1, 0} }, /* 18 */
+ { {128, 1, 129, 1}, {0, 0, 1, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 19 */
+ { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 0}, {0, 0, 0, 0} }, /* 20 */
+ { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 1, 0, 0}, {1, 1, 1, 0} }, /* 21 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 22 */
+ { {128, 1, 1, 1}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {0, 0, 0, 129} }, /* 23 */
+ { {128, 0, 129, 1}, {0, 0, 0, 1}, { 0, 0, 0, 1}, {0, 0, 0, 0} }, /* 24 */
+ { {128, 0, 0, 0}, {1, 0, 0, 0}, {129, 0, 0, 0}, {1, 1, 0, 0} }, /* 25 */
+ { {128, 1, 129, 0}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {0, 1, 1, 0} }, /* 26 */
+ { {128, 0, 129, 1}, {0, 1, 1, 0}, { 0, 1, 1, 0}, {1, 1, 0, 0} }, /* 27 */
+ { {128, 0, 0, 1}, {0, 1, 1, 1}, {129, 1, 1, 0}, {1, 0, 0, 0} }, /* 28 */
+ { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, {0, 0, 0, 0} }, /* 29 */
+ { {128, 1, 129, 1}, {0, 0, 0, 1}, { 1, 0, 0, 0}, {1, 1, 1, 0} }, /* 30 */
+ { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} }, /* 31 */
+ { {128, 1, 0, 1}, {0, 1, 0, 1}, { 0, 1, 0, 1}, {0, 1, 0, 129} }, /* 32 */
+ { {128, 0, 0, 0}, {1, 1, 1, 1}, { 0, 0, 0, 0}, {1, 1, 1, 129} }, /* 33 */
+ { {128, 1, 0, 1}, {1, 0, 129, 0}, { 0, 1, 0, 1}, {1, 0, 1, 0} }, /* 34 */
+ { {128, 0, 1, 1}, {0, 0, 1, 1}, {129, 1, 0, 0}, {1, 1, 0, 0} }, /* 35 */
+ { {128, 0, 129, 1}, {1, 1, 0, 0}, { 0, 0, 1, 1}, {1, 1, 0, 0} }, /* 36 */
+ { {128, 1, 0, 1}, {0, 1, 0, 1}, {129, 0, 1, 0}, {1, 0, 1, 0} }, /* 37 */
+ { {128, 1, 1, 0}, {1, 0, 0, 1}, { 0, 1, 1, 0}, {1, 0, 0, 129} }, /* 38 */
+ { {128, 1, 0, 1}, {1, 0, 1, 0}, { 1, 0, 1, 0}, {0, 1, 0, 129} }, /* 39 */
+ { {128, 1, 129, 1}, {0, 0, 1, 1}, { 1, 1, 0, 0}, {1, 1, 1, 0} }, /* 40 */
+ { {128, 0, 0, 1}, {0, 0, 1, 1}, {129, 1, 0, 0}, {1, 0, 0, 0} }, /* 41 */
+ { {128, 0, 129, 1}, {0, 0, 1, 0}, { 0, 1, 0, 0}, {1, 1, 0, 0} }, /* 42 */
+ { {128, 0, 129, 1}, {1, 0, 1, 1}, { 1, 1, 0, 1}, {1, 1, 0, 0} }, /* 43 */
+ { {128, 1, 129, 0}, {1, 0, 0, 1}, { 1, 0, 0, 1}, {0, 1, 1, 0} }, /* 44 */
+ { {128, 0, 1, 1}, {1, 1, 0, 0}, { 1, 1, 0, 0}, {0, 0, 1, 129} }, /* 45 */
+ { {128, 1, 1, 0}, {0, 1, 1, 0}, { 1, 0, 0, 1}, {1, 0, 0, 129} }, /* 46 */
+ { {128, 0, 0, 0}, {0, 1, 129, 0}, { 0, 1, 1, 0}, {0, 0, 0, 0} }, /* 47 */
+ { {128, 1, 0, 0}, {1, 1, 129, 0}, { 0, 1, 0, 0}, {0, 0, 0, 0} }, /* 48 */
+ { {128, 0, 129, 0}, {0, 1, 1, 1}, { 0, 0, 1, 0}, {0, 0, 0, 0} }, /* 49 */
+ { {128, 0, 0, 0}, {0, 0, 129, 0}, { 0, 1, 1, 1}, {0, 0, 1, 0} }, /* 50 */
+ { {128, 0, 0, 0}, {0, 1, 0, 0}, {129, 1, 1, 0}, {0, 1, 0, 0} }, /* 51 */
+ { {128, 1, 1, 0}, {1, 1, 0, 0}, { 1, 0, 0, 1}, {0, 0, 1, 129} }, /* 52 */
+ { {128, 0, 1, 1}, {0, 1, 1, 0}, { 1, 1, 0, 0}, {1, 0, 0, 129} }, /* 53 */
+ { {128, 1, 129, 0}, {0, 0, 1, 1}, { 1, 0, 0, 1}, {1, 1, 0, 0} }, /* 54 */
+ { {128, 0, 129, 1}, {1, 0, 0, 1}, { 1, 1, 0, 0}, {0, 1, 1, 0} }, /* 55 */
+ { {128, 1, 1, 0}, {1, 1, 0, 0}, { 1, 1, 0, 0}, {1, 0, 0, 129} }, /* 56 */
+ { {128, 1, 1, 0}, {0, 0, 1, 1}, { 0, 0, 1, 1}, {1, 0, 0, 129} }, /* 57 */
+ { {128, 1, 1, 1}, {1, 1, 1, 0}, { 1, 0, 0, 0}, {0, 0, 0, 129} }, /* 58 */
+ { {128, 0, 0, 1}, {1, 0, 0, 0}, { 1, 1, 1, 0}, {0, 1, 1, 129} }, /* 59 */
+ { {128, 0, 0, 0}, {1, 1, 1, 1}, { 0, 0, 1, 1}, {0, 0, 1, 129} }, /* 60 */
+ { {128, 0, 129, 1}, {0, 0, 1, 1}, { 1, 1, 1, 1}, {0, 0, 0, 0} }, /* 61 */
+ { {128, 0, 129, 0}, {0, 0, 1, 0}, { 1, 1, 1, 0}, {1, 1, 1, 0} }, /* 62 */
+ { {128, 1, 0, 0}, {0, 1, 0, 0}, { 0, 1, 1, 1}, {0, 1, 1, 129} } /* 63 */
+ },
+ { /* Partition table for 3-subset BPTC */
+ { {128, 0, 1, 129}, {0, 0, 1, 1}, { 0, 2, 2, 1}, { 2, 2, 2, 130} }, /* 0 */
+ { {128, 0, 0, 129}, {0, 0, 1, 1}, {130, 2, 1, 1}, { 2, 2, 2, 1} }, /* 1 */
+ { {128, 0, 0, 0}, {2, 0, 0, 1}, {130, 2, 1, 1}, { 2, 2, 1, 129} }, /* 2 */
+ { {128, 2, 2, 130}, {0, 0, 2, 2}, { 0, 0, 1, 1}, { 0, 1, 1, 129} }, /* 3 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 1, 2, 2}, { 1, 1, 2, 130} }, /* 4 */
+ { {128, 0, 1, 129}, {0, 0, 1, 1}, { 0, 0, 2, 2}, { 0, 0, 2, 130} }, /* 5 */
+ { {128, 0, 2, 130}, {0, 0, 2, 2}, { 1, 1, 1, 1}, { 1, 1, 1, 129} }, /* 6 */
+ { {128, 0, 1, 1}, {0, 0, 1, 1}, {130, 2, 1, 1}, { 2, 2, 1, 129} }, /* 7 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, {129, 1, 1, 1}, { 2, 2, 2, 130} }, /* 8 */
+ { {128, 0, 0, 0}, {1, 1, 1, 1}, {129, 1, 1, 1}, { 2, 2, 2, 130} }, /* 9 */
+ { {128, 0, 0, 0}, {1, 1, 129, 1}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 10 */
+ { {128, 0, 1, 2}, {0, 0, 129, 2}, { 0, 0, 1, 2}, { 0, 0, 1, 130} }, /* 11 */
+ { {128, 1, 1, 2}, {0, 1, 129, 2}, { 0, 1, 1, 2}, { 0, 1, 1, 130} }, /* 12 */
+ { {128, 1, 2, 2}, {0, 129, 2, 2}, { 0, 1, 2, 2}, { 0, 1, 2, 130} }, /* 13 */
+ { {128, 0, 1, 129}, {0, 1, 1, 2}, { 1, 1, 2, 2}, { 1, 2, 2, 130} }, /* 14 */
+ { {128, 0, 1, 129}, {2, 0, 0, 1}, {130, 2, 0, 0}, { 2, 2, 2, 0} }, /* 15 */
+ { {128, 0, 0, 129}, {0, 0, 1, 1}, { 0, 1, 1, 2}, { 1, 1, 2, 130} }, /* 16 */
+ { {128, 1, 1, 129}, {0, 0, 1, 1}, {130, 0, 0, 1}, { 2, 2, 0, 0} }, /* 17 */
+ { {128, 0, 0, 0}, {1, 1, 2, 2}, {129, 1, 2, 2}, { 1, 1, 2, 130} }, /* 18 */
+ { {128, 0, 2, 130}, {0, 0, 2, 2}, { 0, 0, 2, 2}, { 1, 1, 1, 129} }, /* 19 */
+ { {128, 1, 1, 129}, {0, 1, 1, 1}, { 0, 2, 2, 2}, { 0, 2, 2, 130} }, /* 20 */
+ { {128, 0, 0, 129}, {0, 0, 0, 1}, {130, 2, 2, 1}, { 2, 2, 2, 1} }, /* 21 */
+ { {128, 0, 0, 0}, {0, 0, 129, 1}, { 0, 1, 2, 2}, { 0, 1, 2, 130} }, /* 22 */
+ { {128, 0, 0, 0}, {1, 1, 0, 0}, {130, 2, 129, 0}, { 2, 2, 1, 0} }, /* 23 */
+ { {128, 1, 2, 130}, {0, 129, 2, 2}, { 0, 0, 1, 1}, { 0, 0, 0, 0} }, /* 24 */
+ { {128, 0, 1, 2}, {0, 0, 1, 2}, {129, 1, 2, 2}, { 2, 2, 2, 130} }, /* 25 */
+ { {128, 1, 1, 0}, {1, 2, 130, 1}, {129, 2, 2, 1}, { 0, 1, 1, 0} }, /* 26 */
+ { {128, 0, 0, 0}, {0, 1, 129, 0}, { 1, 2, 130, 1}, { 1, 2, 2, 1} }, /* 27 */
+ { {128, 0, 2, 2}, {1, 1, 0, 2}, {129, 1, 0, 2}, { 0, 0, 2, 130} }, /* 28 */
+ { {128, 1, 1, 0}, {0, 129, 1, 0}, { 2, 0, 0, 2}, { 2, 2, 2, 130} }, /* 29 */
+ { {128, 0, 1, 1}, {0, 1, 2, 2}, { 0, 1, 130, 2}, { 0, 0, 1, 129} }, /* 30 */
+ { {128, 0, 0, 0}, {2, 0, 0, 0}, {130, 2, 1, 1}, { 2, 2, 2, 129} }, /* 31 */
+ { {128, 0, 0, 0}, {0, 0, 0, 2}, {129, 1, 2, 2}, { 1, 2, 2, 130} }, /* 32 */
+ { {128, 2, 2, 130}, {0, 0, 2, 2}, { 0, 0, 1, 2}, { 0, 0, 1, 129} }, /* 33 */
+ { {128, 0, 1, 129}, {0, 0, 1, 2}, { 0, 0, 2, 2}, { 0, 2, 2, 130} }, /* 34 */
+ { {128, 1, 2, 0}, {0, 129, 2, 0}, { 0, 1, 130, 0}, { 0, 1, 2, 0} }, /* 35 */
+ { {128, 0, 0, 0}, {1, 1, 129, 1}, { 2, 2, 130, 2}, { 0, 0, 0, 0} }, /* 36 */
+ { {128, 1, 2, 0}, {1, 2, 0, 1}, {130, 0, 129, 2}, { 0, 1, 2, 0} }, /* 37 */
+ { {128, 1, 2, 0}, {2, 0, 1, 2}, {129, 130, 0, 1}, { 0, 1, 2, 0} }, /* 38 */
+ { {128, 0, 1, 1}, {2, 2, 0, 0}, { 1, 1, 130, 2}, { 0, 0, 1, 129} }, /* 39 */
+ { {128, 0, 1, 1}, {1, 1, 130, 2}, { 2, 2, 0, 0}, { 0, 0, 1, 129} }, /* 40 */
+ { {128, 1, 0, 129}, {0, 1, 0, 1}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 41 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, {130, 1, 2, 1}, { 2, 1, 2, 129} }, /* 42 */
+ { {128, 0, 2, 2}, {1, 129, 2, 2}, { 0, 0, 2, 2}, { 1, 1, 2, 130} }, /* 43 */
+ { {128, 0, 2, 130}, {0, 0, 1, 1}, { 0, 0, 2, 2}, { 0, 0, 1, 129} }, /* 44 */
+ { {128, 2, 2, 0}, {1, 2, 130, 1}, { 0, 2, 2, 0}, { 1, 2, 2, 129} }, /* 45 */
+ { {128, 1, 0, 1}, {2, 2, 130, 2}, { 2, 2, 2, 2}, { 0, 1, 0, 129} }, /* 46 */
+ { {128, 0, 0, 0}, {2, 1, 2, 1}, {130, 1, 2, 1}, { 2, 1, 2, 129} }, /* 47 */
+ { {128, 1, 0, 129}, {0, 1, 0, 1}, { 0, 1, 0, 1}, { 2, 2, 2, 130} }, /* 48 */
+ { {128, 2, 2, 130}, {0, 1, 1, 1}, { 0, 2, 2, 2}, { 0, 1, 1, 129} }, /* 49 */
+ { {128, 0, 0, 2}, {1, 129, 1, 2}, { 0, 0, 0, 2}, { 1, 1, 1, 130} }, /* 50 */
+ { {128, 0, 0, 0}, {2, 129, 1, 2}, { 2, 1, 1, 2}, { 2, 1, 1, 130} }, /* 51 */
+ { {128, 2, 2, 2}, {0, 129, 1, 1}, { 0, 1, 1, 1}, { 0, 2, 2, 130} }, /* 52 */
+ { {128, 0, 0, 2}, {1, 1, 1, 2}, {129, 1, 1, 2}, { 0, 0, 0, 130} }, /* 53 */
+ { {128, 1, 1, 0}, {0, 129, 1, 0}, { 0, 1, 1, 0}, { 2, 2, 2, 130} }, /* 54 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 2, 1, 129, 2}, { 2, 1, 1, 130} }, /* 55 */
+ { {128, 1, 1, 0}, {0, 129, 1, 0}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 56 */
+ { {128, 0, 2, 2}, {0, 0, 1, 1}, { 0, 0, 129, 1}, { 0, 0, 2, 130} }, /* 57 */
+ { {128, 0, 2, 2}, {1, 1, 2, 2}, {129, 1, 2, 2}, { 0, 0, 2, 130} }, /* 58 */
+ { {128, 0, 0, 0}, {0, 0, 0, 0}, { 0, 0, 0, 0}, { 2, 129, 1, 130} }, /* 59 */
+ { {128, 0, 0, 130}, {0, 0, 0, 1}, { 0, 0, 0, 2}, { 0, 0, 0, 129} }, /* 60 */
+ { {128, 2, 2, 2}, {1, 2, 2, 2}, { 0, 2, 2, 2}, {129, 2, 2, 130} }, /* 61 */
+ { {128, 1, 0, 129}, {2, 2, 2, 2}, { 2, 2, 2, 2}, { 2, 2, 2, 130} }, /* 62 */
+ { {128, 1, 1, 129}, {2, 0, 1, 1}, {130, 2, 0, 1}, { 2, 2, 2, 0} } /* 63 */
+ }
+ };
+
+ static int aWeight2[] = { 0, 21, 43, 64 };
+ static int aWeight3[] = { 0, 9, 18, 27, 37, 46, 55, 64 };
+ static int aWeight4[] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 };
+
+ static unsigned char sModeHasPBits = 0b11001011;
+
+ bcdec__bitstream_t bstream;
+ int mode, partition, numPartitions, numEndpoints, i, j, k, rotation, partitionSet;
+ int indexSelectionBit, indexBits, indexBits2, index, index2;
+ int endpoints[6][4];
+ char indices[4][4];
+ int r, g, b, a;
+ int* weights, * weights2;
+ unsigned char* decompressed;
+
+ decompressed = (unsigned char*)decompressedBlock;
+
+ bstream.low = ((unsigned long long*)compressedBlock)[0];
+ bstream.high = ((unsigned long long*)compressedBlock)[1];
+
+ for (mode = 0; mode < 8 && (0 == bcdec__bitstream_read_bit(&bstream)); ++mode);
+
+ /* unexpected mode, clear the block (transparent black) */
+ if (mode >= 8) {
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ decompressed[j * 4 + 0] = 0;
+ decompressed[j * 4 + 1] = 0;
+ decompressed[j * 4 + 2] = 0;
+ decompressed[j * 4 + 3] = 0;
+ }
+ decompressed += destinationPitch;
+ }
+
+ return;
+ }
+
+ partition = 0;
+ numPartitions = 1;
+ rotation = 0;
+ indexSelectionBit = 0;
+
+ if (mode == 0 || mode == 1 || mode == 2 || mode == 3 || mode == 7) {
+ numPartitions = (mode == 0 || mode == 2) ? 3 : 2;
+ partition = bcdec__bitstream_read_bits(&bstream, (mode == 0) ? 4 : 6);
+ }
+
+ numEndpoints = numPartitions * 2;
+
+ if (mode == 4 || mode == 5) {
+ rotation = bcdec__bitstream_read_bits(&bstream, 2);
+
+ if (mode == 4) {
+ indexSelectionBit = bcdec__bitstream_read_bit(&bstream);
+ }
+ }
+
+ /* Extract endpoints */
+ /* RGB */
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < numEndpoints; ++j) {
+ endpoints[j][i] = bcdec__bitstream_read_bits(&bstream, actual_bits_count[0][mode]);
+ }
+ }
+ /* Alpha (if any) */
+ if (actual_bits_count[1][mode] > 0) {
+ for (j = 0; j < numEndpoints; ++j) {
+ endpoints[j][3] = bcdec__bitstream_read_bits(&bstream, actual_bits_count[1][mode]);
+ }
+ }
+
+ /* Fully decode endpoints */
+ /* First handle modes that have P-bits */
+ if (mode == 0 || mode == 1 || mode == 3 || mode == 6 || mode == 7) {
+ for (i = 0; i < numEndpoints; ++i) {
+ /* component-wise left-shift */
+ for (j = 0; j < 4; ++j) {
+ endpoints[i][j] <<= 1;
+ }
+ }
+
+ /* if P-bit is shared */
+ if (mode == 1) {
+ i = bcdec__bitstream_read_bit(&bstream);
+ j = bcdec__bitstream_read_bit(&bstream);
+
+ /* rgb component-wise insert pbits */
+ for (k = 0; k < 3; ++k) {
+ endpoints[0][k] |= i;
+ endpoints[1][k] |= i;
+ endpoints[2][k] |= j;
+ endpoints[3][k] |= j;
+ }
+ } else if (sModeHasPBits & (1 << mode)) {
+ /* unique P-bit per endpoint */
+ for (i = 0; i < numEndpoints; ++i) {
+ j = bcdec__bitstream_read_bit(&bstream);
+ for (k = 0; k < 4; ++k) {
+ endpoints[i][k] |= j;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < numEndpoints; ++i) {
+ /* get color components precision including pbit */
+ j = actual_bits_count[0][mode] + ((sModeHasPBits >> mode) & 1);
+
+ for (k = 0; k < 3; ++k) {
+ /* left shift endpoint components so that their MSB lies in bit 7 */
+ endpoints[i][k] = endpoints[i][k] << (8 - j);
+ /* Replicate each component's MSB into the LSBs revealed by the left-shift operation above */
+ endpoints[i][k] = endpoints[i][k] | (endpoints[i][k] >> j);
+ }
+
+ /* get alpha component precision including pbit */
+ j = actual_bits_count[1][mode] + ((sModeHasPBits >> mode) & 1);
+
+ /* left shift endpoint components so that their MSB lies in bit 7 */
+ endpoints[i][3] = endpoints[i][3] << (8 - j);
+ /* Replicate each component's MSB into the LSBs revealed by the left-shift operation above */
+ endpoints[i][3] = endpoints[i][3] | (endpoints[i][3] >> j);
+ }
+
+ /* If this mode does not explicitly define the alpha component */
+ /* set alpha equal to 1.0 */
+ if (!actual_bits_count[1][mode]) {
+ for (j = 0; j < numEndpoints; ++j) {
+ endpoints[j][3] = 0xFF;
+ }
+ }
+
+ /* Determine weights tables */
+ indexBits = (mode == 0 || mode == 1) ? 3 : ((mode == 6) ? 4 : 2);
+ indexBits2 = (mode == 4) ? 3 : ((mode == 5) ? 2 : 0);
+ weights = (indexBits == 2) ? aWeight2 : ((indexBits == 3) ? aWeight3 : aWeight4);
+ weights2 = (indexBits2 == 2) ? aWeight2 : aWeight3;
+
+ /* Quite inconvenient that indices aren't interleaved so we have to make 2 passes here */
+ /* Pass #1: collecting color indices */
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ partitionSet = (numPartitions == 1) ? ((i | j) ? 0 : 128) : partition_sets[numPartitions - 2][partition][i][j];
+
+ indexBits = (mode == 0 || mode == 1) ? 3 : ((mode == 6) ? 4 : 2);
+ /* fix-up index is specified with one less bit */
+ /* The fix-up index for subset 0 is always index 0 */
+ if (partitionSet & 0x80) {
+ indexBits--;
+ }
+
+ indices[i][j] = bcdec__bitstream_read_bits(&bstream, indexBits);
+ }
+ }
+
+ /* Pass #2: reading alpha indices (if any) and interpolating & rotating */
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ partitionSet = (numPartitions == 1) ? ((i|j) ? 0 : 128) : partition_sets[numPartitions - 2][partition][i][j];
+ partitionSet &= 0x03;
+
+ index = indices[i][j];
+
+ if (!indexBits2) {
+ r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights, index);
+ g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights, index);
+ b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights, index);
+ a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights, index);
+ } else {
+ index2 = bcdec__bitstream_read_bits(&bstream, (i|j) ? indexBits2 : (indexBits2 - 1));
+ /* The index value for interpolating color comes from the secondary index bits for the texel
+ if the mode has an index selection bit and its value is one, and from the primary index bits otherwise.
+ The alpha index comes from the secondary index bits if the block has a secondary index and
+ the block either doesn’t have an index selection bit or that bit is zero, and from the primary index bits otherwise. */
+ if (!indexSelectionBit) {
+ r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights, index);
+ g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights, index);
+ b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights, index);
+ a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights2, index2);
+ } else {
+ r = bcdec__interpolate(endpoints[partitionSet * 2][0], endpoints[partitionSet * 2 + 1][0], weights2, index2);
+ g = bcdec__interpolate(endpoints[partitionSet * 2][1], endpoints[partitionSet * 2 + 1][1], weights2, index2);
+ b = bcdec__interpolate(endpoints[partitionSet * 2][2], endpoints[partitionSet * 2 + 1][2], weights2, index2);
+ a = bcdec__interpolate(endpoints[partitionSet * 2][3], endpoints[partitionSet * 2 + 1][3], weights, index);
+ }
+ }
+
+ switch (rotation) {
+ case 1: { /* 01 – Block format is Scalar(R) Vector(AGB) - swap A and R */
+ bcdec__swap_values(&a, &r);
+ } break;
+ case 2: { /* 10 – Block format is Scalar(G) Vector(RAB) - swap A and G */
+ bcdec__swap_values(&a, &g);
+ } break;
+ case 3: { /* 11 - Block format is Scalar(B) Vector(RGA) - swap A and B */
+ bcdec__swap_values(&a, &b);
+ } break;
+ }
+
+ decompressed[j * 4 + 0] = r;
+ decompressed[j * 4 + 1] = g;
+ decompressed[j * 4 + 2] = b;
+ decompressed[j * 4 + 3] = a;
+ }
+
+ decompressed += destinationPitch;
+ }
+}
+
+#endif /* BCDEC_IMPLEMENTATION */
+
+#endif /* BCDEC_HEADER_INCLUDED */
+
+/* LICENSE:
+
+This software is available under 2 licenses -- choose whichever you prefer.
+
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+
+Copyright (c) 2022 Sergii Kudlai
+
+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.
+
+------------------------------------------------------------------------------
+ALTERNATIVE B - The Unlicense
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+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 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.
+
+For more information, please refer to <https://unlicense.org>
+
+*/ \ No newline at end of file
diff --git a/thirdparty/openxr/COPYING.adoc b/thirdparty/openxr/COPYING.adoc
index 18c85fa6c7..d700a19d7b 100644
--- a/thirdparty/openxr/COPYING.adoc
+++ b/thirdparty/openxr/COPYING.adoc
@@ -6,7 +6,7 @@
This document is shared across a number of OpenXR GitHub projects, as the
set of files in those projects is partially overlapping.
-(There is a single "source of truth" internal Khronos GitLab repo these
+(There is a single "source of truth" internal Khronos GitLab monorepo these
GitHub repositories interact with.)
== Licenses
@@ -17,7 +17,7 @@ https://reuse.software/spec/[REUSE 3.0 specification] with clear copyright
holders and license identifier listed for each file, preferably in each
file.
Where this is not possible, or e.g. when we are using files unmodified from
-other open-source projects, license data is listed:
+other open source projects, license data is listed:
* in an adjacent file of the same name, with the additional extension
"`.license`"
diff --git a/thirdparty/openxr/include/openxr/openxr.h b/thirdparty/openxr/include/openxr/openxr.h
index 9ac66d8c69..f094b0f72b 100644
--- a/thirdparty/openxr/include/openxr/openxr.h
+++ b/thirdparty/openxr/include/openxr/openxr.h
@@ -26,7 +26,7 @@ extern "C" {
((((major) & 0xffffULL) << 48) | (((minor) & 0xffffULL) << 32) | ((patch) & 0xffffffffULL))
// OpenXR current version number.
-#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 1, 38)
+#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 1, 41)
// OpenXR 1.0 version number
#define XR_API_VERSION_1_0 XR_MAKE_VERSION(1, 0, XR_VERSION_PATCH(XR_CURRENT_API_VERSION))
@@ -242,6 +242,11 @@ typedef enum XrResult {
XR_ERROR_LOCALIZATION_MAP_PERMISSION_DENIED_ML = -1000139004,
XR_ERROR_LOCALIZATION_MAP_ALREADY_EXISTS_ML = -1000139005,
XR_ERROR_LOCALIZATION_MAP_CANNOT_EXPORT_CLOUD_MAP_ML = -1000139006,
+ XR_ERROR_SPATIAL_ANCHORS_PERMISSION_DENIED_ML = -1000140000,
+ XR_ERROR_SPATIAL_ANCHORS_NOT_LOCALIZED_ML = -1000140001,
+ XR_ERROR_SPATIAL_ANCHORS_OUT_OF_MAP_BOUNDS_ML = -1000140002,
+ XR_ERROR_SPATIAL_ANCHORS_SPACE_NOT_LOCATABLE_ML = -1000140003,
+ XR_ERROR_SPATIAL_ANCHORS_ANCHOR_NOT_FOUND_ML = -1000141000,
XR_ERROR_SPATIAL_ANCHOR_NAME_NOT_FOUND_MSFT = -1000142001,
XR_ERROR_SPATIAL_ANCHOR_NAME_INVALID_MSFT = -1000142002,
XR_SCENE_MARKER_DATA_NOT_STRING_MSFT = 1000147000,
@@ -258,6 +263,10 @@ typedef enum XrResult {
XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT = -1000429001,
XR_ERROR_FUTURE_PENDING_EXT = -1000469001,
XR_ERROR_FUTURE_INVALID_EXT = -1000469002,
+ XR_ERROR_SYSTEM_NOTIFICATION_PERMISSION_DENIED_ML = -1000473000,
+ XR_ERROR_SYSTEM_NOTIFICATION_INCOMPATIBLE_SKU_ML = -1000473001,
+ XR_ERROR_WORLD_MESH_DETECTOR_PERMISSION_DENIED_ML = -1000474000,
+ XR_ERROR_WORLD_MESH_DETECTOR_SPACE_NOT_LOCATABLE_ML = -1000474001,
XR_ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED_KHR = XR_ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED,
XR_ERROR_PERMISSION_INSUFFICIENT_KHR = XR_ERROR_PERMISSION_INSUFFICIENT,
XR_RESULT_MAX_ENUM = 0x7FFFFFFF
@@ -346,6 +355,9 @@ typedef enum XrStructureType {
XR_TYPE_GRAPHICS_BINDING_D3D12_KHR = 1000028000,
XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR = 1000028001,
XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR = 1000028002,
+ XR_TYPE_GRAPHICS_BINDING_METAL_KHR = 1000029000,
+ XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR = 1000029001,
+ XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR = 1000029002,
XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT = 1000030000,
XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT = 1000030001,
XR_TYPE_VISIBILITY_MASK_KHR = 1000031000,
@@ -492,6 +504,22 @@ typedef enum XrStructureType {
XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML = 1000139002,
XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML = 1000139003,
XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML = 1000139004,
+ XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML = 1000140000,
+ XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML = 1000140001,
+ XR_TYPE_SPATIAL_ANCHOR_STATE_ML = 1000140002,
+ XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML = 1000141000,
+ XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML = 1000141001,
+ XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML = 1000141002,
+ XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML = 1000141003,
+ XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML = 1000141004,
+ XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML = 1000141005,
+ XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML = 1000141006,
+ XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML = 1000141007,
+ XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML = 1000141008,
+ XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML = 1000141009,
+ XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML = 1000141010,
+ XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML = 1000141011,
+ XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML = 1000141012,
XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML = 1000472000,
XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML = 1000472001,
XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML = 1000472002,
@@ -599,6 +627,11 @@ typedef enum XrStructureType {
XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC = 1000318002,
XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC = 1000319000,
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC = 1000319001,
+ XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC = 1000320000,
+ XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC = 1000320001,
+ XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC = 1000320002,
+ XR_TYPE_BODY_JOINT_LOCATIONS_HTC = 1000320003,
+ XR_TYPE_BODY_SKELETON_HTC = 1000320004,
XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT = 1000373000,
XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX = 1000375000,
XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX = 1000375001,
@@ -617,6 +650,19 @@ typedef enum XrStructureType {
XR_TYPE_FUTURE_POLL_RESULT_EXT = 1000469003,
XR_TYPE_EVENT_DATA_USER_PRESENCE_CHANGED_EXT = 1000470000,
XR_TYPE_SYSTEM_USER_PRESENCE_PROPERTIES_EXT = 1000470001,
+ XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML = 1000473000,
+ XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML = 1000474001,
+ XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML = 1000474002,
+ XR_TYPE_WORLD_MESH_BLOCK_STATE_ML = 1000474003,
+ XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML = 1000474004,
+ XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML = 1000474005,
+ XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML = 1000474006,
+ XR_TYPE_WORLD_MESH_BUFFER_ML = 1000474007,
+ XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML = 1000474008,
+ XR_TYPE_WORLD_MESH_GET_INFO_ML = 1000474009,
+ XR_TYPE_WORLD_MESH_BLOCK_ML = 1000474010,
+ XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML = 1000474011,
+ XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML = 1000474012,
XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR,
XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR,
XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR,
@@ -713,6 +759,7 @@ typedef enum XrObjectType {
XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB = 1000118004,
XR_OBJECT_TYPE_MARKER_DETECTOR_ML = 1000138000,
XR_OBJECT_TYPE_EXPORTED_LOCALIZATION_MAP_ML = 1000139000,
+ XR_OBJECT_TYPE_SPATIAL_ANCHORS_STORAGE_ML = 1000141000,
XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT = 1000142000,
XR_OBJECT_TYPE_FACE_TRACKER_FB = 1000201000,
XR_OBJECT_TYPE_EYE_TRACKER_FB = 1000202000,
@@ -723,7 +770,9 @@ typedef enum XrObjectType {
XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_PROVIDER_META = 1000291000,
XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_META = 1000291001,
XR_OBJECT_TYPE_PASSTHROUGH_HTC = 1000317000,
+ XR_OBJECT_TYPE_BODY_TRACKER_HTC = 1000320000,
XR_OBJECT_TYPE_PLANE_DETECTOR_EXT = 1000429000,
+ XR_OBJECT_TYPE_WORLD_MESH_DETECTOR_ML = 1000474000,
XR_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
} XrObjectType;
typedef XrFlags64 XrInstanceCreateFlags;
@@ -2184,7 +2233,7 @@ typedef struct XrEventDataMainSessionVisibilityChangedEXTX {
// XR_VARJO_quad_views is a preprocessor guard. Do not pass it to API calls.
#define XR_VARJO_quad_views 1
-#define XR_VARJO_quad_views_SPEC_VERSION 1
+#define XR_VARJO_quad_views_SPEC_VERSION 2
#define XR_VARJO_QUAD_VIEWS_EXTENSION_NAME "XR_VARJO_quad_views"
@@ -4982,6 +5031,245 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetExportedLocalizationMapDataML(
#endif /* !XR_NO_PROTOTYPES */
+// XR_ML_spatial_anchors is a preprocessor guard. Do not pass it to API calls.
+#define XR_ML_spatial_anchors 1
+XR_DEFINE_OPAQUE_64(XrFutureEXT)
+#define XR_ML_spatial_anchors_SPEC_VERSION 1
+#define XR_ML_SPATIAL_ANCHORS_EXTENSION_NAME "XR_ML_spatial_anchors"
+
+typedef enum XrSpatialAnchorConfidenceML {
+ XR_SPATIAL_ANCHOR_CONFIDENCE_LOW_ML = 0,
+ XR_SPATIAL_ANCHOR_CONFIDENCE_MEDIUM_ML = 1,
+ XR_SPATIAL_ANCHOR_CONFIDENCE_HIGH_ML = 2,
+ XR_SPATIAL_ANCHOR_CONFIDENCE_MAX_ENUM_ML = 0x7FFFFFFF
+} XrSpatialAnchorConfidenceML;
+typedef struct XR_MAY_ALIAS XrSpatialAnchorsCreateInfoBaseHeaderML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrSpatialAnchorsCreateInfoBaseHeaderML;
+
+typedef struct XrSpatialAnchorsCreateInfoFromPoseML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSpace baseSpace;
+ XrPosef poseInBaseSpace;
+ XrTime time;
+} XrSpatialAnchorsCreateInfoFromPoseML;
+
+typedef struct XrCreateSpatialAnchorsCompletionML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrResult futureResult;
+ uint32_t spaceCount;
+ XrSpace* spaces;
+} XrCreateSpatialAnchorsCompletionML;
+
+typedef struct XrSpatialAnchorStateML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrSpatialAnchorConfidenceML confidence;
+} XrSpatialAnchorStateML;
+
+typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorsAsyncML)(XrSession session, const XrSpatialAnchorsCreateInfoBaseHeaderML* createInfo, XrFutureEXT* future);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorsCompleteML)(XrSession session, XrFutureEXT future, XrCreateSpatialAnchorsCompletionML* completion);
+typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialAnchorStateML)(XrSpace anchor, XrSpatialAnchorStateML* state);
+
+#ifndef XR_NO_PROTOTYPES
+#ifdef XR_EXTENSION_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorsAsyncML(
+ XrSession session,
+ const XrSpatialAnchorsCreateInfoBaseHeaderML* createInfo,
+ XrFutureEXT* future);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorsCompleteML(
+ XrSession session,
+ XrFutureEXT future,
+ XrCreateSpatialAnchorsCompletionML* completion);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialAnchorStateML(
+ XrSpace anchor,
+ XrSpatialAnchorStateML* state);
+#endif /* XR_EXTENSION_PROTOTYPES */
+#endif /* !XR_NO_PROTOTYPES */
+
+
+// XR_ML_spatial_anchors_storage is a preprocessor guard. Do not pass it to API calls.
+#define XR_ML_spatial_anchors_storage 1
+XR_DEFINE_HANDLE(XrSpatialAnchorsStorageML)
+#define XR_ML_spatial_anchors_storage_SPEC_VERSION 1
+#define XR_ML_SPATIAL_ANCHORS_STORAGE_EXTENSION_NAME "XR_ML_spatial_anchors_storage"
+typedef struct XrSpatialAnchorsCreateStorageInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrSpatialAnchorsCreateStorageInfoML;
+
+typedef struct XR_MAY_ALIAS XrSpatialAnchorsQueryInfoBaseHeaderML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrSpatialAnchorsQueryInfoBaseHeaderML;
+
+typedef struct XrSpatialAnchorsQueryInfoRadiusML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSpace baseSpace;
+ XrVector3f center;
+ XrTime time;
+ float radius;
+} XrSpatialAnchorsQueryInfoRadiusML;
+
+typedef struct XrSpatialAnchorsQueryCompletionML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrResult futureResult;
+ uint32_t uuidCapacityInput;
+ uint32_t uuidCountOutput;
+ XrUuidEXT* uuids;
+} XrSpatialAnchorsQueryCompletionML;
+
+typedef struct XrSpatialAnchorsCreateInfoFromUuidsML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSpatialAnchorsStorageML storage;
+ uint32_t uuidCount;
+ const XrUuidEXT* uuids;
+} XrSpatialAnchorsCreateInfoFromUuidsML;
+
+typedef struct XrSpatialAnchorsPublishInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ uint32_t anchorCount;
+ const XrSpace* anchors;
+ uint64_t expiration;
+} XrSpatialAnchorsPublishInfoML;
+
+typedef struct XrSpatialAnchorsPublishCompletionML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrResult futureResult;
+ uint32_t uuidCount;
+ XrUuidEXT* uuids;
+} XrSpatialAnchorsPublishCompletionML;
+
+typedef struct XrSpatialAnchorsDeleteInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ uint32_t uuidCount;
+ const XrUuidEXT* uuids;
+} XrSpatialAnchorsDeleteInfoML;
+
+typedef struct XrSpatialAnchorsDeleteCompletionML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrResult futureResult;
+} XrSpatialAnchorsDeleteCompletionML;
+
+typedef struct XrSpatialAnchorsUpdateExpirationInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ uint32_t uuidCount;
+ const XrUuidEXT* uuids;
+ uint64_t expiration;
+} XrSpatialAnchorsUpdateExpirationInfoML;
+
+typedef struct XrSpatialAnchorsUpdateExpirationCompletionML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrResult futureResult;
+} XrSpatialAnchorsUpdateExpirationCompletionML;
+
+typedef struct XrSpatialAnchorCompletionResultML {
+ XrUuidEXT uuid;
+ XrResult result;
+} XrSpatialAnchorCompletionResultML;
+
+// XrSpatialAnchorsPublishCompletionDetailsML extends XrSpatialAnchorsPublishCompletionML
+typedef struct XrSpatialAnchorsPublishCompletionDetailsML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t resultCount;
+ XrSpatialAnchorCompletionResultML* results;
+} XrSpatialAnchorsPublishCompletionDetailsML;
+
+// XrSpatialAnchorsDeleteCompletionDetailsML extends XrSpatialAnchorsDeleteCompletionML
+typedef struct XrSpatialAnchorsDeleteCompletionDetailsML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t resultCount;
+ XrSpatialAnchorCompletionResultML* results;
+} XrSpatialAnchorsDeleteCompletionDetailsML;
+
+// XrSpatialAnchorsUpdateExpirationCompletionDetailsML extends XrSpatialAnchorsUpdateExpirationCompletionML
+typedef struct XrSpatialAnchorsUpdateExpirationCompletionDetailsML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t resultCount;
+ XrSpatialAnchorCompletionResultML* results;
+} XrSpatialAnchorsUpdateExpirationCompletionDetailsML;
+
+typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorsStorageML)(XrSession session, const XrSpatialAnchorsCreateStorageInfoML* createInfo, XrSpatialAnchorsStorageML* storage);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialAnchorsStorageML)(XrSpatialAnchorsStorageML storage);
+typedef XrResult (XRAPI_PTR *PFN_xrQuerySpatialAnchorsAsyncML)(XrSpatialAnchorsStorageML storage, const XrSpatialAnchorsQueryInfoBaseHeaderML* queryInfo, XrFutureEXT* future);
+typedef XrResult (XRAPI_PTR *PFN_xrQuerySpatialAnchorsCompleteML)(XrSpatialAnchorsStorageML storage, XrFutureEXT future, XrSpatialAnchorsQueryCompletionML* completion);
+typedef XrResult (XRAPI_PTR *PFN_xrPublishSpatialAnchorsAsyncML)(XrSpatialAnchorsStorageML storage, const XrSpatialAnchorsPublishInfoML* publishInfo, XrFutureEXT* future);
+typedef XrResult (XRAPI_PTR *PFN_xrPublishSpatialAnchorsCompleteML)(XrSpatialAnchorsStorageML storage, XrFutureEXT future, XrSpatialAnchorsPublishCompletionML* completion);
+typedef XrResult (XRAPI_PTR *PFN_xrDeleteSpatialAnchorsAsyncML)(XrSpatialAnchorsStorageML storage, const XrSpatialAnchorsDeleteInfoML* deleteInfo, XrFutureEXT* future);
+typedef XrResult (XRAPI_PTR *PFN_xrDeleteSpatialAnchorsCompleteML)(XrSpatialAnchorsStorageML storage, XrFutureEXT future, XrSpatialAnchorsDeleteCompletionML* completion);
+typedef XrResult (XRAPI_PTR *PFN_xrUpdateSpatialAnchorsExpirationAsyncML)(XrSpatialAnchorsStorageML storage, const XrSpatialAnchorsUpdateExpirationInfoML* updateInfo, XrFutureEXT* future);
+typedef XrResult (XRAPI_PTR *PFN_xrUpdateSpatialAnchorsExpirationCompleteML)(XrSpatialAnchorsStorageML storage, XrFutureEXT future, XrSpatialAnchorsUpdateExpirationCompletionML* completion);
+
+#ifndef XR_NO_PROTOTYPES
+#ifdef XR_EXTENSION_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorsStorageML(
+ XrSession session,
+ const XrSpatialAnchorsCreateStorageInfoML* createInfo,
+ XrSpatialAnchorsStorageML* storage);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialAnchorsStorageML(
+ XrSpatialAnchorsStorageML storage);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrQuerySpatialAnchorsAsyncML(
+ XrSpatialAnchorsStorageML storage,
+ const XrSpatialAnchorsQueryInfoBaseHeaderML* queryInfo,
+ XrFutureEXT* future);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrQuerySpatialAnchorsCompleteML(
+ XrSpatialAnchorsStorageML storage,
+ XrFutureEXT future,
+ XrSpatialAnchorsQueryCompletionML* completion);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrPublishSpatialAnchorsAsyncML(
+ XrSpatialAnchorsStorageML storage,
+ const XrSpatialAnchorsPublishInfoML* publishInfo,
+ XrFutureEXT* future);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrPublishSpatialAnchorsCompleteML(
+ XrSpatialAnchorsStorageML storage,
+ XrFutureEXT future,
+ XrSpatialAnchorsPublishCompletionML* completion);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDeleteSpatialAnchorsAsyncML(
+ XrSpatialAnchorsStorageML storage,
+ const XrSpatialAnchorsDeleteInfoML* deleteInfo,
+ XrFutureEXT* future);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDeleteSpatialAnchorsCompleteML(
+ XrSpatialAnchorsStorageML storage,
+ XrFutureEXT future,
+ XrSpatialAnchorsDeleteCompletionML* completion);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSpatialAnchorsExpirationAsyncML(
+ XrSpatialAnchorsStorageML storage,
+ const XrSpatialAnchorsUpdateExpirationInfoML* updateInfo,
+ XrFutureEXT* future);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSpatialAnchorsExpirationCompleteML(
+ XrSpatialAnchorsStorageML storage,
+ XrFutureEXT future,
+ XrSpatialAnchorsUpdateExpirationCompletionML* completion);
+#endif /* XR_EXTENSION_PROTOTYPES */
+#endif /* !XR_NO_PROTOTYPES */
+
+
// XR_MSFT_spatial_anchor_persistence is a preprocessor guard. Do not pass it to API calls.
#define XR_MSFT_spatial_anchor_persistence 1
XR_DEFINE_HANDLE(XrSpatialAnchorStoreConnectionMSFT)
@@ -7052,6 +7340,131 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialAnchorNameHTC(
#endif /* !XR_NO_PROTOTYPES */
+// XR_HTC_body_tracking is a preprocessor guard. Do not pass it to API calls.
+#define XR_HTC_body_tracking 1
+
+#define XR_BODY_JOINT_COUNT_HTC 26
+
+XR_DEFINE_HANDLE(XrBodyTrackerHTC)
+#define XR_HTC_body_tracking_SPEC_VERSION 1
+#define XR_HTC_BODY_TRACKING_EXTENSION_NAME "XR_HTC_body_tracking"
+
+typedef enum XrBodyJointHTC {
+ XR_BODY_JOINT_PELVIS_HTC = 0,
+ XR_BODY_JOINT_LEFT_HIP_HTC = 1,
+ XR_BODY_JOINT_LEFT_KNEE_HTC = 2,
+ XR_BODY_JOINT_LEFT_ANKLE_HTC = 3,
+ XR_BODY_JOINT_LEFT_FEET_HTC = 4,
+ XR_BODY_JOINT_RIGHT_HIP_HTC = 5,
+ XR_BODY_JOINT_RIGHT_KNEE_HTC = 6,
+ XR_BODY_JOINT_RIGHT_ANKLE_HTC = 7,
+ XR_BODY_JOINT_RIGHT_FEET_HTC = 8,
+ XR_BODY_JOINT_WAIST_HTC = 9,
+ XR_BODY_JOINT_SPINE_LOWER_HTC = 10,
+ XR_BODY_JOINT_SPINE_MIDDLE_HTC = 11,
+ XR_BODY_JOINT_SPINE_HIGH_HTC = 12,
+ XR_BODY_JOINT_CHEST_HTC = 13,
+ XR_BODY_JOINT_NECK_HTC = 14,
+ XR_BODY_JOINT_HEAD_HTC = 15,
+ XR_BODY_JOINT_LEFT_CLAVICLE_HTC = 16,
+ XR_BODY_JOINT_LEFT_SCAPULA_HTC = 17,
+ XR_BODY_JOINT_LEFT_ARM_HTC = 18,
+ XR_BODY_JOINT_LEFT_ELBOW_HTC = 19,
+ XR_BODY_JOINT_LEFT_WRIST_HTC = 20,
+ XR_BODY_JOINT_RIGHT_CLAVICLE_HTC = 21,
+ XR_BODY_JOINT_RIGHT_SCAPULA_HTC = 22,
+ XR_BODY_JOINT_RIGHT_ARM_HTC = 23,
+ XR_BODY_JOINT_RIGHT_ELBOW_HTC = 24,
+ XR_BODY_JOINT_RIGHT_WRIST_HTC = 25,
+ XR_BODY_JOINT_MAX_ENUM_HTC = 0x7FFFFFFF
+} XrBodyJointHTC;
+
+typedef enum XrBodyJointSetHTC {
+ XR_BODY_JOINT_SET_FULL_HTC = 0,
+ XR_BODY_JOINT_SET_MAX_ENUM_HTC = 0x7FFFFFFF
+} XrBodyJointSetHTC;
+
+typedef enum XrBodyJointConfidenceHTC {
+ XR_BODY_JOINT_CONFIDENCE_NONE_HTC = 0,
+ XR_BODY_JOINT_CONFIDENCE_LOW_HTC = 1,
+ XR_BODY_JOINT_CONFIDENCE_HIGH_HTC = 2,
+ XR_BODY_JOINT_CONFIDENCE_MAX_ENUM_HTC = 0x7FFFFFFF
+} XrBodyJointConfidenceHTC;
+// XrSystemBodyTrackingPropertiesHTC extends XrSystemProperties
+typedef struct XrSystemBodyTrackingPropertiesHTC {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrBool32 supportsBodyTracking;
+} XrSystemBodyTrackingPropertiesHTC;
+
+typedef struct XrBodyTrackerCreateInfoHTC {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrBodyJointSetHTC bodyJointSet;
+} XrBodyTrackerCreateInfoHTC;
+
+typedef struct XrBodyJointsLocateInfoHTC {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSpace baseSpace;
+ XrTime time;
+} XrBodyJointsLocateInfoHTC;
+
+typedef struct XrBodyJointLocationHTC {
+ XrSpaceLocationFlags locationFlags;
+ XrPosef pose;
+} XrBodyJointLocationHTC;
+
+typedef struct XrBodyJointLocationsHTC {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrSpaceLocationFlags combinedLocationFlags;
+ XrBodyJointConfidenceHTC confidenceLevel;
+ uint32_t jointLocationCount;
+ XrBodyJointLocationHTC* jointLocations;
+ uint32_t skeletonGenerationId;
+} XrBodyJointLocationsHTC;
+
+typedef struct XrBodySkeletonJointHTC {
+ XrPosef pose;
+} XrBodySkeletonJointHTC;
+
+typedef struct XrBodySkeletonHTC {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t jointCount;
+ XrBodySkeletonJointHTC* joints;
+} XrBodySkeletonHTC;
+
+typedef XrResult (XRAPI_PTR *PFN_xrCreateBodyTrackerHTC)(XrSession session, const XrBodyTrackerCreateInfoHTC* createInfo, XrBodyTrackerHTC* bodyTracker);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroyBodyTrackerHTC)(XrBodyTrackerHTC bodyTracker);
+typedef XrResult (XRAPI_PTR *PFN_xrLocateBodyJointsHTC)(XrBodyTrackerHTC bodyTracker, const XrBodyJointsLocateInfoHTC* locateInfo, XrBodyJointLocationsHTC* locations);
+typedef XrResult (XRAPI_PTR *PFN_xrGetBodySkeletonHTC)(XrBodyTrackerHTC bodyTracker, XrSpace baseSpace, uint32_t skeletonGenerationId, XrBodySkeletonHTC* skeleton);
+
+#ifndef XR_NO_PROTOTYPES
+#ifdef XR_EXTENSION_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateBodyTrackerHTC(
+ XrSession session,
+ const XrBodyTrackerCreateInfoHTC* createInfo,
+ XrBodyTrackerHTC* bodyTracker);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroyBodyTrackerHTC(
+ XrBodyTrackerHTC bodyTracker);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrLocateBodyJointsHTC(
+ XrBodyTrackerHTC bodyTracker,
+ const XrBodyJointsLocateInfoHTC* locateInfo,
+ XrBodyJointLocationsHTC* locations);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetBodySkeletonHTC(
+ XrBodyTrackerHTC bodyTracker,
+ XrSpace baseSpace,
+ uint32_t skeletonGenerationId,
+ XrBodySkeletonHTC* skeleton);
+#endif /* XR_EXTENSION_PROTOTYPES */
+#endif /* !XR_NO_PROTOTYPES */
+
+
// XR_EXT_active_action_set_priority is a preprocessor guard. Do not pass it to API calls.
#define XR_EXT_active_action_set_priority 1
#define XR_EXT_active_action_set_priority_SPEC_VERSION 1
@@ -7313,7 +7726,6 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetPlanePolygonBufferEXT(
// XR_EXT_future is a preprocessor guard. Do not pass it to API calls.
#define XR_EXT_future 1
-XR_DEFINE_OPAQUE_64(XrFutureEXT)
#define XR_EXT_future_SPEC_VERSION 1
#define XR_EXT_FUTURE_EXTENSION_NAME "XR_EXT_future"
#define XR_NULL_FUTURE_EXT 0
@@ -7440,6 +7852,232 @@ XRAPI_ATTR XrResult XRAPI_CALL xrEnableUserCalibrationEventsML(
#endif /* !XR_NO_PROTOTYPES */
+// XR_ML_system_notifications is a preprocessor guard. Do not pass it to API calls.
+#define XR_ML_system_notifications 1
+#define XR_ML_system_notifications_SPEC_VERSION 1
+#define XR_ML_SYSTEM_NOTIFICATIONS_EXTENSION_NAME "XR_ML_system_notifications"
+typedef struct XrSystemNotificationsSetInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrBool32 suppressNotifications;
+} XrSystemNotificationsSetInfoML;
+
+typedef XrResult (XRAPI_PTR *PFN_xrSetSystemNotificationsML)(XrInstance instance, const XrSystemNotificationsSetInfoML* info);
+
+#ifndef XR_NO_PROTOTYPES
+#ifdef XR_EXTENSION_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrSetSystemNotificationsML(
+ XrInstance instance,
+ const XrSystemNotificationsSetInfoML* info);
+#endif /* XR_EXTENSION_PROTOTYPES */
+#endif /* !XR_NO_PROTOTYPES */
+
+
+// XR_ML_world_mesh_detection is a preprocessor guard. Do not pass it to API calls.
+#define XR_ML_world_mesh_detection 1
+XR_DEFINE_HANDLE(XrWorldMeshDetectorML)
+#define XR_ML_world_mesh_detection_SPEC_VERSION 1
+#define XR_ML_WORLD_MESH_DETECTION_EXTENSION_NAME "XR_ML_world_mesh_detection"
+
+typedef enum XrWorldMeshDetectorLodML {
+ XR_WORLD_MESH_DETECTOR_LOD_MINIMUM_ML = 0,
+ XR_WORLD_MESH_DETECTOR_LOD_MEDIUM_ML = 1,
+ XR_WORLD_MESH_DETECTOR_LOD_MAXIMUM_ML = 2,
+ XR_WORLD_MESH_DETECTOR_LOD_MAX_ENUM_ML = 0x7FFFFFFF
+} XrWorldMeshDetectorLodML;
+
+typedef enum XrWorldMeshBlockStatusML {
+ XR_WORLD_MESH_BLOCK_STATUS_NEW_ML = 0,
+ XR_WORLD_MESH_BLOCK_STATUS_UPDATED_ML = 1,
+ XR_WORLD_MESH_BLOCK_STATUS_DELETED_ML = 2,
+ XR_WORLD_MESH_BLOCK_STATUS_UNCHANGED_ML = 3,
+ XR_WORLD_MESH_BLOCK_STATUS_MAX_ENUM_ML = 0x7FFFFFFF
+} XrWorldMeshBlockStatusML;
+
+typedef enum XrWorldMeshBlockResultML {
+ XR_WORLD_MESH_BLOCK_RESULT_SUCCESS_ML = 0,
+ XR_WORLD_MESH_BLOCK_RESULT_FAILED_ML = 1,
+ XR_WORLD_MESH_BLOCK_RESULT_PENDING_ML = 2,
+ XR_WORLD_MESH_BLOCK_RESULT_PARTIAL_UPDATE_ML = 3,
+ XR_WORLD_MESH_BLOCK_RESULT_MAX_ENUM_ML = 0x7FFFFFFF
+} XrWorldMeshBlockResultML;
+typedef XrFlags64 XrWorldMeshDetectorFlagsML;
+
+// Flag bits for XrWorldMeshDetectorFlagsML
+static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_POINT_CLOUD_BIT_ML = 0x00000001;
+static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_COMPUTE_NORMALS_BIT_ML = 0x00000002;
+static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_COMPUTE_CONFIDENCE_BIT_ML = 0x00000004;
+static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_PLANARIZE_BIT_ML = 0x00000008;
+static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_REMOVE_MESH_SKIRT_BIT_ML = 0x00000010;
+static const XrWorldMeshDetectorFlagsML XR_WORLD_MESH_DETECTOR_INDEX_ORDER_CW_BIT_ML = 0x00000020;
+
+typedef struct XrWorldMeshDetectorCreateInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrWorldMeshDetectorCreateInfoML;
+
+typedef struct XrWorldMeshBlockStateML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrUuidEXT uuid;
+ XrPosef meshBoundingBoxCenter;
+ XrExtent3DfEXT meshBoundingBoxExtents;
+ XrTime lastUpdateTime;
+ XrWorldMeshBlockStatusML status;
+} XrWorldMeshBlockStateML;
+
+typedef struct XrWorldMeshStateRequestInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSpace baseSpace;
+ XrTime time;
+ XrPosef boundingBoxCenter;
+ XrExtent3DfEXT boundingBoxExtents;
+} XrWorldMeshStateRequestInfoML;
+
+typedef struct XrWorldMeshStateRequestCompletionML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrResult futureResult;
+ XrTime timestamp;
+ uint32_t meshBlockStateCapacityInput;
+ uint32_t meshBlockStateCountOutput;
+ XrWorldMeshBlockStateML* meshBlockStates;
+} XrWorldMeshStateRequestCompletionML;
+
+typedef struct XrWorldMeshBufferRecommendedSizeInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ uint32_t maxBlockCount;
+} XrWorldMeshBufferRecommendedSizeInfoML;
+
+typedef struct XrWorldMeshBufferSizeML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t size;
+} XrWorldMeshBufferSizeML;
+
+typedef struct XrWorldMeshBufferML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t bufferSize;
+ void* XR_MAY_ALIAS buffer;
+} XrWorldMeshBufferML;
+
+typedef struct XrWorldMeshBlockRequestML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrUuidEXT uuid;
+ XrWorldMeshDetectorLodML lod;
+} XrWorldMeshBlockRequestML;
+
+typedef struct XrWorldMeshGetInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrWorldMeshDetectorFlagsML flags;
+ float fillHoleLength;
+ float disconnectedComponentArea;
+ uint32_t blockCount;
+ XrWorldMeshBlockRequestML* blocks;
+} XrWorldMeshGetInfoML;
+
+typedef struct XrWorldMeshBlockML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrUuidEXT uuid;
+ XrWorldMeshBlockResultML blockResult;
+ XrWorldMeshDetectorLodML lod;
+ XrWorldMeshDetectorFlagsML flags;
+ uint32_t indexCount;
+ uint16_t* indexBuffer;
+ uint32_t vertexCount;
+ XrVector3f* vertexBuffer;
+ uint32_t normalCount;
+ XrVector3f* normalBuffer;
+ uint32_t confidenceCount;
+ float* confidenceBuffer;
+} XrWorldMeshBlockML;
+
+typedef struct XrWorldMeshRequestCompletionInfoML {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSpace meshSpace;
+ XrTime meshSpaceLocateTime;
+} XrWorldMeshRequestCompletionInfoML;
+
+typedef struct XrWorldMeshRequestCompletionML {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrResult futureResult;
+ uint32_t blockCount;
+ XrWorldMeshBlockML* blocks;
+} XrWorldMeshRequestCompletionML;
+
+typedef XrResult (XRAPI_PTR *PFN_xrCreateWorldMeshDetectorML)(XrSession session, const XrWorldMeshDetectorCreateInfoML* createInfo, XrWorldMeshDetectorML* detector);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroyWorldMeshDetectorML)(XrWorldMeshDetectorML detector);
+typedef XrResult (XRAPI_PTR *PFN_xrRequestWorldMeshStateAsyncML)(XrWorldMeshDetectorML detector, const XrWorldMeshStateRequestInfoML* stateRequest, XrFutureEXT* future);
+typedef XrResult (XRAPI_PTR *PFN_xrRequestWorldMeshStateCompleteML)(XrWorldMeshDetectorML detector, XrFutureEXT future, XrWorldMeshStateRequestCompletionML* completion);
+typedef XrResult (XRAPI_PTR *PFN_xrGetWorldMeshBufferRecommendSizeML)(XrWorldMeshDetectorML detector, const XrWorldMeshBufferRecommendedSizeInfoML* sizeInfo, XrWorldMeshBufferSizeML* size);
+typedef XrResult (XRAPI_PTR *PFN_xrAllocateWorldMeshBufferML)(XrWorldMeshDetectorML detector, const XrWorldMeshBufferSizeML* size, XrWorldMeshBufferML* buffer);
+typedef XrResult (XRAPI_PTR *PFN_xrFreeWorldMeshBufferML)(XrWorldMeshDetectorML detector, const XrWorldMeshBufferML* buffer);
+typedef XrResult (XRAPI_PTR *PFN_xrRequestWorldMeshAsyncML)(XrWorldMeshDetectorML detector, const XrWorldMeshGetInfoML* getInfo, XrWorldMeshBufferML* buffer, XrFutureEXT* future);
+typedef XrResult (XRAPI_PTR *PFN_xrRequestWorldMeshCompleteML)(XrWorldMeshDetectorML detector, const XrWorldMeshRequestCompletionInfoML* completionInfo, XrFutureEXT future, XrWorldMeshRequestCompletionML* completion);
+
+#ifndef XR_NO_PROTOTYPES
+#ifdef XR_EXTENSION_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateWorldMeshDetectorML(
+ XrSession session,
+ const XrWorldMeshDetectorCreateInfoML* createInfo,
+ XrWorldMeshDetectorML* detector);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroyWorldMeshDetectorML(
+ XrWorldMeshDetectorML detector);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrRequestWorldMeshStateAsyncML(
+ XrWorldMeshDetectorML detector,
+ const XrWorldMeshStateRequestInfoML* stateRequest,
+ XrFutureEXT* future);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrRequestWorldMeshStateCompleteML(
+ XrWorldMeshDetectorML detector,
+ XrFutureEXT future,
+ XrWorldMeshStateRequestCompletionML* completion);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetWorldMeshBufferRecommendSizeML(
+ XrWorldMeshDetectorML detector,
+ const XrWorldMeshBufferRecommendedSizeInfoML* sizeInfo,
+ XrWorldMeshBufferSizeML* size);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrAllocateWorldMeshBufferML(
+ XrWorldMeshDetectorML detector,
+ const XrWorldMeshBufferSizeML* size,
+ XrWorldMeshBufferML* buffer);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrFreeWorldMeshBufferML(
+ XrWorldMeshDetectorML detector,
+ const XrWorldMeshBufferML* buffer);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrRequestWorldMeshAsyncML(
+ XrWorldMeshDetectorML detector,
+ const XrWorldMeshGetInfoML* getInfo,
+ XrWorldMeshBufferML* buffer,
+ XrFutureEXT* future);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrRequestWorldMeshCompleteML(
+ XrWorldMeshDetectorML detector,
+ const XrWorldMeshRequestCompletionInfoML* completionInfo,
+ XrFutureEXT future,
+ XrWorldMeshRequestCompletionML* completion);
+#endif /* XR_EXTENSION_PROTOTYPES */
+#endif /* !XR_NO_PROTOTYPES */
+
+
+// XR_ML_view_configuration_depth_range_change is a preprocessor guard. Do not pass it to API calls.
+#define XR_ML_view_configuration_depth_range_change 1
+#define XR_ML_view_configuration_depth_range_change_SPEC_VERSION 1
+#define XR_ML_VIEW_CONFIGURATION_DEPTH_RANGE_CHANGE_EXTENSION_NAME "XR_ML_view_configuration_depth_range_change"
+
+
// XR_YVR_controller_interaction is a preprocessor guard. Do not pass it to API calls.
#define XR_YVR_controller_interaction 1
#define XR_YVR_controller_interaction_SPEC_VERSION 1
diff --git a/thirdparty/openxr/include/openxr/openxr_platform.h b/thirdparty/openxr/include/openxr/openxr_platform.h
index cbe1008906..dfd74aa5d2 100644
--- a/thirdparty/openxr/include/openxr/openxr_platform.h
+++ b/thirdparty/openxr/include/openxr/openxr_platform.h
@@ -356,6 +356,43 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D12GraphicsRequirementsKHR(
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_D3D12 */
+#ifdef XR_USE_GRAPHICS_API_METAL
+
+// XR_KHR_metal_enable is a preprocessor guard. Do not pass it to API calls.
+#define XR_KHR_metal_enable 1
+#define XR_KHR_metal_enable_SPEC_VERSION 1
+#define XR_KHR_METAL_ENABLE_EXTENSION_NAME "XR_KHR_metal_enable"
+// XrGraphicsBindingMetalKHR extends XrSessionCreateInfo
+typedef struct XrGraphicsBindingMetalKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ void* XR_MAY_ALIAS commandQueue;
+} XrGraphicsBindingMetalKHR;
+
+typedef struct XrSwapchainImageMetalKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ void* XR_MAY_ALIAS texture;
+} XrSwapchainImageMetalKHR;
+
+typedef struct XrGraphicsRequirementsMetalKHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ void* XR_MAY_ALIAS metalDevice;
+} XrGraphicsRequirementsMetalKHR;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetMetalGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsMetalKHR* graphicsRequirements);
+
+#ifndef XR_NO_PROTOTYPES
+#ifdef XR_EXTENSION_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetMetalGraphicsRequirementsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrGraphicsRequirementsMetalKHR* graphicsRequirements);
+#endif /* XR_EXTENSION_PROTOTYPES */
+#endif /* !XR_NO_PROTOTYPES */
+#endif /* XR_USE_GRAPHICS_API_METAL */
+
#ifdef XR_USE_PLATFORM_WIN32
// XR_KHR_win32_convert_performance_counter_time is a preprocessor guard. Do not pass it to API calls.
diff --git a/thirdparty/openxr/include/openxr/openxr_reflection.h b/thirdparty/openxr/include/openxr/openxr_reflection.h
index b9d45689a7..4bea81c236 100644
--- a/thirdparty/openxr/include/openxr/openxr_reflection.h
+++ b/thirdparty/openxr/include/openxr/openxr_reflection.h
@@ -128,6 +128,11 @@ XR_ENUM_STR(XrResult);
_(XR_ERROR_LOCALIZATION_MAP_PERMISSION_DENIED_ML, -1000139004) \
_(XR_ERROR_LOCALIZATION_MAP_ALREADY_EXISTS_ML, -1000139005) \
_(XR_ERROR_LOCALIZATION_MAP_CANNOT_EXPORT_CLOUD_MAP_ML, -1000139006) \
+ _(XR_ERROR_SPATIAL_ANCHORS_PERMISSION_DENIED_ML, -1000140000) \
+ _(XR_ERROR_SPATIAL_ANCHORS_NOT_LOCALIZED_ML, -1000140001) \
+ _(XR_ERROR_SPATIAL_ANCHORS_OUT_OF_MAP_BOUNDS_ML, -1000140002) \
+ _(XR_ERROR_SPATIAL_ANCHORS_SPACE_NOT_LOCATABLE_ML, -1000140003) \
+ _(XR_ERROR_SPATIAL_ANCHORS_ANCHOR_NOT_FOUND_ML, -1000141000) \
_(XR_ERROR_SPATIAL_ANCHOR_NAME_NOT_FOUND_MSFT, -1000142001) \
_(XR_ERROR_SPATIAL_ANCHOR_NAME_INVALID_MSFT, -1000142002) \
_(XR_SCENE_MARKER_DATA_NOT_STRING_MSFT, 1000147000) \
@@ -144,6 +149,10 @@ XR_ENUM_STR(XrResult);
_(XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT, -1000429001) \
_(XR_ERROR_FUTURE_PENDING_EXT, -1000469001) \
_(XR_ERROR_FUTURE_INVALID_EXT, -1000469002) \
+ _(XR_ERROR_SYSTEM_NOTIFICATION_PERMISSION_DENIED_ML, -1000473000) \
+ _(XR_ERROR_SYSTEM_NOTIFICATION_INCOMPATIBLE_SKU_ML, -1000473001) \
+ _(XR_ERROR_WORLD_MESH_DETECTOR_PERMISSION_DENIED_ML, -1000474000) \
+ _(XR_ERROR_WORLD_MESH_DETECTOR_SPACE_NOT_LOCATABLE_ML, -1000474001) \
_(XR_RESULT_MAX_ENUM, 0x7FFFFFFF)
#define XR_LIST_ENUM_XrStructureType(_) \
@@ -229,6 +238,9 @@ XR_ENUM_STR(XrResult);
_(XR_TYPE_GRAPHICS_BINDING_D3D12_KHR, 1000028000) \
_(XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR, 1000028001) \
_(XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR, 1000028002) \
+ _(XR_TYPE_GRAPHICS_BINDING_METAL_KHR, 1000029000) \
+ _(XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR, 1000029001) \
+ _(XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR, 1000029002) \
_(XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT, 1000030000) \
_(XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT, 1000030001) \
_(XR_TYPE_VISIBILITY_MASK_KHR, 1000031000) \
@@ -375,6 +387,22 @@ XR_ENUM_STR(XrResult);
_(XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML, 1000139002) \
_(XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML, 1000139003) \
_(XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML, 1000139004) \
+ _(XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML, 1000140000) \
+ _(XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML, 1000140001) \
+ _(XR_TYPE_SPATIAL_ANCHOR_STATE_ML, 1000140002) \
+ _(XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML, 1000141000) \
+ _(XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML, 1000141001) \
+ _(XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML, 1000141002) \
+ _(XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML, 1000141003) \
+ _(XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML, 1000141004) \
+ _(XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML, 1000141005) \
+ _(XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML, 1000141006) \
+ _(XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML, 1000141007) \
+ _(XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML, 1000141008) \
+ _(XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML, 1000141009) \
+ _(XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML, 1000141010) \
+ _(XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML, 1000141011) \
+ _(XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML, 1000141012) \
_(XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML, 1000472000) \
_(XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML, 1000472001) \
_(XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML, 1000472002) \
@@ -482,6 +510,11 @@ XR_ENUM_STR(XrResult);
_(XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC, 1000318002) \
_(XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC, 1000319000) \
_(XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC, 1000319001) \
+ _(XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC, 1000320000) \
+ _(XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC, 1000320001) \
+ _(XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC, 1000320002) \
+ _(XR_TYPE_BODY_JOINT_LOCATIONS_HTC, 1000320003) \
+ _(XR_TYPE_BODY_SKELETON_HTC, 1000320004) \
_(XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT, 1000373000) \
_(XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX, 1000375000) \
_(XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX, 1000375001) \
@@ -500,6 +533,19 @@ XR_ENUM_STR(XrResult);
_(XR_TYPE_FUTURE_POLL_RESULT_EXT, 1000469003) \
_(XR_TYPE_EVENT_DATA_USER_PRESENCE_CHANGED_EXT, 1000470000) \
_(XR_TYPE_SYSTEM_USER_PRESENCE_PROPERTIES_EXT, 1000470001) \
+ _(XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML, 1000473000) \
+ _(XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML, 1000474001) \
+ _(XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML, 1000474002) \
+ _(XR_TYPE_WORLD_MESH_BLOCK_STATE_ML, 1000474003) \
+ _(XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML, 1000474004) \
+ _(XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML, 1000474005) \
+ _(XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML, 1000474006) \
+ _(XR_TYPE_WORLD_MESH_BUFFER_ML, 1000474007) \
+ _(XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML, 1000474008) \
+ _(XR_TYPE_WORLD_MESH_GET_INFO_ML, 1000474009) \
+ _(XR_TYPE_WORLD_MESH_BLOCK_ML, 1000474010) \
+ _(XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML, 1000474011) \
+ _(XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML, 1000474012) \
_(XR_STRUCTURE_TYPE_MAX_ENUM, 0x7FFFFFFF)
#define XR_LIST_ENUM_XrFormFactor(_) \
@@ -579,6 +625,7 @@ XR_ENUM_STR(XrResult);
_(XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB, 1000118004) \
_(XR_OBJECT_TYPE_MARKER_DETECTOR_ML, 1000138000) \
_(XR_OBJECT_TYPE_EXPORTED_LOCALIZATION_MAP_ML, 1000139000) \
+ _(XR_OBJECT_TYPE_SPATIAL_ANCHORS_STORAGE_ML, 1000141000) \
_(XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT, 1000142000) \
_(XR_OBJECT_TYPE_FACE_TRACKER_FB, 1000201000) \
_(XR_OBJECT_TYPE_EYE_TRACKER_FB, 1000202000) \
@@ -589,7 +636,9 @@ XR_ENUM_STR(XrResult);
_(XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_PROVIDER_META, 1000291000) \
_(XR_OBJECT_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_META, 1000291001) \
_(XR_OBJECT_TYPE_PASSTHROUGH_HTC, 1000317000) \
+ _(XR_OBJECT_TYPE_BODY_TRACKER_HTC, 1000320000) \
_(XR_OBJECT_TYPE_PLANE_DETECTOR_EXT, 1000429000) \
+ _(XR_OBJECT_TYPE_WORLD_MESH_DETECTOR_ML, 1000474000) \
_(XR_OBJECT_TYPE_MAX_ENUM, 0x7FFFFFFF)
#define XR_LIST_ENUM_XrLoaderInterfaceStructs(_) \
@@ -1053,6 +1102,12 @@ XR_ENUM_STR(XrResult);
_(XR_LOCALIZATION_MAP_CONFIDENCE_EXCELLENT_ML, 3) \
_(XR_LOCALIZATION_MAP_CONFIDENCE_MAX_ENUM_ML, 0x7FFFFFFF)
+#define XR_LIST_ENUM_XrSpatialAnchorConfidenceML(_) \
+ _(XR_SPATIAL_ANCHOR_CONFIDENCE_LOW_ML, 0) \
+ _(XR_SPATIAL_ANCHOR_CONFIDENCE_MEDIUM_ML, 1) \
+ _(XR_SPATIAL_ANCHOR_CONFIDENCE_HIGH_ML, 2) \
+ _(XR_SPATIAL_ANCHOR_CONFIDENCE_MAX_ENUM_ML, 0x7FFFFFFF)
+
#define XR_LIST_ENUM_XrSceneMarkerTypeMSFT(_) \
_(XR_SCENE_MARKER_TYPE_QR_CODE_MSFT, 1) \
_(XR_SCENE_MARKER_TYPE_MAX_ENUM_MSFT, 0x7FFFFFFF)
@@ -1363,6 +1418,45 @@ XR_ENUM_STR(XrResult);
_(XR_FOVEATION_LEVEL_HIGH_HTC, 3) \
_(XR_FOVEATION_LEVEL_MAX_ENUM_HTC, 0x7FFFFFFF)
+#define XR_LIST_ENUM_XrBodyJointHTC(_) \
+ _(XR_BODY_JOINT_PELVIS_HTC, 0) \
+ _(XR_BODY_JOINT_LEFT_HIP_HTC, 1) \
+ _(XR_BODY_JOINT_LEFT_KNEE_HTC, 2) \
+ _(XR_BODY_JOINT_LEFT_ANKLE_HTC, 3) \
+ _(XR_BODY_JOINT_LEFT_FEET_HTC, 4) \
+ _(XR_BODY_JOINT_RIGHT_HIP_HTC, 5) \
+ _(XR_BODY_JOINT_RIGHT_KNEE_HTC, 6) \
+ _(XR_BODY_JOINT_RIGHT_ANKLE_HTC, 7) \
+ _(XR_BODY_JOINT_RIGHT_FEET_HTC, 8) \
+ _(XR_BODY_JOINT_WAIST_HTC, 9) \
+ _(XR_BODY_JOINT_SPINE_LOWER_HTC, 10) \
+ _(XR_BODY_JOINT_SPINE_MIDDLE_HTC, 11) \
+ _(XR_BODY_JOINT_SPINE_HIGH_HTC, 12) \
+ _(XR_BODY_JOINT_CHEST_HTC, 13) \
+ _(XR_BODY_JOINT_NECK_HTC, 14) \
+ _(XR_BODY_JOINT_HEAD_HTC, 15) \
+ _(XR_BODY_JOINT_LEFT_CLAVICLE_HTC, 16) \
+ _(XR_BODY_JOINT_LEFT_SCAPULA_HTC, 17) \
+ _(XR_BODY_JOINT_LEFT_ARM_HTC, 18) \
+ _(XR_BODY_JOINT_LEFT_ELBOW_HTC, 19) \
+ _(XR_BODY_JOINT_LEFT_WRIST_HTC, 20) \
+ _(XR_BODY_JOINT_RIGHT_CLAVICLE_HTC, 21) \
+ _(XR_BODY_JOINT_RIGHT_SCAPULA_HTC, 22) \
+ _(XR_BODY_JOINT_RIGHT_ARM_HTC, 23) \
+ _(XR_BODY_JOINT_RIGHT_ELBOW_HTC, 24) \
+ _(XR_BODY_JOINT_RIGHT_WRIST_HTC, 25) \
+ _(XR_BODY_JOINT_MAX_ENUM_HTC, 0x7FFFFFFF)
+
+#define XR_LIST_ENUM_XrBodyJointSetHTC(_) \
+ _(XR_BODY_JOINT_SET_FULL_HTC, 0) \
+ _(XR_BODY_JOINT_SET_MAX_ENUM_HTC, 0x7FFFFFFF)
+
+#define XR_LIST_ENUM_XrBodyJointConfidenceHTC(_) \
+ _(XR_BODY_JOINT_CONFIDENCE_NONE_HTC, 0) \
+ _(XR_BODY_JOINT_CONFIDENCE_LOW_HTC, 1) \
+ _(XR_BODY_JOINT_CONFIDENCE_HIGH_HTC, 2) \
+ _(XR_BODY_JOINT_CONFIDENCE_MAX_ENUM_HTC, 0x7FFFFFFF)
+
#define XR_LIST_ENUM_XrForceFeedbackCurlLocationMNDX(_) \
_(XR_FORCE_FEEDBACK_CURL_LOCATION_THUMB_CURL_MNDX, 0) \
_(XR_FORCE_FEEDBACK_CURL_LOCATION_INDEX_CURL_MNDX, 1) \
@@ -1418,6 +1512,26 @@ XR_ENUM_STR(XrResult);
_(XR_EYE_CALIBRATION_STATUS_FINE_ML, 3) \
_(XR_EYE_CALIBRATION_STATUS_MAX_ENUM_ML, 0x7FFFFFFF)
+#define XR_LIST_ENUM_XrWorldMeshDetectorLodML(_) \
+ _(XR_WORLD_MESH_DETECTOR_LOD_MINIMUM_ML, 0) \
+ _(XR_WORLD_MESH_DETECTOR_LOD_MEDIUM_ML, 1) \
+ _(XR_WORLD_MESH_DETECTOR_LOD_MAXIMUM_ML, 2) \
+ _(XR_WORLD_MESH_DETECTOR_LOD_MAX_ENUM_ML, 0x7FFFFFFF)
+
+#define XR_LIST_ENUM_XrWorldMeshBlockStatusML(_) \
+ _(XR_WORLD_MESH_BLOCK_STATUS_NEW_ML, 0) \
+ _(XR_WORLD_MESH_BLOCK_STATUS_UPDATED_ML, 1) \
+ _(XR_WORLD_MESH_BLOCK_STATUS_DELETED_ML, 2) \
+ _(XR_WORLD_MESH_BLOCK_STATUS_UNCHANGED_ML, 3) \
+ _(XR_WORLD_MESH_BLOCK_STATUS_MAX_ENUM_ML, 0x7FFFFFFF)
+
+#define XR_LIST_ENUM_XrWorldMeshBlockResultML(_) \
+ _(XR_WORLD_MESH_BLOCK_RESULT_SUCCESS_ML, 0) \
+ _(XR_WORLD_MESH_BLOCK_RESULT_FAILED_ML, 1) \
+ _(XR_WORLD_MESH_BLOCK_RESULT_PENDING_ML, 2) \
+ _(XR_WORLD_MESH_BLOCK_RESULT_PARTIAL_UPDATE_ML, 3) \
+ _(XR_WORLD_MESH_BLOCK_RESULT_MAX_ENUM_ML, 0x7FFFFFFF)
+
#define XR_LIST_BITS_XrInstanceCreateFlags(_)
#define XR_LIST_BITS_XrSessionCreateFlags(_)
@@ -1622,6 +1736,14 @@ XR_ENUM_STR(XrResult);
#define XR_LIST_BITS_XrPlaneDetectorFlagsEXT(_) \
_(XR_PLANE_DETECTOR_ENABLE_CONTOUR_BIT_EXT, 0x00000001) \
+#define XR_LIST_BITS_XrWorldMeshDetectorFlagsML(_) \
+ _(XR_WORLD_MESH_DETECTOR_POINT_CLOUD_BIT_ML, 0x00000001) \
+ _(XR_WORLD_MESH_DETECTOR_COMPUTE_NORMALS_BIT_ML, 0x00000002) \
+ _(XR_WORLD_MESH_DETECTOR_COMPUTE_CONFIDENCE_BIT_ML, 0x00000004) \
+ _(XR_WORLD_MESH_DETECTOR_PLANARIZE_BIT_ML, 0x00000008) \
+ _(XR_WORLD_MESH_DETECTOR_REMOVE_MESH_SKIRT_BIT_ML, 0x00000010) \
+ _(XR_WORLD_MESH_DETECTOR_INDEX_ORDER_CW_BIT_ML, 0x00000020) \
+
/// Calls your macro with the name of each member of XrApiLayerProperties, in order.
#define XR_LIST_STRUCT_XrApiLayerProperties(_) \
_(type) \
@@ -2442,6 +2564,24 @@ XR_ENUM_STR(XrResult);
_(adapterLuid) \
_(minFeatureLevel) \
+/// Calls your macro with the name of each member of XrGraphicsBindingMetalKHR, in order.
+#define XR_LIST_STRUCT_XrGraphicsBindingMetalKHR(_) \
+ _(type) \
+ _(next) \
+ _(commandQueue) \
+
+/// Calls your macro with the name of each member of XrSwapchainImageMetalKHR, in order.
+#define XR_LIST_STRUCT_XrSwapchainImageMetalKHR(_) \
+ _(type) \
+ _(next) \
+ _(texture) \
+
+/// Calls your macro with the name of each member of XrGraphicsRequirementsMetalKHR, in order.
+#define XR_LIST_STRUCT_XrGraphicsRequirementsMetalKHR(_) \
+ _(type) \
+ _(next) \
+ _(metalDevice) \
+
/// Calls your macro with the name of each member of XrVisibilityMaskKHR, in order.
#define XR_LIST_STRUCT_XrVisibilityMaskKHR(_) \
_(type) \
@@ -3711,6 +3851,138 @@ XR_ENUM_STR(XrResult);
_(next) \
_(enabled) \
+/// Calls your macro with the name of each member of XrSpatialAnchorsCreateInfoBaseHeaderML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsCreateInfoBaseHeaderML(_) \
+ _(type) \
+ _(next) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsCreateInfoFromPoseML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsCreateInfoFromPoseML(_) \
+ _(type) \
+ _(next) \
+ _(baseSpace) \
+ _(poseInBaseSpace) \
+ _(time) \
+
+/// Calls your macro with the name of each member of XrCreateSpatialAnchorsCompletionML, in order.
+#define XR_LIST_STRUCT_XrCreateSpatialAnchorsCompletionML(_) \
+ _(type) \
+ _(next) \
+ _(futureResult) \
+ _(spaceCount) \
+ _(spaces) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorStateML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorStateML(_) \
+ _(type) \
+ _(next) \
+ _(confidence) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsCreateStorageInfoML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsCreateStorageInfoML(_) \
+ _(type) \
+ _(next) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsQueryInfoBaseHeaderML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsQueryInfoBaseHeaderML(_) \
+ _(type) \
+ _(next) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsQueryInfoRadiusML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsQueryInfoRadiusML(_) \
+ _(type) \
+ _(next) \
+ _(baseSpace) \
+ _(center) \
+ _(time) \
+ _(radius) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsQueryCompletionML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsQueryCompletionML(_) \
+ _(type) \
+ _(next) \
+ _(futureResult) \
+ _(uuidCapacityInput) \
+ _(uuidCountOutput) \
+ _(uuids) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsCreateInfoFromUuidsML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsCreateInfoFromUuidsML(_) \
+ _(type) \
+ _(next) \
+ _(storage) \
+ _(uuidCount) \
+ _(uuids) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsPublishInfoML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsPublishInfoML(_) \
+ _(type) \
+ _(next) \
+ _(anchorCount) \
+ _(anchors) \
+ _(expiration) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsPublishCompletionML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsPublishCompletionML(_) \
+ _(type) \
+ _(next) \
+ _(futureResult) \
+ _(uuidCount) \
+ _(uuids) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsDeleteInfoML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsDeleteInfoML(_) \
+ _(type) \
+ _(next) \
+ _(uuidCount) \
+ _(uuids) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsDeleteCompletionML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsDeleteCompletionML(_) \
+ _(type) \
+ _(next) \
+ _(futureResult) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsUpdateExpirationInfoML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsUpdateExpirationInfoML(_) \
+ _(type) \
+ _(next) \
+ _(uuidCount) \
+ _(uuids) \
+ _(expiration) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsUpdateExpirationCompletionML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsUpdateExpirationCompletionML(_) \
+ _(type) \
+ _(next) \
+ _(futureResult) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorCompletionResultML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorCompletionResultML(_) \
+ _(uuid) \
+ _(result) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsPublishCompletionDetailsML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsPublishCompletionDetailsML(_) \
+ _(type) \
+ _(next) \
+ _(resultCount) \
+ _(results) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsDeleteCompletionDetailsML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsDeleteCompletionDetailsML(_) \
+ _(type) \
+ _(next) \
+ _(resultCount) \
+ _(results) \
+
+/// Calls your macro with the name of each member of XrSpatialAnchorsUpdateExpirationCompletionDetailsML, in order.
+#define XR_LIST_STRUCT_XrSpatialAnchorsUpdateExpirationCompletionDetailsML(_) \
+ _(type) \
+ _(next) \
+ _(resultCount) \
+ _(results) \
+
/// Calls your macro with the name of each member of XrSpatialAnchorPersistenceNameMSFT, in order.
#define XR_LIST_STRUCT_XrSpatialAnchorPersistenceNameMSFT(_) \
_(name) \
@@ -4571,6 +4843,51 @@ XR_ENUM_STR(XrResult);
_(poseInSpace) \
_(name) \
+/// Calls your macro with the name of each member of XrSystemBodyTrackingPropertiesHTC, in order.
+#define XR_LIST_STRUCT_XrSystemBodyTrackingPropertiesHTC(_) \
+ _(type) \
+ _(next) \
+ _(supportsBodyTracking) \
+
+/// Calls your macro with the name of each member of XrBodyTrackerCreateInfoHTC, in order.
+#define XR_LIST_STRUCT_XrBodyTrackerCreateInfoHTC(_) \
+ _(type) \
+ _(next) \
+ _(bodyJointSet) \
+
+/// Calls your macro with the name of each member of XrBodyJointsLocateInfoHTC, in order.
+#define XR_LIST_STRUCT_XrBodyJointsLocateInfoHTC(_) \
+ _(type) \
+ _(next) \
+ _(baseSpace) \
+ _(time) \
+
+/// Calls your macro with the name of each member of XrBodyJointLocationHTC, in order.
+#define XR_LIST_STRUCT_XrBodyJointLocationHTC(_) \
+ _(locationFlags) \
+ _(pose) \
+
+/// Calls your macro with the name of each member of XrBodyJointLocationsHTC, in order.
+#define XR_LIST_STRUCT_XrBodyJointLocationsHTC(_) \
+ _(type) \
+ _(next) \
+ _(combinedLocationFlags) \
+ _(confidenceLevel) \
+ _(jointLocationCount) \
+ _(jointLocations) \
+ _(skeletonGenerationId) \
+
+/// Calls your macro with the name of each member of XrBodySkeletonJointHTC, in order.
+#define XR_LIST_STRUCT_XrBodySkeletonJointHTC(_) \
+ _(pose) \
+
+/// Calls your macro with the name of each member of XrBodySkeletonHTC, in order.
+#define XR_LIST_STRUCT_XrBodySkeletonHTC(_) \
+ _(type) \
+ _(next) \
+ _(jointCount) \
+ _(joints) \
+
/// Calls your macro with the name of each member of XrActiveActionSetPriorityEXT, in order.
#define XR_LIST_STRUCT_XrActiveActionSetPriorityEXT(_) \
_(actionSet) \
@@ -4739,6 +5056,114 @@ XR_ENUM_STR(XrResult);
_(next) \
_(enabled) \
+/// Calls your macro with the name of each member of XrSystemNotificationsSetInfoML, in order.
+#define XR_LIST_STRUCT_XrSystemNotificationsSetInfoML(_) \
+ _(type) \
+ _(next) \
+ _(suppressNotifications) \
+
+/// Calls your macro with the name of each member of XrWorldMeshDetectorCreateInfoML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshDetectorCreateInfoML(_) \
+ _(type) \
+ _(next) \
+
+/// Calls your macro with the name of each member of XrWorldMeshBlockStateML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshBlockStateML(_) \
+ _(type) \
+ _(next) \
+ _(uuid) \
+ _(meshBoundingBoxCenter) \
+ _(meshBoundingBoxExtents) \
+ _(lastUpdateTime) \
+ _(status) \
+
+/// Calls your macro with the name of each member of XrWorldMeshStateRequestInfoML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshStateRequestInfoML(_) \
+ _(type) \
+ _(next) \
+ _(baseSpace) \
+ _(time) \
+ _(boundingBoxCenter) \
+ _(boundingBoxExtents) \
+
+/// Calls your macro with the name of each member of XrWorldMeshStateRequestCompletionML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshStateRequestCompletionML(_) \
+ _(type) \
+ _(next) \
+ _(futureResult) \
+ _(timestamp) \
+ _(meshBlockStateCapacityInput) \
+ _(meshBlockStateCountOutput) \
+ _(meshBlockStates) \
+
+/// Calls your macro with the name of each member of XrWorldMeshBufferRecommendedSizeInfoML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshBufferRecommendedSizeInfoML(_) \
+ _(type) \
+ _(next) \
+ _(maxBlockCount) \
+
+/// Calls your macro with the name of each member of XrWorldMeshBufferSizeML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshBufferSizeML(_) \
+ _(type) \
+ _(next) \
+ _(size) \
+
+/// Calls your macro with the name of each member of XrWorldMeshBufferML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshBufferML(_) \
+ _(type) \
+ _(next) \
+ _(bufferSize) \
+ _(buffer) \
+
+/// Calls your macro with the name of each member of XrWorldMeshBlockRequestML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshBlockRequestML(_) \
+ _(type) \
+ _(next) \
+ _(uuid) \
+ _(lod) \
+
+/// Calls your macro with the name of each member of XrWorldMeshGetInfoML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshGetInfoML(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+ _(fillHoleLength) \
+ _(disconnectedComponentArea) \
+ _(blockCount) \
+ _(blocks) \
+
+/// Calls your macro with the name of each member of XrWorldMeshBlockML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshBlockML(_) \
+ _(type) \
+ _(next) \
+ _(uuid) \
+ _(blockResult) \
+ _(lod) \
+ _(flags) \
+ _(indexCount) \
+ _(indexBuffer) \
+ _(vertexCount) \
+ _(vertexBuffer) \
+ _(normalCount) \
+ _(normalBuffer) \
+ _(confidenceCount) \
+ _(confidenceBuffer) \
+
+/// Calls your macro with the name of each member of XrWorldMeshRequestCompletionInfoML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshRequestCompletionInfoML(_) \
+ _(type) \
+ _(next) \
+ _(meshSpace) \
+ _(meshSpaceLocateTime) \
+
+/// Calls your macro with the name of each member of XrWorldMeshRequestCompletionML, in order.
+#define XR_LIST_STRUCT_XrWorldMeshRequestCompletionML(_) \
+ _(type) \
+ _(next) \
+ _(futureResult) \
+ _(blockCount) \
+ _(blocks) \
+
/// Calls your macro with the structure type name and the XrStructureType constant for
@@ -4747,6 +5172,7 @@ XR_ENUM_STR(XrResult);
XR_LIST_STRUCTURE_TYPES_CORE(_) \
XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_) \
XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_) \
XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_) \
XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_) \
XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_) \
@@ -4962,6 +5388,22 @@ XR_ENUM_STR(XrResult);
_(XrMapLocalizationRequestInfoML, XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML) \
_(XrLocalizationMapImportInfoML, XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML) \
_(XrLocalizationEnableEventsInfoML, XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML) \
+ _(XrSpatialAnchorsCreateInfoFromPoseML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML) \
+ _(XrCreateSpatialAnchorsCompletionML, XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML) \
+ _(XrSpatialAnchorStateML, XR_TYPE_SPATIAL_ANCHOR_STATE_ML) \
+ _(XrSpatialAnchorsCreateStorageInfoML, XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML) \
+ _(XrSpatialAnchorsQueryInfoRadiusML, XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML) \
+ _(XrSpatialAnchorsQueryCompletionML, XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML) \
+ _(XrSpatialAnchorsCreateInfoFromUuidsML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML) \
+ _(XrSpatialAnchorsPublishInfoML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML) \
+ _(XrSpatialAnchorsPublishCompletionML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML) \
+ _(XrSpatialAnchorsDeleteInfoML, XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML) \
+ _(XrSpatialAnchorsDeleteCompletionML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML) \
+ _(XrSpatialAnchorsUpdateExpirationInfoML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML) \
+ _(XrSpatialAnchorsUpdateExpirationCompletionML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML) \
+ _(XrSpatialAnchorsPublishCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML) \
+ _(XrSpatialAnchorsDeleteCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML) \
+ _(XrSpatialAnchorsUpdateExpirationCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML) \
_(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \
_(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \
_(XrSceneMarkersMSFT, XR_TYPE_SCENE_MARKERS_MSFT) \
@@ -5061,6 +5503,11 @@ XR_ENUM_STR(XrResult);
_(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \
_(XrSystemAnchorPropertiesHTC, XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC) \
_(XrSpatialAnchorCreateInfoHTC, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC) \
+ _(XrSystemBodyTrackingPropertiesHTC, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC) \
+ _(XrBodyTrackerCreateInfoHTC, XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC) \
+ _(XrBodyJointsLocateInfoHTC, XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC) \
+ _(XrBodyJointLocationsHTC, XR_TYPE_BODY_JOINT_LOCATIONS_HTC) \
+ _(XrBodySkeletonHTC, XR_TYPE_BODY_SKELETON_HTC) \
_(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \
_(XrSystemForceFeedbackCurlPropertiesMNDX, XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX) \
_(XrForceFeedbackCurlApplyLocationsMNDX, XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX) \
@@ -5082,6 +5529,19 @@ XR_ENUM_STR(XrResult);
_(XrEventDataHeadsetFitChangedML, XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML) \
_(XrEventDataEyeCalibrationChangedML, XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML) \
_(XrUserCalibrationEnableEventsInfoML, XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML) \
+ _(XrSystemNotificationsSetInfoML, XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML) \
+ _(XrWorldMeshDetectorCreateInfoML, XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML) \
+ _(XrWorldMeshBlockStateML, XR_TYPE_WORLD_MESH_BLOCK_STATE_ML) \
+ _(XrWorldMeshStateRequestInfoML, XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML) \
+ _(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \
+ _(XrWorldMeshBufferRecommendedSizeInfoML, XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML) \
+ _(XrWorldMeshBufferSizeML, XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML) \
+ _(XrWorldMeshBufferML, XR_TYPE_WORLD_MESH_BUFFER_ML) \
+ _(XrWorldMeshBlockRequestML, XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML) \
+ _(XrWorldMeshGetInfoML, XR_TYPE_WORLD_MESH_GET_INFO_ML) \
+ _(XrWorldMeshBlockML, XR_TYPE_WORLD_MESH_BLOCK_ML) \
+ _(XrWorldMeshRequestCompletionInfoML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML) \
+ _(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \
#if defined(XR_USE_GRAPHICS_API_D3D11)
@@ -5108,6 +5568,18 @@ XR_ENUM_STR(XrResult);
#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_)
#endif
+#if defined(XR_USE_GRAPHICS_API_METAL)
+/// Implementation detail of XR_LIST_STRUCTURE_TYPES()
+/// Structure types available only when XR_USE_GRAPHICS_API_METAL is defined
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_) \
+ _(XrGraphicsBindingMetalKHR, XR_TYPE_GRAPHICS_BINDING_METAL_KHR) \
+ _(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \
+ _(XrGraphicsRequirementsMetalKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR) \
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_)
+#endif
+
#if defined(XR_USE_GRAPHICS_API_OPENGL)
/// Implementation detail of XR_LIST_STRUCTURE_TYPES()
/// Structure types available only when XR_USE_GRAPHICS_API_OPENGL is defined
@@ -5264,6 +5736,7 @@ XR_ENUM_STR(XrResult);
_(XR_KHR_vulkan_enable, 26) \
_(XR_KHR_D3D11_enable, 28) \
_(XR_KHR_D3D12_enable, 29) \
+ _(XR_KHR_metal_enable, 30) \
_(XR_EXT_eye_gaze_interaction, 31) \
_(XR_KHR_visibility_mask, 32) \
_(XR_EXTX_overlay, 34) \
@@ -5340,6 +5813,8 @@ XR_ENUM_STR(XrResult);
_(XR_ML_compat, 138) \
_(XR_ML_marker_understanding, 139) \
_(XR_ML_localization_map, 140) \
+ _(XR_ML_spatial_anchors, 141) \
+ _(XR_ML_spatial_anchors_storage, 142) \
_(XR_MSFT_spatial_anchor_persistence, 143) \
_(XR_MSFT_scene_marker, 148) \
_(XR_ULTRALEAP_hand_tracking_forearm, 150) \
@@ -5390,6 +5865,7 @@ XR_ENUM_STR(XrResult);
_(XR_HTC_passthrough, 318) \
_(XR_HTC_foveation, 319) \
_(XR_HTC_anchor, 320) \
+ _(XR_HTC_body_tracking, 321) \
_(XR_EXT_active_action_set_priority, 374) \
_(XR_MNDX_force_feedback_curl, 376) \
_(XR_BD_controller_interaction, 385) \
@@ -5401,6 +5877,9 @@ XR_ENUM_STR(XrResult);
_(XR_EXT_user_presence, 471) \
_(XR_KHR_locate_spaces, 472) \
_(XR_ML_user_calibration, 473) \
+ _(XR_ML_system_notifications, 474) \
+ _(XR_ML_world_mesh_detection, 475) \
+ _(XR_ML_view_configuration_depth_range_change, 484) \
_(XR_YVR_controller_interaction, 498) \
_(XR_EXT_composition_layer_inverted_alpha, 555) \
_(XR_KHR_maintenance1, 711) \
@@ -5546,6 +6025,14 @@ XR_ENUM_STR(XrResult);
_(GetD3D12GraphicsRequirementsKHR, KHR_D3D12_enable) \
+/// For every function defined by XR_KHR_metal_enable in this version of the spec,
+/// calls your macro with the function name and extension name.
+/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
+/// because it is easy to add back but impossible to remove with the preprocessor.
+#define XR_LIST_FUNCTIONS_XR_KHR_metal_enable(_) \
+ _(GetMetalGraphicsRequirementsKHR, KHR_metal_enable) \
+
+
/// For every function defined by XR_KHR_visibility_mask in this version of the spec,
/// calls your macro with the function name and extension name.
/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
@@ -5932,6 +6419,33 @@ XR_ENUM_STR(XrResult);
_(GetExportedLocalizationMapDataML, ML_localization_map) \
+/// For every function defined by XR_ML_spatial_anchors in this version of the spec,
+/// calls your macro with the function name and extension name.
+/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
+/// because it is easy to add back but impossible to remove with the preprocessor.
+#define XR_LIST_FUNCTIONS_XR_ML_spatial_anchors(_) \
+ _(CreateSpatialAnchorsAsyncML, ML_spatial_anchors) \
+ _(CreateSpatialAnchorsCompleteML, ML_spatial_anchors) \
+ _(GetSpatialAnchorStateML, ML_spatial_anchors) \
+
+
+/// For every function defined by XR_ML_spatial_anchors_storage in this version of the spec,
+/// calls your macro with the function name and extension name.
+/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
+/// because it is easy to add back but impossible to remove with the preprocessor.
+#define XR_LIST_FUNCTIONS_XR_ML_spatial_anchors_storage(_) \
+ _(CreateSpatialAnchorsStorageML, ML_spatial_anchors_storage) \
+ _(DestroySpatialAnchorsStorageML, ML_spatial_anchors_storage) \
+ _(QuerySpatialAnchorsAsyncML, ML_spatial_anchors_storage) \
+ _(QuerySpatialAnchorsCompleteML, ML_spatial_anchors_storage) \
+ _(PublishSpatialAnchorsAsyncML, ML_spatial_anchors_storage) \
+ _(PublishSpatialAnchorsCompleteML, ML_spatial_anchors_storage) \
+ _(DeleteSpatialAnchorsAsyncML, ML_spatial_anchors_storage) \
+ _(DeleteSpatialAnchorsCompleteML, ML_spatial_anchors_storage) \
+ _(UpdateSpatialAnchorsExpirationAsyncML, ML_spatial_anchors_storage) \
+ _(UpdateSpatialAnchorsExpirationCompleteML, ML_spatial_anchors_storage) \
+
+
/// For every function defined by XR_MSFT_spatial_anchor_persistence in this version of the spec,
/// calls your macro with the function name and extension name.
/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
@@ -6220,6 +6734,17 @@ XR_ENUM_STR(XrResult);
_(GetSpatialAnchorNameHTC, HTC_anchor) \
+/// For every function defined by XR_HTC_body_tracking in this version of the spec,
+/// calls your macro with the function name and extension name.
+/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
+/// because it is easy to add back but impossible to remove with the preprocessor.
+#define XR_LIST_FUNCTIONS_XR_HTC_body_tracking(_) \
+ _(CreateBodyTrackerHTC, HTC_body_tracking) \
+ _(DestroyBodyTrackerHTC, HTC_body_tracking) \
+ _(LocateBodyJointsHTC, HTC_body_tracking) \
+ _(GetBodySkeletonHTC, HTC_body_tracking) \
+
+
/// For every function defined by XR_MNDX_force_feedback_curl in this version of the spec,
/// calls your macro with the function name and extension name.
/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
@@ -6258,6 +6783,30 @@ XR_ENUM_STR(XrResult);
_(EnableUserCalibrationEventsML, ML_user_calibration) \
+/// For every function defined by XR_ML_system_notifications in this version of the spec,
+/// calls your macro with the function name and extension name.
+/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
+/// because it is easy to add back but impossible to remove with the preprocessor.
+#define XR_LIST_FUNCTIONS_XR_ML_system_notifications(_) \
+ _(SetSystemNotificationsML, ML_system_notifications) \
+
+
+/// For every function defined by XR_ML_world_mesh_detection in this version of the spec,
+/// calls your macro with the function name and extension name.
+/// Trims the leading `xr` from the function name and the leading `XR_` from the feature name,
+/// because it is easy to add back but impossible to remove with the preprocessor.
+#define XR_LIST_FUNCTIONS_XR_ML_world_mesh_detection(_) \
+ _(CreateWorldMeshDetectorML, ML_world_mesh_detection) \
+ _(DestroyWorldMeshDetectorML, ML_world_mesh_detection) \
+ _(RequestWorldMeshStateAsyncML, ML_world_mesh_detection) \
+ _(RequestWorldMeshStateCompleteML, ML_world_mesh_detection) \
+ _(GetWorldMeshBufferRecommendSizeML, ML_world_mesh_detection) \
+ _(AllocateWorldMeshBufferML, ML_world_mesh_detection) \
+ _(FreeWorldMeshBufferML, ML_world_mesh_detection) \
+ _(RequestWorldMeshAsyncML, ML_world_mesh_detection) \
+ _(RequestWorldMeshCompleteML, ML_world_mesh_detection) \
+
+
#endif
diff --git a/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h b/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h
index 50466abc1b..bffab47cc5 100644
--- a/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h
+++ b/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h
@@ -238,6 +238,53 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a
+/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpatialAnchorsCreateInfoBaseHeaderML
+#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML(_avail, _unavail) \
+ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML_CORE(_avail, _unavail) \
+
+
+// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML()
+#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsCreateInfoBaseHeaderML_CORE(_avail, _unavail) \
+ _avail(XrSpatialAnchorsCreateInfoFromPoseML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML) \
+ _avail(XrSpatialAnchorsCreateInfoFromUuidsML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML) \
+
+
+
+
+
+/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrFutureCompletionBaseHeaderEXT
+#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT(_avail, _unavail) \
+ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \
+
+
+// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT()
+#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \
+ _avail(XrCreateSpatialAnchorsCompletionML, XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML) \
+ _avail(XrSpatialAnchorsQueryCompletionML, XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML) \
+ _avail(XrSpatialAnchorsPublishCompletionML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML) \
+ _avail(XrSpatialAnchorsDeleteCompletionML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML) \
+ _avail(XrSpatialAnchorsUpdateExpirationCompletionML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML) \
+ _avail(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \
+ _avail(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \
+ _avail(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \
+
+
+
+
+
+/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpatialAnchorsQueryInfoBaseHeaderML
+#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML(_avail, _unavail) \
+ _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML_CORE(_avail, _unavail) \
+
+
+// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML()
+#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpatialAnchorsQueryInfoBaseHeaderML_CORE(_avail, _unavail) \
+ _avail(XrSpatialAnchorsQueryInfoRadiusML, XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML) \
+
+
+
+
+
/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrSpaceQueryInfoBaseHeaderFB
#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB(_avail, _unavail) \
_impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrSpaceQueryInfoBaseHeaderFB_CORE(_avail, _unavail) \
@@ -265,18 +312,5 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a
-/// Like XR_LIST_ALL_STRUCTURE_TYPES, but only includes types whose parent struct type is XrFutureCompletionBaseHeaderEXT
-#define XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT(_avail, _unavail) \
- _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \
-
-
-// Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT()
-#define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrFutureCompletionBaseHeaderEXT_CORE(_avail, _unavail) \
- _avail(XrFutureCompletionEXT, XR_TYPE_FUTURE_COMPLETION_EXT) \
-
-
-
-
-
#endif
diff --git a/thirdparty/openxr/include/openxr/openxr_reflection_structs.h b/thirdparty/openxr/include/openxr/openxr_reflection_structs.h
index e87e55b560..b1ab8e7779 100644
--- a/thirdparty/openxr/include/openxr/openxr_reflection_structs.h
+++ b/thirdparty/openxr/include/openxr/openxr_reflection_structs.h
@@ -27,6 +27,7 @@ This file contains expansion macros (X Macros) for OpenXR structures.
_impl_XR_LIST_ALL_STRUCTURE_TYPES_CORE(_avail, _unavail) \
_impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_avail, _unavail) \
_impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_avail, _unavail) \
+ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \
_impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \
_impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_avail, _unavail) \
_impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_avail, _unavail) \
@@ -242,6 +243,22 @@ This file contains expansion macros (X Macros) for OpenXR structures.
_avail(XrMapLocalizationRequestInfoML, XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML) \
_avail(XrLocalizationMapImportInfoML, XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML) \
_avail(XrLocalizationEnableEventsInfoML, XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML) \
+ _avail(XrSpatialAnchorsCreateInfoFromPoseML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML) \
+ _avail(XrCreateSpatialAnchorsCompletionML, XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML) \
+ _avail(XrSpatialAnchorStateML, XR_TYPE_SPATIAL_ANCHOR_STATE_ML) \
+ _avail(XrSpatialAnchorsCreateStorageInfoML, XR_TYPE_SPATIAL_ANCHORS_CREATE_STORAGE_INFO_ML) \
+ _avail(XrSpatialAnchorsQueryInfoRadiusML, XR_TYPE_SPATIAL_ANCHORS_QUERY_INFO_RADIUS_ML) \
+ _avail(XrSpatialAnchorsQueryCompletionML, XR_TYPE_SPATIAL_ANCHORS_QUERY_COMPLETION_ML) \
+ _avail(XrSpatialAnchorsCreateInfoFromUuidsML, XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_UUIDS_ML) \
+ _avail(XrSpatialAnchorsPublishInfoML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_INFO_ML) \
+ _avail(XrSpatialAnchorsPublishCompletionML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_ML) \
+ _avail(XrSpatialAnchorsDeleteInfoML, XR_TYPE_SPATIAL_ANCHORS_DELETE_INFO_ML) \
+ _avail(XrSpatialAnchorsDeleteCompletionML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_ML) \
+ _avail(XrSpatialAnchorsUpdateExpirationInfoML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_INFO_ML) \
+ _avail(XrSpatialAnchorsUpdateExpirationCompletionML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_ML) \
+ _avail(XrSpatialAnchorsPublishCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_PUBLISH_COMPLETION_DETAILS_ML) \
+ _avail(XrSpatialAnchorsDeleteCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_DELETE_COMPLETION_DETAILS_ML) \
+ _avail(XrSpatialAnchorsUpdateExpirationCompletionDetailsML, XR_TYPE_SPATIAL_ANCHORS_UPDATE_EXPIRATION_COMPLETION_DETAILS_ML) \
_avail(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \
_avail(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \
_avail(XrSceneMarkersMSFT, XR_TYPE_SCENE_MARKERS_MSFT) \
@@ -341,6 +358,11 @@ This file contains expansion macros (X Macros) for OpenXR structures.
_avail(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \
_avail(XrSystemAnchorPropertiesHTC, XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC) \
_avail(XrSpatialAnchorCreateInfoHTC, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC) \
+ _avail(XrSystemBodyTrackingPropertiesHTC, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_HTC) \
+ _avail(XrBodyTrackerCreateInfoHTC, XR_TYPE_BODY_TRACKER_CREATE_INFO_HTC) \
+ _avail(XrBodyJointsLocateInfoHTC, XR_TYPE_BODY_JOINTS_LOCATE_INFO_HTC) \
+ _avail(XrBodyJointLocationsHTC, XR_TYPE_BODY_JOINT_LOCATIONS_HTC) \
+ _avail(XrBodySkeletonHTC, XR_TYPE_BODY_SKELETON_HTC) \
_avail(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \
_avail(XrSystemForceFeedbackCurlPropertiesMNDX, XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX) \
_avail(XrForceFeedbackCurlApplyLocationsMNDX, XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX) \
@@ -362,6 +384,19 @@ This file contains expansion macros (X Macros) for OpenXR structures.
_avail(XrEventDataHeadsetFitChangedML, XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML) \
_avail(XrEventDataEyeCalibrationChangedML, XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML) \
_avail(XrUserCalibrationEnableEventsInfoML, XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML) \
+ _avail(XrSystemNotificationsSetInfoML, XR_TYPE_SYSTEM_NOTIFICATIONS_SET_INFO_ML) \
+ _avail(XrWorldMeshDetectorCreateInfoML, XR_TYPE_WORLD_MESH_DETECTOR_CREATE_INFO_ML) \
+ _avail(XrWorldMeshBlockStateML, XR_TYPE_WORLD_MESH_BLOCK_STATE_ML) \
+ _avail(XrWorldMeshStateRequestInfoML, XR_TYPE_WORLD_MESH_STATE_REQUEST_INFO_ML) \
+ _avail(XrWorldMeshStateRequestCompletionML, XR_TYPE_WORLD_MESH_STATE_REQUEST_COMPLETION_ML) \
+ _avail(XrWorldMeshBufferRecommendedSizeInfoML, XR_TYPE_WORLD_MESH_BUFFER_RECOMMENDED_SIZE_INFO_ML) \
+ _avail(XrWorldMeshBufferSizeML, XR_TYPE_WORLD_MESH_BUFFER_SIZE_ML) \
+ _avail(XrWorldMeshBufferML, XR_TYPE_WORLD_MESH_BUFFER_ML) \
+ _avail(XrWorldMeshBlockRequestML, XR_TYPE_WORLD_MESH_BLOCK_REQUEST_ML) \
+ _avail(XrWorldMeshGetInfoML, XR_TYPE_WORLD_MESH_GET_INFO_ML) \
+ _avail(XrWorldMeshBlockML, XR_TYPE_WORLD_MESH_BLOCK_ML) \
+ _avail(XrWorldMeshRequestCompletionInfoML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_INFO_ML) \
+ _avail(XrWorldMeshRequestCompletionML, XR_TYPE_WORLD_MESH_REQUEST_COMPLETION_ML) \
#if defined(XR_USE_GRAPHICS_API_D3D11)
@@ -392,6 +427,20 @@ This file contains expansion macros (X Macros) for OpenXR structures.
#endif
+#if defined(XR_USE_GRAPHICS_API_METAL)
+#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \
+ _avail(XrGraphicsBindingMetalKHR, XR_TYPE_GRAPHICS_BINDING_METAL_KHR) \
+ _avail(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \
+ _avail(XrGraphicsRequirementsMetalKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR) \
+
+#else
+#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_METAL(_avail, _unavail) \
+ _unavail(XrGraphicsBindingMetalKHR, XR_TYPE_GRAPHICS_BINDING_METAL_KHR) \
+ _unavail(XrSwapchainImageMetalKHR, XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR) \
+ _unavail(XrGraphicsRequirementsMetalKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR) \
+
+#endif
+
#if defined(XR_USE_GRAPHICS_API_OPENGL)
#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_avail, _unavail) \
_avail(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \
diff --git a/thirdparty/openxr/src/common/platform_utils.hpp b/thirdparty/openxr/src/common/platform_utils.hpp
index d047c17d9d..19cd41cbb2 100644
--- a/thirdparty/openxr/src/common/platform_utils.hpp
+++ b/thirdparty/openxr/src/common/platform_utils.hpp
@@ -91,21 +91,22 @@ namespace detail {
static inline char* ImplGetEnv(const char* name) { return getenv(name); }
+// clang-format off
static inline char* ImplGetSecureEnv(const char* name) {
#ifdef HAVE_SECURE_GETENV
return secure_getenv(name);
#elif defined(HAVE___SECURE_GETENV)
return __secure_getenv(name);
#else
-// clang-format off
#pragma message( \
"Warning: Falling back to non-secure getenv for environmental" \
"lookups! Consider updating to a different libc.")
- // clang-format on
return ImplGetEnv(name);
#endif
}
+// clang-format on
+
} // namespace detail
#endif // defined(XR_OS_LINUX) || defined(XR_OS_APPLE)
diff --git a/thirdparty/openxr/src/common/xr_linear.h b/thirdparty/openxr/src/common/xr_linear.h
index 2b295ed304..cc525d3357 100644
--- a/thirdparty/openxr/src/common/xr_linear.h
+++ b/thirdparty/openxr/src/common/xr_linear.h
@@ -134,7 +134,7 @@ static const XrColor4f XrColorCyan = {0.0f, 1.0f, 1.0f, 1.0f};
static const XrColor4f XrColorLightGrey = {0.7f, 0.7f, 0.7f, 1.0f};
static const XrColor4f XrColorDarkGrey = {0.3f, 0.3f, 0.3f, 1.0f};
-typedef enum GraphicsAPI { GRAPHICS_VULKAN, GRAPHICS_OPENGL, GRAPHICS_OPENGL_ES, GRAPHICS_D3D } GraphicsAPI;
+typedef enum GraphicsAPI { GRAPHICS_VULKAN, GRAPHICS_OPENGL, GRAPHICS_OPENGL_ES, GRAPHICS_D3D, GRAPHICS_METAL } GraphicsAPI;
// Column-major, pre-multiplied. This type does not exist in the OpenXR API and is provided for convenience.
typedef struct XrMatrix4x4f {
diff --git a/thirdparty/openxr/src/loader/android_utilities.cpp b/thirdparty/openxr/src/loader/android_utilities.cpp
index 5c9b846b5a..1f7424b8e6 100644
--- a/thirdparty/openxr/src/loader/android_utilities.cpp
+++ b/thirdparty/openxr/src/loader/android_utilities.cpp
@@ -15,6 +15,7 @@
#include <openxr/openxr.h>
+#include <dlfcn.h>
#include <sstream>
#include <vector>
#include <android/log.h>
@@ -82,7 +83,6 @@ static Uri makeContentUri(bool systemBroker, int majorVersion, const char *abi)
.appendPath(abi)
.appendPath(RUNTIMES_PATH)
.appendPath(TABLE_PATH);
- ContentUris::appendId(builder, 0);
return builder.build();
}
@@ -175,7 +175,6 @@ static inline jni::Array<std::string> makeArray(std::initializer_list<const char
}
return ret;
}
-static constexpr auto TAG = "OpenXR-Loader";
#if defined(__arm__)
static constexpr auto ABI = "armeabi-v7l";
@@ -313,26 +312,41 @@ int getActiveRuntimeVirtualManifest(wrap::android::content::Context const &conte
cursor.moveToFirst();
- auto filename = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::SO_FILENAME));
- auto libDir = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::NATIVE_LIB_DIR));
- auto packageName = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::PACKAGE_NAME));
-
- auto hasFunctions = cursor.getInt(cursor.getColumnIndex(active_runtime::Columns::HAS_FUNCTIONS)) == 1;
- __android_log_print(ANDROID_LOG_INFO, TAG, "Got runtime: package: %s, so filename: %s, native lib dir: %s, has functions: %s",
- packageName.c_str(), filename.c_str(), libDir.c_str(), (hasFunctions ? "yes" : "no"));
+ do {
+ auto filename = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::SO_FILENAME));
+ auto libDir = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::NATIVE_LIB_DIR));
+ auto packageName = cursor.getString(cursor.getColumnIndex(active_runtime::Columns::PACKAGE_NAME));
+
+ auto hasFunctions = cursor.getInt(cursor.getColumnIndex(active_runtime::Columns::HAS_FUNCTIONS)) == 1;
+ ALOGI("Got runtime: package: %s, so filename: %s, native lib dir: %s, has functions: %s", packageName.c_str(),
+ filename.c_str(), libDir.c_str(), (hasFunctions ? "yes" : "no"));
+
+ auto lib_path = libDir + "/" + filename;
+ auto *lib = dlopen(lib_path.c_str(), RTLD_LAZY | RTLD_LOCAL);
+ if (lib) {
+ // we found a runtime that we can dlopen, use it.
+ dlclose(lib);
+
+ JsonManifestBuilder builder{"runtime", lib_path};
+ if (hasFunctions) {
+ int result = populateFunctions(context, systemBroker, packageName, builder);
+ if (result != 0) {
+ ALOGW("Unable to populate functions from runtime: %s, checking for more records...", lib_path.c_str());
+ continue;
+ }
+ }
+ virtualManifest = builder.build();
+ cursor.close();
+ return 0;
+ }
+ // this runtime was not accessible, see if the broker has more runtimes on
+ // offer.
+ ALOGV("Unable to open broker provided runtime at %s, checking for more records...", lib_path.c_str());
+ } while (cursor.moveToNext());
- auto lib_path = libDir + "/" + filename;
+ ALOGE("Unable to open any of the broker provided runtimes.");
cursor.close();
-
- JsonManifestBuilder builder{"runtime", lib_path};
- if (hasFunctions) {
- int result = populateFunctions(context, systemBroker, packageName, builder);
- if (result != 0) {
- return result;
- }
- }
- virtualManifest = builder.build();
- return 0;
+ return -1;
}
} // namespace openxr_android
diff --git a/thirdparty/openxr/src/loader/loader_core.cpp b/thirdparty/openxr/src/loader/loader_core.cpp
index 8bf2609a08..a0d81b28dc 100644
--- a/thirdparty/openxr/src/loader/loader_core.cpp
+++ b/thirdparty/openxr/src/loader/loader_core.cpp
@@ -334,7 +334,7 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrDestroyInstance(XrInstance instanc
return result;
}
- const std::unique_ptr<XrGeneratedDispatchTable> &dispatch_table = loader_instance->DispatchTable();
+ const std::unique_ptr<XrGeneratedDispatchTableCore> &dispatch_table = loader_instance->DispatchTable();
// If we allocated a default debug utils messenger, free it
XrDebugUtilsMessengerEXT messenger = loader_instance->DefaultDebugUtilsMessenger();
@@ -546,7 +546,7 @@ LoaderTrampolineSessionBeginDebugUtilsLabelRegionEXT(XrSession session, const Xr
return result;
}
LoaderLogger::GetInstance().BeginLabelRegion(session, labelInfo);
- const std::unique_ptr<XrGeneratedDispatchTable> &dispatch_table = loader_instance->DispatchTable();
+ const std::unique_ptr<XrGeneratedDispatchTableCore> &dispatch_table = loader_instance->DispatchTable();
if (nullptr != dispatch_table->SessionBeginDebugUtilsLabelRegionEXT) {
return dispatch_table->SessionBeginDebugUtilsLabelRegionEXT(session, labelInfo);
}
@@ -567,7 +567,7 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderTrampolineSessionEndDebugUtilsLabelR
}
LoaderLogger::GetInstance().EndLabelRegion(session);
- const std::unique_ptr<XrGeneratedDispatchTable> &dispatch_table = loader_instance->DispatchTable();
+ const std::unique_ptr<XrGeneratedDispatchTableCore> &dispatch_table = loader_instance->DispatchTable();
if (nullptr != dispatch_table->SessionEndDebugUtilsLabelRegionEXT) {
return dispatch_table->SessionEndDebugUtilsLabelRegionEXT(session);
}
@@ -597,7 +597,7 @@ LoaderTrampolineSessionInsertDebugUtilsLabelEXT(XrSession session, const XrDebug
LoaderLogger::GetInstance().InsertLabel(session, labelInfo);
- const std::unique_ptr<XrGeneratedDispatchTable> &dispatch_table = loader_instance->DispatchTable();
+ const std::unique_ptr<XrGeneratedDispatchTableCore> &dispatch_table = loader_instance->DispatchTable();
if (nullptr != dispatch_table->SessionInsertDebugUtilsLabelEXT) {
return dispatch_table->SessionInsertDebugUtilsLabelEXT(session, labelInfo);
}
@@ -643,7 +643,7 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermCreateDebugUtilsMessengerEXT(XrInstan
"xrCreateDebugUtilsMessengerEXT", "invalid messenger pointer");
return XR_ERROR_VALIDATION_FAILURE;
}
- const XrGeneratedDispatchTable *dispatch_table = RuntimeInterface::GetDispatchTable(instance);
+ const XrGeneratedDispatchTableCore *dispatch_table = RuntimeInterface::GetDispatchTable(instance);
XrResult result = XR_SUCCESS;
// This extension is supported entirely by the loader which means the runtime may or may not support it.
if (nullptr != dispatch_table->CreateDebugUtilsMessengerEXT) {
@@ -664,7 +664,7 @@ XRLOADER_ABI_CATCH_FALLBACK
XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermDestroyDebugUtilsMessengerEXT(XrDebugUtilsMessengerEXT messenger) XRLOADER_ABI_TRY {
LoaderLogger::LogVerboseMessage("xrDestroyDebugUtilsMessengerEXT", "Entering loader terminator");
- const XrGeneratedDispatchTable *dispatch_table = RuntimeInterface::GetDebugUtilsMessengerDispatchTable(messenger);
+ const XrGeneratedDispatchTableCore *dispatch_table = RuntimeInterface::GetDebugUtilsMessengerDispatchTable(messenger);
XrResult result = XR_SUCCESS;
LoaderLogger::GetInstance().RemoveLogRecorder(MakeHandleGeneric(messenger));
RuntimeInterface::GetRuntime().ForgetDebugMessenger(messenger);
@@ -684,7 +684,7 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermSubmitDebugUtilsMessageEXT(
XrInstance instance, XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes,
const XrDebugUtilsMessengerCallbackDataEXT *callbackData) XRLOADER_ABI_TRY {
LoaderLogger::LogVerboseMessage("xrSubmitDebugUtilsMessageEXT", "Entering loader terminator");
- const XrGeneratedDispatchTable *dispatch_table = RuntimeInterface::GetDispatchTable(instance);
+ const XrGeneratedDispatchTableCore *dispatch_table = RuntimeInterface::GetDispatchTable(instance);
XrResult result = XR_SUCCESS;
if (nullptr != dispatch_table->SubmitDebugUtilsMessageEXT) {
result = dispatch_table->SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, callbackData);
@@ -701,7 +701,7 @@ XRLOADER_ABI_CATCH_FALLBACK
XRAPI_ATTR XrResult XRAPI_CALL
LoaderXrTermSetDebugUtilsObjectNameEXT(XrInstance instance, const XrDebugUtilsObjectNameInfoEXT *nameInfo) XRLOADER_ABI_TRY {
LoaderLogger::LogVerboseMessage("xrSetDebugUtilsObjectNameEXT", "Entering loader terminator");
- const XrGeneratedDispatchTable *dispatch_table = RuntimeInterface::GetDispatchTable(instance);
+ const XrGeneratedDispatchTableCore *dispatch_table = RuntimeInterface::GetDispatchTable(instance);
XrResult result = XR_SUCCESS;
if (nullptr != dispatch_table->SetDebugUtilsObjectNameEXT) {
result = dispatch_table->SetDebugUtilsObjectNameEXT(instance, nameInfo);
diff --git a/thirdparty/openxr/src/loader/loader_instance.cpp b/thirdparty/openxr/src/loader/loader_instance.cpp
index f18230087f..09521ecf47 100644
--- a/thirdparty/openxr/src/loader/loader_instance.cpp
+++ b/thirdparty/openxr/src/loader/loader_instance.cpp
@@ -278,12 +278,12 @@ LoaderInstance::LoaderInstance(XrInstance instance, const XrInstanceCreateInfo*
: _runtime_instance(instance),
_topmost_gipa(topmost_gipa),
_api_layer_interfaces(std::move(api_layer_interfaces)),
- _dispatch_table(new XrGeneratedDispatchTable{}) {
+ _dispatch_table(new XrGeneratedDispatchTableCore{}) {
for (uint32_t ext = 0; ext < create_info->enabledExtensionCount; ++ext) {
_enabled_extensions.push_back(create_info->enabledExtensionNames[ext]);
}
- GeneratedXrPopulateDispatchTable(_dispatch_table.get(), instance, topmost_gipa);
+ GeneratedXrPopulateDispatchTableCore(_dispatch_table.get(), instance, topmost_gipa);
}
LoaderInstance::~LoaderInstance() {
diff --git a/thirdparty/openxr/src/loader/loader_instance.hpp b/thirdparty/openxr/src/loader/loader_instance.hpp
index b99e6b047f..93cd5dc6a4 100644
--- a/thirdparty/openxr/src/loader/loader_instance.hpp
+++ b/thirdparty/openxr/src/loader/loader_instance.hpp
@@ -23,7 +23,7 @@
#include <vector>
class ApiLayerInterface;
-struct XrGeneratedDispatchTable;
+struct XrGeneratedDispatchTableCore;
class LoaderInstance;
// Manage the single loader instance that is available.
@@ -54,7 +54,7 @@ class LoaderInstance {
virtual ~LoaderInstance();
XrInstance GetInstanceHandle() { return _runtime_instance; }
- const std::unique_ptr<XrGeneratedDispatchTable>& DispatchTable() { return _dispatch_table; }
+ const std::unique_ptr<XrGeneratedDispatchTableCore>& DispatchTable() { return _dispatch_table; }
std::vector<std::unique_ptr<ApiLayerInterface>>& LayerInterfaces() { return _api_layer_interfaces; }
bool ExtensionIsEnabled(const std::string& extension);
XrDebugUtilsMessengerEXT DefaultDebugUtilsMessenger() { return _messenger; }
@@ -71,7 +71,7 @@ class LoaderInstance {
std::vector<std::string> _enabled_extensions;
std::vector<std::unique_ptr<ApiLayerInterface>> _api_layer_interfaces;
- std::unique_ptr<XrGeneratedDispatchTable> _dispatch_table;
+ std::unique_ptr<XrGeneratedDispatchTableCore> _dispatch_table;
// Internal debug messenger created during xrCreateInstance
XrDebugUtilsMessengerEXT _messenger{XR_NULL_HANDLE};
};
diff --git a/thirdparty/openxr/src/loader/manifest_file.cpp b/thirdparty/openxr/src/loader/manifest_file.cpp
index 4e3e5b4947..ca212d3435 100644
--- a/thirdparty/openxr/src/loader/manifest_file.cpp
+++ b/thirdparty/openxr/src/loader/manifest_file.cpp
@@ -75,11 +75,12 @@ static inline bool StringEndsWith(const std::string &value, const std::string &e
}
// If the file found is a manifest file name, add it to the out_files manifest list.
-static void AddIfJson(const std::string &full_file, std::vector<std::string> &manifest_files) {
+static bool AddIfJson(const std::string &full_file, std::vector<std::string> &manifest_files) {
if (full_file.empty() || !StringEndsWith(full_file, ".json")) {
- return;
+ return false;
}
manifest_files.push_back(full_file);
+ return true;
}
// Check the current path for any manifest files. If the provided search_path is a directory, look for
@@ -381,7 +382,6 @@ static void ReadRuntimeDataFilesInRegistry(const std::string &runtime_registry_l
if (ERROR_SUCCESS != open_value) {
LoaderLogger::LogWarningMessage("",
"ReadRuntimeDataFilesInRegistry - failed to open registry key " + full_registry_location);
-
return;
}
@@ -391,7 +391,23 @@ static void ReadRuntimeDataFilesInRegistry(const std::string &runtime_registry_l
LoaderLogger::LogWarningMessage(
"", "ReadRuntimeDataFilesInRegistry - failed to read registry value " + default_runtime_value_name);
} else {
- AddFilesInPath(wide_to_utf8(value_w), false, manifest_files);
+ // Not using AddFilesInPath here (as only api_layer manifest paths allow multiple
+ // separated paths)
+ // Small time-of-check vs time-of-use issue here but it mainly only affects the error message.
+ // It does not introduce a security defect.
+ std::string activeRuntimePath = wide_to_utf8(value_w);
+ if (FileSysUtilsIsRegularFile(activeRuntimePath)) {
+ // If the file exists, try to add it
+ std::string absolute_path;
+ FileSysUtilsGetAbsolutePath(activeRuntimePath, absolute_path);
+ if (!AddIfJson(absolute_path, manifest_files)) {
+ LoaderLogger::LogErrorMessage(
+ "", "ReadRuntimeDataFilesInRegistry - registry runtime path is not json " + activeRuntimePath);
+ }
+ } else {
+ LoaderLogger::LogErrorMessage(
+ "", "ReadRuntimeDataFilesInRegistry - registry runtime path does not exist " + activeRuntimePath);
+ }
}
RegCloseKey(hkey);
@@ -757,8 +773,7 @@ void ApiLayerManifestFile::AddManifestFilesAndroid(const std::string &openxr_com
}
std::istringstream json_stream(std::string{buf, length});
- CreateIfValid(ManifestFileType::MANIFEST_TYPE_EXPLICIT_API_LAYER, filename, json_stream,
- &ApiLayerManifestFile::LocateLibraryInAssets, manifest_files);
+ CreateIfValid(type, filename, json_stream, &ApiLayerManifestFile::LocateLibraryInAssets, manifest_files);
}
}
#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
diff --git a/thirdparty/openxr/src/loader/runtime_interface.cpp b/thirdparty/openxr/src/loader/runtime_interface.cpp
index a0296c738c..32feea6dde 100644
--- a/thirdparty/openxr/src/loader/runtime_interface.cpp
+++ b/thirdparty/openxr/src/loader/runtime_interface.cpp
@@ -126,6 +126,10 @@ XrResult RuntimeInterface::TryLoadingSingleRuntime(const std::string& openxr_com
XrResult res = XR_ERROR_RUNTIME_FAILURE;
if (nullptr != negotiate) {
res = negotiate(&loader_info, &runtime_info);
+ } else {
+ std::string error_message = "RuntimeInterface::LoadRuntime failed to find negotiate function ";
+ error_message += function_name;
+ LoaderLogger::LogErrorMessage(openxr_command, error_message);
}
// If we supposedly succeeded, but got a nullptr for GetInstanceProcAddr
// then something still went wrong, so return with an error.
@@ -270,8 +274,8 @@ XrResult RuntimeInterface::GetInstanceProcAddr(XrInstance instance, const char*
return GetInstance()->_get_instance_proc_addr(instance, name, function);
}
-const XrGeneratedDispatchTable* RuntimeInterface::GetDispatchTable(XrInstance instance) {
- XrGeneratedDispatchTable* table = nullptr;
+const XrGeneratedDispatchTableCore* RuntimeInterface::GetDispatchTable(XrInstance instance) {
+ XrGeneratedDispatchTableCore* table = nullptr;
std::lock_guard<std::mutex> mlock(GetInstance()->_dispatch_table_mutex);
auto it = GetInstance()->_dispatch_table_map.find(instance);
if (it != GetInstance()->_dispatch_table_map.end()) {
@@ -280,7 +284,7 @@ const XrGeneratedDispatchTable* RuntimeInterface::GetDispatchTable(XrInstance in
return table;
}
-const XrGeneratedDispatchTable* RuntimeInterface::GetDebugUtilsMessengerDispatchTable(XrDebugUtilsMessengerEXT messenger) {
+const XrGeneratedDispatchTableCore* RuntimeInterface::GetDebugUtilsMessengerDispatchTable(XrDebugUtilsMessengerEXT messenger) {
XrInstance runtime_instance = XR_NULL_HANDLE;
{
std::lock_guard<std::mutex> mlock(GetInstance()->_messenger_to_instance_mutex);
@@ -349,8 +353,8 @@ XrResult RuntimeInterface::CreateInstance(const XrInstanceCreateInfo* info, XrIn
res = rt_xrCreateInstance(info, instance);
if (XR_SUCCEEDED(res)) {
create_succeeded = true;
- std::unique_ptr<XrGeneratedDispatchTable> dispatch_table(new XrGeneratedDispatchTable());
- GeneratedXrPopulateDispatchTable(dispatch_table.get(), *instance, _get_instance_proc_addr);
+ std::unique_ptr<XrGeneratedDispatchTableCore> dispatch_table(new XrGeneratedDispatchTableCore());
+ GeneratedXrPopulateDispatchTableCore(dispatch_table.get(), *instance, _get_instance_proc_addr);
std::lock_guard<std::mutex> mlock(_dispatch_table_mutex);
_dispatch_table_map[*instance] = std::move(dispatch_table);
}
diff --git a/thirdparty/openxr/src/loader/runtime_interface.hpp b/thirdparty/openxr/src/loader/runtime_interface.hpp
index 093f8ba767..3d45b12946 100644
--- a/thirdparty/openxr/src/loader/runtime_interface.hpp
+++ b/thirdparty/openxr/src/loader/runtime_interface.hpp
@@ -24,7 +24,7 @@ class Value;
}
class RuntimeManifestFile;
-struct XrGeneratedDispatchTable;
+struct XrGeneratedDispatchTableCore;
class RuntimeInterface {
public:
@@ -37,8 +37,8 @@ class RuntimeInterface {
static XrResult GetInstanceProcAddr(XrInstance instance, const char* name, PFN_xrVoidFunction* function);
// Get the direct dispatch table to this runtime, without API layers or loader terminators.
- static const XrGeneratedDispatchTable* GetDispatchTable(XrInstance instance);
- static const XrGeneratedDispatchTable* GetDebugUtilsMessengerDispatchTable(XrDebugUtilsMessengerEXT messenger);
+ static const XrGeneratedDispatchTableCore* GetDispatchTable(XrInstance instance);
+ static const XrGeneratedDispatchTableCore* GetDebugUtilsMessengerDispatchTable(XrDebugUtilsMessengerEXT messenger);
void GetInstanceExtensionProperties(std::vector<XrExtensionProperties>& extension_properties);
bool SupportsExtension(const std::string& extension_name);
@@ -66,7 +66,7 @@ class RuntimeInterface {
LoaderPlatformLibraryHandle _runtime_library;
PFN_xrGetInstanceProcAddr _get_instance_proc_addr;
- std::unordered_map<XrInstance, std::unique_ptr<XrGeneratedDispatchTable>> _dispatch_table_map;
+ std::unordered_map<XrInstance, std::unique_ptr<XrGeneratedDispatchTableCore>> _dispatch_table_map;
std::mutex _dispatch_table_mutex;
std::unordered_map<XrDebugUtilsMessengerEXT, XrInstance> _messenger_to_instance_map;
std::mutex _messenger_to_instance_mutex;
diff --git a/thirdparty/openxr/src/loader/xr_generated_loader.cpp b/thirdparty/openxr/src/loader/xr_generated_loader.cpp
index 7bddbdc3ea..d7f1ed18c1 100644
--- a/thirdparty/openxr/src/loader/xr_generated_loader.cpp
+++ b/thirdparty/openxr/src/loader/xr_generated_loader.cpp
@@ -697,4 +697,17 @@ extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrStopHapticFeedback(
}
XRLOADER_ABI_CATCH_FALLBACK
+extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrLocateSpaces(
+ XrSession session,
+ const XrSpacesLocateInfo* locateInfo,
+ XrSpaceLocations* spaceLocations) XRLOADER_ABI_TRY {
+ LoaderInstance* loader_instance;
+ XrResult result = ActiveLoaderInstance::Get(&loader_instance, "xrLocateSpaces");
+ if (XR_SUCCEEDED(result)) {
+ result = loader_instance->DispatchTable()->LocateSpaces(session, locateInfo, spaceLocations);
+ }
+ return result;
+}
+XRLOADER_ABI_CATCH_FALLBACK
+
diff --git a/thirdparty/openxr/src/loader/xr_generated_loader.hpp b/thirdparty/openxr/src/loader/xr_generated_loader.hpp
index 68a6b9470d..9a6c915421 100644
--- a/thirdparty/openxr/src/loader/xr_generated_loader.hpp
+++ b/thirdparty/openxr/src/loader/xr_generated_loader.hpp
@@ -245,6 +245,10 @@ extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrApplyHapticFeedback(
extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrStopHapticFeedback(
XrSession session,
const XrHapticActionInfo* hapticActionInfo);
+extern "C" LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrLocateSpaces(
+ XrSession session,
+ const XrSpacesLocateInfo* locateInfo,
+ XrSpaceLocations* spaceLocations);
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/thirdparty/openxr/src/xr_generated_dispatch_table_core.c b/thirdparty/openxr/src/xr_generated_dispatch_table_core.c
index e73e8b2b95..aaf854704b 100644
--- a/thirdparty/openxr/src/xr_generated_dispatch_table_core.c
+++ b/thirdparty/openxr/src/xr_generated_dispatch_table_core.c
@@ -37,7 +37,7 @@
extern "C" {
#endif
// Helper function to populate an instance dispatch table
-void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table,
+void GeneratedXrPopulateDispatchTableCore(struct XrGeneratedDispatchTableCore *table,
XrInstance instance,
PFN_xrGetInstanceProcAddr get_inst_proc_addr) {
@@ -96,6 +96,9 @@ void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table,
(get_inst_proc_addr(instance, "xrApplyHapticFeedback", (PFN_xrVoidFunction*)&table->ApplyHapticFeedback));
(get_inst_proc_addr(instance, "xrStopHapticFeedback", (PFN_xrVoidFunction*)&table->StopHapticFeedback));
+ // ---- Core 1.1 commands
+ (get_inst_proc_addr(instance, "xrLocateSpaces", (PFN_xrVoidFunction*)&table->LocateSpaces));
+
// ---- XR_EXT_debug_utils extension commands
(get_inst_proc_addr(instance, "xrSetDebugUtilsObjectNameEXT", (PFN_xrVoidFunction*)&table->SetDebugUtilsObjectNameEXT));
(get_inst_proc_addr(instance, "xrCreateDebugUtilsMessengerEXT", (PFN_xrVoidFunction*)&table->CreateDebugUtilsMessengerEXT));
diff --git a/thirdparty/openxr/src/xr_generated_dispatch_table_core.h b/thirdparty/openxr/src/xr_generated_dispatch_table_core.h
index 5871231267..69abf10b93 100644
--- a/thirdparty/openxr/src/xr_generated_dispatch_table_core.h
+++ b/thirdparty/openxr/src/xr_generated_dispatch_table_core.h
@@ -38,7 +38,7 @@
extern "C" {
#endif
// Generated dispatch table
-struct XrGeneratedDispatchTable {
+struct XrGeneratedDispatchTableCore {
// ---- Core 1.0 commands
PFN_xrGetInstanceProcAddr GetInstanceProcAddr;
@@ -97,6 +97,9 @@ struct XrGeneratedDispatchTable {
PFN_xrApplyHapticFeedback ApplyHapticFeedback;
PFN_xrStopHapticFeedback StopHapticFeedback;
+ // ---- Core 1.1 commands
+ PFN_xrLocateSpaces LocateSpaces;
+
// ---- XR_EXT_debug_utils extension commands
PFN_xrSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
PFN_xrCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT;
@@ -109,7 +112,7 @@ struct XrGeneratedDispatchTable {
// Prototype for dispatch table helper function
-void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table,
+void GeneratedXrPopulateDispatchTableCore(struct XrGeneratedDispatchTableCore *table,
XrInstance instance,
PFN_xrGetInstanceProcAddr get_inst_proc_addr);
diff --git a/thirdparty/squish/LICENSE.txt b/thirdparty/squish/LICENSE.txt
deleted file mode 100644
index e491e36226..0000000000
--- a/thirdparty/squish/LICENSE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
-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.
diff --git a/thirdparty/squish/alpha.cpp b/thirdparty/squish/alpha.cpp
deleted file mode 100644
index 7039c1a3b8..0000000000
--- a/thirdparty/squish/alpha.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 "alpha.h"
-
-#include <climits>
-#include <algorithm>
-
-namespace squish {
-
-static int FloatToInt( float a, int limit )
-{
- // use ANSI round-to-zero behaviour to get round-to-nearest
- int i = ( int )( a + 0.5f );
-
- // clamp to the limit
- if( i < 0 )
- i = 0;
- else if( i > limit )
- i = limit;
-
- // done
- return i;
-}
-
-void CompressAlphaDxt3( u8 const* rgba, int mask, void* block )
-{
- u8* bytes = reinterpret_cast< u8* >( block );
-
- // quantise and pack the alpha values pairwise
- for( int i = 0; i < 8; ++i )
- {
- // quantise down to 4 bits
- float alpha1 = ( float )rgba[8*i + 3] * ( 15.0f/255.0f );
- float alpha2 = ( float )rgba[8*i + 7] * ( 15.0f/255.0f );
- int quant1 = FloatToInt( alpha1, 15 );
- int quant2 = FloatToInt( alpha2, 15 );
-
- // set alpha to zero where masked
- int bit1 = 1 << ( 2*i );
- int bit2 = 1 << ( 2*i + 1 );
- if( ( mask & bit1 ) == 0 )
- quant1 = 0;
- if( ( mask & bit2 ) == 0 )
- quant2 = 0;
-
- // pack into the byte
- bytes[i] = ( u8 )( quant1 | ( quant2 << 4 ) );
- }
-}
-
-void DecompressAlphaDxt3( u8* rgba, void const* block )
-{
- u8 const* bytes = reinterpret_cast< u8 const* >( block );
-
- // unpack the alpha values pairwise
- for( int i = 0; i < 8; ++i )
- {
- // quantise down to 4 bits
- u8 quant = bytes[i];
-
- // unpack the values
- u8 lo = quant & 0x0f;
- u8 hi = quant & 0xf0;
-
- // convert back up to bytes
- rgba[8*i + 3] = lo | ( lo << 4 );
- rgba[8*i + 7] = hi | ( hi >> 4 );
- }
-}
-
-static void FixRange( int& min, int& max, int steps )
-{
- if( max - min < steps )
- max = std::min( min + steps, 255 );
- if( max - min < steps )
- min = std::max( 0, max - steps );
-}
-
-static int FitCodes( u8 const* rgba, int mask, u8 const* codes, u8* indices )
-{
- // fit each alpha value to the codebook
- int err = 0;
- for( int i = 0; i < 16; ++i )
- {
- // check this pixel is valid
- int bit = 1 << i;
- if( ( mask & bit ) == 0 )
- {
- // use the first code
- indices[i] = 0;
- continue;
- }
-
- // find the least error and corresponding index
- int value = rgba[4*i + 3];
- int least = INT_MAX;
- int index = 0;
- for( int j = 0; j < 8; ++j )
- {
- // get the squared error from this code
- int dist = ( int )value - ( int )codes[j];
- dist *= dist;
-
- // compare with the best so far
- if( dist < least )
- {
- least = dist;
- index = j;
- }
- }
-
- // save this index and accumulate the error
- indices[i] = ( u8 )index;
- err += least;
- }
-
- // return the total error
- return err;
-}
-
-static void WriteAlphaBlock( int alpha0, int alpha1, u8 const* indices, void* block )
-{
- u8* bytes = reinterpret_cast< u8* >( block );
-
- // write the first two bytes
- bytes[0] = ( u8 )alpha0;
- bytes[1] = ( u8 )alpha1;
-
- // pack the indices with 3 bits each
- u8* dest = bytes + 2;
- u8 const* src = indices;
- for( int i = 0; i < 2; ++i )
- {
- // pack 8 3-bit values
- int value = 0;
- for( int j = 0; j < 8; ++j )
- {
- int index = *src++;
- value |= ( index << 3*j );
- }
-
- // store in 3 bytes
- for( int j = 0; j < 3; ++j )
- {
- int byte = ( value >> 8*j ) & 0xff;
- *dest++ = ( u8 )byte;
- }
- }
-}
-
-static void WriteAlphaBlock5( int alpha0, int alpha1, u8 const* indices, void* block )
-{
- // check the relative values of the endpoints
- if( alpha0 > alpha1 )
- {
- // swap the indices
- u8 swapped[16];
- for( int i = 0; i < 16; ++i )
- {
- u8 index = indices[i];
- if( index == 0 )
- swapped[i] = 1;
- else if( index == 1 )
- swapped[i] = 0;
- else if( index <= 5 )
- swapped[i] = 7 - index;
- else
- swapped[i] = index;
- }
-
- // write the block
- WriteAlphaBlock( alpha1, alpha0, swapped, block );
- }
- else
- {
- // write the block
- WriteAlphaBlock( alpha0, alpha1, indices, block );
- }
-}
-
-static void WriteAlphaBlock7( int alpha0, int alpha1, u8 const* indices, void* block )
-{
- // check the relative values of the endpoints
- if( alpha0 < alpha1 )
- {
- // swap the indices
- u8 swapped[16];
- for( int i = 0; i < 16; ++i )
- {
- u8 index = indices[i];
- if( index == 0 )
- swapped[i] = 1;
- else if( index == 1 )
- swapped[i] = 0;
- else
- swapped[i] = 9 - index;
- }
-
- // write the block
- WriteAlphaBlock( alpha1, alpha0, swapped, block );
- }
- else
- {
- // write the block
- WriteAlphaBlock( alpha0, alpha1, indices, block );
- }
-}
-
-void CompressAlphaDxt5( u8 const* rgba, int mask, void* block )
-{
- // get the range for 5-alpha and 7-alpha interpolation
- int min5 = 255;
- int max5 = 0;
- int min7 = 255;
- int max7 = 0;
- for( int i = 0; i < 16; ++i )
- {
- // check this pixel is valid
- int bit = 1 << i;
- if( ( mask & bit ) == 0 )
- continue;
-
- // incorporate into the min/max
- int value = rgba[4*i + 3];
- if( value < min7 )
- min7 = value;
- if( value > max7 )
- max7 = value;
- if( value != 0 && value < min5 )
- min5 = value;
- if( value != 255 && value > max5 )
- max5 = value;
- }
-
- // handle the case that no valid range was found
- if( min5 > max5 )
- min5 = max5;
- if( min7 > max7 )
- min7 = max7;
-
- // fix the range to be the minimum in each case
- FixRange( min5, max5, 5 );
- FixRange( min7, max7, 7 );
-
- // set up the 5-alpha code book
- u8 codes5[8];
- codes5[0] = ( u8 )min5;
- codes5[1] = ( u8 )max5;
- for( int i = 1; i < 5; ++i )
- codes5[1 + i] = ( u8 )( ( ( 5 - i )*min5 + i*max5 )/5 );
- codes5[6] = 0;
- codes5[7] = 255;
-
- // set up the 7-alpha code book
- u8 codes7[8];
- codes7[0] = ( u8 )min7;
- codes7[1] = ( u8 )max7;
- for( int i = 1; i < 7; ++i )
- codes7[1 + i] = ( u8 )( ( ( 7 - i )*min7 + i*max7 )/7 );
-
- // fit the data to both code books
- u8 indices5[16];
- u8 indices7[16];
- int err5 = FitCodes( rgba, mask, codes5, indices5 );
- int err7 = FitCodes( rgba, mask, codes7, indices7 );
-
- // save the block with least error
- if( err5 <= err7 )
- WriteAlphaBlock5( min5, max5, indices5, block );
- else
- WriteAlphaBlock7( min7, max7, indices7, block );
-}
-
-void DecompressAlphaDxt5( u8* rgba, void const* block )
-{
- // get the two alpha values
- u8 const* bytes = reinterpret_cast< u8 const* >( block );
- int alpha0 = bytes[0];
- int alpha1 = bytes[1];
-
- // compare the values to build the codebook
- u8 codes[8];
- codes[0] = ( u8 )alpha0;
- codes[1] = ( u8 )alpha1;
- if( alpha0 <= alpha1 )
- {
- // use 5-alpha codebook
- for( int i = 1; i < 5; ++i )
- codes[1 + i] = ( u8 )( ( ( 5 - i )*alpha0 + i*alpha1 )/5 );
- codes[6] = 0;
- codes[7] = 255;
- }
- else
- {
- // use 7-alpha codebook
- for( int i = 1; i < 7; ++i )
- codes[1 + i] = ( u8 )( ( ( 7 - i )*alpha0 + i*alpha1 )/7 );
- }
-
- // decode the indices
- u8 indices[16];
- u8 const* src = bytes + 2;
- u8* dest = indices;
- for( int i = 0; i < 2; ++i )
- {
- // grab 3 bytes
- int value = 0;
- for( int j = 0; j < 3; ++j )
- {
- int byte = *src++;
- value |= ( byte << 8*j );
- }
-
- // unpack 8 3-bit values from it
- for( int j = 0; j < 8; ++j )
- {
- int index = ( value >> 3*j ) & 0x7;
- *dest++ = ( u8 )index;
- }
- }
-
- // write out the indexed codebook values
- for( int i = 0; i < 16; ++i )
- rgba[4*i + 3] = codes[indices[i]];
-}
-
-} // namespace squish
diff --git a/thirdparty/squish/alpha.h b/thirdparty/squish/alpha.h
deleted file mode 100644
index a1fffd4049..0000000000
--- a/thirdparty/squish/alpha.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_ALPHA_H
-#define SQUISH_ALPHA_H
-
-#include "squish.h"
-
-namespace squish {
-
-void CompressAlphaDxt3( u8 const* rgba, int mask, void* block );
-void CompressAlphaDxt5( u8 const* rgba, int mask, void* block );
-
-void DecompressAlphaDxt3( u8* rgba, void const* block );
-void DecompressAlphaDxt5( u8* rgba, void const* block );
-
-} // namespace squish
-
-#endif // ndef SQUISH_ALPHA_H
diff --git a/thirdparty/squish/clusterfit.cpp b/thirdparty/squish/clusterfit.cpp
deleted file mode 100644
index 1610ecb5d8..0000000000
--- a/thirdparty/squish/clusterfit.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
- Copyright (c) 2007 Ignacio Castano icastano@nvidia.com
-
- 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 "clusterfit.h"
-#include "colourset.h"
-#include "colourblock.h"
-#include <cfloat>
-
-namespace squish {
-
-ClusterFit::ClusterFit( ColourSet const* colours, int flags, float* metric )
- : ColourFit( colours, flags )
-{
- // set the iteration count
- m_iterationCount = ( m_flags & kColourIterativeClusterFit ) ? kMaxIterations : 1;
-
- // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f)
- if( metric )
- m_metric = Vec4( metric[0], metric[1], metric[2], 1.0f );
- else
- m_metric = VEC4_CONST( 1.0f );
-
- // initialise the best error
- m_besterror = VEC4_CONST( FLT_MAX );
-
- // cache some values
- int const count = m_colours->GetCount();
- Vec3 const* values = m_colours->GetPoints();
-
- // get the covariance matrix
- Sym3x3 covariance = ComputeWeightedCovariance( count, values, m_colours->GetWeights() );
-
- // compute the principle component
- m_principle = ComputePrincipleComponent( covariance );
-}
-
-bool ClusterFit::ConstructOrdering( Vec3 const& axis, int iteration )
-{
- // cache some values
- int const count = m_colours->GetCount();
- Vec3 const* values = m_colours->GetPoints();
-
- // build the list of dot products
- float dps[16];
- u8* order = ( u8* )m_order + 16*iteration;
- for( int i = 0; i < count; ++i )
- {
- dps[i] = Dot( values[i], axis );
- order[i] = ( u8 )i;
- }
-
- // stable sort using them
- for( int i = 0; i < count; ++i )
- {
- for( int j = i; j > 0 && dps[j] < dps[j - 1]; --j )
- {
- std::swap( dps[j], dps[j - 1] );
- std::swap( order[j], order[j - 1] );
- }
- }
-
- // check this ordering is unique
- for( int it = 0; it < iteration; ++it )
- {
- u8 const* prev = ( u8* )m_order + 16*it;
- bool same = true;
- for( int i = 0; i < count; ++i )
- {
- if( order[i] != prev[i] )
- {
- same = false;
- break;
- }
- }
- if( same )
- return false;
- }
-
- // copy the ordering and weight all the points
- Vec3 const* unweighted = m_colours->GetPoints();
- float const* weights = m_colours->GetWeights();
- m_xsum_wsum = VEC4_CONST( 0.0f );
- for( int i = 0; i < count; ++i )
- {
- int j = order[i];
- Vec4 p( unweighted[j].X(), unweighted[j].Y(), unweighted[j].Z(), 1.0f );
- Vec4 w( weights[j] );
- Vec4 x = p*w;
- m_points_weights[i] = x;
- m_xsum_wsum += x;
- }
- return true;
-}
-
-void ClusterFit::Compress3( void* block )
-{
- // declare variables
- int const count = m_colours->GetCount();
- Vec4 const two = VEC4_CONST( 2.0 );
- Vec4 const one = VEC4_CONST( 1.0f );
- Vec4 const half_half2( 0.5f, 0.5f, 0.5f, 0.25f );
- Vec4 const zero = VEC4_CONST( 0.0f );
- Vec4 const half = VEC4_CONST( 0.5f );
- Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f );
- Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f );
-
- // prepare an ordering using the principle axis
- ConstructOrdering( m_principle, 0 );
-
- // check all possible clusters and iterate on the total order
- Vec4 beststart = VEC4_CONST( 0.0f );
- Vec4 bestend = VEC4_CONST( 0.0f );
- Vec4 besterror = m_besterror;
- u8 bestindices[16];
- int bestiteration = 0;
- int besti = 0, bestj = 0;
-
- // loop over iterations (we avoid the case that all points in first or last cluster)
- for( int iterationIndex = 0;; )
- {
- // first cluster [0,i) is at the start
- Vec4 part0 = VEC4_CONST( 0.0f );
- for( int i = 0; i < count; ++i )
- {
- // second cluster [i,j) is half along
- Vec4 part1 = ( i == 0 ) ? m_points_weights[0] : VEC4_CONST( 0.0f );
- int jmin = ( i == 0 ) ? 1 : i;
- for( int j = jmin;; )
- {
- // last cluster [j,count) is at the end
- Vec4 part2 = m_xsum_wsum - part1 - part0;
-
- // compute least squares terms directly
- Vec4 alphax_sum = MultiplyAdd( part1, half_half2, part0 );
- Vec4 alpha2_sum = alphax_sum.SplatW();
-
- Vec4 betax_sum = MultiplyAdd( part1, half_half2, part2 );
- Vec4 beta2_sum = betax_sum.SplatW();
-
- Vec4 alphabeta_sum = ( part1*half_half2 ).SplatW();
-
- // compute the least-squares optimal points
- Vec4 factor = Reciprocal( NegativeMultiplySubtract( alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum ) );
- Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_sum, alphax_sum*beta2_sum )*factor;
- Vec4 b = NegativeMultiplySubtract( alphax_sum, alphabeta_sum, betax_sum*alpha2_sum )*factor;
-
- // clamp to the grid
- a = Min( one, Max( zero, a ) );
- b = Min( one, Max( zero, b ) );
- a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp;
- b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp;
-
- // compute the error (we skip the constant xxsum)
- Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum );
- Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum );
- Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 );
- Vec4 e4 = MultiplyAdd( two, e3, e1 );
-
- // apply the metric to the error term
- Vec4 e5 = e4*m_metric;
- Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ();
-
- // keep the solution if it wins
- if( CompareAnyLessThan( error, besterror ) )
- {
- beststart = a;
- bestend = b;
- besti = i;
- bestj = j;
- besterror = error;
- bestiteration = iterationIndex;
- }
-
- // advance
- if( j == count )
- break;
- part1 += m_points_weights[j];
- ++j;
- }
-
- // advance
- part0 += m_points_weights[i];
- }
-
- // stop if we didn't improve in this iteration
- if( bestiteration != iterationIndex )
- break;
-
- // advance if possible
- ++iterationIndex;
- if( iterationIndex == m_iterationCount )
- break;
-
- // stop if a new iteration is an ordering that has already been tried
- Vec3 axis = ( bestend - beststart ).GetVec3();
- if( !ConstructOrdering( axis, iterationIndex ) )
- break;
- }
-
- // save the block if necessary
- if( CompareAnyLessThan( besterror, m_besterror ) )
- {
- // remap the indices
- u8 const* order = ( u8* )m_order + 16*bestiteration;
-
- u8 unordered[16];
- for( int m = 0; m < besti; ++m )
- unordered[order[m]] = 0;
- for( int m = besti; m < bestj; ++m )
- unordered[order[m]] = 2;
- for( int m = bestj; m < count; ++m )
- unordered[order[m]] = 1;
-
- m_colours->RemapIndices( unordered, bestindices );
-
- // save the block
- WriteColourBlock3( beststart.GetVec3(), bestend.GetVec3(), bestindices, block );
-
- // save the error
- m_besterror = besterror;
- }
-}
-
-void ClusterFit::Compress4( void* block )
-{
- // declare variables
- int const count = m_colours->GetCount();
- Vec4 const two = VEC4_CONST( 2.0f );
- Vec4 const one = VEC4_CONST( 1.0f );
- Vec4 const onethird_onethird2( 1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 1.0f/9.0f );
- Vec4 const twothirds_twothirds2( 2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f, 4.0f/9.0f );
- Vec4 const twonineths = VEC4_CONST( 2.0f/9.0f );
- Vec4 const zero = VEC4_CONST( 0.0f );
- Vec4 const half = VEC4_CONST( 0.5f );
- Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f );
- Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f );
-
- // prepare an ordering using the principle axis
- ConstructOrdering( m_principle, 0 );
-
- // check all possible clusters and iterate on the total order
- Vec4 beststart = VEC4_CONST( 0.0f );
- Vec4 bestend = VEC4_CONST( 0.0f );
- Vec4 besterror = m_besterror;
- u8 bestindices[16];
- int bestiteration = 0;
- int besti = 0, bestj = 0, bestk = 0;
-
- // loop over iterations (we avoid the case that all points in first or last cluster)
- for( int iterationIndex = 0;; )
- {
- // first cluster [0,i) is at the start
- Vec4 part0 = VEC4_CONST( 0.0f );
- for( int i = 0; i < count; ++i )
- {
- // second cluster [i,j) is one third along
- Vec4 part1 = VEC4_CONST( 0.0f );
- for( int j = i;; )
- {
- // third cluster [j,k) is two thirds along
- Vec4 part2 = ( j == 0 ) ? m_points_weights[0] : VEC4_CONST( 0.0f );
- int kmin = ( j == 0 ) ? 1 : j;
- for( int k = kmin;; )
- {
- // last cluster [k,count) is at the end
- Vec4 part3 = m_xsum_wsum - part2 - part1 - part0;
-
- // compute least squares terms directly
- Vec4 const alphax_sum = MultiplyAdd( part2, onethird_onethird2, MultiplyAdd( part1, twothirds_twothirds2, part0 ) );
- Vec4 const alpha2_sum = alphax_sum.SplatW();
-
- Vec4 const betax_sum = MultiplyAdd( part1, onethird_onethird2, MultiplyAdd( part2, twothirds_twothirds2, part3 ) );
- Vec4 const beta2_sum = betax_sum.SplatW();
-
- Vec4 const alphabeta_sum = twonineths*( part1 + part2 ).SplatW();
-
- // compute the least-squares optimal points
- Vec4 factor = Reciprocal( NegativeMultiplySubtract( alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum ) );
- Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_sum, alphax_sum*beta2_sum )*factor;
- Vec4 b = NegativeMultiplySubtract( alphax_sum, alphabeta_sum, betax_sum*alpha2_sum )*factor;
-
- // clamp to the grid
- a = Min( one, Max( zero, a ) );
- b = Min( one, Max( zero, b ) );
- a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp;
- b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp;
-
- // compute the error (we skip the constant xxsum)
- Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum );
- Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum );
- Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 );
- Vec4 e4 = MultiplyAdd( two, e3, e1 );
-
- // apply the metric to the error term
- Vec4 e5 = e4*m_metric;
- Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ();
-
- // keep the solution if it wins
- if( CompareAnyLessThan( error, besterror ) )
- {
- beststart = a;
- bestend = b;
- besterror = error;
- besti = i;
- bestj = j;
- bestk = k;
- bestiteration = iterationIndex;
- }
-
- // advance
- if( k == count )
- break;
- part2 += m_points_weights[k];
- ++k;
- }
-
- // advance
- if( j == count )
- break;
- part1 += m_points_weights[j];
- ++j;
- }
-
- // advance
- part0 += m_points_weights[i];
- }
-
- // stop if we didn't improve in this iteration
- if( bestiteration != iterationIndex )
- break;
-
- // advance if possible
- ++iterationIndex;
- if( iterationIndex == m_iterationCount )
- break;
-
- // stop if a new iteration is an ordering that has already been tried
- Vec3 axis = ( bestend - beststart ).GetVec3();
- if( !ConstructOrdering( axis, iterationIndex ) )
- break;
- }
-
- // save the block if necessary
- if( CompareAnyLessThan( besterror, m_besterror ) )
- {
- // remap the indices
- u8 const* order = ( u8* )m_order + 16*bestiteration;
-
- u8 unordered[16];
- for( int m = 0; m < besti; ++m )
- unordered[order[m]] = 0;
- for( int m = besti; m < bestj; ++m )
- unordered[order[m]] = 2;
- for( int m = bestj; m < bestk; ++m )
- unordered[order[m]] = 3;
- for( int m = bestk; m < count; ++m )
- unordered[order[m]] = 1;
-
- m_colours->RemapIndices( unordered, bestindices );
-
- // save the block
- WriteColourBlock4( beststart.GetVec3(), bestend.GetVec3(), bestindices, block );
-
- // save the error
- m_besterror = besterror;
- }
-}
-
-} // namespace squish
diff --git a/thirdparty/squish/clusterfit.h b/thirdparty/squish/clusterfit.h
deleted file mode 100644
index 999396b262..0000000000
--- a/thirdparty/squish/clusterfit.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
- Copyright (c) 2007 Ignacio Castano icastano@nvidia.com
-
- 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 SQUISH_CLUSTERFIT_H
-#define SQUISH_CLUSTERFIT_H
-
-#include "squish.h"
-#include "maths.h"
-#include "simd.h"
-#include "colourfit.h"
-
-namespace squish {
-
-class ClusterFit : public ColourFit
-{
-public:
- ClusterFit( ColourSet const* colours, int flags, float* metric );
-
-private:
- bool ConstructOrdering( Vec3 const& axis, int iteration );
-
- virtual void Compress3( void* block );
- virtual void Compress4( void* block );
-
- enum { kMaxIterations = 8 };
-
- int m_iterationCount;
- Vec3 m_principle;
- u8 m_order[16*kMaxIterations];
- Vec4 m_points_weights[16];
- Vec4 m_xsum_wsum;
- Vec4 m_metric;
- Vec4 m_besterror;
-};
-
-} // namespace squish
-
-#endif // ndef SQUISH_CLUSTERFIT_H
diff --git a/thirdparty/squish/colourblock.cpp b/thirdparty/squish/colourblock.cpp
deleted file mode 100644
index f14c9362bd..0000000000
--- a/thirdparty/squish/colourblock.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 "colourblock.h"
-// -- GODOT start --
-#include "alpha.h"
-// -- GODOT end --
-
-namespace squish {
-
-static int FloatToInt( float a, int limit )
-{
- // use ANSI round-to-zero behaviour to get round-to-nearest
- int i = ( int )( a + 0.5f );
-
- // clamp to the limit
- if( i < 0 )
- i = 0;
- else if( i > limit )
- i = limit;
-
- // done
- return i;
-}
-
-static int FloatTo565( Vec3::Arg colour )
-{
- // get the components in the correct range
- int r = FloatToInt( 31.0f*colour.X(), 31 );
- int g = FloatToInt( 63.0f*colour.Y(), 63 );
- int b = FloatToInt( 31.0f*colour.Z(), 31 );
-
- // pack into a single value
- return ( r << 11 ) | ( g << 5 ) | b;
-}
-
-static void WriteColourBlock( int a, int b, u8* indices, void* block )
-{
- // get the block as bytes
- u8* bytes = ( u8* )block;
-
- // write the endpoints
- bytes[0] = ( u8 )( a & 0xff );
- bytes[1] = ( u8 )( a >> 8 );
- bytes[2] = ( u8 )( b & 0xff );
- bytes[3] = ( u8 )( b >> 8 );
-
- // write the indices
- for( int i = 0; i < 4; ++i )
- {
- u8 const* ind = indices + 4*i;
- bytes[4 + i] = ind[0] | ( ind[1] << 2 ) | ( ind[2] << 4 ) | ( ind[3] << 6 );
- }
-}
-
-void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block )
-{
- // get the packed values
- int a = FloatTo565( start );
- int b = FloatTo565( end );
-
- // remap the indices
- u8 remapped[16];
- if( a <= b )
- {
- // use the indices directly
- for( int i = 0; i < 16; ++i )
- remapped[i] = indices[i];
- }
- else
- {
- // swap a and b
- std::swap( a, b );
- for( int i = 0; i < 16; ++i )
- {
- if( indices[i] == 0 )
- remapped[i] = 1;
- else if( indices[i] == 1 )
- remapped[i] = 0;
- else
- remapped[i] = indices[i];
- }
- }
-
- // write the block
- WriteColourBlock( a, b, remapped, block );
-}
-
-void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block )
-{
- // get the packed values
- int a = FloatTo565( start );
- int b = FloatTo565( end );
-
- // remap the indices
- u8 remapped[16];
- if( a < b )
- {
- // swap a and b
- std::swap( a, b );
- for( int i = 0; i < 16; ++i )
- remapped[i] = ( indices[i] ^ 0x1 ) & 0x3;
- }
- else if( a == b )
- {
- // use index 0
- for( int i = 0; i < 16; ++i )
- remapped[i] = 0;
- }
- else
- {
- // use the indices directly
- for( int i = 0; i < 16; ++i )
- remapped[i] = indices[i];
- }
-
- // write the block
- WriteColourBlock( a, b, remapped, block );
-}
-
-static int Unpack565( u8 const* packed, u8* colour )
-{
- // build the packed value
- int value = ( int )packed[0] | ( ( int )packed[1] << 8 );
-
- // get the components in the stored range
- u8 red = ( u8 )( ( value >> 11 ) & 0x1f );
- u8 green = ( u8 )( ( value >> 5 ) & 0x3f );
- u8 blue = ( u8 )( value & 0x1f );
-
- // scale up to 8 bits
- colour[0] = ( red << 3 ) | ( red >> 2 );
- colour[1] = ( green << 2 ) | ( green >> 4 );
- colour[2] = ( blue << 3 ) | ( blue >> 2 );
- colour[3] = 255;
-
- // return the value
- return value;
-}
-
-void DecompressColour( u8* rgba, void const* block, bool isDxt1 )
-{
- // get the block bytes
- u8 const* bytes = reinterpret_cast< u8 const* >( block );
-
- // unpack the endpoints
- u8 codes[16];
- int a = Unpack565( bytes, codes );
- int b = Unpack565( bytes + 2, codes + 4 );
-
- // generate the midpoints
- for( int i = 0; i < 3; ++i )
- {
- int c = codes[i];
- int d = codes[4 + i];
-
- if( isDxt1 && a <= b )
- {
- codes[8 + i] = ( u8 )( ( c + d )/2 );
- codes[12 + i] = 0;
- }
- else
- {
- codes[8 + i] = ( u8 )( ( 2*c + d )/3 );
- codes[12 + i] = ( u8 )( ( c + 2*d )/3 );
- }
- }
-
- // fill in alpha for the intermediate values
- codes[8 + 3] = 255;
- codes[12 + 3] = ( isDxt1 && a <= b ) ? 0 : 255;
-
- // unpack the indices
- u8 indices[16];
- for( int i = 0; i < 4; ++i )
- {
- u8* ind = indices + 4*i;
- u8 packed = bytes[4 + i];
-
- ind[0] = packed & 0x3;
- ind[1] = ( packed >> 2 ) & 0x3;
- ind[2] = ( packed >> 4 ) & 0x3;
- ind[3] = ( packed >> 6 ) & 0x3;
- }
-
- // store out the colours
- for( int i = 0; i < 16; ++i )
- {
- u8 offset = 4*indices[i];
- for( int j = 0; j < 4; ++j )
- rgba[4*i + j] = codes[offset + j];
- }
-}
-
-// -- GODOT start --
-void DecompressColourBc4( u8* rgba, void const* block)
-{
- DecompressAlphaDxt5(rgba,block);
- for ( int i = 0; i < 16; ++i ) {
- rgba[i*4] = rgba[i*4 + 3];
- rgba[i*4 + 1] = 0;
- rgba[i*4 + 2] = 0;
- rgba[i*4 + 3] = 255;
- }
-}
-
-void DecompressColourBc5( u8* rgba, void const* block)
-{
- void const* rblock = block;
- void const* gblock = reinterpret_cast< u8 const* >( block ) + 8;
- DecompressAlphaDxt5(rgba,rblock);
- for ( int i = 0; i < 16; ++i ) {
- rgba[i*4] = rgba[i*4 + 3];
- }
- DecompressAlphaDxt5(rgba,gblock);
- for ( int i = 0; i < 16; ++i ) {
- rgba[i*4+1] = rgba[i*4 + 3];
- rgba[i*4 + 2] = 0;
- rgba[i*4 + 3] = 255;
- }
-}
-// -- GODOT end --
-
-
-} // namespace squish
diff --git a/thirdparty/squish/colourblock.h b/thirdparty/squish/colourblock.h
deleted file mode 100644
index e1eb9e4917..0000000000
--- a/thirdparty/squish/colourblock.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_COLOURBLOCK_H
-#define SQUISH_COLOURBLOCK_H
-
-#include "squish.h"
-#include "maths.h"
-
-namespace squish {
-
-void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block );
-void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block );
-
-void DecompressColour( u8* rgba, void const* block, bool isDxt1 );
-// -- GODOT start --
-void DecompressColourBc4( u8* rgba, void const* block );
-void DecompressColourBc5( u8* rgba, void const* block );
-// -- GODOT end --
-
-} // namespace squish
-
-#endif // ndef SQUISH_COLOURBLOCK_H
diff --git a/thirdparty/squish/colourfit.cpp b/thirdparty/squish/colourfit.cpp
deleted file mode 100644
index e45b656557..0000000000
--- a/thirdparty/squish/colourfit.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 "colourfit.h"
-#include "colourset.h"
-
-namespace squish {
-
-ColourFit::ColourFit( ColourSet const* colours, int flags )
- : m_colours( colours ),
- m_flags( flags )
-{
-}
-
-ColourFit::~ColourFit()
-{
-}
-
-void ColourFit::Compress( void* block )
-{
- bool isDxt1 = ( ( m_flags & kDxt1 ) != 0 );
- if( isDxt1 )
- {
- Compress3( block );
- if( !m_colours->IsTransparent() )
- Compress4( block );
- }
- else
- Compress4( block );
-}
-
-} // namespace squish
diff --git a/thirdparty/squish/colourfit.h b/thirdparty/squish/colourfit.h
deleted file mode 100644
index e73dceb2eb..0000000000
--- a/thirdparty/squish/colourfit.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_COLOURFIT_H
-#define SQUISH_COLOURFIT_H
-
-#include "squish.h"
-#include "maths.h"
-
-#include <climits>
-
-namespace squish {
-
-class ColourSet;
-
-class ColourFit
-{
-public:
- ColourFit( ColourSet const* colours, int flags );
- virtual ~ColourFit();
-
- void Compress( void* block );
-
-protected:
- virtual void Compress3( void* block ) = 0;
- virtual void Compress4( void* block ) = 0;
-
- ColourSet const* m_colours;
- int m_flags;
-};
-
-} // namespace squish
-
-#endif // ndef SQUISH_COLOURFIT_H
diff --git a/thirdparty/squish/colourset.cpp b/thirdparty/squish/colourset.cpp
deleted file mode 100644
index e900556471..0000000000
--- a/thirdparty/squish/colourset.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 "colourset.h"
-
-namespace squish {
-
-ColourSet::ColourSet( u8 const* rgba, int mask, int flags )
- : m_count( 0 ),
- m_transparent( false )
-{
- // check the compression mode for dxt1
- bool isDxt1 = ( ( flags & kDxt1 ) != 0 );
- bool weightByAlpha = ( ( flags & kWeightColourByAlpha ) != 0 );
-
- // create the minimal set
- for( int i = 0; i < 16; ++i )
- {
- // check this pixel is enabled
- int bit = 1 << i;
- if( ( mask & bit ) == 0 )
- {
- m_remap[i] = -1;
- continue;
- }
-
- // check for transparent pixels when using dxt1
- if( isDxt1 && rgba[4*i + 3] < 128 )
- {
- m_remap[i] = -1;
- m_transparent = true;
- continue;
- }
-
- // loop over previous points for a match
- for( int j = 0;; ++j )
- {
- // allocate a new point
- if( j == i )
- {
- // normalise coordinates to [0,1]
- float x = ( float )rgba[4*i] / 255.0f;
- float y = ( float )rgba[4*i + 1] / 255.0f;
- float z = ( float )rgba[4*i + 2] / 255.0f;
-
- // ensure there is always non-zero weight even for zero alpha
- float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f;
-
- // add the point
- m_points[m_count] = Vec3( x, y, z );
- m_weights[m_count] = ( weightByAlpha ? w : 1.0f );
- m_remap[i] = m_count;
-
- // advance
- ++m_count;
- break;
- }
-
- // check for a match
- int oldbit = 1 << j;
- bool match = ( ( mask & oldbit ) != 0 )
- && ( rgba[4*i] == rgba[4*j] )
- && ( rgba[4*i + 1] == rgba[4*j + 1] )
- && ( rgba[4*i + 2] == rgba[4*j + 2] )
- && ( rgba[4*j + 3] >= 128 || !isDxt1 );
- if( match )
- {
- // get the index of the match
- int index = m_remap[j];
-
- // ensure there is always non-zero weight even for zero alpha
- float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f;
-
- // map to this point and increase the weight
- m_weights[index] += ( weightByAlpha ? w : 1.0f );
- m_remap[i] = index;
- break;
- }
- }
- }
-
- // square root the weights
- for( int i = 0; i < m_count; ++i )
- m_weights[i] = std::sqrt( m_weights[i] );
-}
-
-void ColourSet::RemapIndices( u8 const* source, u8* target ) const
-{
- for( int i = 0; i < 16; ++i )
- {
- int j = m_remap[i];
- if( j == -1 )
- target[i] = 3;
- else
- target[i] = source[j];
- }
-}
-
-} // namespace squish
diff --git a/thirdparty/squish/colourset.h b/thirdparty/squish/colourset.h
deleted file mode 100644
index e13bb6fc35..0000000000
--- a/thirdparty/squish/colourset.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_COLOURSET_H
-#define SQUISH_COLOURSET_H
-
-#include "squish.h"
-#include "maths.h"
-
-namespace squish {
-
-/*! @brief Represents a set of block colours
-*/
-class ColourSet
-{
-public:
- ColourSet( u8 const* rgba, int mask, int flags );
-
- int GetCount() const { return m_count; }
- Vec3 const* GetPoints() const { return m_points; }
- float const* GetWeights() const { return m_weights; }
- bool IsTransparent() const { return m_transparent; }
-
- void RemapIndices( u8 const* source, u8* target ) const;
-
-private:
- int m_count;
- Vec3 m_points[16];
- float m_weights[16];
- int m_remap[16];
- bool m_transparent;
-};
-
-} // namespace sqish
-
-#endif // ndef SQUISH_COLOURSET_H
diff --git a/thirdparty/squish/config.h b/thirdparty/squish/config.h
deleted file mode 100644
index 05f8d72598..0000000000
--- a/thirdparty/squish/config.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_CONFIG_H
-#define SQUISH_CONFIG_H
-
-// Set to 1 when building squish to use Altivec instructions.
-#ifndef SQUISH_USE_ALTIVEC
-#define SQUISH_USE_ALTIVEC 0
-#endif
-
-// Set to 1 or 2 when building squish to use SSE or SSE2 instructions.
-// -- GODOT start --
-#ifdef _MSC_VER
- #if defined(_M_IX86_FP)
- #if _M_IX86_FP >= 2
- #define SQUISH_USE_SSE 2
- #elif _M_IX86_FP >= 1
- #define SQUISH_USE_SSE 1
- #endif
- #elif defined(_M_X64)
- #define SQUISH_USE_SSE 2
- #endif
-#else
- #if defined(__SSE2__)
- #define SQUISH_USE_SSE 2
- #elif defined(__SSE__)
- #define SQUISH_USE_SSE 1
- #endif
-#endif
-// -- GODOT end --
-
-#ifndef SQUISH_USE_SSE
-#define SQUISH_USE_SSE 0
-#endif
-
-// Internally set SQUISH_USE_SIMD when either Altivec or SSE is available.
-#if SQUISH_USE_ALTIVEC && SQUISH_USE_SSE
-#error "Cannot enable both Altivec and SSE!"
-#endif
-#if SQUISH_USE_ALTIVEC || SQUISH_USE_SSE
-#define SQUISH_USE_SIMD 1
-#else
-#define SQUISH_USE_SIMD 0
-#endif
-
-#endif // ndef SQUISH_CONFIG_H
diff --git a/thirdparty/squish/maths.cpp b/thirdparty/squish/maths.cpp
deleted file mode 100644
index 4fa0bcfb35..0000000000
--- a/thirdparty/squish/maths.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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.
-
- -------------------------------------------------------------------------- */
-
-/*! @file
-
- The symmetric eigensystem solver algorithm is from
- http://www.geometrictools.com/Documentation/EigenSymmetric3x3.pdf
-*/
-
-#include "maths.h"
-#include "simd.h"
-#include <cfloat>
-
-namespace squish {
-
-Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights )
-{
- // compute the centroid
- float total = 0.0f;
- Vec3 centroid( 0.0f );
- for( int i = 0; i < n; ++i )
- {
- total += weights[i];
- centroid += weights[i]*points[i];
- }
- if( total > FLT_EPSILON )
- centroid /= total;
-
- // accumulate the covariance matrix
- Sym3x3 covariance( 0.0f );
- for( int i = 0; i < n; ++i )
- {
- Vec3 a = points[i] - centroid;
- Vec3 b = weights[i]*a;
-
- covariance[0] += a.X()*b.X();
- covariance[1] += a.X()*b.Y();
- covariance[2] += a.X()*b.Z();
- covariance[3] += a.Y()*b.Y();
- covariance[4] += a.Y()*b.Z();
- covariance[5] += a.Z()*b.Z();
- }
-
- // return it
- return covariance;
-}
-
-#if 0
-
-static Vec3 GetMultiplicity1Evector( Sym3x3 const& matrix, float evalue )
-{
- // compute M
- Sym3x3 m;
- m[0] = matrix[0] - evalue;
- m[1] = matrix[1];
- m[2] = matrix[2];
- m[3] = matrix[3] - evalue;
- m[4] = matrix[4];
- m[5] = matrix[5] - evalue;
-
- // compute U
- Sym3x3 u;
- u[0] = m[3]*m[5] - m[4]*m[4];
- u[1] = m[2]*m[4] - m[1]*m[5];
- u[2] = m[1]*m[4] - m[2]*m[3];
- u[3] = m[0]*m[5] - m[2]*m[2];
- u[4] = m[1]*m[2] - m[4]*m[0];
- u[5] = m[0]*m[3] - m[1]*m[1];
-
- // find the largest component
- float mc = std::fabs( u[0] );
- int mi = 0;
- for( int i = 1; i < 6; ++i )
- {
- float c = std::fabs( u[i] );
- if( c > mc )
- {
- mc = c;
- mi = i;
- }
- }
-
- // pick the column with this component
- switch( mi )
- {
- case 0:
- return Vec3( u[0], u[1], u[2] );
-
- case 1:
- case 3:
- return Vec3( u[1], u[3], u[4] );
-
- default:
- return Vec3( u[2], u[4], u[5] );
- }
-}
-
-static Vec3 GetMultiplicity2Evector( Sym3x3 const& matrix, float evalue )
-{
- // compute M
- Sym3x3 m;
- m[0] = matrix[0] - evalue;
- m[1] = matrix[1];
- m[2] = matrix[2];
- m[3] = matrix[3] - evalue;
- m[4] = matrix[4];
- m[5] = matrix[5] - evalue;
-
- // find the largest component
- float mc = std::fabs( m[0] );
- int mi = 0;
- for( int i = 1; i < 6; ++i )
- {
- float c = std::fabs( m[i] );
- if( c > mc )
- {
- mc = c;
- mi = i;
- }
- }
-
- // pick the first eigenvector based on this index
- switch( mi )
- {
- case 0:
- case 1:
- return Vec3( -m[1], m[0], 0.0f );
-
- case 2:
- return Vec3( m[2], 0.0f, -m[0] );
-
- case 3:
- case 4:
- return Vec3( 0.0f, -m[4], m[3] );
-
- default:
- return Vec3( 0.0f, -m[5], m[4] );
- }
-}
-
-Vec3 ComputePrincipleComponent( Sym3x3 const& matrix )
-{
- // compute the cubic coefficients
- float c0 = matrix[0]*matrix[3]*matrix[5]
- + 2.0f*matrix[1]*matrix[2]*matrix[4]
- - matrix[0]*matrix[4]*matrix[4]
- - matrix[3]*matrix[2]*matrix[2]
- - matrix[5]*matrix[1]*matrix[1];
- float c1 = matrix[0]*matrix[3] + matrix[0]*matrix[5] + matrix[3]*matrix[5]
- - matrix[1]*matrix[1] - matrix[2]*matrix[2] - matrix[4]*matrix[4];
- float c2 = matrix[0] + matrix[3] + matrix[5];
-
- // compute the quadratic coefficients
- float a = c1 - ( 1.0f/3.0f )*c2*c2;
- float b = ( -2.0f/27.0f )*c2*c2*c2 + ( 1.0f/3.0f )*c1*c2 - c0;
-
- // compute the root count check
- float Q = 0.25f*b*b + ( 1.0f/27.0f )*a*a*a;
-
- // test the multiplicity
- if( FLT_EPSILON < Q )
- {
- // only one root, which implies we have a multiple of the identity
- return Vec3( 1.0f );
- }
- else if( Q < -FLT_EPSILON )
- {
- // three distinct roots
- float theta = std::atan2( std::sqrt( -Q ), -0.5f*b );
- float rho = std::sqrt( 0.25f*b*b - Q );
-
- float rt = std::pow( rho, 1.0f/3.0f );
- float ct = std::cos( theta/3.0f );
- float st = std::sin( theta/3.0f );
-
- float l1 = ( 1.0f/3.0f )*c2 + 2.0f*rt*ct;
- float l2 = ( 1.0f/3.0f )*c2 - rt*( ct + ( float )sqrt( 3.0f )*st );
- float l3 = ( 1.0f/3.0f )*c2 - rt*( ct - ( float )sqrt( 3.0f )*st );
-
- // pick the larger
- if( std::fabs( l2 ) > std::fabs( l1 ) )
- l1 = l2;
- if( std::fabs( l3 ) > std::fabs( l1 ) )
- l1 = l3;
-
- // get the eigenvector
- return GetMultiplicity1Evector( matrix, l1 );
- }
- else // if( -FLT_EPSILON <= Q && Q <= FLT_EPSILON )
- {
- // two roots
- float rt;
- if( b < 0.0f )
- rt = -std::pow( -0.5f*b, 1.0f/3.0f );
- else
- rt = std::pow( 0.5f*b, 1.0f/3.0f );
-
- float l1 = ( 1.0f/3.0f )*c2 + rt; // repeated
- float l2 = ( 1.0f/3.0f )*c2 - 2.0f*rt;
-
- // get the eigenvector
- if( std::fabs( l1 ) > std::fabs( l2 ) )
- return GetMultiplicity2Evector( matrix, l1 );
- else
- return GetMultiplicity1Evector( matrix, l2 );
- }
-}
-
-#else
-
-#define POWER_ITERATION_COUNT 8
-
-Vec3 ComputePrincipleComponent( Sym3x3 const& matrix )
-{
- Vec4 const row0( matrix[0], matrix[1], matrix[2], 0.0f );
- Vec4 const row1( matrix[1], matrix[3], matrix[4], 0.0f );
- Vec4 const row2( matrix[2], matrix[4], matrix[5], 0.0f );
- Vec4 v = VEC4_CONST( 1.0f );
- for( int i = 0; i < POWER_ITERATION_COUNT; ++i )
- {
- // matrix multiply
- Vec4 w = row0*v.SplatX();
- w = MultiplyAdd(row1, v.SplatY(), w);
- w = MultiplyAdd(row2, v.SplatZ(), w);
-
- // get max component from xyz in all channels
- Vec4 a = Max(w.SplatX(), Max(w.SplatY(), w.SplatZ()));
-
- // divide through and advance
- v = w*Reciprocal(a);
- }
- return v.GetVec3();
-}
-
-#endif
-
-} // namespace squish
diff --git a/thirdparty/squish/maths.h b/thirdparty/squish/maths.h
deleted file mode 100644
index 59c32196b1..0000000000
--- a/thirdparty/squish/maths.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_MATHS_H
-#define SQUISH_MATHS_H
-
-#include <cmath>
-#include <algorithm>
-#include "config.h"
-
-namespace squish {
-
-class Vec3
-{
-public:
- typedef Vec3 const& Arg;
-
- Vec3()
- {
- }
-
- explicit Vec3( float s )
- {
- m_x = s;
- m_y = s;
- m_z = s;
- }
-
- Vec3( float x, float y, float z )
- {
- m_x = x;
- m_y = y;
- m_z = z;
- }
-
- float X() const { return m_x; }
- float Y() const { return m_y; }
- float Z() const { return m_z; }
-
- Vec3 operator-() const
- {
- return Vec3( -m_x, -m_y, -m_z );
- }
-
- Vec3& operator+=( Arg v )
- {
- m_x += v.m_x;
- m_y += v.m_y;
- m_z += v.m_z;
- return *this;
- }
-
- Vec3& operator-=( Arg v )
- {
- m_x -= v.m_x;
- m_y -= v.m_y;
- m_z -= v.m_z;
- return *this;
- }
-
- Vec3& operator*=( Arg v )
- {
- m_x *= v.m_x;
- m_y *= v.m_y;
- m_z *= v.m_z;
- return *this;
- }
-
- Vec3& operator*=( float s )
- {
- m_x *= s;
- m_y *= s;
- m_z *= s;
- return *this;
- }
-
- Vec3& operator/=( Arg v )
- {
- m_x /= v.m_x;
- m_y /= v.m_y;
- m_z /= v.m_z;
- return *this;
- }
-
- Vec3& operator/=( float s )
- {
- float t = 1.0f/s;
- m_x *= t;
- m_y *= t;
- m_z *= t;
- return *this;
- }
-
- friend Vec3 operator+( Arg left, Arg right )
- {
- Vec3 copy( left );
- return copy += right;
- }
-
- friend Vec3 operator-( Arg left, Arg right )
- {
- Vec3 copy( left );
- return copy -= right;
- }
-
- friend Vec3 operator*( Arg left, Arg right )
- {
- Vec3 copy( left );
- return copy *= right;
- }
-
- friend Vec3 operator*( Arg left, float right )
- {
- Vec3 copy( left );
- return copy *= right;
- }
-
- friend Vec3 operator*( float left, Arg right )
- {
- Vec3 copy( right );
- return copy *= left;
- }
-
- friend Vec3 operator/( Arg left, Arg right )
- {
- Vec3 copy( left );
- return copy /= right;
- }
-
- friend Vec3 operator/( Arg left, float right )
- {
- Vec3 copy( left );
- return copy /= right;
- }
-
- friend float Dot( Arg left, Arg right )
- {
- return left.m_x*right.m_x + left.m_y*right.m_y + left.m_z*right.m_z;
- }
-
- friend Vec3 Min( Arg left, Arg right )
- {
- return Vec3(
- std::min( left.m_x, right.m_x ),
- std::min( left.m_y, right.m_y ),
- std::min( left.m_z, right.m_z )
- );
- }
-
- friend Vec3 Max( Arg left, Arg right )
- {
- return Vec3(
- std::max( left.m_x, right.m_x ),
- std::max( left.m_y, right.m_y ),
- std::max( left.m_z, right.m_z )
- );
- }
-
- friend Vec3 Truncate( Arg v )
- {
- return Vec3(
- v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ),
- v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ),
- v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z )
- );
- }
-
-private:
- float m_x;
- float m_y;
- float m_z;
-};
-
-inline float LengthSquared( Vec3::Arg v )
-{
- return Dot( v, v );
-}
-
-class Sym3x3
-{
-public:
- Sym3x3()
- {
- }
-
- Sym3x3( float s )
- {
- for( int i = 0; i < 6; ++i )
- m_x[i] = s;
- }
-
- float operator[]( int index ) const
- {
- return m_x[index];
- }
-
- float& operator[]( int index )
- {
- return m_x[index];
- }
-
-private:
- float m_x[6];
-};
-
-Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights );
-Vec3 ComputePrincipleComponent( Sym3x3 const& matrix );
-
-} // namespace squish
-
-#endif // ndef SQUISH_MATHS_H
diff --git a/thirdparty/squish/patches/config_sse.patch b/thirdparty/squish/patches/config_sse.patch
deleted file mode 100644
index 047701ee32..0000000000
--- a/thirdparty/squish/patches/config_sse.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-diff --git a/thirdparty/squish/config.h b/thirdparty/squish/config.h
-index 92edefe966..05f8d72598 100644
---- a/thirdparty/squish/config.h
-+++ b/thirdparty/squish/config.h
-@@ -32,6 +32,26 @@
- #endif
-
- // Set to 1 or 2 when building squish to use SSE or SSE2 instructions.
-+// -- GODOT start --
-+#ifdef _MSC_VER
-+ #if defined(_M_IX86_FP)
-+ #if _M_IX86_FP >= 2
-+ #define SQUISH_USE_SSE 2
-+ #elif _M_IX86_FP >= 1
-+ #define SQUISH_USE_SSE 1
-+ #endif
-+ #elif defined(_M_X64)
-+ #define SQUISH_USE_SSE 2
-+ #endif
-+#else
-+ #if defined(__SSE2__)
-+ #define SQUISH_USE_SSE 2
-+ #elif defined(__SSE__)
-+ #define SQUISH_USE_SSE 1
-+ #endif
-+#endif
-+// -- GODOT end --
-+
- #ifndef SQUISH_USE_SSE
- #define SQUISH_USE_SSE 0
- #endif
diff --git a/thirdparty/squish/patches/decompress_bc4_bc5.patch b/thirdparty/squish/patches/decompress_bc4_bc5.patch
deleted file mode 100644
index 949375560c..0000000000
--- a/thirdparty/squish/patches/decompress_bc4_bc5.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-diff --git a/thirdparty/squish/colourblock.cpp b/thirdparty/squish/colourblock.cpp
-index af8b980365..f14c9362bd 100644
---- a/thirdparty/squish/colourblock.cpp
-+++ b/thirdparty/squish/colourblock.cpp
-@@ -24,6 +24,9 @@
- -------------------------------------------------------------------------- */
-
- #include "colourblock.h"
-+// -- GODOT start --
-+#include "alpha.h"
-+// -- GODOT end --
-
- namespace squish {
-
-@@ -211,4 +214,34 @@ void DecompressColour( u8* rgba, void const* block, bool isDxt1 )
- }
- }
-
-+// -- GODOT start --
-+void DecompressColourBc4( u8* rgba, void const* block)
-+{
-+ DecompressAlphaDxt5(rgba,block);
-+ for ( int i = 0; i < 16; ++i ) {
-+ rgba[i*4] = rgba[i*4 + 3];
-+ rgba[i*4 + 1] = 0;
-+ rgba[i*4 + 2] = 0;
-+ rgba[i*4 + 3] = 255;
-+ }
-+}
-+
-+void DecompressColourBc5( u8* rgba, void const* block)
-+{
-+ void const* rblock = block;
-+ void const* gblock = reinterpret_cast< u8 const* >( block ) + 8;
-+ DecompressAlphaDxt5(rgba,rblock);
-+ for ( int i = 0; i < 16; ++i ) {
-+ rgba[i*4] = rgba[i*4 + 3];
-+ }
-+ DecompressAlphaDxt5(rgba,gblock);
-+ for ( int i = 0; i < 16; ++i ) {
-+ rgba[i*4+1] = rgba[i*4 + 3];
-+ rgba[i*4 + 2] = 0;
-+ rgba[i*4 + 3] = 255;
-+ }
-+}
-+// -- GODOT end --
-+
-+
- } // namespace squish
-diff --git a/thirdparty/squish/colourblock.h b/thirdparty/squish/colourblock.h
-index fee2cd7c5d..e1eb9e4917 100644
---- a/thirdparty/squish/colourblock.h
-+++ b/thirdparty/squish/colourblock.h
-@@ -35,6 +35,10 @@ void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void*
- void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block );
-
- void DecompressColour( u8* rgba, void const* block, bool isDxt1 );
-+// -- GODOT start --
-+void DecompressColourBc4( u8* rgba, void const* block );
-+void DecompressColourBc5( u8* rgba, void const* block );
-+// -- GODOT end --
-
- } // namespace squish
-
-diff --git a/thirdparty/squish/squish.cpp b/thirdparty/squish/squish.cpp
-index 1d22a64ad6..086ba11cd0 100644
---- a/thirdparty/squish/squish.cpp
-+++ b/thirdparty/squish/squish.cpp
-@@ -135,7 +135,15 @@ void Decompress( u8* rgba, void const* block, int flags )
- colourBlock = reinterpret_cast< u8 const* >( block ) + 8;
-
- // decompress colour
-- DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 );
-+ // -- GODOT start --
-+ //DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 );
-+ if(( flags & ( kBc4 ) ) != 0)
-+ DecompressColourBc4( rgba, colourBlock);
-+ else if(( flags & ( kBc5 ) ) != 0)
-+ DecompressColourBc5( rgba, colourBlock);
-+ else
-+ DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 );
-+ // -- GODOT end --
-
- // decompress alpha separately if necessary
- if( ( flags & kDxt3 ) != 0 )
diff --git a/thirdparty/squish/rangefit.cpp b/thirdparty/squish/rangefit.cpp
deleted file mode 100644
index adc07ed7d2..0000000000
--- a/thirdparty/squish/rangefit.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 "rangefit.h"
-#include "colourset.h"
-#include "colourblock.h"
-#include <cfloat>
-
-namespace squish {
-
-RangeFit::RangeFit( ColourSet const* colours, int flags, float* metric )
- : ColourFit( colours, flags )
-{
- // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f)
- if( metric )
- m_metric = Vec3( metric[0], metric[1], metric[2] );
- else
- m_metric = Vec3( 1.0f );
-
- // initialise the best error
- m_besterror = FLT_MAX;
-
- // cache some values
- int const count = m_colours->GetCount();
- Vec3 const* values = m_colours->GetPoints();
- float const* weights = m_colours->GetWeights();
-
- // get the covariance matrix
- Sym3x3 covariance = ComputeWeightedCovariance( count, values, weights );
-
- // compute the principle component
- Vec3 principle = ComputePrincipleComponent( covariance );
-
- // get the min and max range as the codebook endpoints
- Vec3 start( 0.0f );
- Vec3 end( 0.0f );
- if( count > 0 )
- {
- float min, max;
-
- // compute the range
- start = end = values[0];
- min = max = Dot( values[0], principle );
- for( int i = 1; i < count; ++i )
- {
- float val = Dot( values[i], principle );
- if( val < min )
- {
- start = values[i];
- min = val;
- }
- else if( val > max )
- {
- end = values[i];
- max = val;
- }
- }
- }
-
- // clamp the output to [0, 1]
- Vec3 const one( 1.0f );
- Vec3 const zero( 0.0f );
- start = Min( one, Max( zero, start ) );
- end = Min( one, Max( zero, end ) );
-
- // clamp to the grid and save
- Vec3 const grid( 31.0f, 63.0f, 31.0f );
- Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f );
- Vec3 const half( 0.5f );
- m_start = Truncate( grid*start + half )*gridrcp;
- m_end = Truncate( grid*end + half )*gridrcp;
-}
-
-void RangeFit::Compress3( void* block )
-{
- // cache some values
- int const count = m_colours->GetCount();
- Vec3 const* values = m_colours->GetPoints();
-
- // create a codebook
- Vec3 codes[3];
- codes[0] = m_start;
- codes[1] = m_end;
- codes[2] = 0.5f*m_start + 0.5f*m_end;
-
- // match each point to the closest code
- u8 closest[16];
- float error = 0.0f;
- for( int i = 0; i < count; ++i )
- {
- // find the closest code
- float dist = FLT_MAX;
- int idx = 0;
- for( int j = 0; j < 3; ++j )
- {
- float d = LengthSquared( m_metric*( values[i] - codes[j] ) );
- if( d < dist )
- {
- dist = d;
- idx = j;
- }
- }
-
- // save the index
- closest[i] = ( u8 )idx;
-
- // accumulate the error
- error += dist;
- }
-
- // save this scheme if it wins
- if( error < m_besterror )
- {
- // remap the indices
- u8 indices[16];
- m_colours->RemapIndices( closest, indices );
-
- // save the block
- WriteColourBlock3( m_start, m_end, indices, block );
-
- // save the error
- m_besterror = error;
- }
-}
-
-void RangeFit::Compress4( void* block )
-{
- // cache some values
- int const count = m_colours->GetCount();
- Vec3 const* values = m_colours->GetPoints();
-
- // create a codebook
- Vec3 codes[4];
- codes[0] = m_start;
- codes[1] = m_end;
- codes[2] = ( 2.0f/3.0f )*m_start + ( 1.0f/3.0f )*m_end;
- codes[3] = ( 1.0f/3.0f )*m_start + ( 2.0f/3.0f )*m_end;
-
- // match each point to the closest code
- u8 closest[16];
- float error = 0.0f;
- for( int i = 0; i < count; ++i )
- {
- // find the closest code
- float dist = FLT_MAX;
- int idx = 0;
- for( int j = 0; j < 4; ++j )
- {
- float d = LengthSquared( m_metric*( values[i] - codes[j] ) );
- if( d < dist )
- {
- dist = d;
- idx = j;
- }
- }
-
- // save the index
- closest[i] = ( u8 )idx;
-
- // accumulate the error
- error += dist;
- }
-
- // save this scheme if it wins
- if( error < m_besterror )
- {
- // remap the indices
- u8 indices[16];
- m_colours->RemapIndices( closest, indices );
-
- // save the block
- WriteColourBlock4( m_start, m_end, indices, block );
-
- // save the error
- m_besterror = error;
- }
-}
-
-} // namespace squish
diff --git a/thirdparty/squish/rangefit.h b/thirdparty/squish/rangefit.h
deleted file mode 100644
index bdb21a9007..0000000000
--- a/thirdparty/squish/rangefit.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_RANGEFIT_H
-#define SQUISH_RANGEFIT_H
-
-#include "squish.h"
-#include "colourfit.h"
-#include "maths.h"
-
-namespace squish {
-
-class ColourSet;
-
-class RangeFit : public ColourFit
-{
-public:
- RangeFit( ColourSet const* colours, int flags, float* metric );
-
-private:
- virtual void Compress3( void* block );
- virtual void Compress4( void* block );
-
- Vec3 m_metric;
- Vec3 m_start;
- Vec3 m_end;
- float m_besterror;
-};
-
-} // squish
-
-#endif // ndef SQUISH_RANGEFIT_H
diff --git a/thirdparty/squish/simd.h b/thirdparty/squish/simd.h
deleted file mode 100644
index 1e02fa160e..0000000000
--- a/thirdparty/squish/simd.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_SIMD_H
-#define SQUISH_SIMD_H
-
-#include "maths.h"
-
-#if SQUISH_USE_ALTIVEC
-#include "simd_ve.h"
-#elif SQUISH_USE_SSE
-#include "simd_sse.h"
-#else
-#include "simd_float.h"
-#endif
-
-
-#endif // ndef SQUISH_SIMD_H
diff --git a/thirdparty/squish/simd_float.h b/thirdparty/squish/simd_float.h
deleted file mode 100644
index 030ea70950..0000000000
--- a/thirdparty/squish/simd_float.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_SIMD_FLOAT_H
-#define SQUISH_SIMD_FLOAT_H
-
-#include <algorithm>
-
-namespace squish {
-
-#define VEC4_CONST( X ) Vec4( X )
-
-class Vec4
-{
-public:
- typedef Vec4 const& Arg;
-
- Vec4() {}
-
- explicit Vec4( float s )
- : m_x( s ),
- m_y( s ),
- m_z( s ),
- m_w( s )
- {
- }
-
- Vec4( float x, float y, float z, float w )
- : m_x( x ),
- m_y( y ),
- m_z( z ),
- m_w( w )
- {
- }
-
- Vec3 GetVec3() const
- {
- return Vec3( m_x, m_y, m_z );
- }
-
- Vec4 SplatX() const { return Vec4( m_x ); }
- Vec4 SplatY() const { return Vec4( m_y ); }
- Vec4 SplatZ() const { return Vec4( m_z ); }
- Vec4 SplatW() const { return Vec4( m_w ); }
-
- Vec4& operator+=( Arg v )
- {
- m_x += v.m_x;
- m_y += v.m_y;
- m_z += v.m_z;
- m_w += v.m_w;
- return *this;
- }
-
- Vec4& operator-=( Arg v )
- {
- m_x -= v.m_x;
- m_y -= v.m_y;
- m_z -= v.m_z;
- m_w -= v.m_w;
- return *this;
- }
-
- Vec4& operator*=( Arg v )
- {
- m_x *= v.m_x;
- m_y *= v.m_y;
- m_z *= v.m_z;
- m_w *= v.m_w;
- return *this;
- }
-
- friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right )
- {
- Vec4 copy( left );
- return copy += right;
- }
-
- friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right )
- {
- Vec4 copy( left );
- return copy -= right;
- }
-
- friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right )
- {
- Vec4 copy( left );
- return copy *= right;
- }
-
- //! Returns a*b + c
- friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
- {
- return a*b + c;
- }
-
- //! Returns -( a*b - c )
- friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
- {
- return c - a*b;
- }
-
- friend Vec4 Reciprocal( Vec4::Arg v )
- {
- return Vec4(
- 1.0f/v.m_x,
- 1.0f/v.m_y,
- 1.0f/v.m_z,
- 1.0f/v.m_w
- );
- }
-
- friend Vec4 Min( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4(
- std::min( left.m_x, right.m_x ),
- std::min( left.m_y, right.m_y ),
- std::min( left.m_z, right.m_z ),
- std::min( left.m_w, right.m_w )
- );
- }
-
- friend Vec4 Max( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4(
- std::max( left.m_x, right.m_x ),
- std::max( left.m_y, right.m_y ),
- std::max( left.m_z, right.m_z ),
- std::max( left.m_w, right.m_w )
- );
- }
-
- friend Vec4 Truncate( Vec4::Arg v )
- {
- return Vec4(
- v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ),
- v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ),
- v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z ),
- v.m_w > 0.0f ? std::floor( v.m_w ) : std::ceil( v.m_w )
- );
- }
-
- friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right )
- {
- return left.m_x < right.m_x
- || left.m_y < right.m_y
- || left.m_z < right.m_z
- || left.m_w < right.m_w;
- }
-
-private:
- float m_x;
- float m_y;
- float m_z;
- float m_w;
-};
-
-} // namespace squish
-
-#endif // ndef SQUISH_SIMD_FLOAT_H
-
diff --git a/thirdparty/squish/simd_sse.h b/thirdparty/squish/simd_sse.h
deleted file mode 100644
index 2e8be4ca7b..0000000000
--- a/thirdparty/squish/simd_sse.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_SIMD_SSE_H
-#define SQUISH_SIMD_SSE_H
-
-#include <xmmintrin.h>
-#if ( SQUISH_USE_SSE > 1 )
-#include <emmintrin.h>
-#endif
-
-#define SQUISH_SSE_SPLAT( a ) \
- ( ( a ) | ( ( a ) << 2 ) | ( ( a ) << 4 ) | ( ( a ) << 6 ) )
-
-#define SQUISH_SSE_SHUF( x, y, z, w ) \
- ( ( x ) | ( ( y ) << 2 ) | ( ( z ) << 4 ) | ( ( w ) << 6 ) )
-
-namespace squish {
-
-#define VEC4_CONST( X ) Vec4( X )
-
-class Vec4
-{
-public:
- typedef Vec4 const& Arg;
-
- Vec4() {}
-
- explicit Vec4( __m128 v ) : m_v( v ) {}
-
- Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {}
-
- Vec4& operator=( Vec4 const& arg )
- {
- m_v = arg.m_v;
- return *this;
- }
-
- explicit Vec4( float s ) : m_v( _mm_set1_ps( s ) ) {}
-
- Vec4( float x, float y, float z, float w ) : m_v( _mm_setr_ps( x, y, z, w ) ) {}
-
- Vec3 GetVec3() const
- {
-#ifdef __GNUC__
- __attribute__ ((__aligned__ (16))) float c[4];
-#else
- __declspec(align(16)) float c[4];
-#endif
- _mm_store_ps( c, m_v );
- return Vec3( c[0], c[1], c[2] );
- }
-
- Vec4 SplatX() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 0 ) ) ); }
- Vec4 SplatY() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 1 ) ) ); }
- Vec4 SplatZ() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 2 ) ) ); }
- Vec4 SplatW() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 3 ) ) ); }
-
- Vec4& operator+=( Arg v )
- {
- m_v = _mm_add_ps( m_v, v.m_v );
- return *this;
- }
-
- Vec4& operator-=( Arg v )
- {
- m_v = _mm_sub_ps( m_v, v.m_v );
- return *this;
- }
-
- Vec4& operator*=( Arg v )
- {
- m_v = _mm_mul_ps( m_v, v.m_v );
- return *this;
- }
-
- friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( _mm_add_ps( left.m_v, right.m_v ) );
- }
-
- friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( _mm_sub_ps( left.m_v, right.m_v ) );
- }
-
- friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( _mm_mul_ps( left.m_v, right.m_v ) );
- }
-
- //! Returns a*b + c
- friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
- {
- return Vec4( _mm_add_ps( _mm_mul_ps( a.m_v, b.m_v ), c.m_v ) );
- }
-
- //! Returns -( a*b - c )
- friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
- {
- return Vec4( _mm_sub_ps( c.m_v, _mm_mul_ps( a.m_v, b.m_v ) ) );
- }
-
- friend Vec4 Reciprocal( Vec4::Arg v )
- {
- // get the reciprocal estimate
- __m128 estimate = _mm_rcp_ps( v.m_v );
-
- // one round of Newton-Rhaphson refinement
- __m128 diff = _mm_sub_ps( _mm_set1_ps( 1.0f ), _mm_mul_ps( estimate, v.m_v ) );
- return Vec4( _mm_add_ps( _mm_mul_ps( diff, estimate ), estimate ) );
- }
-
- friend Vec4 Min( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( _mm_min_ps( left.m_v, right.m_v ) );
- }
-
- friend Vec4 Max( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( _mm_max_ps( left.m_v, right.m_v ) );
- }
-
- friend Vec4 Truncate( Vec4::Arg v )
- {
-#if ( SQUISH_USE_SSE == 1 )
- // convert to ints
- __m128 input = v.m_v;
- __m64 lo = _mm_cvttps_pi32( input );
- __m64 hi = _mm_cvttps_pi32( _mm_movehl_ps( input, input ) );
-
- // convert to floats
- __m128 part = _mm_movelh_ps( input, _mm_cvtpi32_ps( input, hi ) );
- __m128 truncated = _mm_cvtpi32_ps( part, lo );
-
- // clear out the MMX multimedia state to allow FP calls later
- _mm_empty();
- return Vec4( truncated );
-#else
- // use SSE2 instructions
- return Vec4( _mm_cvtepi32_ps( _mm_cvttps_epi32( v.m_v ) ) );
-#endif
- }
-
- friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right )
- {
- __m128 bits = _mm_cmplt_ps( left.m_v, right.m_v );
- int value = _mm_movemask_ps( bits );
- return value != 0;
- }
-
-private:
- __m128 m_v;
-};
-
-} // namespace squish
-
-#endif // ndef SQUISH_SIMD_SSE_H
diff --git a/thirdparty/squish/simd_ve.h b/thirdparty/squish/simd_ve.h
deleted file mode 100644
index 08a1537503..0000000000
--- a/thirdparty/squish/simd_ve.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_SIMD_VE_H
-#define SQUISH_SIMD_VE_H
-
-#include <altivec.h>
-#undef bool
-
-namespace squish {
-
-#define VEC4_CONST( X ) Vec4( ( vector float ){ X } )
-
-class Vec4
-{
-public:
- typedef Vec4 Arg;
-
- Vec4() {}
-
- explicit Vec4( vector float v ) : m_v( v ) {}
-
- Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {}
-
- Vec4& operator=( Vec4 const& arg )
- {
- m_v = arg.m_v;
- return *this;
- }
-
- explicit Vec4( float s )
- {
- union { vector float v; float c[4]; } u;
- u.c[0] = s;
- u.c[1] = s;
- u.c[2] = s;
- u.c[3] = s;
- m_v = u.v;
- }
-
- Vec4( float x, float y, float z, float w )
- {
- union { vector float v; float c[4]; } u;
- u.c[0] = x;
- u.c[1] = y;
- u.c[2] = z;
- u.c[3] = w;
- m_v = u.v;
- }
-
- Vec3 GetVec3() const
- {
- union { vector float v; float c[4]; } u;
- u.v = m_v;
- return Vec3( u.c[0], u.c[1], u.c[2] );
- }
-
- Vec4 SplatX() const { return Vec4( vec_splat( m_v, 0 ) ); }
- Vec4 SplatY() const { return Vec4( vec_splat( m_v, 1 ) ); }
- Vec4 SplatZ() const { return Vec4( vec_splat( m_v, 2 ) ); }
- Vec4 SplatW() const { return Vec4( vec_splat( m_v, 3 ) ); }
-
- Vec4& operator+=( Arg v )
- {
- m_v = vec_add( m_v, v.m_v );
- return *this;
- }
-
- Vec4& operator-=( Arg v )
- {
- m_v = vec_sub( m_v, v.m_v );
- return *this;
- }
-
- Vec4& operator*=( Arg v )
- {
- m_v = vec_madd( m_v, v.m_v, ( vector float ){ -0.0f } );
- return *this;
- }
-
- friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( vec_add( left.m_v, right.m_v ) );
- }
-
- friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( vec_sub( left.m_v, right.m_v ) );
- }
-
- friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( vec_madd( left.m_v, right.m_v, ( vector float ){ -0.0f } ) );
- }
-
- //! Returns a*b + c
- friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
- {
- return Vec4( vec_madd( a.m_v, b.m_v, c.m_v ) );
- }
-
- //! Returns -( a*b - c )
- friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
- {
- return Vec4( vec_nmsub( a.m_v, b.m_v, c.m_v ) );
- }
-
- friend Vec4 Reciprocal( Vec4::Arg v )
- {
- // get the reciprocal estimate
- vector float estimate = vec_re( v.m_v );
-
- // one round of Newton-Rhaphson refinement
- vector float diff = vec_nmsub( estimate, v.m_v, ( vector float ){ 1.0f } );
- return Vec4( vec_madd( diff, estimate, estimate ) );
- }
-
- friend Vec4 Min( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( vec_min( left.m_v, right.m_v ) );
- }
-
- friend Vec4 Max( Vec4::Arg left, Vec4::Arg right )
- {
- return Vec4( vec_max( left.m_v, right.m_v ) );
- }
-
- friend Vec4 Truncate( Vec4::Arg v )
- {
- return Vec4( vec_trunc( v.m_v ) );
- }
-
- friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right )
- {
- return vec_any_lt( left.m_v, right.m_v ) != 0;
- }
-
-private:
- vector float m_v;
-};
-
-} // namespace squish
-
-#endif // ndef SQUISH_SIMD_VE_H
diff --git a/thirdparty/squish/singlecolourfit.cpp b/thirdparty/squish/singlecolourfit.cpp
deleted file mode 100644
index cef0ebc410..0000000000
--- a/thirdparty/squish/singlecolourfit.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 "singlecolourfit.h"
-#include "colourset.h"
-#include "colourblock.h"
-
-namespace squish {
-
-struct SourceBlock
-{
- u8 start;
- u8 end;
- u8 error;
-};
-
-struct SingleColourLookup
-{
- SourceBlock sources[2];
-};
-
-#include "singlecolourlookup.inl"
-
-static int FloatToInt( float a, int limit )
-{
- // use ANSI round-to-zero behaviour to get round-to-nearest
- int i = ( int )( a + 0.5f );
-
- // clamp to the limit
- if( i < 0 )
- i = 0;
- else if( i > limit )
- i = limit;
-
- // done
- return i;
-}
-
-SingleColourFit::SingleColourFit( ColourSet const* colours, int flags )
- : ColourFit( colours, flags )
-{
- // grab the single colour
- Vec3 const* values = m_colours->GetPoints();
- m_colour[0] = ( u8 )FloatToInt( 255.0f*values->X(), 255 );
- m_colour[1] = ( u8 )FloatToInt( 255.0f*values->Y(), 255 );
- m_colour[2] = ( u8 )FloatToInt( 255.0f*values->Z(), 255 );
-
- // initialise the best error
- m_besterror = INT_MAX;
-}
-
-void SingleColourFit::Compress3( void* block )
-{
- // build the table of lookups
- SingleColourLookup const* const lookups[] =
- {
- lookup_5_3,
- lookup_6_3,
- lookup_5_3
- };
-
- // find the best end-points and index
- ComputeEndPoints( lookups );
-
- // build the block if we win
- if( m_error < m_besterror )
- {
- // remap the indices
- u8 indices[16];
- m_colours->RemapIndices( &m_index, indices );
-
- // save the block
- WriteColourBlock3( m_start, m_end, indices, block );
-
- // save the error
- m_besterror = m_error;
- }
-}
-
-void SingleColourFit::Compress4( void* block )
-{
- // build the table of lookups
- SingleColourLookup const* const lookups[] =
- {
- lookup_5_4,
- lookup_6_4,
- lookup_5_4
- };
-
- // find the best end-points and index
- ComputeEndPoints( lookups );
-
- // build the block if we win
- if( m_error < m_besterror )
- {
- // remap the indices
- u8 indices[16];
- m_colours->RemapIndices( &m_index, indices );
-
- // save the block
- WriteColourBlock4( m_start, m_end, indices, block );
-
- // save the error
- m_besterror = m_error;
- }
-}
-
-void SingleColourFit::ComputeEndPoints( SingleColourLookup const* const* lookups )
-{
- // check each index combination (endpoint or intermediate)
- m_error = INT_MAX;
- for( int index = 0; index < 2; ++index )
- {
- // check the error for this codebook index
- SourceBlock const* sources[3];
- int error = 0;
- for( int channel = 0; channel < 3; ++channel )
- {
- // grab the lookup table and index for this channel
- SingleColourLookup const* lookup = lookups[channel];
- int target = m_colour[channel];
-
- // store a pointer to the source for this channel
- sources[channel] = lookup[target].sources + index;
-
- // accumulate the error
- int diff = sources[channel]->error;
- error += diff*diff;
- }
-
- // keep it if the error is lower
- if( error < m_error )
- {
- m_start = Vec3(
- ( float )sources[0]->start/31.0f,
- ( float )sources[1]->start/63.0f,
- ( float )sources[2]->start/31.0f
- );
- m_end = Vec3(
- ( float )sources[0]->end/31.0f,
- ( float )sources[1]->end/63.0f,
- ( float )sources[2]->end/31.0f
- );
- m_index = ( u8 )( 2*index );
- m_error = error;
- }
- }
-}
-
-} // namespace squish
diff --git a/thirdparty/squish/singlecolourfit.h b/thirdparty/squish/singlecolourfit.h
deleted file mode 100644
index 974ce77256..0000000000
--- a/thirdparty/squish/singlecolourfit.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_SINGLECOLOURFIT_H
-#define SQUISH_SINGLECOLOURFIT_H
-
-#include "squish.h"
-#include "colourfit.h"
-
-namespace squish {
-
-class ColourSet;
-struct SingleColourLookup;
-
-class SingleColourFit : public ColourFit
-{
-public:
- SingleColourFit( ColourSet const* colours, int flags );
-
-private:
- virtual void Compress3( void* block );
- virtual void Compress4( void* block );
-
- void ComputeEndPoints( SingleColourLookup const* const* lookups );
-
- u8 m_colour[3];
- Vec3 m_start;
- Vec3 m_end;
- u8 m_index;
- int m_error;
- int m_besterror;
-};
-
-} // namespace squish
-
-#endif // ndef SQUISH_SINGLECOLOURFIT_H
diff --git a/thirdparty/squish/singlecolourlookup.inl b/thirdparty/squish/singlecolourlookup.inl
deleted file mode 100644
index 5b44a1e5e6..0000000000
--- a/thirdparty/squish/singlecolourlookup.inl
+++ /dev/null
@@ -1,1064 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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.
-
- -------------------------------------------------------------------------- */
-
-static SingleColourLookup const lookup_5_3[] =
-{
- { { { 0, 0, 0 }, { 0, 0, 0 } } },
- { { { 0, 0, 1 }, { 0, 0, 1 } } },
- { { { 0, 0, 2 }, { 0, 0, 2 } } },
- { { { 0, 0, 3 }, { 0, 1, 1 } } },
- { { { 0, 0, 4 }, { 0, 1, 0 } } },
- { { { 1, 0, 3 }, { 0, 1, 1 } } },
- { { { 1, 0, 2 }, { 0, 1, 2 } } },
- { { { 1, 0, 1 }, { 0, 2, 1 } } },
- { { { 1, 0, 0 }, { 0, 2, 0 } } },
- { { { 1, 0, 1 }, { 0, 2, 1 } } },
- { { { 1, 0, 2 }, { 0, 2, 2 } } },
- { { { 1, 0, 3 }, { 0, 3, 1 } } },
- { { { 1, 0, 4 }, { 0, 3, 0 } } },
- { { { 2, 0, 3 }, { 0, 3, 1 } } },
- { { { 2, 0, 2 }, { 0, 3, 2 } } },
- { { { 2, 0, 1 }, { 0, 4, 1 } } },
- { { { 2, 0, 0 }, { 0, 4, 0 } } },
- { { { 2, 0, 1 }, { 0, 4, 1 } } },
- { { { 2, 0, 2 }, { 0, 4, 2 } } },
- { { { 2, 0, 3 }, { 0, 5, 1 } } },
- { { { 2, 0, 4 }, { 0, 5, 0 } } },
- { { { 3, 0, 3 }, { 0, 5, 1 } } },
- { { { 3, 0, 2 }, { 0, 5, 2 } } },
- { { { 3, 0, 1 }, { 0, 6, 1 } } },
- { { { 3, 0, 0 }, { 0, 6, 0 } } },
- { { { 3, 0, 1 }, { 0, 6, 1 } } },
- { { { 3, 0, 2 }, { 0, 6, 2 } } },
- { { { 3, 0, 3 }, { 0, 7, 1 } } },
- { { { 3, 0, 4 }, { 0, 7, 0 } } },
- { { { 4, 0, 4 }, { 0, 7, 1 } } },
- { { { 4, 0, 3 }, { 0, 7, 2 } } },
- { { { 4, 0, 2 }, { 1, 7, 1 } } },
- { { { 4, 0, 1 }, { 1, 7, 0 } } },
- { { { 4, 0, 0 }, { 0, 8, 0 } } },
- { { { 4, 0, 1 }, { 0, 8, 1 } } },
- { { { 4, 0, 2 }, { 2, 7, 1 } } },
- { { { 4, 0, 3 }, { 2, 7, 0 } } },
- { { { 4, 0, 4 }, { 0, 9, 0 } } },
- { { { 5, 0, 3 }, { 0, 9, 1 } } },
- { { { 5, 0, 2 }, { 3, 7, 1 } } },
- { { { 5, 0, 1 }, { 3, 7, 0 } } },
- { { { 5, 0, 0 }, { 0, 10, 0 } } },
- { { { 5, 0, 1 }, { 0, 10, 1 } } },
- { { { 5, 0, 2 }, { 0, 10, 2 } } },
- { { { 5, 0, 3 }, { 0, 11, 1 } } },
- { { { 5, 0, 4 }, { 0, 11, 0 } } },
- { { { 6, 0, 3 }, { 0, 11, 1 } } },
- { { { 6, 0, 2 }, { 0, 11, 2 } } },
- { { { 6, 0, 1 }, { 0, 12, 1 } } },
- { { { 6, 0, 0 }, { 0, 12, 0 } } },
- { { { 6, 0, 1 }, { 0, 12, 1 } } },
- { { { 6, 0, 2 }, { 0, 12, 2 } } },
- { { { 6, 0, 3 }, { 0, 13, 1 } } },
- { { { 6, 0, 4 }, { 0, 13, 0 } } },
- { { { 7, 0, 3 }, { 0, 13, 1 } } },
- { { { 7, 0, 2 }, { 0, 13, 2 } } },
- { { { 7, 0, 1 }, { 0, 14, 1 } } },
- { { { 7, 0, 0 }, { 0, 14, 0 } } },
- { { { 7, 0, 1 }, { 0, 14, 1 } } },
- { { { 7, 0, 2 }, { 0, 14, 2 } } },
- { { { 7, 0, 3 }, { 0, 15, 1 } } },
- { { { 7, 0, 4 }, { 0, 15, 0 } } },
- { { { 8, 0, 4 }, { 0, 15, 1 } } },
- { { { 8, 0, 3 }, { 0, 15, 2 } } },
- { { { 8, 0, 2 }, { 1, 15, 1 } } },
- { { { 8, 0, 1 }, { 1, 15, 0 } } },
- { { { 8, 0, 0 }, { 0, 16, 0 } } },
- { { { 8, 0, 1 }, { 0, 16, 1 } } },
- { { { 8, 0, 2 }, { 2, 15, 1 } } },
- { { { 8, 0, 3 }, { 2, 15, 0 } } },
- { { { 8, 0, 4 }, { 0, 17, 0 } } },
- { { { 9, 0, 3 }, { 0, 17, 1 } } },
- { { { 9, 0, 2 }, { 3, 15, 1 } } },
- { { { 9, 0, 1 }, { 3, 15, 0 } } },
- { { { 9, 0, 0 }, { 0, 18, 0 } } },
- { { { 9, 0, 1 }, { 0, 18, 1 } } },
- { { { 9, 0, 2 }, { 0, 18, 2 } } },
- { { { 9, 0, 3 }, { 0, 19, 1 } } },
- { { { 9, 0, 4 }, { 0, 19, 0 } } },
- { { { 10, 0, 3 }, { 0, 19, 1 } } },
- { { { 10, 0, 2 }, { 0, 19, 2 } } },
- { { { 10, 0, 1 }, { 0, 20, 1 } } },
- { { { 10, 0, 0 }, { 0, 20, 0 } } },
- { { { 10, 0, 1 }, { 0, 20, 1 } } },
- { { { 10, 0, 2 }, { 0, 20, 2 } } },
- { { { 10, 0, 3 }, { 0, 21, 1 } } },
- { { { 10, 0, 4 }, { 0, 21, 0 } } },
- { { { 11, 0, 3 }, { 0, 21, 1 } } },
- { { { 11, 0, 2 }, { 0, 21, 2 } } },
- { { { 11, 0, 1 }, { 0, 22, 1 } } },
- { { { 11, 0, 0 }, { 0, 22, 0 } } },
- { { { 11, 0, 1 }, { 0, 22, 1 } } },
- { { { 11, 0, 2 }, { 0, 22, 2 } } },
- { { { 11, 0, 3 }, { 0, 23, 1 } } },
- { { { 11, 0, 4 }, { 0, 23, 0 } } },
- { { { 12, 0, 4 }, { 0, 23, 1 } } },
- { { { 12, 0, 3 }, { 0, 23, 2 } } },
- { { { 12, 0, 2 }, { 1, 23, 1 } } },
- { { { 12, 0, 1 }, { 1, 23, 0 } } },
- { { { 12, 0, 0 }, { 0, 24, 0 } } },
- { { { 12, 0, 1 }, { 0, 24, 1 } } },
- { { { 12, 0, 2 }, { 2, 23, 1 } } },
- { { { 12, 0, 3 }, { 2, 23, 0 } } },
- { { { 12, 0, 4 }, { 0, 25, 0 } } },
- { { { 13, 0, 3 }, { 0, 25, 1 } } },
- { { { 13, 0, 2 }, { 3, 23, 1 } } },
- { { { 13, 0, 1 }, { 3, 23, 0 } } },
- { { { 13, 0, 0 }, { 0, 26, 0 } } },
- { { { 13, 0, 1 }, { 0, 26, 1 } } },
- { { { 13, 0, 2 }, { 0, 26, 2 } } },
- { { { 13, 0, 3 }, { 0, 27, 1 } } },
- { { { 13, 0, 4 }, { 0, 27, 0 } } },
- { { { 14, 0, 3 }, { 0, 27, 1 } } },
- { { { 14, 0, 2 }, { 0, 27, 2 } } },
- { { { 14, 0, 1 }, { 0, 28, 1 } } },
- { { { 14, 0, 0 }, { 0, 28, 0 } } },
- { { { 14, 0, 1 }, { 0, 28, 1 } } },
- { { { 14, 0, 2 }, { 0, 28, 2 } } },
- { { { 14, 0, 3 }, { 0, 29, 1 } } },
- { { { 14, 0, 4 }, { 0, 29, 0 } } },
- { { { 15, 0, 3 }, { 0, 29, 1 } } },
- { { { 15, 0, 2 }, { 0, 29, 2 } } },
- { { { 15, 0, 1 }, { 0, 30, 1 } } },
- { { { 15, 0, 0 }, { 0, 30, 0 } } },
- { { { 15, 0, 1 }, { 0, 30, 1 } } },
- { { { 15, 0, 2 }, { 0, 30, 2 } } },
- { { { 15, 0, 3 }, { 0, 31, 1 } } },
- { { { 15, 0, 4 }, { 0, 31, 0 } } },
- { { { 16, 0, 4 }, { 0, 31, 1 } } },
- { { { 16, 0, 3 }, { 0, 31, 2 } } },
- { { { 16, 0, 2 }, { 1, 31, 1 } } },
- { { { 16, 0, 1 }, { 1, 31, 0 } } },
- { { { 16, 0, 0 }, { 4, 28, 0 } } },
- { { { 16, 0, 1 }, { 4, 28, 1 } } },
- { { { 16, 0, 2 }, { 2, 31, 1 } } },
- { { { 16, 0, 3 }, { 2, 31, 0 } } },
- { { { 16, 0, 4 }, { 4, 29, 0 } } },
- { { { 17, 0, 3 }, { 4, 29, 1 } } },
- { { { 17, 0, 2 }, { 3, 31, 1 } } },
- { { { 17, 0, 1 }, { 3, 31, 0 } } },
- { { { 17, 0, 0 }, { 4, 30, 0 } } },
- { { { 17, 0, 1 }, { 4, 30, 1 } } },
- { { { 17, 0, 2 }, { 4, 30, 2 } } },
- { { { 17, 0, 3 }, { 4, 31, 1 } } },
- { { { 17, 0, 4 }, { 4, 31, 0 } } },
- { { { 18, 0, 3 }, { 4, 31, 1 } } },
- { { { 18, 0, 2 }, { 4, 31, 2 } } },
- { { { 18, 0, 1 }, { 5, 31, 1 } } },
- { { { 18, 0, 0 }, { 5, 31, 0 } } },
- { { { 18, 0, 1 }, { 5, 31, 1 } } },
- { { { 18, 0, 2 }, { 5, 31, 2 } } },
- { { { 18, 0, 3 }, { 6, 31, 1 } } },
- { { { 18, 0, 4 }, { 6, 31, 0 } } },
- { { { 19, 0, 3 }, { 6, 31, 1 } } },
- { { { 19, 0, 2 }, { 6, 31, 2 } } },
- { { { 19, 0, 1 }, { 7, 31, 1 } } },
- { { { 19, 0, 0 }, { 7, 31, 0 } } },
- { { { 19, 0, 1 }, { 7, 31, 1 } } },
- { { { 19, 0, 2 }, { 7, 31, 2 } } },
- { { { 19, 0, 3 }, { 8, 31, 1 } } },
- { { { 19, 0, 4 }, { 8, 31, 0 } } },
- { { { 20, 0, 4 }, { 8, 31, 1 } } },
- { { { 20, 0, 3 }, { 8, 31, 2 } } },
- { { { 20, 0, 2 }, { 9, 31, 1 } } },
- { { { 20, 0, 1 }, { 9, 31, 0 } } },
- { { { 20, 0, 0 }, { 12, 28, 0 } } },
- { { { 20, 0, 1 }, { 12, 28, 1 } } },
- { { { 20, 0, 2 }, { 10, 31, 1 } } },
- { { { 20, 0, 3 }, { 10, 31, 0 } } },
- { { { 20, 0, 4 }, { 12, 29, 0 } } },
- { { { 21, 0, 3 }, { 12, 29, 1 } } },
- { { { 21, 0, 2 }, { 11, 31, 1 } } },
- { { { 21, 0, 1 }, { 11, 31, 0 } } },
- { { { 21, 0, 0 }, { 12, 30, 0 } } },
- { { { 21, 0, 1 }, { 12, 30, 1 } } },
- { { { 21, 0, 2 }, { 12, 30, 2 } } },
- { { { 21, 0, 3 }, { 12, 31, 1 } } },
- { { { 21, 0, 4 }, { 12, 31, 0 } } },
- { { { 22, 0, 3 }, { 12, 31, 1 } } },
- { { { 22, 0, 2 }, { 12, 31, 2 } } },
- { { { 22, 0, 1 }, { 13, 31, 1 } } },
- { { { 22, 0, 0 }, { 13, 31, 0 } } },
- { { { 22, 0, 1 }, { 13, 31, 1 } } },
- { { { 22, 0, 2 }, { 13, 31, 2 } } },
- { { { 22, 0, 3 }, { 14, 31, 1 } } },
- { { { 22, 0, 4 }, { 14, 31, 0 } } },
- { { { 23, 0, 3 }, { 14, 31, 1 } } },
- { { { 23, 0, 2 }, { 14, 31, 2 } } },
- { { { 23, 0, 1 }, { 15, 31, 1 } } },
- { { { 23, 0, 0 }, { 15, 31, 0 } } },
- { { { 23, 0, 1 }, { 15, 31, 1 } } },
- { { { 23, 0, 2 }, { 15, 31, 2 } } },
- { { { 23, 0, 3 }, { 16, 31, 1 } } },
- { { { 23, 0, 4 }, { 16, 31, 0 } } },
- { { { 24, 0, 4 }, { 16, 31, 1 } } },
- { { { 24, 0, 3 }, { 16, 31, 2 } } },
- { { { 24, 0, 2 }, { 17, 31, 1 } } },
- { { { 24, 0, 1 }, { 17, 31, 0 } } },
- { { { 24, 0, 0 }, { 20, 28, 0 } } },
- { { { 24, 0, 1 }, { 20, 28, 1 } } },
- { { { 24, 0, 2 }, { 18, 31, 1 } } },
- { { { 24, 0, 3 }, { 18, 31, 0 } } },
- { { { 24, 0, 4 }, { 20, 29, 0 } } },
- { { { 25, 0, 3 }, { 20, 29, 1 } } },
- { { { 25, 0, 2 }, { 19, 31, 1 } } },
- { { { 25, 0, 1 }, { 19, 31, 0 } } },
- { { { 25, 0, 0 }, { 20, 30, 0 } } },
- { { { 25, 0, 1 }, { 20, 30, 1 } } },
- { { { 25, 0, 2 }, { 20, 30, 2 } } },
- { { { 25, 0, 3 }, { 20, 31, 1 } } },
- { { { 25, 0, 4 }, { 20, 31, 0 } } },
- { { { 26, 0, 3 }, { 20, 31, 1 } } },
- { { { 26, 0, 2 }, { 20, 31, 2 } } },
- { { { 26, 0, 1 }, { 21, 31, 1 } } },
- { { { 26, 0, 0 }, { 21, 31, 0 } } },
- { { { 26, 0, 1 }, { 21, 31, 1 } } },
- { { { 26, 0, 2 }, { 21, 31, 2 } } },
- { { { 26, 0, 3 }, { 22, 31, 1 } } },
- { { { 26, 0, 4 }, { 22, 31, 0 } } },
- { { { 27, 0, 3 }, { 22, 31, 1 } } },
- { { { 27, 0, 2 }, { 22, 31, 2 } } },
- { { { 27, 0, 1 }, { 23, 31, 1 } } },
- { { { 27, 0, 0 }, { 23, 31, 0 } } },
- { { { 27, 0, 1 }, { 23, 31, 1 } } },
- { { { 27, 0, 2 }, { 23, 31, 2 } } },
- { { { 27, 0, 3 }, { 24, 31, 1 } } },
- { { { 27, 0, 4 }, { 24, 31, 0 } } },
- { { { 28, 0, 4 }, { 24, 31, 1 } } },
- { { { 28, 0, 3 }, { 24, 31, 2 } } },
- { { { 28, 0, 2 }, { 25, 31, 1 } } },
- { { { 28, 0, 1 }, { 25, 31, 0 } } },
- { { { 28, 0, 0 }, { 28, 28, 0 } } },
- { { { 28, 0, 1 }, { 28, 28, 1 } } },
- { { { 28, 0, 2 }, { 26, 31, 1 } } },
- { { { 28, 0, 3 }, { 26, 31, 0 } } },
- { { { 28, 0, 4 }, { 28, 29, 0 } } },
- { { { 29, 0, 3 }, { 28, 29, 1 } } },
- { { { 29, 0, 2 }, { 27, 31, 1 } } },
- { { { 29, 0, 1 }, { 27, 31, 0 } } },
- { { { 29, 0, 0 }, { 28, 30, 0 } } },
- { { { 29, 0, 1 }, { 28, 30, 1 } } },
- { { { 29, 0, 2 }, { 28, 30, 2 } } },
- { { { 29, 0, 3 }, { 28, 31, 1 } } },
- { { { 29, 0, 4 }, { 28, 31, 0 } } },
- { { { 30, 0, 3 }, { 28, 31, 1 } } },
- { { { 30, 0, 2 }, { 28, 31, 2 } } },
- { { { 30, 0, 1 }, { 29, 31, 1 } } },
- { { { 30, 0, 0 }, { 29, 31, 0 } } },
- { { { 30, 0, 1 }, { 29, 31, 1 } } },
- { { { 30, 0, 2 }, { 29, 31, 2 } } },
- { { { 30, 0, 3 }, { 30, 31, 1 } } },
- { { { 30, 0, 4 }, { 30, 31, 0 } } },
- { { { 31, 0, 3 }, { 30, 31, 1 } } },
- { { { 31, 0, 2 }, { 30, 31, 2 } } },
- { { { 31, 0, 1 }, { 31, 31, 1 } } },
- { { { 31, 0, 0 }, { 31, 31, 0 } } }
-};
-
-static SingleColourLookup const lookup_6_3[] =
-{
- { { { 0, 0, 0 }, { 0, 0, 0 } } },
- { { { 0, 0, 1 }, { 0, 1, 1 } } },
- { { { 0, 0, 2 }, { 0, 1, 0 } } },
- { { { 1, 0, 1 }, { 0, 2, 1 } } },
- { { { 1, 0, 0 }, { 0, 2, 0 } } },
- { { { 1, 0, 1 }, { 0, 3, 1 } } },
- { { { 1, 0, 2 }, { 0, 3, 0 } } },
- { { { 2, 0, 1 }, { 0, 4, 1 } } },
- { { { 2, 0, 0 }, { 0, 4, 0 } } },
- { { { 2, 0, 1 }, { 0, 5, 1 } } },
- { { { 2, 0, 2 }, { 0, 5, 0 } } },
- { { { 3, 0, 1 }, { 0, 6, 1 } } },
- { { { 3, 0, 0 }, { 0, 6, 0 } } },
- { { { 3, 0, 1 }, { 0, 7, 1 } } },
- { { { 3, 0, 2 }, { 0, 7, 0 } } },
- { { { 4, 0, 1 }, { 0, 8, 1 } } },
- { { { 4, 0, 0 }, { 0, 8, 0 } } },
- { { { 4, 0, 1 }, { 0, 9, 1 } } },
- { { { 4, 0, 2 }, { 0, 9, 0 } } },
- { { { 5, 0, 1 }, { 0, 10, 1 } } },
- { { { 5, 0, 0 }, { 0, 10, 0 } } },
- { { { 5, 0, 1 }, { 0, 11, 1 } } },
- { { { 5, 0, 2 }, { 0, 11, 0 } } },
- { { { 6, 0, 1 }, { 0, 12, 1 } } },
- { { { 6, 0, 0 }, { 0, 12, 0 } } },
- { { { 6, 0, 1 }, { 0, 13, 1 } } },
- { { { 6, 0, 2 }, { 0, 13, 0 } } },
- { { { 7, 0, 1 }, { 0, 14, 1 } } },
- { { { 7, 0, 0 }, { 0, 14, 0 } } },
- { { { 7, 0, 1 }, { 0, 15, 1 } } },
- { { { 7, 0, 2 }, { 0, 15, 0 } } },
- { { { 8, 0, 1 }, { 0, 16, 1 } } },
- { { { 8, 0, 0 }, { 0, 16, 0 } } },
- { { { 8, 0, 1 }, { 0, 17, 1 } } },
- { { { 8, 0, 2 }, { 0, 17, 0 } } },
- { { { 9, 0, 1 }, { 0, 18, 1 } } },
- { { { 9, 0, 0 }, { 0, 18, 0 } } },
- { { { 9, 0, 1 }, { 0, 19, 1 } } },
- { { { 9, 0, 2 }, { 0, 19, 0 } } },
- { { { 10, 0, 1 }, { 0, 20, 1 } } },
- { { { 10, 0, 0 }, { 0, 20, 0 } } },
- { { { 10, 0, 1 }, { 0, 21, 1 } } },
- { { { 10, 0, 2 }, { 0, 21, 0 } } },
- { { { 11, 0, 1 }, { 0, 22, 1 } } },
- { { { 11, 0, 0 }, { 0, 22, 0 } } },
- { { { 11, 0, 1 }, { 0, 23, 1 } } },
- { { { 11, 0, 2 }, { 0, 23, 0 } } },
- { { { 12, 0, 1 }, { 0, 24, 1 } } },
- { { { 12, 0, 0 }, { 0, 24, 0 } } },
- { { { 12, 0, 1 }, { 0, 25, 1 } } },
- { { { 12, 0, 2 }, { 0, 25, 0 } } },
- { { { 13, 0, 1 }, { 0, 26, 1 } } },
- { { { 13, 0, 0 }, { 0, 26, 0 } } },
- { { { 13, 0, 1 }, { 0, 27, 1 } } },
- { { { 13, 0, 2 }, { 0, 27, 0 } } },
- { { { 14, 0, 1 }, { 0, 28, 1 } } },
- { { { 14, 0, 0 }, { 0, 28, 0 } } },
- { { { 14, 0, 1 }, { 0, 29, 1 } } },
- { { { 14, 0, 2 }, { 0, 29, 0 } } },
- { { { 15, 0, 1 }, { 0, 30, 1 } } },
- { { { 15, 0, 0 }, { 0, 30, 0 } } },
- { { { 15, 0, 1 }, { 0, 31, 1 } } },
- { { { 15, 0, 2 }, { 0, 31, 0 } } },
- { { { 16, 0, 2 }, { 1, 31, 1 } } },
- { { { 16, 0, 1 }, { 1, 31, 0 } } },
- { { { 16, 0, 0 }, { 0, 32, 0 } } },
- { { { 16, 0, 1 }, { 2, 31, 0 } } },
- { { { 16, 0, 2 }, { 0, 33, 0 } } },
- { { { 17, 0, 1 }, { 3, 31, 0 } } },
- { { { 17, 0, 0 }, { 0, 34, 0 } } },
- { { { 17, 0, 1 }, { 4, 31, 0 } } },
- { { { 17, 0, 2 }, { 0, 35, 0 } } },
- { { { 18, 0, 1 }, { 5, 31, 0 } } },
- { { { 18, 0, 0 }, { 0, 36, 0 } } },
- { { { 18, 0, 1 }, { 6, 31, 0 } } },
- { { { 18, 0, 2 }, { 0, 37, 0 } } },
- { { { 19, 0, 1 }, { 7, 31, 0 } } },
- { { { 19, 0, 0 }, { 0, 38, 0 } } },
- { { { 19, 0, 1 }, { 8, 31, 0 } } },
- { { { 19, 0, 2 }, { 0, 39, 0 } } },
- { { { 20, 0, 1 }, { 9, 31, 0 } } },
- { { { 20, 0, 0 }, { 0, 40, 0 } } },
- { { { 20, 0, 1 }, { 10, 31, 0 } } },
- { { { 20, 0, 2 }, { 0, 41, 0 } } },
- { { { 21, 0, 1 }, { 11, 31, 0 } } },
- { { { 21, 0, 0 }, { 0, 42, 0 } } },
- { { { 21, 0, 1 }, { 12, 31, 0 } } },
- { { { 21, 0, 2 }, { 0, 43, 0 } } },
- { { { 22, 0, 1 }, { 13, 31, 0 } } },
- { { { 22, 0, 0 }, { 0, 44, 0 } } },
- { { { 22, 0, 1 }, { 14, 31, 0 } } },
- { { { 22, 0, 2 }, { 0, 45, 0 } } },
- { { { 23, 0, 1 }, { 15, 31, 0 } } },
- { { { 23, 0, 0 }, { 0, 46, 0 } } },
- { { { 23, 0, 1 }, { 0, 47, 1 } } },
- { { { 23, 0, 2 }, { 0, 47, 0 } } },
- { { { 24, 0, 1 }, { 0, 48, 1 } } },
- { { { 24, 0, 0 }, { 0, 48, 0 } } },
- { { { 24, 0, 1 }, { 0, 49, 1 } } },
- { { { 24, 0, 2 }, { 0, 49, 0 } } },
- { { { 25, 0, 1 }, { 0, 50, 1 } } },
- { { { 25, 0, 0 }, { 0, 50, 0 } } },
- { { { 25, 0, 1 }, { 0, 51, 1 } } },
- { { { 25, 0, 2 }, { 0, 51, 0 } } },
- { { { 26, 0, 1 }, { 0, 52, 1 } } },
- { { { 26, 0, 0 }, { 0, 52, 0 } } },
- { { { 26, 0, 1 }, { 0, 53, 1 } } },
- { { { 26, 0, 2 }, { 0, 53, 0 } } },
- { { { 27, 0, 1 }, { 0, 54, 1 } } },
- { { { 27, 0, 0 }, { 0, 54, 0 } } },
- { { { 27, 0, 1 }, { 0, 55, 1 } } },
- { { { 27, 0, 2 }, { 0, 55, 0 } } },
- { { { 28, 0, 1 }, { 0, 56, 1 } } },
- { { { 28, 0, 0 }, { 0, 56, 0 } } },
- { { { 28, 0, 1 }, { 0, 57, 1 } } },
- { { { 28, 0, 2 }, { 0, 57, 0 } } },
- { { { 29, 0, 1 }, { 0, 58, 1 } } },
- { { { 29, 0, 0 }, { 0, 58, 0 } } },
- { { { 29, 0, 1 }, { 0, 59, 1 } } },
- { { { 29, 0, 2 }, { 0, 59, 0 } } },
- { { { 30, 0, 1 }, { 0, 60, 1 } } },
- { { { 30, 0, 0 }, { 0, 60, 0 } } },
- { { { 30, 0, 1 }, { 0, 61, 1 } } },
- { { { 30, 0, 2 }, { 0, 61, 0 } } },
- { { { 31, 0, 1 }, { 0, 62, 1 } } },
- { { { 31, 0, 0 }, { 0, 62, 0 } } },
- { { { 31, 0, 1 }, { 0, 63, 1 } } },
- { { { 31, 0, 2 }, { 0, 63, 0 } } },
- { { { 32, 0, 2 }, { 1, 63, 1 } } },
- { { { 32, 0, 1 }, { 1, 63, 0 } } },
- { { { 32, 0, 0 }, { 16, 48, 0 } } },
- { { { 32, 0, 1 }, { 2, 63, 0 } } },
- { { { 32, 0, 2 }, { 16, 49, 0 } } },
- { { { 33, 0, 1 }, { 3, 63, 0 } } },
- { { { 33, 0, 0 }, { 16, 50, 0 } } },
- { { { 33, 0, 1 }, { 4, 63, 0 } } },
- { { { 33, 0, 2 }, { 16, 51, 0 } } },
- { { { 34, 0, 1 }, { 5, 63, 0 } } },
- { { { 34, 0, 0 }, { 16, 52, 0 } } },
- { { { 34, 0, 1 }, { 6, 63, 0 } } },
- { { { 34, 0, 2 }, { 16, 53, 0 } } },
- { { { 35, 0, 1 }, { 7, 63, 0 } } },
- { { { 35, 0, 0 }, { 16, 54, 0 } } },
- { { { 35, 0, 1 }, { 8, 63, 0 } } },
- { { { 35, 0, 2 }, { 16, 55, 0 } } },
- { { { 36, 0, 1 }, { 9, 63, 0 } } },
- { { { 36, 0, 0 }, { 16, 56, 0 } } },
- { { { 36, 0, 1 }, { 10, 63, 0 } } },
- { { { 36, 0, 2 }, { 16, 57, 0 } } },
- { { { 37, 0, 1 }, { 11, 63, 0 } } },
- { { { 37, 0, 0 }, { 16, 58, 0 } } },
- { { { 37, 0, 1 }, { 12, 63, 0 } } },
- { { { 37, 0, 2 }, { 16, 59, 0 } } },
- { { { 38, 0, 1 }, { 13, 63, 0 } } },
- { { { 38, 0, 0 }, { 16, 60, 0 } } },
- { { { 38, 0, 1 }, { 14, 63, 0 } } },
- { { { 38, 0, 2 }, { 16, 61, 0 } } },
- { { { 39, 0, 1 }, { 15, 63, 0 } } },
- { { { 39, 0, 0 }, { 16, 62, 0 } } },
- { { { 39, 0, 1 }, { 16, 63, 1 } } },
- { { { 39, 0, 2 }, { 16, 63, 0 } } },
- { { { 40, 0, 1 }, { 17, 63, 1 } } },
- { { { 40, 0, 0 }, { 17, 63, 0 } } },
- { { { 40, 0, 1 }, { 18, 63, 1 } } },
- { { { 40, 0, 2 }, { 18, 63, 0 } } },
- { { { 41, 0, 1 }, { 19, 63, 1 } } },
- { { { 41, 0, 0 }, { 19, 63, 0 } } },
- { { { 41, 0, 1 }, { 20, 63, 1 } } },
- { { { 41, 0, 2 }, { 20, 63, 0 } } },
- { { { 42, 0, 1 }, { 21, 63, 1 } } },
- { { { 42, 0, 0 }, { 21, 63, 0 } } },
- { { { 42, 0, 1 }, { 22, 63, 1 } } },
- { { { 42, 0, 2 }, { 22, 63, 0 } } },
- { { { 43, 0, 1 }, { 23, 63, 1 } } },
- { { { 43, 0, 0 }, { 23, 63, 0 } } },
- { { { 43, 0, 1 }, { 24, 63, 1 } } },
- { { { 43, 0, 2 }, { 24, 63, 0 } } },
- { { { 44, 0, 1 }, { 25, 63, 1 } } },
- { { { 44, 0, 0 }, { 25, 63, 0 } } },
- { { { 44, 0, 1 }, { 26, 63, 1 } } },
- { { { 44, 0, 2 }, { 26, 63, 0 } } },
- { { { 45, 0, 1 }, { 27, 63, 1 } } },
- { { { 45, 0, 0 }, { 27, 63, 0 } } },
- { { { 45, 0, 1 }, { 28, 63, 1 } } },
- { { { 45, 0, 2 }, { 28, 63, 0 } } },
- { { { 46, 0, 1 }, { 29, 63, 1 } } },
- { { { 46, 0, 0 }, { 29, 63, 0 } } },
- { { { 46, 0, 1 }, { 30, 63, 1 } } },
- { { { 46, 0, 2 }, { 30, 63, 0 } } },
- { { { 47, 0, 1 }, { 31, 63, 1 } } },
- { { { 47, 0, 0 }, { 31, 63, 0 } } },
- { { { 47, 0, 1 }, { 32, 63, 1 } } },
- { { { 47, 0, 2 }, { 32, 63, 0 } } },
- { { { 48, 0, 2 }, { 33, 63, 1 } } },
- { { { 48, 0, 1 }, { 33, 63, 0 } } },
- { { { 48, 0, 0 }, { 48, 48, 0 } } },
- { { { 48, 0, 1 }, { 34, 63, 0 } } },
- { { { 48, 0, 2 }, { 48, 49, 0 } } },
- { { { 49, 0, 1 }, { 35, 63, 0 } } },
- { { { 49, 0, 0 }, { 48, 50, 0 } } },
- { { { 49, 0, 1 }, { 36, 63, 0 } } },
- { { { 49, 0, 2 }, { 48, 51, 0 } } },
- { { { 50, 0, 1 }, { 37, 63, 0 } } },
- { { { 50, 0, 0 }, { 48, 52, 0 } } },
- { { { 50, 0, 1 }, { 38, 63, 0 } } },
- { { { 50, 0, 2 }, { 48, 53, 0 } } },
- { { { 51, 0, 1 }, { 39, 63, 0 } } },
- { { { 51, 0, 0 }, { 48, 54, 0 } } },
- { { { 51, 0, 1 }, { 40, 63, 0 } } },
- { { { 51, 0, 2 }, { 48, 55, 0 } } },
- { { { 52, 0, 1 }, { 41, 63, 0 } } },
- { { { 52, 0, 0 }, { 48, 56, 0 } } },
- { { { 52, 0, 1 }, { 42, 63, 0 } } },
- { { { 52, 0, 2 }, { 48, 57, 0 } } },
- { { { 53, 0, 1 }, { 43, 63, 0 } } },
- { { { 53, 0, 0 }, { 48, 58, 0 } } },
- { { { 53, 0, 1 }, { 44, 63, 0 } } },
- { { { 53, 0, 2 }, { 48, 59, 0 } } },
- { { { 54, 0, 1 }, { 45, 63, 0 } } },
- { { { 54, 0, 0 }, { 48, 60, 0 } } },
- { { { 54, 0, 1 }, { 46, 63, 0 } } },
- { { { 54, 0, 2 }, { 48, 61, 0 } } },
- { { { 55, 0, 1 }, { 47, 63, 0 } } },
- { { { 55, 0, 0 }, { 48, 62, 0 } } },
- { { { 55, 0, 1 }, { 48, 63, 1 } } },
- { { { 55, 0, 2 }, { 48, 63, 0 } } },
- { { { 56, 0, 1 }, { 49, 63, 1 } } },
- { { { 56, 0, 0 }, { 49, 63, 0 } } },
- { { { 56, 0, 1 }, { 50, 63, 1 } } },
- { { { 56, 0, 2 }, { 50, 63, 0 } } },
- { { { 57, 0, 1 }, { 51, 63, 1 } } },
- { { { 57, 0, 0 }, { 51, 63, 0 } } },
- { { { 57, 0, 1 }, { 52, 63, 1 } } },
- { { { 57, 0, 2 }, { 52, 63, 0 } } },
- { { { 58, 0, 1 }, { 53, 63, 1 } } },
- { { { 58, 0, 0 }, { 53, 63, 0 } } },
- { { { 58, 0, 1 }, { 54, 63, 1 } } },
- { { { 58, 0, 2 }, { 54, 63, 0 } } },
- { { { 59, 0, 1 }, { 55, 63, 1 } } },
- { { { 59, 0, 0 }, { 55, 63, 0 } } },
- { { { 59, 0, 1 }, { 56, 63, 1 } } },
- { { { 59, 0, 2 }, { 56, 63, 0 } } },
- { { { 60, 0, 1 }, { 57, 63, 1 } } },
- { { { 60, 0, 0 }, { 57, 63, 0 } } },
- { { { 60, 0, 1 }, { 58, 63, 1 } } },
- { { { 60, 0, 2 }, { 58, 63, 0 } } },
- { { { 61, 0, 1 }, { 59, 63, 1 } } },
- { { { 61, 0, 0 }, { 59, 63, 0 } } },
- { { { 61, 0, 1 }, { 60, 63, 1 } } },
- { { { 61, 0, 2 }, { 60, 63, 0 } } },
- { { { 62, 0, 1 }, { 61, 63, 1 } } },
- { { { 62, 0, 0 }, { 61, 63, 0 } } },
- { { { 62, 0, 1 }, { 62, 63, 1 } } },
- { { { 62, 0, 2 }, { 62, 63, 0 } } },
- { { { 63, 0, 1 }, { 63, 63, 1 } } },
- { { { 63, 0, 0 }, { 63, 63, 0 } } }
-};
-
-static SingleColourLookup const lookup_5_4[] =
-{
- { { { 0, 0, 0 }, { 0, 0, 0 } } },
- { { { 0, 0, 1 }, { 0, 1, 1 } } },
- { { { 0, 0, 2 }, { 0, 1, 0 } } },
- { { { 0, 0, 3 }, { 0, 1, 1 } } },
- { { { 0, 0, 4 }, { 0, 2, 1 } } },
- { { { 1, 0, 3 }, { 0, 2, 0 } } },
- { { { 1, 0, 2 }, { 0, 2, 1 } } },
- { { { 1, 0, 1 }, { 0, 3, 1 } } },
- { { { 1, 0, 0 }, { 0, 3, 0 } } },
- { { { 1, 0, 1 }, { 1, 2, 1 } } },
- { { { 1, 0, 2 }, { 1, 2, 0 } } },
- { { { 1, 0, 3 }, { 0, 4, 0 } } },
- { { { 1, 0, 4 }, { 0, 5, 1 } } },
- { { { 2, 0, 3 }, { 0, 5, 0 } } },
- { { { 2, 0, 2 }, { 0, 5, 1 } } },
- { { { 2, 0, 1 }, { 0, 6, 1 } } },
- { { { 2, 0, 0 }, { 0, 6, 0 } } },
- { { { 2, 0, 1 }, { 2, 3, 1 } } },
- { { { 2, 0, 2 }, { 2, 3, 0 } } },
- { { { 2, 0, 3 }, { 0, 7, 0 } } },
- { { { 2, 0, 4 }, { 1, 6, 1 } } },
- { { { 3, 0, 3 }, { 1, 6, 0 } } },
- { { { 3, 0, 2 }, { 0, 8, 0 } } },
- { { { 3, 0, 1 }, { 0, 9, 1 } } },
- { { { 3, 0, 0 }, { 0, 9, 0 } } },
- { { { 3, 0, 1 }, { 0, 9, 1 } } },
- { { { 3, 0, 2 }, { 0, 10, 1 } } },
- { { { 3, 0, 3 }, { 0, 10, 0 } } },
- { { { 3, 0, 4 }, { 2, 7, 1 } } },
- { { { 4, 0, 4 }, { 2, 7, 0 } } },
- { { { 4, 0, 3 }, { 0, 11, 0 } } },
- { { { 4, 0, 2 }, { 1, 10, 1 } } },
- { { { 4, 0, 1 }, { 1, 10, 0 } } },
- { { { 4, 0, 0 }, { 0, 12, 0 } } },
- { { { 4, 0, 1 }, { 0, 13, 1 } } },
- { { { 4, 0, 2 }, { 0, 13, 0 } } },
- { { { 4, 0, 3 }, { 0, 13, 1 } } },
- { { { 4, 0, 4 }, { 0, 14, 1 } } },
- { { { 5, 0, 3 }, { 0, 14, 0 } } },
- { { { 5, 0, 2 }, { 2, 11, 1 } } },
- { { { 5, 0, 1 }, { 2, 11, 0 } } },
- { { { 5, 0, 0 }, { 0, 15, 0 } } },
- { { { 5, 0, 1 }, { 1, 14, 1 } } },
- { { { 5, 0, 2 }, { 1, 14, 0 } } },
- { { { 5, 0, 3 }, { 0, 16, 0 } } },
- { { { 5, 0, 4 }, { 0, 17, 1 } } },
- { { { 6, 0, 3 }, { 0, 17, 0 } } },
- { { { 6, 0, 2 }, { 0, 17, 1 } } },
- { { { 6, 0, 1 }, { 0, 18, 1 } } },
- { { { 6, 0, 0 }, { 0, 18, 0 } } },
- { { { 6, 0, 1 }, { 2, 15, 1 } } },
- { { { 6, 0, 2 }, { 2, 15, 0 } } },
- { { { 6, 0, 3 }, { 0, 19, 0 } } },
- { { { 6, 0, 4 }, { 1, 18, 1 } } },
- { { { 7, 0, 3 }, { 1, 18, 0 } } },
- { { { 7, 0, 2 }, { 0, 20, 0 } } },
- { { { 7, 0, 1 }, { 0, 21, 1 } } },
- { { { 7, 0, 0 }, { 0, 21, 0 } } },
- { { { 7, 0, 1 }, { 0, 21, 1 } } },
- { { { 7, 0, 2 }, { 0, 22, 1 } } },
- { { { 7, 0, 3 }, { 0, 22, 0 } } },
- { { { 7, 0, 4 }, { 2, 19, 1 } } },
- { { { 8, 0, 4 }, { 2, 19, 0 } } },
- { { { 8, 0, 3 }, { 0, 23, 0 } } },
- { { { 8, 0, 2 }, { 1, 22, 1 } } },
- { { { 8, 0, 1 }, { 1, 22, 0 } } },
- { { { 8, 0, 0 }, { 0, 24, 0 } } },
- { { { 8, 0, 1 }, { 0, 25, 1 } } },
- { { { 8, 0, 2 }, { 0, 25, 0 } } },
- { { { 8, 0, 3 }, { 0, 25, 1 } } },
- { { { 8, 0, 4 }, { 0, 26, 1 } } },
- { { { 9, 0, 3 }, { 0, 26, 0 } } },
- { { { 9, 0, 2 }, { 2, 23, 1 } } },
- { { { 9, 0, 1 }, { 2, 23, 0 } } },
- { { { 9, 0, 0 }, { 0, 27, 0 } } },
- { { { 9, 0, 1 }, { 1, 26, 1 } } },
- { { { 9, 0, 2 }, { 1, 26, 0 } } },
- { { { 9, 0, 3 }, { 0, 28, 0 } } },
- { { { 9, 0, 4 }, { 0, 29, 1 } } },
- { { { 10, 0, 3 }, { 0, 29, 0 } } },
- { { { 10, 0, 2 }, { 0, 29, 1 } } },
- { { { 10, 0, 1 }, { 0, 30, 1 } } },
- { { { 10, 0, 0 }, { 0, 30, 0 } } },
- { { { 10, 0, 1 }, { 2, 27, 1 } } },
- { { { 10, 0, 2 }, { 2, 27, 0 } } },
- { { { 10, 0, 3 }, { 0, 31, 0 } } },
- { { { 10, 0, 4 }, { 1, 30, 1 } } },
- { { { 11, 0, 3 }, { 1, 30, 0 } } },
- { { { 11, 0, 2 }, { 4, 24, 0 } } },
- { { { 11, 0, 1 }, { 1, 31, 1 } } },
- { { { 11, 0, 0 }, { 1, 31, 0 } } },
- { { { 11, 0, 1 }, { 1, 31, 1 } } },
- { { { 11, 0, 2 }, { 2, 30, 1 } } },
- { { { 11, 0, 3 }, { 2, 30, 0 } } },
- { { { 11, 0, 4 }, { 2, 31, 1 } } },
- { { { 12, 0, 4 }, { 2, 31, 0 } } },
- { { { 12, 0, 3 }, { 4, 27, 0 } } },
- { { { 12, 0, 2 }, { 3, 30, 1 } } },
- { { { 12, 0, 1 }, { 3, 30, 0 } } },
- { { { 12, 0, 0 }, { 4, 28, 0 } } },
- { { { 12, 0, 1 }, { 3, 31, 1 } } },
- { { { 12, 0, 2 }, { 3, 31, 0 } } },
- { { { 12, 0, 3 }, { 3, 31, 1 } } },
- { { { 12, 0, 4 }, { 4, 30, 1 } } },
- { { { 13, 0, 3 }, { 4, 30, 0 } } },
- { { { 13, 0, 2 }, { 6, 27, 1 } } },
- { { { 13, 0, 1 }, { 6, 27, 0 } } },
- { { { 13, 0, 0 }, { 4, 31, 0 } } },
- { { { 13, 0, 1 }, { 5, 30, 1 } } },
- { { { 13, 0, 2 }, { 5, 30, 0 } } },
- { { { 13, 0, 3 }, { 8, 24, 0 } } },
- { { { 13, 0, 4 }, { 5, 31, 1 } } },
- { { { 14, 0, 3 }, { 5, 31, 0 } } },
- { { { 14, 0, 2 }, { 5, 31, 1 } } },
- { { { 14, 0, 1 }, { 6, 30, 1 } } },
- { { { 14, 0, 0 }, { 6, 30, 0 } } },
- { { { 14, 0, 1 }, { 6, 31, 1 } } },
- { { { 14, 0, 2 }, { 6, 31, 0 } } },
- { { { 14, 0, 3 }, { 8, 27, 0 } } },
- { { { 14, 0, 4 }, { 7, 30, 1 } } },
- { { { 15, 0, 3 }, { 7, 30, 0 } } },
- { { { 15, 0, 2 }, { 8, 28, 0 } } },
- { { { 15, 0, 1 }, { 7, 31, 1 } } },
- { { { 15, 0, 0 }, { 7, 31, 0 } } },
- { { { 15, 0, 1 }, { 7, 31, 1 } } },
- { { { 15, 0, 2 }, { 8, 30, 1 } } },
- { { { 15, 0, 3 }, { 8, 30, 0 } } },
- { { { 15, 0, 4 }, { 10, 27, 1 } } },
- { { { 16, 0, 4 }, { 10, 27, 0 } } },
- { { { 16, 0, 3 }, { 8, 31, 0 } } },
- { { { 16, 0, 2 }, { 9, 30, 1 } } },
- { { { 16, 0, 1 }, { 9, 30, 0 } } },
- { { { 16, 0, 0 }, { 12, 24, 0 } } },
- { { { 16, 0, 1 }, { 9, 31, 1 } } },
- { { { 16, 0, 2 }, { 9, 31, 0 } } },
- { { { 16, 0, 3 }, { 9, 31, 1 } } },
- { { { 16, 0, 4 }, { 10, 30, 1 } } },
- { { { 17, 0, 3 }, { 10, 30, 0 } } },
- { { { 17, 0, 2 }, { 10, 31, 1 } } },
- { { { 17, 0, 1 }, { 10, 31, 0 } } },
- { { { 17, 0, 0 }, { 12, 27, 0 } } },
- { { { 17, 0, 1 }, { 11, 30, 1 } } },
- { { { 17, 0, 2 }, { 11, 30, 0 } } },
- { { { 17, 0, 3 }, { 12, 28, 0 } } },
- { { { 17, 0, 4 }, { 11, 31, 1 } } },
- { { { 18, 0, 3 }, { 11, 31, 0 } } },
- { { { 18, 0, 2 }, { 11, 31, 1 } } },
- { { { 18, 0, 1 }, { 12, 30, 1 } } },
- { { { 18, 0, 0 }, { 12, 30, 0 } } },
- { { { 18, 0, 1 }, { 14, 27, 1 } } },
- { { { 18, 0, 2 }, { 14, 27, 0 } } },
- { { { 18, 0, 3 }, { 12, 31, 0 } } },
- { { { 18, 0, 4 }, { 13, 30, 1 } } },
- { { { 19, 0, 3 }, { 13, 30, 0 } } },
- { { { 19, 0, 2 }, { 16, 24, 0 } } },
- { { { 19, 0, 1 }, { 13, 31, 1 } } },
- { { { 19, 0, 0 }, { 13, 31, 0 } } },
- { { { 19, 0, 1 }, { 13, 31, 1 } } },
- { { { 19, 0, 2 }, { 14, 30, 1 } } },
- { { { 19, 0, 3 }, { 14, 30, 0 } } },
- { { { 19, 0, 4 }, { 14, 31, 1 } } },
- { { { 20, 0, 4 }, { 14, 31, 0 } } },
- { { { 20, 0, 3 }, { 16, 27, 0 } } },
- { { { 20, 0, 2 }, { 15, 30, 1 } } },
- { { { 20, 0, 1 }, { 15, 30, 0 } } },
- { { { 20, 0, 0 }, { 16, 28, 0 } } },
- { { { 20, 0, 1 }, { 15, 31, 1 } } },
- { { { 20, 0, 2 }, { 15, 31, 0 } } },
- { { { 20, 0, 3 }, { 15, 31, 1 } } },
- { { { 20, 0, 4 }, { 16, 30, 1 } } },
- { { { 21, 0, 3 }, { 16, 30, 0 } } },
- { { { 21, 0, 2 }, { 18, 27, 1 } } },
- { { { 21, 0, 1 }, { 18, 27, 0 } } },
- { { { 21, 0, 0 }, { 16, 31, 0 } } },
- { { { 21, 0, 1 }, { 17, 30, 1 } } },
- { { { 21, 0, 2 }, { 17, 30, 0 } } },
- { { { 21, 0, 3 }, { 20, 24, 0 } } },
- { { { 21, 0, 4 }, { 17, 31, 1 } } },
- { { { 22, 0, 3 }, { 17, 31, 0 } } },
- { { { 22, 0, 2 }, { 17, 31, 1 } } },
- { { { 22, 0, 1 }, { 18, 30, 1 } } },
- { { { 22, 0, 0 }, { 18, 30, 0 } } },
- { { { 22, 0, 1 }, { 18, 31, 1 } } },
- { { { 22, 0, 2 }, { 18, 31, 0 } } },
- { { { 22, 0, 3 }, { 20, 27, 0 } } },
- { { { 22, 0, 4 }, { 19, 30, 1 } } },
- { { { 23, 0, 3 }, { 19, 30, 0 } } },
- { { { 23, 0, 2 }, { 20, 28, 0 } } },
- { { { 23, 0, 1 }, { 19, 31, 1 } } },
- { { { 23, 0, 0 }, { 19, 31, 0 } } },
- { { { 23, 0, 1 }, { 19, 31, 1 } } },
- { { { 23, 0, 2 }, { 20, 30, 1 } } },
- { { { 23, 0, 3 }, { 20, 30, 0 } } },
- { { { 23, 0, 4 }, { 22, 27, 1 } } },
- { { { 24, 0, 4 }, { 22, 27, 0 } } },
- { { { 24, 0, 3 }, { 20, 31, 0 } } },
- { { { 24, 0, 2 }, { 21, 30, 1 } } },
- { { { 24, 0, 1 }, { 21, 30, 0 } } },
- { { { 24, 0, 0 }, { 24, 24, 0 } } },
- { { { 24, 0, 1 }, { 21, 31, 1 } } },
- { { { 24, 0, 2 }, { 21, 31, 0 } } },
- { { { 24, 0, 3 }, { 21, 31, 1 } } },
- { { { 24, 0, 4 }, { 22, 30, 1 } } },
- { { { 25, 0, 3 }, { 22, 30, 0 } } },
- { { { 25, 0, 2 }, { 22, 31, 1 } } },
- { { { 25, 0, 1 }, { 22, 31, 0 } } },
- { { { 25, 0, 0 }, { 24, 27, 0 } } },
- { { { 25, 0, 1 }, { 23, 30, 1 } } },
- { { { 25, 0, 2 }, { 23, 30, 0 } } },
- { { { 25, 0, 3 }, { 24, 28, 0 } } },
- { { { 25, 0, 4 }, { 23, 31, 1 } } },
- { { { 26, 0, 3 }, { 23, 31, 0 } } },
- { { { 26, 0, 2 }, { 23, 31, 1 } } },
- { { { 26, 0, 1 }, { 24, 30, 1 } } },
- { { { 26, 0, 0 }, { 24, 30, 0 } } },
- { { { 26, 0, 1 }, { 26, 27, 1 } } },
- { { { 26, 0, 2 }, { 26, 27, 0 } } },
- { { { 26, 0, 3 }, { 24, 31, 0 } } },
- { { { 26, 0, 4 }, { 25, 30, 1 } } },
- { { { 27, 0, 3 }, { 25, 30, 0 } } },
- { { { 27, 0, 2 }, { 28, 24, 0 } } },
- { { { 27, 0, 1 }, { 25, 31, 1 } } },
- { { { 27, 0, 0 }, { 25, 31, 0 } } },
- { { { 27, 0, 1 }, { 25, 31, 1 } } },
- { { { 27, 0, 2 }, { 26, 30, 1 } } },
- { { { 27, 0, 3 }, { 26, 30, 0 } } },
- { { { 27, 0, 4 }, { 26, 31, 1 } } },
- { { { 28, 0, 4 }, { 26, 31, 0 } } },
- { { { 28, 0, 3 }, { 28, 27, 0 } } },
- { { { 28, 0, 2 }, { 27, 30, 1 } } },
- { { { 28, 0, 1 }, { 27, 30, 0 } } },
- { { { 28, 0, 0 }, { 28, 28, 0 } } },
- { { { 28, 0, 1 }, { 27, 31, 1 } } },
- { { { 28, 0, 2 }, { 27, 31, 0 } } },
- { { { 28, 0, 3 }, { 27, 31, 1 } } },
- { { { 28, 0, 4 }, { 28, 30, 1 } } },
- { { { 29, 0, 3 }, { 28, 30, 0 } } },
- { { { 29, 0, 2 }, { 30, 27, 1 } } },
- { { { 29, 0, 1 }, { 30, 27, 0 } } },
- { { { 29, 0, 0 }, { 28, 31, 0 } } },
- { { { 29, 0, 1 }, { 29, 30, 1 } } },
- { { { 29, 0, 2 }, { 29, 30, 0 } } },
- { { { 29, 0, 3 }, { 29, 30, 1 } } },
- { { { 29, 0, 4 }, { 29, 31, 1 } } },
- { { { 30, 0, 3 }, { 29, 31, 0 } } },
- { { { 30, 0, 2 }, { 29, 31, 1 } } },
- { { { 30, 0, 1 }, { 30, 30, 1 } } },
- { { { 30, 0, 0 }, { 30, 30, 0 } } },
- { { { 30, 0, 1 }, { 30, 31, 1 } } },
- { { { 30, 0, 2 }, { 30, 31, 0 } } },
- { { { 30, 0, 3 }, { 30, 31, 1 } } },
- { { { 30, 0, 4 }, { 31, 30, 1 } } },
- { { { 31, 0, 3 }, { 31, 30, 0 } } },
- { { { 31, 0, 2 }, { 31, 30, 1 } } },
- { { { 31, 0, 1 }, { 31, 31, 1 } } },
- { { { 31, 0, 0 }, { 31, 31, 0 } } }
-};
-
-static SingleColourLookup const lookup_6_4[] =
-{
- { { { 0, 0, 0 }, { 0, 0, 0 } } },
- { { { 0, 0, 1 }, { 0, 1, 0 } } },
- { { { 0, 0, 2 }, { 0, 2, 0 } } },
- { { { 1, 0, 1 }, { 0, 3, 1 } } },
- { { { 1, 0, 0 }, { 0, 3, 0 } } },
- { { { 1, 0, 1 }, { 0, 4, 0 } } },
- { { { 1, 0, 2 }, { 0, 5, 0 } } },
- { { { 2, 0, 1 }, { 0, 6, 1 } } },
- { { { 2, 0, 0 }, { 0, 6, 0 } } },
- { { { 2, 0, 1 }, { 0, 7, 0 } } },
- { { { 2, 0, 2 }, { 0, 8, 0 } } },
- { { { 3, 0, 1 }, { 0, 9, 1 } } },
- { { { 3, 0, 0 }, { 0, 9, 0 } } },
- { { { 3, 0, 1 }, { 0, 10, 0 } } },
- { { { 3, 0, 2 }, { 0, 11, 0 } } },
- { { { 4, 0, 1 }, { 0, 12, 1 } } },
- { { { 4, 0, 0 }, { 0, 12, 0 } } },
- { { { 4, 0, 1 }, { 0, 13, 0 } } },
- { { { 4, 0, 2 }, { 0, 14, 0 } } },
- { { { 5, 0, 1 }, { 0, 15, 1 } } },
- { { { 5, 0, 0 }, { 0, 15, 0 } } },
- { { { 5, 0, 1 }, { 0, 16, 0 } } },
- { { { 5, 0, 2 }, { 1, 15, 0 } } },
- { { { 6, 0, 1 }, { 0, 17, 0 } } },
- { { { 6, 0, 0 }, { 0, 18, 0 } } },
- { { { 6, 0, 1 }, { 0, 19, 0 } } },
- { { { 6, 0, 2 }, { 3, 14, 0 } } },
- { { { 7, 0, 1 }, { 0, 20, 0 } } },
- { { { 7, 0, 0 }, { 0, 21, 0 } } },
- { { { 7, 0, 1 }, { 0, 22, 0 } } },
- { { { 7, 0, 2 }, { 4, 15, 0 } } },
- { { { 8, 0, 1 }, { 0, 23, 0 } } },
- { { { 8, 0, 0 }, { 0, 24, 0 } } },
- { { { 8, 0, 1 }, { 0, 25, 0 } } },
- { { { 8, 0, 2 }, { 6, 14, 0 } } },
- { { { 9, 0, 1 }, { 0, 26, 0 } } },
- { { { 9, 0, 0 }, { 0, 27, 0 } } },
- { { { 9, 0, 1 }, { 0, 28, 0 } } },
- { { { 9, 0, 2 }, { 7, 15, 0 } } },
- { { { 10, 0, 1 }, { 0, 29, 0 } } },
- { { { 10, 0, 0 }, { 0, 30, 0 } } },
- { { { 10, 0, 1 }, { 0, 31, 0 } } },
- { { { 10, 0, 2 }, { 9, 14, 0 } } },
- { { { 11, 0, 1 }, { 0, 32, 0 } } },
- { { { 11, 0, 0 }, { 0, 33, 0 } } },
- { { { 11, 0, 1 }, { 2, 30, 0 } } },
- { { { 11, 0, 2 }, { 0, 34, 0 } } },
- { { { 12, 0, 1 }, { 0, 35, 0 } } },
- { { { 12, 0, 0 }, { 0, 36, 0 } } },
- { { { 12, 0, 1 }, { 3, 31, 0 } } },
- { { { 12, 0, 2 }, { 0, 37, 0 } } },
- { { { 13, 0, 1 }, { 0, 38, 0 } } },
- { { { 13, 0, 0 }, { 0, 39, 0 } } },
- { { { 13, 0, 1 }, { 5, 30, 0 } } },
- { { { 13, 0, 2 }, { 0, 40, 0 } } },
- { { { 14, 0, 1 }, { 0, 41, 0 } } },
- { { { 14, 0, 0 }, { 0, 42, 0 } } },
- { { { 14, 0, 1 }, { 6, 31, 0 } } },
- { { { 14, 0, 2 }, { 0, 43, 0 } } },
- { { { 15, 0, 1 }, { 0, 44, 0 } } },
- { { { 15, 0, 0 }, { 0, 45, 0 } } },
- { { { 15, 0, 1 }, { 8, 30, 0 } } },
- { { { 15, 0, 2 }, { 0, 46, 0 } } },
- { { { 16, 0, 2 }, { 0, 47, 0 } } },
- { { { 16, 0, 1 }, { 1, 46, 0 } } },
- { { { 16, 0, 0 }, { 0, 48, 0 } } },
- { { { 16, 0, 1 }, { 0, 49, 0 } } },
- { { { 16, 0, 2 }, { 0, 50, 0 } } },
- { { { 17, 0, 1 }, { 2, 47, 0 } } },
- { { { 17, 0, 0 }, { 0, 51, 0 } } },
- { { { 17, 0, 1 }, { 0, 52, 0 } } },
- { { { 17, 0, 2 }, { 0, 53, 0 } } },
- { { { 18, 0, 1 }, { 4, 46, 0 } } },
- { { { 18, 0, 0 }, { 0, 54, 0 } } },
- { { { 18, 0, 1 }, { 0, 55, 0 } } },
- { { { 18, 0, 2 }, { 0, 56, 0 } } },
- { { { 19, 0, 1 }, { 5, 47, 0 } } },
- { { { 19, 0, 0 }, { 0, 57, 0 } } },
- { { { 19, 0, 1 }, { 0, 58, 0 } } },
- { { { 19, 0, 2 }, { 0, 59, 0 } } },
- { { { 20, 0, 1 }, { 7, 46, 0 } } },
- { { { 20, 0, 0 }, { 0, 60, 0 } } },
- { { { 20, 0, 1 }, { 0, 61, 0 } } },
- { { { 20, 0, 2 }, { 0, 62, 0 } } },
- { { { 21, 0, 1 }, { 8, 47, 0 } } },
- { { { 21, 0, 0 }, { 0, 63, 0 } } },
- { { { 21, 0, 1 }, { 1, 62, 0 } } },
- { { { 21, 0, 2 }, { 1, 63, 0 } } },
- { { { 22, 0, 1 }, { 10, 46, 0 } } },
- { { { 22, 0, 0 }, { 2, 62, 0 } } },
- { { { 22, 0, 1 }, { 2, 63, 0 } } },
- { { { 22, 0, 2 }, { 3, 62, 0 } } },
- { { { 23, 0, 1 }, { 11, 47, 0 } } },
- { { { 23, 0, 0 }, { 3, 63, 0 } } },
- { { { 23, 0, 1 }, { 4, 62, 0 } } },
- { { { 23, 0, 2 }, { 4, 63, 0 } } },
- { { { 24, 0, 1 }, { 13, 46, 0 } } },
- { { { 24, 0, 0 }, { 5, 62, 0 } } },
- { { { 24, 0, 1 }, { 5, 63, 0 } } },
- { { { 24, 0, 2 }, { 6, 62, 0 } } },
- { { { 25, 0, 1 }, { 14, 47, 0 } } },
- { { { 25, 0, 0 }, { 6, 63, 0 } } },
- { { { 25, 0, 1 }, { 7, 62, 0 } } },
- { { { 25, 0, 2 }, { 7, 63, 0 } } },
- { { { 26, 0, 1 }, { 16, 45, 0 } } },
- { { { 26, 0, 0 }, { 8, 62, 0 } } },
- { { { 26, 0, 1 }, { 8, 63, 0 } } },
- { { { 26, 0, 2 }, { 9, 62, 0 } } },
- { { { 27, 0, 1 }, { 16, 48, 0 } } },
- { { { 27, 0, 0 }, { 9, 63, 0 } } },
- { { { 27, 0, 1 }, { 10, 62, 0 } } },
- { { { 27, 0, 2 }, { 10, 63, 0 } } },
- { { { 28, 0, 1 }, { 16, 51, 0 } } },
- { { { 28, 0, 0 }, { 11, 62, 0 } } },
- { { { 28, 0, 1 }, { 11, 63, 0 } } },
- { { { 28, 0, 2 }, { 12, 62, 0 } } },
- { { { 29, 0, 1 }, { 16, 54, 0 } } },
- { { { 29, 0, 0 }, { 12, 63, 0 } } },
- { { { 29, 0, 1 }, { 13, 62, 0 } } },
- { { { 29, 0, 2 }, { 13, 63, 0 } } },
- { { { 30, 0, 1 }, { 16, 57, 0 } } },
- { { { 30, 0, 0 }, { 14, 62, 0 } } },
- { { { 30, 0, 1 }, { 14, 63, 0 } } },
- { { { 30, 0, 2 }, { 15, 62, 0 } } },
- { { { 31, 0, 1 }, { 16, 60, 0 } } },
- { { { 31, 0, 0 }, { 15, 63, 0 } } },
- { { { 31, 0, 1 }, { 24, 46, 0 } } },
- { { { 31, 0, 2 }, { 16, 62, 0 } } },
- { { { 32, 0, 2 }, { 16, 63, 0 } } },
- { { { 32, 0, 1 }, { 17, 62, 0 } } },
- { { { 32, 0, 0 }, { 25, 47, 0 } } },
- { { { 32, 0, 1 }, { 17, 63, 0 } } },
- { { { 32, 0, 2 }, { 18, 62, 0 } } },
- { { { 33, 0, 1 }, { 18, 63, 0 } } },
- { { { 33, 0, 0 }, { 27, 46, 0 } } },
- { { { 33, 0, 1 }, { 19, 62, 0 } } },
- { { { 33, 0, 2 }, { 19, 63, 0 } } },
- { { { 34, 0, 1 }, { 20, 62, 0 } } },
- { { { 34, 0, 0 }, { 28, 47, 0 } } },
- { { { 34, 0, 1 }, { 20, 63, 0 } } },
- { { { 34, 0, 2 }, { 21, 62, 0 } } },
- { { { 35, 0, 1 }, { 21, 63, 0 } } },
- { { { 35, 0, 0 }, { 30, 46, 0 } } },
- { { { 35, 0, 1 }, { 22, 62, 0 } } },
- { { { 35, 0, 2 }, { 22, 63, 0 } } },
- { { { 36, 0, 1 }, { 23, 62, 0 } } },
- { { { 36, 0, 0 }, { 31, 47, 0 } } },
- { { { 36, 0, 1 }, { 23, 63, 0 } } },
- { { { 36, 0, 2 }, { 24, 62, 0 } } },
- { { { 37, 0, 1 }, { 24, 63, 0 } } },
- { { { 37, 0, 0 }, { 32, 47, 0 } } },
- { { { 37, 0, 1 }, { 25, 62, 0 } } },
- { { { 37, 0, 2 }, { 25, 63, 0 } } },
- { { { 38, 0, 1 }, { 26, 62, 0 } } },
- { { { 38, 0, 0 }, { 32, 50, 0 } } },
- { { { 38, 0, 1 }, { 26, 63, 0 } } },
- { { { 38, 0, 2 }, { 27, 62, 0 } } },
- { { { 39, 0, 1 }, { 27, 63, 0 } } },
- { { { 39, 0, 0 }, { 32, 53, 0 } } },
- { { { 39, 0, 1 }, { 28, 62, 0 } } },
- { { { 39, 0, 2 }, { 28, 63, 0 } } },
- { { { 40, 0, 1 }, { 29, 62, 0 } } },
- { { { 40, 0, 0 }, { 32, 56, 0 } } },
- { { { 40, 0, 1 }, { 29, 63, 0 } } },
- { { { 40, 0, 2 }, { 30, 62, 0 } } },
- { { { 41, 0, 1 }, { 30, 63, 0 } } },
- { { { 41, 0, 0 }, { 32, 59, 0 } } },
- { { { 41, 0, 1 }, { 31, 62, 0 } } },
- { { { 41, 0, 2 }, { 31, 63, 0 } } },
- { { { 42, 0, 1 }, { 32, 61, 0 } } },
- { { { 42, 0, 0 }, { 32, 62, 0 } } },
- { { { 42, 0, 1 }, { 32, 63, 0 } } },
- { { { 42, 0, 2 }, { 41, 46, 0 } } },
- { { { 43, 0, 1 }, { 33, 62, 0 } } },
- { { { 43, 0, 0 }, { 33, 63, 0 } } },
- { { { 43, 0, 1 }, { 34, 62, 0 } } },
- { { { 43, 0, 2 }, { 42, 47, 0 } } },
- { { { 44, 0, 1 }, { 34, 63, 0 } } },
- { { { 44, 0, 0 }, { 35, 62, 0 } } },
- { { { 44, 0, 1 }, { 35, 63, 0 } } },
- { { { 44, 0, 2 }, { 44, 46, 0 } } },
- { { { 45, 0, 1 }, { 36, 62, 0 } } },
- { { { 45, 0, 0 }, { 36, 63, 0 } } },
- { { { 45, 0, 1 }, { 37, 62, 0 } } },
- { { { 45, 0, 2 }, { 45, 47, 0 } } },
- { { { 46, 0, 1 }, { 37, 63, 0 } } },
- { { { 46, 0, 0 }, { 38, 62, 0 } } },
- { { { 46, 0, 1 }, { 38, 63, 0 } } },
- { { { 46, 0, 2 }, { 47, 46, 0 } } },
- { { { 47, 0, 1 }, { 39, 62, 0 } } },
- { { { 47, 0, 0 }, { 39, 63, 0 } } },
- { { { 47, 0, 1 }, { 40, 62, 0 } } },
- { { { 47, 0, 2 }, { 48, 46, 0 } } },
- { { { 48, 0, 2 }, { 40, 63, 0 } } },
- { { { 48, 0, 1 }, { 41, 62, 0 } } },
- { { { 48, 0, 0 }, { 41, 63, 0 } } },
- { { { 48, 0, 1 }, { 48, 49, 0 } } },
- { { { 48, 0, 2 }, { 42, 62, 0 } } },
- { { { 49, 0, 1 }, { 42, 63, 0 } } },
- { { { 49, 0, 0 }, { 43, 62, 0 } } },
- { { { 49, 0, 1 }, { 48, 52, 0 } } },
- { { { 49, 0, 2 }, { 43, 63, 0 } } },
- { { { 50, 0, 1 }, { 44, 62, 0 } } },
- { { { 50, 0, 0 }, { 44, 63, 0 } } },
- { { { 50, 0, 1 }, { 48, 55, 0 } } },
- { { { 50, 0, 2 }, { 45, 62, 0 } } },
- { { { 51, 0, 1 }, { 45, 63, 0 } } },
- { { { 51, 0, 0 }, { 46, 62, 0 } } },
- { { { 51, 0, 1 }, { 48, 58, 0 } } },
- { { { 51, 0, 2 }, { 46, 63, 0 } } },
- { { { 52, 0, 1 }, { 47, 62, 0 } } },
- { { { 52, 0, 0 }, { 47, 63, 0 } } },
- { { { 52, 0, 1 }, { 48, 61, 0 } } },
- { { { 52, 0, 2 }, { 48, 62, 0 } } },
- { { { 53, 0, 1 }, { 56, 47, 0 } } },
- { { { 53, 0, 0 }, { 48, 63, 0 } } },
- { { { 53, 0, 1 }, { 49, 62, 0 } } },
- { { { 53, 0, 2 }, { 49, 63, 0 } } },
- { { { 54, 0, 1 }, { 58, 46, 0 } } },
- { { { 54, 0, 0 }, { 50, 62, 0 } } },
- { { { 54, 0, 1 }, { 50, 63, 0 } } },
- { { { 54, 0, 2 }, { 51, 62, 0 } } },
- { { { 55, 0, 1 }, { 59, 47, 0 } } },
- { { { 55, 0, 0 }, { 51, 63, 0 } } },
- { { { 55, 0, 1 }, { 52, 62, 0 } } },
- { { { 55, 0, 2 }, { 52, 63, 0 } } },
- { { { 56, 0, 1 }, { 61, 46, 0 } } },
- { { { 56, 0, 0 }, { 53, 62, 0 } } },
- { { { 56, 0, 1 }, { 53, 63, 0 } } },
- { { { 56, 0, 2 }, { 54, 62, 0 } } },
- { { { 57, 0, 1 }, { 62, 47, 0 } } },
- { { { 57, 0, 0 }, { 54, 63, 0 } } },
- { { { 57, 0, 1 }, { 55, 62, 0 } } },
- { { { 57, 0, 2 }, { 55, 63, 0 } } },
- { { { 58, 0, 1 }, { 56, 62, 1 } } },
- { { { 58, 0, 0 }, { 56, 62, 0 } } },
- { { { 58, 0, 1 }, { 56, 63, 0 } } },
- { { { 58, 0, 2 }, { 57, 62, 0 } } },
- { { { 59, 0, 1 }, { 57, 63, 1 } } },
- { { { 59, 0, 0 }, { 57, 63, 0 } } },
- { { { 59, 0, 1 }, { 58, 62, 0 } } },
- { { { 59, 0, 2 }, { 58, 63, 0 } } },
- { { { 60, 0, 1 }, { 59, 62, 1 } } },
- { { { 60, 0, 0 }, { 59, 62, 0 } } },
- { { { 60, 0, 1 }, { 59, 63, 0 } } },
- { { { 60, 0, 2 }, { 60, 62, 0 } } },
- { { { 61, 0, 1 }, { 60, 63, 1 } } },
- { { { 61, 0, 0 }, { 60, 63, 0 } } },
- { { { 61, 0, 1 }, { 61, 62, 0 } } },
- { { { 61, 0, 2 }, { 61, 63, 0 } } },
- { { { 62, 0, 1 }, { 62, 62, 1 } } },
- { { { 62, 0, 0 }, { 62, 62, 0 } } },
- { { { 62, 0, 1 }, { 62, 63, 0 } } },
- { { { 62, 0, 2 }, { 63, 62, 0 } } },
- { { { 63, 0, 1 }, { 63, 63, 1 } } },
- { { { 63, 0, 0 }, { 63, 63, 0 } } }
-};
diff --git a/thirdparty/squish/squish.cpp b/thirdparty/squish/squish.cpp
deleted file mode 100644
index 1de1da3e52..0000000000
--- a/thirdparty/squish/squish.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 <string.h>
-#include "squish.h"
-#include "colourset.h"
-#include "maths.h"
-#include "rangefit.h"
-#include "clusterfit.h"
-#include "colourblock.h"
-#include "alpha.h"
-#include "singlecolourfit.h"
-
-namespace squish {
-
-static int FixFlags( int flags )
-{
- // grab the flag bits
- int method = flags & ( kDxt1 | kDxt3 | kDxt5 | kBc4 | kBc5 );
- int fit = flags & ( kColourIterativeClusterFit | kColourClusterFit | kColourRangeFit );
- int extra = flags & kWeightColourByAlpha;
-
- // set defaults
- if ( method != kDxt3
- && method != kDxt5
- && method != kBc4
- && method != kBc5 )
- {
- method = kDxt1;
- }
- if( fit != kColourRangeFit && fit != kColourIterativeClusterFit )
- fit = kColourClusterFit;
-
- // done
- return method | fit | extra;
-}
-
-void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric )
-{
- // fix any bad flags
- flags = FixFlags( flags );
-
- if ( ( flags & ( kBc4 | kBc5 ) ) != 0 )
- {
- u8 alpha[16*4];
- for( int i = 0; i < 16; ++i )
- {
- alpha[i*4 + 3] = rgba[i*4 + 0]; // copy R to A
- }
-
- u8* rBlock = reinterpret_cast< u8* >( block );
- CompressAlphaDxt5( alpha, mask, rBlock );
-
- if ( ( flags & ( kBc5 ) ) != 0 )
- {
- for( int i = 0; i < 16; ++i )
- {
- alpha[i*4 + 3] = rgba[i*4 + 1]; // copy G to A
- }
-
- u8* gBlock = reinterpret_cast< u8* >( block ) + 8;
- CompressAlphaDxt5( alpha, mask, gBlock );
- }
-
- return;
- }
-
- // get the block locations
- void* colourBlock = block;
- void* alphaBlock = block;
- if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 )
- colourBlock = reinterpret_cast< u8* >( block ) + 8;
-
- // create the minimal point set
- ColourSet colours( rgba, mask, flags );
-
- // check the compression type and compress colour
- if( colours.GetCount() == 1 )
- {
- // always do a single colour fit
- SingleColourFit fit( &colours, flags );
- fit.Compress( colourBlock );
- }
- else if( ( flags & kColourRangeFit ) != 0 || colours.GetCount() == 0 )
- {
- // do a range fit
- RangeFit fit( &colours, flags, metric );
- fit.Compress( colourBlock );
- }
- else
- {
- // default to a cluster fit (could be iterative or not)
- ClusterFit fit( &colours, flags, metric );
- fit.Compress( colourBlock );
- }
-
- // compress alpha separately if necessary
- if( ( flags & kDxt3 ) != 0 )
- CompressAlphaDxt3( rgba, mask, alphaBlock );
- else if( ( flags & kDxt5 ) != 0 )
- CompressAlphaDxt5( rgba, mask, alphaBlock );
-}
-
-void Decompress( u8* rgba, void const* block, int flags )
-{
- // fix any bad flags
- flags = FixFlags( flags );
-
- // get the block locations
- void const* colourBlock = block;
- void const* alphaBlock = block;
- if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 )
- colourBlock = reinterpret_cast< u8 const* >( block ) + 8;
-
- // decompress colour
- // -- GODOT start --
- //DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 );
- if(( flags & ( kBc4 ) ) != 0)
- DecompressColourBc4( rgba, colourBlock);
- else if(( flags & ( kBc5 ) ) != 0)
- DecompressColourBc5( rgba, colourBlock);
- else
- DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 );
- // -- GODOT end --
-
- // decompress alpha separately if necessary
- if( ( flags & kDxt3 ) != 0 )
- DecompressAlphaDxt3( rgba, alphaBlock );
- else if( ( flags & kDxt5 ) != 0 )
- DecompressAlphaDxt5( rgba, alphaBlock );
-}
-
-int GetStorageRequirements( int width, int height, int flags )
-{
- // fix any bad flags
- flags = FixFlags( flags );
-
- // compute the storage requirements
- int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 );
- int blocksize = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16;
- return blockcount*blocksize;
-}
-
-void CopyRGBA( u8 const* source, u8* dest, int flags )
-{
- if (flags & kSourceBGRA)
- {
- // convert from bgra to rgba
- dest[0] = source[2];
- dest[1] = source[1];
- dest[2] = source[0];
- dest[3] = source[3];
- }
- else
- {
- for( int i = 0; i < 4; ++i )
- *dest++ = *source++;
- }
-}
-
-void CompressImage( u8 const* rgba, int width, int height, int pitch, void* blocks, int flags, float* metric )
-{
- // fix any bad flags
- flags = FixFlags( flags );
-
- // loop over blocks
-#ifdef SQUISH_USE_OPENMP
-# pragma omp parallel for
-#endif
- for( int y = 0; y < height; y += 4 )
- {
- // initialise the block output
- u8* targetBlock = reinterpret_cast< u8* >( blocks );
- int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16;
- targetBlock += ( (y / 4) * ( (width + 3) / 4) ) * bytesPerBlock;
-
- for( int x = 0; x < width; x += 4 )
- {
- // build the 4x4 block of pixels
- u8 sourceRgba[16*4];
- u8* targetPixel = sourceRgba;
- int mask = 0;
- for( int py = 0; py < 4; ++py )
- {
- for( int px = 0; px < 4; ++px )
- {
- // get the source pixel in the image
- int sx = x + px;
- int sy = y + py;
-
- // enable if we're in the image
- if( sx < width && sy < height )
- {
- // copy the rgba value
- u8 const* sourcePixel = rgba + pitch*sy + 4*sx;
- CopyRGBA(sourcePixel, targetPixel, flags);
- // enable this pixel
- mask |= ( 1 << ( 4*py + px ) );
- }
-
- // advance to the next pixel
- targetPixel += 4;
- }
- }
-
- // compress it into the output
- CompressMasked( sourceRgba, mask, targetBlock, flags, metric );
-
- // advance
- targetBlock += bytesPerBlock;
- }
- }
-}
-
-void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric )
-{
- CompressImage(rgba, width, height, width*4, blocks, flags, metric);
-}
-
-void DecompressImage( u8* rgba, int width, int height, int pitch, void const* blocks, int flags )
-{
- // fix any bad flags
- flags = FixFlags( flags );
-
- // loop over blocks
-#ifdef SQUISH_USE_OPENMP
-# pragma omp parallel for
-#endif
- for( int y = 0; y < height; y += 4 )
- {
- // initialise the block input
- u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks );
- int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16;
- sourceBlock += ( (y / 4) * ( (width + 3) / 4) ) * bytesPerBlock;
-
- for( int x = 0; x < width; x += 4 )
- {
- // decompress the block
- u8 targetRgba[4*16];
- Decompress( targetRgba, sourceBlock, flags );
-
- // write the decompressed pixels to the correct image locations
- u8 const* sourcePixel = targetRgba;
- for( int py = 0; py < 4; ++py )
- {
- for( int px = 0; px < 4; ++px )
- {
- // get the target location
- int sx = x + px;
- int sy = y + py;
-
- // write if we're in the image
- if( sx < width && sy < height )
- {
- // copy the rgba value
- u8* targetPixel = rgba + pitch*sy + 4*sx;
- CopyRGBA(sourcePixel, targetPixel, flags);
- }
-
- // advance to the next pixel
- sourcePixel += 4;
- }
- }
-
- // advance
- sourceBlock += bytesPerBlock;
- }
- }
-}
-
-void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags )
-{
- DecompressImage( rgba, width, height, width*4, blocks, flags );
-}
-
-static double ErrorSq(double x, double y)
-{
- return (x - y) * (x - y);
-}
-
-static void ComputeBlockWMSE(u8 const *original, u8 const *compressed, unsigned int w, unsigned int h, double &cmse, double &amse)
-{
- // Computes the MSE for the block and weights it by the variance of the original block.
- // If the variance of the original block is less than 4 (i.e. a standard deviation of 1 per channel)
- // then the block is close to being a single colour. Quantisation errors in single colour blocks
- // are easier to see than similar errors in blocks that contain more colours, particularly when there
- // are many such blocks in a large area (eg a blue sky background) as they cause banding. Given that
- // banding is easier to see than small errors in "complex" blocks, we weight the errors by a factor
- // of 5. This implies that images with large, single colour areas will have a higher potential WMSE
- // than images with lots of detail.
-
- cmse = amse = 0;
- unsigned int sum_p[4]; // per channel sum of pixels
- unsigned int sum_p2[4]; // per channel sum of pixels squared
- memset(sum_p, 0, sizeof(sum_p));
- memset(sum_p2, 0, sizeof(sum_p2));
- for( unsigned int py = 0; py < 4; ++py )
- {
- for( unsigned int px = 0; px < 4; ++px )
- {
- if( px < w && py < h )
- {
- double pixelCMSE = 0;
- for( int i = 0; i < 3; ++i )
- {
- pixelCMSE += ErrorSq(original[i], compressed[i]);
- sum_p[i] += original[i];
- sum_p2[i] += (unsigned int)original[i]*original[i];
- }
- if( original[3] == 0 && compressed[3] == 0 )
- pixelCMSE = 0; // transparent in both, so colour is inconsequential
- amse += ErrorSq(original[3], compressed[3]);
- cmse += pixelCMSE;
- sum_p[3] += original[3];
- sum_p2[3] += (unsigned int)original[3]*original[3];
- }
- original += 4;
- compressed += 4;
- }
- }
- unsigned int variance = 0;
- for( int i = 0; i < 4; ++i )
- variance += w*h*sum_p2[i] - sum_p[i]*sum_p[i];
- if( variance < 4 * w * w * h * h )
- {
- amse *= 5;
- cmse *= 5;
- }
-}
-
-void ComputeMSE( u8 const *rgba, int width, int height, int pitch, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE )
-{
- // fix any bad flags
- flags = FixFlags( flags );
- colourMSE = alphaMSE = 0;
-
- // initialise the block input
- squish::u8 const* sourceBlock = dxt;
- int bytesPerBlock = ( ( flags & squish::kDxt1 ) != 0 ) ? 8 : 16;
-
- // loop over blocks
- for( int y = 0; y < height; y += 4 )
- {
- for( int x = 0; x < width; x += 4 )
- {
- // decompress the block
- u8 targetRgba[4*16];
- Decompress( targetRgba, sourceBlock, flags );
- u8 const* sourcePixel = targetRgba;
-
- // copy across to a similar pixel block
- u8 originalRgba[4*16];
- u8* originalPixel = originalRgba;
-
- for( int py = 0; py < 4; ++py )
- {
- for( int px = 0; px < 4; ++px )
- {
- int sx = x + px;
- int sy = y + py;
- if( sx < width && sy < height )
- {
- u8 const* targetPixel = rgba + pitch*sy + 4*sx;
- CopyRGBA(targetPixel, originalPixel, flags);
- }
- sourcePixel += 4;
- originalPixel += 4;
- }
- }
-
- // compute the weighted MSE of the block
- double blockCMSE, blockAMSE;
- ComputeBlockWMSE(originalRgba, targetRgba, std::min(4, width - x), std::min(4, height - y), blockCMSE, blockAMSE);
- colourMSE += blockCMSE;
- alphaMSE += blockAMSE;
- // advance
- sourceBlock += bytesPerBlock;
- }
- }
- colourMSE /= (width * height * 3);
- alphaMSE /= (width * height);
-}
-
-void ComputeMSE( u8 const *rgba, int width, int height, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE )
-{
- ComputeMSE(rgba, width, height, width*4, dxt, flags, colourMSE, alphaMSE);
-}
-
-} // namespace squish
diff --git a/thirdparty/squish/squish.h b/thirdparty/squish/squish.h
deleted file mode 100644
index 14c9bb59fb..0000000000
--- a/thirdparty/squish/squish.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
-
- 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 SQUISH_H
-#define SQUISH_H
-
-//! All squish API functions live in this namespace.
-namespace squish {
-
-// -----------------------------------------------------------------------------
-
-//! Typedef a quantity that is a single unsigned byte.
-typedef unsigned char u8;
-
-// -----------------------------------------------------------------------------
-
-enum
-{
- //! Use DXT1 compression.
- kDxt1 = ( 1 << 0 ),
-
- //! Use DXT3 compression.
- kDxt3 = ( 1 << 1 ),
-
- //! Use DXT5 compression.
- kDxt5 = ( 1 << 2 ),
-
- //! Use BC4 compression.
- kBc4 = ( 1 << 3 ),
-
- //! Use BC5 compression.
- kBc5 = ( 1 << 4 ),
-
- //! Use a slow but high quality colour compressor (the default).
- kColourClusterFit = ( 1 << 5 ),
-
- //! Use a fast but low quality colour compressor.
- kColourRangeFit = ( 1 << 6 ),
-
- //! Weight the colour by alpha during cluster fit (disabled by default).
- kWeightColourByAlpha = ( 1 << 7 ),
-
- //! Use a very slow but very high quality colour compressor.
- kColourIterativeClusterFit = ( 1 << 8 ),
-
- //! Source is BGRA rather than RGBA
- kSourceBGRA = ( 1 << 9 )
-};
-
-// -----------------------------------------------------------------------------
-
-/*! @brief Compresses a 4x4 block of pixels.
-
- @param rgba The rgba values of the 16 source pixels.
- @param mask The valid pixel mask.
- @param block Storage for the compressed DXT block.
- @param flags Compression flags.
- @param metric An optional perceptual metric.
-
- The source pixels should be presented as a contiguous array of 16 rgba
- values, with each component as 1 byte each. In memory this should be:
-
- { r1, g1, b1, a1, .... , r16, g16, b16, a16 }
-
- The mask parameter enables only certain pixels within the block. The lowest
- bit enables the first pixel and so on up to the 16th bit. Bits beyond the
- 16th bit are ignored. Pixels that are not enabled are allowed to take
- arbitrary colours in the output block. An example of how this can be used
- is in the CompressImage function to disable pixels outside the bounds of
- the image when the width or height is not divisible by 4.
-
- The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression,
- however, DXT1 will be used by default if none is specified. When using DXT1
- compression, 8 bytes of storage are required for the compressed DXT block.
- DXT3 and DXT5 compression require 16 bytes of storage per block.
-
- The flags parameter can also specify a preferred colour compressor to use
- when fitting the RGB components of the data. Possible colour compressors
- are: kColourClusterFit (the default), kColourRangeFit (very fast, low
- quality) or kColourIterativeClusterFit (slowest, best quality).
-
- When using kColourClusterFit or kColourIterativeClusterFit, an additional
- flag can be specified to weight the importance of each pixel by its alpha
- value. For images that are rendered using alpha blending, this can
- significantly increase the perceived quality.
-
- The metric parameter can be used to weight the relative importance of each
- colour channel, or pass NULL to use the default uniform weight of
- { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
- allowed either uniform or "perceptual" weights with the fixed values
- { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
- contiguous array of 3 floats.
-*/
-void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric = 0 );
-
-// -----------------------------------------------------------------------------
-
-/*! @brief Compresses a 4x4 block of pixels.
-
- @param rgba The rgba values of the 16 source pixels.
- @param block Storage for the compressed DXT block.
- @param flags Compression flags.
- @param metric An optional perceptual metric.
-
- The source pixels should be presented as a contiguous array of 16 rgba
- values, with each component as 1 byte each. In memory this should be:
-
- { r1, g1, b1, a1, .... , r16, g16, b16, a16 }
-
- The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression,
- however, DXT1 will be used by default if none is specified. When using DXT1
- compression, 8 bytes of storage are required for the compressed DXT block.
- DXT3 and DXT5 compression require 16 bytes of storage per block.
-
- The flags parameter can also specify a preferred colour compressor to use
- when fitting the RGB components of the data. Possible colour compressors
- are: kColourClusterFit (the default), kColourRangeFit (very fast, low
- quality) or kColourIterativeClusterFit (slowest, best quality).
-
- When using kColourClusterFit or kColourIterativeClusterFit, an additional
- flag can be specified to weight the importance of each pixel by its alpha
- value. For images that are rendered using alpha blending, this can
- significantly increase the perceived quality.
-
- The metric parameter can be used to weight the relative importance of each
- colour channel, or pass NULL to use the default uniform weight of
- { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
- allowed either uniform or "perceptual" weights with the fixed values
- { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
- contiguous array of 3 floats.
-
- This method is an inline that calls CompressMasked with a mask of 0xffff,
- provided for compatibility with older versions of squish.
-*/
-inline void Compress( u8 const* rgba, void* block, int flags, float* metric = 0 )
-{
- CompressMasked( rgba, 0xffff, block, flags, metric );
-}
-
-// -----------------------------------------------------------------------------
-
-/*! @brief Decompresses a 4x4 block of pixels.
-
- @param rgba Storage for the 16 decompressed pixels.
- @param block The compressed DXT block.
- @param flags Compression flags.
-
- The decompressed pixels will be written as a contiguous array of 16 rgba
- values, with each component as 1 byte each. In memory this is:
-
- { r1, g1, b1, a1, .... , r16, g16, b16, a16 }
-
- The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression,
- however, DXT1 will be used by default if none is specified. All other flags
- are ignored.
-*/
-void Decompress( u8* rgba, void const* block, int flags );
-
-// -----------------------------------------------------------------------------
-
-/*! @brief Computes the amount of compressed storage required.
-
- @param width The width of the image.
- @param height The height of the image.
- @param flags Compression flags.
-
- The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression,
- however, DXT1 will be used by default if none is specified. All other flags
- are ignored.
-
- Most DXT images will be a multiple of 4 in each dimension, but this
- function supports arbitrary size images by allowing the outer blocks to
- be only partially used.
-*/
-int GetStorageRequirements( int width, int height, int flags );
-
-// -----------------------------------------------------------------------------
-
-/*! @brief Compresses an image in memory.
-
- @param rgba The pixels of the source.
- @param width The width of the source image.
- @param height The height of the source image.
- @param pitch The pitch of the source image.
- @param blocks Storage for the compressed output.
- @param flags Compression flags.
- @param metric An optional perceptual metric.
-
- The source pixels should be presented as a contiguous array of width*height
- rgba values, with each component as 1 byte each. In memory this should be:
-
- { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height
-
- The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression,
- however, DXT1 will be used by default if none is specified. When using DXT1
- compression, 8 bytes of storage are required for each compressed DXT block.
- DXT3 and DXT5 compression require 16 bytes of storage per block.
-
- The flags parameter can also specify a preferred colour compressor to use
- when fitting the RGB components of the data. Possible colour compressors
- are: kColourClusterFit (the default), kColourRangeFit (very fast, low
- quality) or kColourIterativeClusterFit (slowest, best quality).
-
- When using kColourClusterFit or kColourIterativeClusterFit, an additional
- flag can be specified to weight the importance of each pixel by its alpha
- value. For images that are rendered using alpha blending, this can
- significantly increase the perceived quality.
-
- The metric parameter can be used to weight the relative importance of each
- colour channel, or pass NULL to use the default uniform weight of
- { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
- allowed either uniform or "perceptual" weights with the fixed values
- { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
- contiguous array of 3 floats.
-
- Internally this function calls squish::CompressMasked for each block, which
- allows for pixels outside the image to take arbitrary values. The function
- squish::GetStorageRequirements can be called to compute the amount of memory
- to allocate for the compressed output.
-
- Note on compression quality: When compressing textures with
- libsquish it is recommended to apply a gamma-correction
- beforehand. This will reduce the blockiness in dark areas. The
- level of necessary gamma-correction is platform dependent. For
- example, a gamma correction with gamma = 0.5 before compression
- and gamma = 2.0 after decompression yields good results on the
- Windows platform but for other platforms like MacOS X a different
- gamma value may be more suitable.
-*/
-void CompressImage( u8 const* rgba, int width, int height, int pitch, void* blocks, int flags, float* metric = 0 );
-void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric = 0 );
-
-// -----------------------------------------------------------------------------
-
-/*! @brief Decompresses an image in memory.
-
- @param rgba Storage for the decompressed pixels.
- @param width The width of the source image.
- @param height The height of the source image.
- @param pitch The pitch of the decompressed pixels.
- @param blocks The compressed DXT blocks.
- @param flags Compression flags.
-
- The decompressed pixels will be written as a contiguous array of width*height
- 16 rgba values, with each component as 1 byte each. In memory this is:
-
- { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height
-
- The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression,
- however, DXT1 will be used by default if none is specified. All other flags
- are ignored.
-
- Internally this function calls squish::Decompress for each block.
-*/
-void DecompressImage( u8* rgba, int width, int height, int pitch, void const* blocks, int flags );
-void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags );
-
-// -----------------------------------------------------------------------------
-
-/*! @brief Computes MSE of an compressed image in memory.
-
- @param rgba The original image pixels.
- @param width The width of the source image.
- @param height The height of the source image.
- @param pitch The pitch of the source image.
- @param dxt The compressed dxt blocks
- @param flags Compression flags.
- @param colourMSE The MSE of the colour values.
- @param alphaMSE The MSE of the alpha values.
-
- The colour MSE and alpha MSE are computed across all pixels. The colour MSE is
- averaged across all rgb values (i.e. colourMSE = sum sum_k ||dxt.k - rgba.k||/3)
-
- The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression,
- however, DXT1 will be used by default if none is specified. All other flags
- are ignored.
-
- Internally this function calls squish::Decompress for each block.
-*/
-void ComputeMSE(u8 const *rgba, int width, int height, int pitch, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE);
-void ComputeMSE(u8 const *rgba, int width, int height, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE);
-
-// -----------------------------------------------------------------------------
-
-} // namespace squish
-
-#endif // ndef SQUISH_H