diff --git a/modules/openxr/doc_classes/OpenXRAPIExtension.xml b/modules/openxr/doc_classes/OpenXRAPIExtension.xml index 48608375c3..27207045ee 100644 --- a/modules/openxr/doc_classes/OpenXRAPIExtension.xml +++ b/modules/openxr/doc_classes/OpenXRAPIExtension.xml @@ -257,6 +257,14 @@ [b]Note:[/b] This cannot be called after the OpenXR session has started. However, it can be called in [method OpenXRExtensionWrapper._on_session_created]. + + + + + Registers the given extension as modifying [code]XrCompositionLayerProjection[/code] via the [method OpenXRExtensionWrapper._set_projection_layer_and_get_next_pointer] virtual method. + [b]Note:[/b] This cannot be called after the OpenXR session has started. However, it can be called in [method OpenXRExtensionWrapper._on_session_created]. + + @@ -339,6 +347,14 @@ [b]Note:[/b] This cannot be called while the OpenXR session is still running. + + + + + Unregisters the given extension as modifying [code]XrCompositionLayerProjection[/code]. + [b]Note:[/b] This cannot be called while the OpenXR session is still running. + + diff --git a/modules/openxr/doc_classes/OpenXRExtensionWrapper.xml b/modules/openxr/doc_classes/OpenXRExtensionWrapper.xml index f216ad91ba..cf4a692410 100644 --- a/modules/openxr/doc_classes/OpenXRExtensionWrapper.xml +++ b/modules/openxr/doc_classes/OpenXRExtensionWrapper.xml @@ -276,6 +276,14 @@ Add additional data structures when the OpenXR instance is created. [param xr_version] specifies the OpenXR version we're instantiating. + + + + + Adds additional data structures to [code]XrCompositionLayerProjection[/code]. + This will only be called if the extension previously registered itself with [method OpenXRAPIExtension.register_projection_layer_extension]. + + diff --git a/modules/openxr/extensions/openxr_extension_wrapper.cpp b/modules/openxr/extensions/openxr_extension_wrapper.cpp index 58df171f9a..8ff23692f2 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper.cpp +++ b/modules/openxr/extensions/openxr_extension_wrapper.cpp @@ -43,6 +43,7 @@ void OpenXRExtensionWrapper::_bind_methods() { GDVIRTUAL_BIND(_set_projection_views_and_get_next_pointer, "view_index", "next_pointer"); GDVIRTUAL_BIND(_set_frame_wait_info_and_get_next_pointer, "next_pointer"); GDVIRTUAL_BIND(_set_frame_end_info_and_get_next_pointer, "next_pointer"); + GDVIRTUAL_BIND(_set_projection_layer_and_get_next_pointer, "next_pointer"); GDVIRTUAL_BIND(_set_view_locate_info_and_get_next_pointer, "next_pointer"); GDVIRTUAL_BIND(_set_reference_space_create_info_and_get_next_pointer, "reference_space_type", "next_pointer"); GDVIRTUAL_BIND(_prepare_view_configuration, "view_count"); @@ -210,6 +211,16 @@ void *OpenXRExtensionWrapper::set_frame_end_info_and_get_next_pointer(void *p_ne return nullptr; } +void *OpenXRExtensionWrapper::set_projection_layer_and_get_next_pointer(void *p_next_pointer) { + uint64_t pointer = 0; + + if (GDVIRTUAL_CALL(_set_projection_layer_and_get_next_pointer, GDExtensionPtr(p_next_pointer), pointer)) { + return reinterpret_cast(pointer); + } + + return nullptr; +} + void OpenXRExtensionWrapper::prepare_view_configuration(uint32_t p_view_count) { GDVIRTUAL_CALL(_prepare_view_configuration, p_view_count); } diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h index 47b5e37d43..a29dec218b 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper.h +++ b/modules/openxr/extensions/openxr_extension_wrapper.h @@ -88,6 +88,8 @@ public: virtual void *set_frame_wait_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when calling xrWaitFrame virtual void *set_view_locate_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when calling xrLocateViews virtual void *set_frame_end_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when calling xrEndFrame + // This will only be called for extensions registered via OpenXRAPI::register_projection_layer_extension(). + virtual void *set_projection_layer_and_get_next_pointer(void *p_next_pointer); // Add additional data structures to XrCompositionLayerProjection virtual void prepare_view_configuration(uint32_t p_view_count); virtual void *set_view_configuration_and_get_next_pointer(uint32_t p_view, void *p_next_pointer); // Add additional data structures when calling xrEnumerateViewConfiguration @@ -102,6 +104,7 @@ public: GDVIRTUAL2R(uint64_t, _set_projection_views_and_get_next_pointer, int, GDExtensionPtr); GDVIRTUAL1R(uint64_t, _set_frame_wait_info_and_get_next_pointer, GDExtensionPtr); GDVIRTUAL1R(uint64_t, _set_frame_end_info_and_get_next_pointer, GDExtensionPtr); + GDVIRTUAL1R(uint64_t, _set_projection_layer_and_get_next_pointer, GDExtensionPtr); GDVIRTUAL1R(uint64_t, _set_view_locate_info_and_get_next_pointer, GDExtensionPtr); GDVIRTUAL2R(uint64_t, _set_reference_space_create_info_and_get_next_pointer, int, GDExtensionPtr); GDVIRTUAL0R(int, _get_composition_layer_count); diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index d7ba393671..86cbabc5c3 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -2655,6 +2655,15 @@ void OpenXRAPI::end_frame() { layer_flags |= XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT; } + void *projection_layer_next_pointer = nullptr; + for (OpenXRExtensionWrapper *extension : projection_layer_extensions) { + void *np = extension->set_projection_layer_and_get_next_pointer(projection_layer_next_pointer); + if (np != nullptr) { + projection_layer_next_pointer = np; + } + } + + render_state.projection_layer.next = projection_layer_next_pointer; render_state.projection_layer.layerFlags = layer_flags; render_state.projection_layer.space = render_state.play_space; render_state.projection_layer.viewCount = (uint32_t)render_state.projection_views.size(); @@ -2905,6 +2914,7 @@ OpenXRAPI::OpenXRAPI() { OpenXRAPI::~OpenXRAPI() { composition_layer_providers.clear(); frame_info_extensions.clear(); + projection_layer_extensions.clear(); supported_extensions.clear(); layer_properties.clear(); @@ -3959,6 +3969,14 @@ void OpenXRAPI::unregister_frame_info_extension(OpenXRExtensionWrapper *p_extens frame_info_extensions.erase(p_extension); } +void OpenXRAPI::register_projection_layer_extension(OpenXRExtensionWrapper *p_extension) { + projection_layer_extensions.append(p_extension); +} + +void OpenXRAPI::unregister_projection_layer_extension(OpenXRExtensionWrapper *p_extension) { + projection_layer_extensions.erase(p_extension); +} + const Vector OpenXRAPI::get_supported_environment_blend_modes() { return supported_environment_blend_modes; } diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index e462c26a75..36d948560c 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -107,6 +107,9 @@ private: // frame info extensions Vector frame_info_extensions; + // projection layer extensions + Vector projection_layer_extensions; + // view configuration LocalVector supported_view_configuration_types; @@ -632,6 +635,9 @@ public: void register_frame_info_extension(OpenXRExtensionWrapper *p_extension); void unregister_frame_info_extension(OpenXRExtensionWrapper *p_extension); + void register_projection_layer_extension(OpenXRExtensionWrapper *p_extension); + void unregister_projection_layer_extension(OpenXRExtensionWrapper *p_extension); + const Vector get_supported_environment_blend_modes(); bool is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const; diff --git a/modules/openxr/openxr_api_extension.cpp b/modules/openxr/openxr_api_extension.cpp index 14017c2653..0de8e9c805 100644 --- a/modules/openxr/openxr_api_extension.cpp +++ b/modules/openxr/openxr_api_extension.cpp @@ -76,6 +76,9 @@ void OpenXRAPIExtension::_bind_methods() { ClassDB::bind_method(D_METHOD("register_frame_info_extension", "extension"), &OpenXRAPIExtension::register_frame_info_extension); ClassDB::bind_method(D_METHOD("unregister_frame_info_extension", "extension"), &OpenXRAPIExtension::unregister_frame_info_extension); + ClassDB::bind_method(D_METHOD("register_projection_layer_extension", "extension"), &OpenXRAPIExtension::register_projection_layer_extension); + ClassDB::bind_method(D_METHOD("unregister_projection_layer_extension", "extension"), &OpenXRAPIExtension::unregister_projection_layer_extension); + ClassDB::bind_method(D_METHOD("get_render_state_z_near"), &OpenXRAPIExtension::get_render_state_z_near); ClassDB::bind_method(D_METHOD("get_render_state_z_far"), &OpenXRAPIExtension::get_render_state_z_far); @@ -281,6 +284,16 @@ void OpenXRAPIExtension::unregister_frame_info_extension(OpenXRExtensionWrapper OpenXRAPI::get_singleton()->unregister_frame_info_extension(p_extension); } +void OpenXRAPIExtension::register_projection_layer_extension(OpenXRExtensionWrapper *p_extension) { + ERR_FAIL_NULL(OpenXRAPI::get_singleton()); + OpenXRAPI::get_singleton()->register_projection_layer_extension(p_extension); +} + +void OpenXRAPIExtension::unregister_projection_layer_extension(OpenXRExtensionWrapper *p_extension) { + ERR_FAIL_NULL(OpenXRAPI::get_singleton()); + OpenXRAPI::get_singleton()->unregister_projection_layer_extension(p_extension); +} + double OpenXRAPIExtension::get_render_state_z_near() { ERR_NOT_ON_RENDER_THREAD_V(0.0); ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), 0.0); diff --git a/modules/openxr/openxr_api_extension.h b/modules/openxr/openxr_api_extension.h index f17e123ab7..103ca4b6c0 100644 --- a/modules/openxr/openxr_api_extension.h +++ b/modules/openxr/openxr_api_extension.h @@ -103,6 +103,9 @@ public: void register_frame_info_extension(OpenXRExtensionWrapper *p_extension); void unregister_frame_info_extension(OpenXRExtensionWrapper *p_extension); + void register_projection_layer_extension(OpenXRExtensionWrapper *p_extension); + void unregister_projection_layer_extension(OpenXRExtensionWrapper *p_extension); + double get_render_state_z_near(); double get_render_state_z_far();