diff options
Diffstat (limited to 'modules/openxr')
18 files changed, 207 insertions, 100 deletions
diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub index 0dd41675b6..d5abbe4c72 100644 --- a/modules/openxr/SCsub +++ b/modules/openxr/SCsub @@ -5,22 +5,13 @@ Import("env_modules") env_openxr = env_modules.Clone() -################################################# -# Add in our Khronos OpenXR loader +# Thirdparty source files thirdparty_obj = [] -thirdparty_dir = "#thirdparty/openxr" - -env_openxr.Prepend( - CPPPATH=[ - thirdparty_dir, - thirdparty_dir + "/include", - thirdparty_dir + "/src", - thirdparty_dir + "/src/common", - thirdparty_dir + "/src/external/jsoncpp/include", - ] -) +# Khronos OpenXR loader + +# Needs even for build against shared library, at least the defines used in public headers. if env["platform"] == "android": # may need to set OPENXR_ANDROID_VERSION_SUFFIX env_openxr.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"]) @@ -41,43 +32,57 @@ elif env["platform"] == "windows": # may need to check and set: # - XR_USE_TIMESPEC -env_thirdparty = env_openxr.Clone() -env_thirdparty.disable_warnings() -env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"]) - -if "-fno-exceptions" in env_thirdparty["CXXFLAGS"]: - env_thirdparty["CXXFLAGS"].remove("-fno-exceptions") -env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"]) - -# add in external jsoncpp dependency -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_reader.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_value.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_writer.cpp") - -# add in load -if env["platform"] != "android": - # On Android the openxr_loader is provided by separate plugins for each device - # Build the engine using object files - khrloader_obj = [] - env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/xr_generated_dispatch_table.c") - - env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/filesystem_utils.cpp") - env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/object_info.cpp") - - env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/api_layer_interface.cpp") - env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_core.cpp") - env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_instance.cpp") - env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_logger_recorders.cpp") - env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_logger.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/xr_generated_loader.cpp") - env.modules_sources += khrloader_obj - -env.modules_sources += thirdparty_obj - -################################################# -# And include our module source +if env["builtin_openxr"]: + thirdparty_dir = "#thirdparty/openxr" + + env_openxr.Prepend( + CPPPATH=[ + thirdparty_dir, + thirdparty_dir + "/include", + thirdparty_dir + "/src", + thirdparty_dir + "/src/common", + thirdparty_dir + "/src/external/jsoncpp/include", + ] + ) + + env_thirdparty = env_openxr.Clone() + env_thirdparty.disable_warnings() + env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"]) + + if "-fno-exceptions" in env_thirdparty["CXXFLAGS"]: + env_thirdparty["CXXFLAGS"].remove("-fno-exceptions") + env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"]) + + # add in external jsoncpp dependency + 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_value.cpp") + env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_writer.cpp") + + # add in load + if env["platform"] != "android": + # On Android the openxr_loader is provided by separate plugins for each device + # Build the engine using object files + khrloader_obj = [] + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/xr_generated_dispatch_table.c") + + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/filesystem_utils.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/object_info.cpp") + + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/api_layer_interface.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_core.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_instance.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_logger_recorders.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_logger.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/xr_generated_loader.cpp") + env.modules_sources += khrloader_obj + + env.modules_sources += thirdparty_obj + + +# Godot source files module_obj = [] diff --git a/modules/openxr/doc_classes/OpenXRAction.xml b/modules/openxr/doc_classes/OpenXRAction.xml index 2696be2465..6a3529e43e 100644 --- a/modules/openxr/doc_classes/OpenXRAction.xml +++ b/modules/openxr/doc_classes/OpenXRAction.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OpenXRAction" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OpenXRAction" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> An OpenXR action. </brief_description> diff --git a/modules/openxr/doc_classes/OpenXRActionMap.xml b/modules/openxr/doc_classes/OpenXRActionMap.xml index 64cd5ca494..b8711635e4 100644 --- a/modules/openxr/doc_classes/OpenXRActionMap.xml +++ b/modules/openxr/doc_classes/OpenXRActionMap.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OpenXRActionMap" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OpenXRActionMap" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> Collection of [OpenXRActionSet] and [OpenXRInteractionProfile] resources for the OpenXR module. </brief_description> diff --git a/modules/openxr/doc_classes/OpenXRActionSet.xml b/modules/openxr/doc_classes/OpenXRActionSet.xml index 92e6f91e32..03dc33d743 100644 --- a/modules/openxr/doc_classes/OpenXRActionSet.xml +++ b/modules/openxr/doc_classes/OpenXRActionSet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OpenXRActionSet" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OpenXRActionSet" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> Collection of [OpenXRAction] resources that make up an action set. </brief_description> diff --git a/modules/openxr/doc_classes/OpenXRHand.xml b/modules/openxr/doc_classes/OpenXRHand.xml index 6e258a468d..cc7766507f 100644 --- a/modules/openxr/doc_classes/OpenXRHand.xml +++ b/modules/openxr/doc_classes/OpenXRHand.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OpenXRHand" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OpenXRHand" inherits="Node3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> Node supporting finger tracking in OpenXR. </brief_description> diff --git a/modules/openxr/doc_classes/OpenXRIPBinding.xml b/modules/openxr/doc_classes/OpenXRIPBinding.xml index f3b14b3179..f274f0868e 100644 --- a/modules/openxr/doc_classes/OpenXRIPBinding.xml +++ b/modules/openxr/doc_classes/OpenXRIPBinding.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OpenXRIPBinding" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OpenXRIPBinding" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> Defines a binding between an [OpenXRAction] and an XR input or output. </brief_description> diff --git a/modules/openxr/doc_classes/OpenXRInteractionProfile.xml b/modules/openxr/doc_classes/OpenXRInteractionProfile.xml index 8c55a3360b..a69bb875fa 100644 --- a/modules/openxr/doc_classes/OpenXRInteractionProfile.xml +++ b/modules/openxr/doc_classes/OpenXRInteractionProfile.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OpenXRInteractionProfile" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OpenXRInteractionProfile" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> Suggested bindings object for OpenXR. </brief_description> diff --git a/modules/openxr/doc_classes/OpenXRInterface.xml b/modules/openxr/doc_classes/OpenXRInterface.xml index b6d52464c0..f0ca649fe4 100644 --- a/modules/openxr/doc_classes/OpenXRInterface.xml +++ b/modules/openxr/doc_classes/OpenXRInterface.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OpenXRInterface" inherits="XRInterface" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OpenXRInterface" inherits="XRInterface" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> Our OpenXR interface. </brief_description> diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h index 920bfe74b7..31f8d23268 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper.h +++ b/modules/openxr/extensions/openxr_extension_wrapper.h @@ -36,8 +36,6 @@ #include "core/templates/hash_map.h" #include "core/templates/rid.h" -#include "thirdparty/openxr/src/common/xr_linear.h" - #include <openxr/openxr.h> class OpenXRAPI; diff --git a/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp index 569895a620..f730f2bd2c 100644 --- a/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp +++ b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp @@ -107,10 +107,6 @@ bool OpenXRFbPassthroughExtensionWrapper::is_passthrough_enabled() { return fb_passthrough_ext && passthrough_handle != XR_NULL_HANDLE && passthrough_layer != XR_NULL_HANDLE; } -bool OpenXRFbPassthroughExtensionWrapper::is_composition_passthrough_layer_ready() { - return fb_passthrough_ext && passthrough_handle != XR_NULL_HANDLE && composition_passthrough_layer.layerHandle != XR_NULL_HANDLE; -} - bool OpenXRFbPassthroughExtensionWrapper::start_passthrough() { if (passthrough_handle == XR_NULL_HANDLE) { return false; @@ -128,6 +124,13 @@ bool OpenXRFbPassthroughExtensionWrapper::start_passthrough() { } // Create the passthrough layer + XrPassthroughLayerCreateInfoFB passthrough_layer_config = { + XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB, + nullptr, + passthrough_handle, + XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB, + XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB, + }; result = xrCreatePassthroughLayerFB(OpenXRAPI::get_singleton()->get_session(), &passthrough_layer_config, &passthrough_layer); if (!is_valid_passthrough_result(result, "Failed to create the passthrough layer")) { stop_passthrough(); @@ -140,14 +143,18 @@ bool OpenXRFbPassthroughExtensionWrapper::start_passthrough() { print_error("Main viewport doesn't have transparent background! Passthrough may not properly render."); } - composition_passthrough_layer.layerHandle = passthrough_layer; - return true; } void OpenXRFbPassthroughExtensionWrapper::on_session_created(const XrSession session) { if (fb_passthrough_ext) { // Create the passthrough feature and start it. + XrPassthroughCreateInfoFB passthrough_create_info = { + XR_TYPE_PASSTHROUGH_CREATE_INFO_FB, + nullptr, + 0, + }; + XrResult result = xrCreatePassthroughFB(OpenXRAPI::get_singleton()->get_session(), &passthrough_create_info, &passthrough_handle); if (!OpenXRAPI::get_singleton()->xr_result(result, "Failed to create passthrough")) { passthrough_handle = XR_NULL_HANDLE; @@ -157,7 +164,8 @@ void OpenXRFbPassthroughExtensionWrapper::on_session_created(const XrSession ses } XrCompositionLayerBaseHeader *OpenXRFbPassthroughExtensionWrapper::get_composition_layer() { - if (is_composition_passthrough_layer_ready()) { + if (is_passthrough_enabled()) { + composition_passthrough_layer.layerHandle = passthrough_layer; return (XrCompositionLayerBaseHeader *)&composition_passthrough_layer; } else { return nullptr; @@ -169,8 +177,6 @@ void OpenXRFbPassthroughExtensionWrapper::stop_passthrough() { return; } - composition_passthrough_layer.layerHandle = XR_NULL_HANDLE; - XrResult result; if (passthrough_layer != XR_NULL_HANDLE) { // Destroy the layer diff --git a/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.h b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.h index 619313809d..045e424202 100644 --- a/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.h +++ b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.h @@ -211,27 +211,12 @@ private: Viewport *get_main_viewport(); - bool is_composition_passthrough_layer_ready(); - static OpenXRFbPassthroughExtensionWrapper *singleton; bool fb_passthrough_ext = false; // required for any passthrough functionality bool fb_triangle_mesh_ext = false; // only use for projected passthrough - XrPassthroughCreateInfoFB passthrough_create_info = { - XR_TYPE_PASSTHROUGH_CREATE_INFO_FB, - nullptr, - 0, - }; XrPassthroughFB passthrough_handle = XR_NULL_HANDLE; - - XrPassthroughLayerCreateInfoFB passthrough_layer_config = { - XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB, - nullptr, - passthrough_handle, - XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB, - XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB, - }; XrPassthroughLayerFB passthrough_layer = XR_NULL_HANDLE; XrCompositionLayerPassthroughFB composition_passthrough_layer = { diff --git a/modules/openxr/extensions/openxr_hand_tracking_extension.cpp b/modules/openxr/extensions/openxr_hand_tracking_extension.cpp index 6fffa1ed07..65559afed0 100644 --- a/modules/openxr/extensions/openxr_hand_tracking_extension.cpp +++ b/modules/openxr/extensions/openxr_hand_tracking_extension.cpp @@ -134,6 +134,10 @@ void OpenXRHandTrackingExtension::on_process() { // process our hands const XrTime time = OpenXRAPI::get_singleton()->get_next_frame_time(); // This data will be used for the next frame we render + if (time == 0) { + // we don't have timing info yet, or we're skipping a frame... + return; + } XrResult result; diff --git a/modules/openxr/extensions/openxr_opengl_extension.cpp b/modules/openxr/extensions/openxr_opengl_extension.cpp index 39b5c61e8e..9038e9f458 100644 --- a/modules/openxr/extensions/openxr_opengl_extension.cpp +++ b/modules/openxr/extensions/openxr_opengl_extension.cpp @@ -278,8 +278,8 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in } bool OpenXROpenGLExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) { - XrMatrix4x4f matrix; - XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far); + OpenXRUtil::XrMatrix4x4f matrix; + OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far); for (int j = 0; j < 4; j++) { for (int i = 0; i < 4; i++) { diff --git a/modules/openxr/extensions/openxr_vulkan_extension.cpp b/modules/openxr/extensions/openxr_vulkan_extension.cpp index 90c1c62050..9429d9e082 100644 --- a/modules/openxr/extensions/openxr_vulkan_extension.cpp +++ b/modules/openxr/extensions/openxr_vulkan_extension.cpp @@ -233,9 +233,9 @@ void OpenXRVulkanExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usab } void OpenXRVulkanExtension::get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) { - p_usable_swap_chains.push_back(VK_FORMAT_R32_SFLOAT); p_usable_swap_chains.push_back(VK_FORMAT_D24_UNORM_S8_UINT); p_usable_swap_chains.push_back(VK_FORMAT_D32_SFLOAT_S8_UINT); + p_usable_swap_chains.push_back(VK_FORMAT_D32_SFLOAT); } bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) { @@ -308,8 +308,8 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UINT; usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; break; - case VK_FORMAT_R32_SFLOAT: - format = RenderingDevice::DATA_FORMAT_R32_SFLOAT; + case VK_FORMAT_D32_SFLOAT: + format = RenderingDevice::DATA_FORMAT_D32_SFLOAT; usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; break; case VK_FORMAT_D24_UNORM_S8_UINT: @@ -381,8 +381,8 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) { // Even though this is a Vulkan renderer we're using OpenGL coordinate systems - XrMatrix4x4f matrix; - XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far); + OpenXRUtil::XrMatrix4x4f matrix; + OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far); for (int j = 0; j < 4; j++) { for (int i = 0; i < 4; i++) { diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 21d9203ead..4ab280f3c3 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -855,18 +855,19 @@ bool OpenXRAPI::create_swapchains() { } if (swapchain_format_to_use == 0) { - swapchain_format_to_use = usable_swapchain_formats[0]; // just use the first one and hope for the best... - print_line("Couldn't find usable depth swap chain format, using", get_swapchain_format_name(swapchain_format_to_use), "instead."); + print_line("Couldn't find usable depth swap chain format, depth buffer will not be submitted."); } else { print_verbose(String("Using depth swap chain format:") + get_swapchain_format_name(swapchain_format_to_use)); - } - if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain, &swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data)) { - return false; - } + // Note, if VK_FORMAT_D32_SFLOAT is used here but we're using the forward+ renderer, we should probably output a warning. - depth_views = (XrCompositionLayerDepthInfoKHR *)memalloc(sizeof(XrCompositionLayerDepthInfoKHR) * view_count); - ERR_FAIL_NULL_V_MSG(depth_views, false, "OpenXR Couldn't allocate memory for depth views"); + if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain, &swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data)) { + return false; + } + + depth_views = (XrCompositionLayerDepthInfoKHR *)memalloc(sizeof(XrCompositionLayerDepthInfoKHR) * view_count); + ERR_FAIL_NULL_V_MSG(depth_views, false, "OpenXR Couldn't allocate memory for depth views"); + } } // We create our velocity swapchain if: @@ -1837,6 +1838,7 @@ RID OpenXRAPI::get_color_texture() { } RID OpenXRAPI::get_depth_texture() { + // Note, image will not be acquired if we didn't have a suitable swap chain format. if (submit_depth_buffer && swapchains[OPENXR_SWAPCHAIN_DEPTH].image_acquired) { return graphics_extension->get_texture(swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data, swapchains[OPENXR_SWAPCHAIN_DEPTH].image_index); } else { diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index 96af2bfc49..9374cb7afa 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -48,8 +48,6 @@ #include "core/templates/vector.h" #include "servers/xr/xr_pose.h" -#include "thirdparty/openxr/src/common/xr_linear.h" - #include <openxr/openxr.h> // Note, OpenXR code that we wrote for our plugin makes use of C++20 notation for initializing structs which ensures zeroing out unspecified members. diff --git a/modules/openxr/openxr_util.cpp b/modules/openxr/openxr_util.cpp index 0c5cdd7113..1d44233337 100644 --- a/modules/openxr/openxr_util.cpp +++ b/modules/openxr/openxr_util.cpp @@ -32,6 +32,8 @@ #include <openxr/openxr_reflection.h> +#include <math.h> + #define XR_ENUM_CASE_STR(name, val) \ case name: \ return #name; @@ -75,3 +77,89 @@ String OpenXRUtil::make_xr_version_string(XrVersion p_version) { return version; } + +// Copied from OpenXR xr_linear.h private header, so we can still link against +// system-provided packages without relying on our `thirdparty` code. + +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2016 Oculus VR, LLC. +// +// SPDX-License-Identifier: Apache-2.0 + +// Creates a projection matrix based on the specified dimensions. +// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API. +// The far plane is placed at infinity if farZ <= nearZ. +// An infinite projection matrix is preferred for rasterization because, except for +// things *right* up against the near plane, it always provides better precision: +// "Tightening the Precision of Perspective Rendering" +// Paul Upchurch, Mathieu Desbrun +// Journal of Graphics Tools, Volume 16, Issue 1, 2012 +void OpenXRUtil::XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const float tanAngleLeft, + const float tanAngleRight, const float tanAngleUp, float const tanAngleDown, + const float nearZ, const float farZ) { + const float tanAngleWidth = tanAngleRight - tanAngleLeft; + + // Set to tanAngleDown - tanAngleUp for a clip space with positive Y down (Vulkan). + // Set to tanAngleUp - tanAngleDown for a clip space with positive Y up (OpenGL / D3D / Metal). + const float tanAngleHeight = graphicsApi == GRAPHICS_VULKAN ? (tanAngleDown - tanAngleUp) : (tanAngleUp - tanAngleDown); + + // Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES). + // Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal). + const float offsetZ = (graphicsApi == GRAPHICS_OPENGL || graphicsApi == GRAPHICS_OPENGL_ES) ? nearZ : 0; + + if (farZ <= nearZ) { + // place the far plane at infinity + result->m[0] = 2.0f / tanAngleWidth; + result->m[4] = 0.0f; + result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth; + result->m[12] = 0.0f; + + result->m[1] = 0.0f; + result->m[5] = 2.0f / tanAngleHeight; + result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight; + result->m[13] = 0.0f; + + result->m[2] = 0.0f; + result->m[6] = 0.0f; + result->m[10] = -1.0f; + result->m[14] = -(nearZ + offsetZ); + + result->m[3] = 0.0f; + result->m[7] = 0.0f; + result->m[11] = -1.0f; + result->m[15] = 0.0f; + } else { + // normal projection + result->m[0] = 2.0f / tanAngleWidth; + result->m[4] = 0.0f; + result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth; + result->m[12] = 0.0f; + + result->m[1] = 0.0f; + result->m[5] = 2.0f / tanAngleHeight; + result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight; + result->m[13] = 0.0f; + + result->m[2] = 0.0f; + result->m[6] = 0.0f; + result->m[10] = -(farZ + offsetZ) / (farZ - nearZ); + result->m[14] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ); + + result->m[3] = 0.0f; + result->m[7] = 0.0f; + result->m[11] = -1.0f; + result->m[15] = 0.0f; + } +} + +// Creates a projection matrix based on the specified FOV. +void OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const XrFovf fov, + const float nearZ, const float farZ) { + const float tanLeft = tanf(fov.angleLeft); + const float tanRight = tanf(fov.angleRight); + + const float tanDown = tanf(fov.angleDown); + const float tanUp = tanf(fov.angleUp); + + XrMatrix4x4f_CreateProjection(result, graphicsApi, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ); +} diff --git a/modules/openxr/openxr_util.h b/modules/openxr/openxr_util.h index 8ad68c0b02..3f36ab9fca 100644 --- a/modules/openxr/openxr_util.h +++ b/modules/openxr/openxr_util.h @@ -44,6 +44,27 @@ public: static String get_action_type_name(XrActionType p_action_type); static String get_environment_blend_mode_name(XrEnvironmentBlendMode p_blend_mode); static String make_xr_version_string(XrVersion p_version); + + // Copied from OpenXR xr_linear.h private header, so we can still link against + // system-provided packages without relying on our `thirdparty` code. + + // Column-major, pre-multiplied. This type does not exist in the OpenXR API and is provided for convenience. + typedef struct XrMatrix4x4f { + float m[16]; + } XrMatrix4x4f; + + typedef enum GraphicsAPI { + GRAPHICS_VULKAN, + GRAPHICS_OPENGL, + GRAPHICS_OPENGL_ES, + GRAPHICS_D3D + } GraphicsAPI; + + static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const float tanAngleLeft, + const float tanAngleRight, const float tanAngleUp, float const tanAngleDown, + const float nearZ, const float farZ); + static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const XrFovf fov, + const float nearZ, const float farZ); }; #endif // OPENXR_UTIL_H |