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();