You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-25 15:37:42 +00:00
OpenXR add core support for Khronos loader
This commit is contained in:
@@ -8,19 +8,16 @@ Import("env_modules")
|
|||||||
|
|
||||||
env_openxr = env_modules.Clone()
|
env_openxr = env_modules.Clone()
|
||||||
|
|
||||||
# Thirdparty source files
|
# Thirdparty source files.
|
||||||
|
|
||||||
thirdparty_obj = []
|
thirdparty_obj = []
|
||||||
|
|
||||||
# Khronos OpenXR loader
|
# Khronos OpenXR loader.
|
||||||
|
|
||||||
# Needs even for build against shared library, at least the defines used in public headers.
|
# Needs even for build against shared library, at least the defines used in public headers.
|
||||||
if env["platform"] == "android":
|
if env["platform"] == "android":
|
||||||
# may need to set OPENXR_ANDROID_VERSION_SUFFIX
|
|
||||||
env_openxr.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"])
|
env_openxr.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"])
|
||||||
env_openxr.AppendUnique(CPPDEFINES=[("JSON_USE_EXCEPTION", 0)])
|
env_openxr.AppendUnique(CPPDEFINES=[("JSON_USE_EXCEPTION", 0)])
|
||||||
|
|
||||||
# may need to include java parts of the openxr loader
|
|
||||||
elif env["platform"] == "linuxbsd":
|
elif env["platform"] == "linuxbsd":
|
||||||
env_openxr.AppendUnique(CPPDEFINES=["XR_OS_LINUX"])
|
env_openxr.AppendUnique(CPPDEFINES=["XR_OS_LINUX"])
|
||||||
|
|
||||||
@@ -31,7 +28,6 @@ elif env["platform"] == "linuxbsd":
|
|||||||
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_EGL", "XRDEPENDENCIES_USE_GLAD"])
|
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_EGL", "XRDEPENDENCIES_USE_GLAD"])
|
||||||
env_openxr.Prepend(CPPPATH=["#thirdparty/glad"])
|
env_openxr.Prepend(CPPPATH=["#thirdparty/glad"])
|
||||||
|
|
||||||
# FIXME: Review what needs to be set for Android and macOS.
|
|
||||||
# FreeBSD uses non-standard getenv functions.
|
# FreeBSD uses non-standard getenv functions.
|
||||||
if not sys.platform.startswith("freebsd"):
|
if not sys.platform.startswith("freebsd"):
|
||||||
env_openxr.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
|
env_openxr.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
|
||||||
@@ -40,12 +36,9 @@ elif env["platform"] == "windows":
|
|||||||
elif env["platform"] == "macos":
|
elif env["platform"] == "macos":
|
||||||
env_openxr.AppendUnique(CPPDEFINES=["XR_OS_APPLE"])
|
env_openxr.AppendUnique(CPPDEFINES=["XR_OS_APPLE"])
|
||||||
|
|
||||||
# There does not seem to be a XR_USE_PLATFORM_XYZ for Apple
|
# There does not seem to be a XR_USE_PLATFORM_XYZ for Apple.
|
||||||
|
|
||||||
|
|
||||||
# may need to check and set:
|
|
||||||
# - XR_USE_TIMESPEC
|
|
||||||
|
|
||||||
if env["builtin_openxr"]:
|
if env["builtin_openxr"]:
|
||||||
thirdparty_dir = "#thirdparty/openxr"
|
thirdparty_dir = "#thirdparty/openxr"
|
||||||
|
|
||||||
@@ -68,16 +61,15 @@ if env["builtin_openxr"]:
|
|||||||
|
|
||||||
env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"])
|
env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"])
|
||||||
|
|
||||||
# add in external jsoncpp dependency
|
# Add in external jsoncpp dependency.
|
||||||
thirdparty_jsoncpp_dir = thirdparty_dir + "/src/external/jsoncpp/src/lib_json/"
|
thirdparty_jsoncpp_dir = thirdparty_dir + "/src/external/jsoncpp/src/lib_json/"
|
||||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_reader.cpp")
|
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_reader.cpp")
|
||||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_value.cpp")
|
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_value.cpp")
|
||||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_writer.cpp")
|
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_writer.cpp")
|
||||||
|
|
||||||
# add in load
|
# Add in the OpenXR loader.
|
||||||
if env["platform"] != "android":
|
if env["platform"] != "android":
|
||||||
# On Android the openxr_loader is provided by separate plugins for each device
|
# On Android the OpenXR loader is handled by the configuration in 'platform/android/java/app/build.gradle'.
|
||||||
# Build the engine using object files
|
|
||||||
khrloader_obj = []
|
khrloader_obj = []
|
||||||
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/xr_generated_dispatch_table_core.c")
|
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/xr_generated_dispatch_table_core.c")
|
||||||
|
|
||||||
@@ -93,13 +85,12 @@ if env["builtin_openxr"]:
|
|||||||
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_properties.cpp")
|
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_properties.cpp")
|
||||||
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/manifest_file.cpp")
|
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/manifest_file.cpp")
|
||||||
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/runtime_interface.cpp")
|
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/runtime_interface.cpp")
|
||||||
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/xr_generated_loader.cpp")
|
|
||||||
env.modules_sources += khrloader_obj
|
env.modules_sources += khrloader_obj
|
||||||
|
|
||||||
env.modules_sources += thirdparty_obj
|
env.modules_sources += thirdparty_obj
|
||||||
|
|
||||||
|
|
||||||
# Godot source files
|
# Godot source files.
|
||||||
|
|
||||||
module_obj = []
|
module_obj = []
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,119 @@
|
|||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/gui/editor_bottom_panel.h"
|
#include "editor/gui/editor_bottom_panel.h"
|
||||||
#include "editor/settings/editor_command_palette.h"
|
#include "editor/settings/editor_command_palette.h"
|
||||||
|
#include "platform/android/export/export_plugin.h"
|
||||||
|
|
||||||
|
#include <openxr/openxr.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// OpenXRExportPlugin
|
||||||
|
|
||||||
|
bool OpenXRExportPlugin::supports_platform(const Ref<EditorExportPlatform> &p_export_platform) const {
|
||||||
|
return p_export_platform->is_class(EditorExportPlatformAndroid::get_class_static());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenXRExportPlugin::is_openxr_mode() const {
|
||||||
|
int xr_mode_index = get_option("xr_features/xr_mode");
|
||||||
|
|
||||||
|
return xr_mode_index == XR_MODE_OPENXR;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenXRExportPlugin::_get_export_option_warning(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const {
|
||||||
|
if (!supports_platform(p_export_platform)) {
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gradle_build = get_option("gradle_build/use_gradle_build");
|
||||||
|
if (is_openxr_mode() && !gradle_build) {
|
||||||
|
return "\"Use Gradle Build\" must be enabled when xr_mode is set to \"OpenXR\".";
|
||||||
|
}
|
||||||
|
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedStringArray OpenXRExportPlugin::get_android_dependencies(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
|
||||||
|
PackedStringArray ret;
|
||||||
|
|
||||||
|
if (!supports_platform(p_export_platform)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_openxr_mode()) {
|
||||||
|
// Loader is always identified by the full API version even if we're initializing for OpenXR 1.0.
|
||||||
|
int major = XR_VERSION_MAJOR(XR_CURRENT_API_VERSION);
|
||||||
|
int minor = XR_VERSION_MINOR(XR_CURRENT_API_VERSION);
|
||||||
|
int patch = XR_VERSION_PATCH(XR_CURRENT_API_VERSION);
|
||||||
|
String openxr_loader = "org.khronos.openxr:openxr_loader_for_android:" + String::num_int64(major) + "." + String::num_int64(minor) + "." + String::num_int64(patch);
|
||||||
|
|
||||||
|
ret.push_back(openxr_loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedStringArray OpenXRExportPlugin::_get_export_features(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
|
||||||
|
PackedStringArray features;
|
||||||
|
|
||||||
|
if (!supports_platform(p_export_platform) || !is_openxr_mode()) {
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder for now
|
||||||
|
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenXRExportPlugin::get_android_manifest_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
|
||||||
|
String contents;
|
||||||
|
|
||||||
|
if (!supports_platform(p_export_platform) || !is_openxr_mode()) {
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
contents += R"n(
|
||||||
|
<uses-permission android:name="org.khronos.openxr.permission.OPENXR" />
|
||||||
|
<uses-permission android:name="org.khronos.openxr.permission.OPENXR_SYSTEM" />
|
||||||
|
|
||||||
|
<queries>
|
||||||
|
<provider android:authorities="org.khronos.openxr.runtime_broker;org.khronos.openxr.system_runtime_broker" />
|
||||||
|
|
||||||
|
<intent>
|
||||||
|
<action android:name="org.khronos.openxr.OpenXRRuntimeService" />
|
||||||
|
</intent>
|
||||||
|
<intent>
|
||||||
|
<action android:name="org.khronos.openxr.OpenXRApiLayerService" />
|
||||||
|
</intent>
|
||||||
|
|
||||||
|
</queries>
|
||||||
|
|
||||||
|
<uses-feature android:name="android.hardware.vr.headtracking" android:required="false" android:version="1" />
|
||||||
|
)n";
|
||||||
|
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenXRExportPlugin::get_android_manifest_activity_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
|
||||||
|
String contents;
|
||||||
|
|
||||||
|
if (!supports_platform(p_export_platform) || !is_openxr_mode()) {
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
contents += R"n(
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
|
<category android:name="org.khronos.openxr.intent.category.IMMERSIVE_HMD" />
|
||||||
|
</intent-filter>
|
||||||
|
)n";
|
||||||
|
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// OpenXREditorPlugin
|
||||||
|
|
||||||
void OpenXREditorPlugin::edit(Object *p_node) {
|
void OpenXREditorPlugin::edit(Object *p_node) {
|
||||||
if (Object::cast_to<OpenXRActionMap>(p_node)) {
|
if (Object::cast_to<OpenXRActionMap>(p_node)) {
|
||||||
@@ -64,3 +177,19 @@ OpenXREditorPlugin::OpenXREditorPlugin() {
|
|||||||
add_control_to_container(CONTAINER_TOOLBAR, select_runtime);
|
add_control_to_container(CONTAINER_TOOLBAR, select_runtime);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenXREditorPlugin::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
// Initialize our export plugin
|
||||||
|
openxr_export_plugin.instantiate();
|
||||||
|
add_export_plugin(openxr_export_plugin);
|
||||||
|
} break;
|
||||||
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
// Clean up our export plugin
|
||||||
|
remove_export_plugin(openxr_export_plugin);
|
||||||
|
|
||||||
|
openxr_export_plugin.unref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,8 +34,27 @@
|
|||||||
#include "openxr_binding_modifier_editor.h"
|
#include "openxr_binding_modifier_editor.h"
|
||||||
#include "openxr_select_runtime.h"
|
#include "openxr_select_runtime.h"
|
||||||
|
|
||||||
|
#include "editor/export/editor_export_plugin.h"
|
||||||
#include "editor/plugins/editor_plugin.h"
|
#include "editor/plugins/editor_plugin.h"
|
||||||
|
|
||||||
|
class OpenXRExportPlugin : public EditorExportPlugin {
|
||||||
|
GDCLASS(OpenXRExportPlugin, EditorExportPlugin)
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool supports_platform(const Ref<EditorExportPlatform> &p_export_platform) const override;
|
||||||
|
virtual PackedStringArray get_android_dependencies(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual String _get_export_option_warning(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const override;
|
||||||
|
|
||||||
|
virtual PackedStringArray _get_export_features(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const override;
|
||||||
|
virtual String get_android_manifest_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const override;
|
||||||
|
virtual String get_android_manifest_activity_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool is_openxr_mode() const;
|
||||||
|
};
|
||||||
|
|
||||||
class OpenXREditorPlugin : public EditorPlugin {
|
class OpenXREditorPlugin : public EditorPlugin {
|
||||||
GDCLASS(OpenXREditorPlugin, EditorPlugin);
|
GDCLASS(OpenXREditorPlugin, EditorPlugin);
|
||||||
|
|
||||||
@@ -53,4 +72,10 @@ public:
|
|||||||
virtual void make_visible(bool p_visible) override;
|
virtual void make_visible(bool p_visible) override;
|
||||||
|
|
||||||
OpenXREditorPlugin();
|
OpenXREditorPlugin();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ref<OpenXRExportPlugin> openxr_export_plugin;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -299,6 +299,29 @@ task validateJavaVersion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Older versions of our vendor plugin include a loader that we no longer need.
|
||||||
|
* This code ensures those are removed.
|
||||||
|
*/
|
||||||
|
tasks.withType( com.android.build.gradle.internal.tasks.MergeNativeLibsTask) {
|
||||||
|
doFirst {
|
||||||
|
externalLibNativeLibs.each { jniDir ->
|
||||||
|
if (jniDir.getCanonicalPath().contains("godot-openxr-") || jniDir.getCanonicalPath().contains("godotopenxr")) {
|
||||||
|
// Delete the 'libopenxr_loader.so' files from the vendors plugin so we only use the version from the
|
||||||
|
// openxr loader dependency.
|
||||||
|
File armFile = new File(jniDir, "arm64-v8a/libopenxr_loader.so")
|
||||||
|
if (armFile.exists()) {
|
||||||
|
armFile.delete()
|
||||||
|
}
|
||||||
|
File x86File = new File(jniDir, "x86_64/libopenxr_loader.so")
|
||||||
|
if (x86File.exists()) {
|
||||||
|
x86File.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When they're scheduled to run, the copy*AARToAppModule tasks generate dependencies for the 'app'
|
When they're scheduled to run, the copy*AARToAppModule tasks generate dependencies for the 'app'
|
||||||
module, so we're ensuring the ':app:preBuild' task is set to run after those tasks.
|
module, so we're ensuring the ':app:preBuild' task is set to run after those tasks.
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ ext.versions = [
|
|||||||
// Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
|
// Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
|
||||||
ndkVersion : '28.1.13356709',
|
ndkVersion : '28.1.13356709',
|
||||||
splashscreenVersion: '1.0.1',
|
splashscreenVersion: '1.0.1',
|
||||||
|
// 'openxrLoaderVersion' should be set to XR_CURRENT_API_VERSION, see 'thirdparty/openxr'
|
||||||
|
openxrLoaderVersion: '1.1.53',
|
||||||
openxrVendorsVersion: '4.2.0-stable',
|
openxrVendorsVersion: '4.2.0-stable',
|
||||||
junitVersion : '1.3.0',
|
junitVersion : '1.3.0',
|
||||||
espressoCoreVersion: '3.7.0',
|
espressoCoreVersion: '3.7.0',
|
||||||
|
|||||||
@@ -203,6 +203,8 @@ dependencies {
|
|||||||
implementation "androidx.constraintlayout:constraintlayout:2.2.1"
|
implementation "androidx.constraintlayout:constraintlayout:2.2.1"
|
||||||
implementation "org.bouncycastle:bcprov-jdk15to18:1.78"
|
implementation "org.bouncycastle:bcprov-jdk15to18:1.78"
|
||||||
|
|
||||||
|
implementation "org.khronos.openxr:openxr_loader_for_android:$versions.openxrLoaderVersion"
|
||||||
|
|
||||||
// Android XR dependencies
|
// Android XR dependencies
|
||||||
androidImplementation "org.godotengine:godot-openxr-vendors-androidxr:$versions.openxrVendorsVersion"
|
androidImplementation "org.godotengine:godot-openxr-vendors-androidxr:$versions.openxrVendorsVersion"
|
||||||
// Meta dependencies
|
// Meta dependencies
|
||||||
@@ -217,3 +219,26 @@ dependencies {
|
|||||||
androidTestImplementation "androidx.test:runner:$versions.testRunnerVersion"
|
androidTestImplementation "androidx.test:runner:$versions.testRunnerVersion"
|
||||||
androidTestUtil "androidx.test:orchestrator:$versions.testOrchestratorVersion"
|
androidTestUtil "androidx.test:orchestrator:$versions.testOrchestratorVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Older versions of our vendor plugin include a loader that we no longer need.
|
||||||
|
* This code ensures those are removed.
|
||||||
|
*/
|
||||||
|
tasks.withType( com.android.build.gradle.internal.tasks.MergeNativeLibsTask) {
|
||||||
|
doFirst {
|
||||||
|
externalLibNativeLibs.each { jniDir ->
|
||||||
|
if (jniDir.getCanonicalPath().contains("godot-openxr-") || jniDir.getCanonicalPath().contains("godotopenxr")) {
|
||||||
|
// Delete the 'libopenxr_loader.so' files from the vendors plugin so we only use the version from the
|
||||||
|
// openxr loader dependency.
|
||||||
|
File armFile = new File(jniDir, "arm64-v8a/libopenxr_loader.so")
|
||||||
|
if (armFile.exists()) {
|
||||||
|
armFile.delete()
|
||||||
|
}
|
||||||
|
File x86File = new File(jniDir, "x86_64/libopenxr_loader.so")
|
||||||
|
if (x86File.exists()) {
|
||||||
|
x86File.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
2
thirdparty/README.md
vendored
2
thirdparty/README.md
vendored
@@ -888,6 +888,8 @@ Exclude:
|
|||||||
`*.{def,expsym,in,json,map,pom,rc,txt}`
|
`*.{def,expsym,in,json,map,pom,rc,txt}`
|
||||||
- All dotfiles
|
- All dotfiles
|
||||||
|
|
||||||
|
Additional:
|
||||||
|
- Update `openxrLoaderVersion` in `platform/android/java/app/config.gradle`
|
||||||
|
|
||||||
## pcre2
|
## pcre2
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user