1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +00:00

Implement OpenXR FB swapchain update extensions

This commit is contained in:
devloglogan
2025-01-20 13:09:20 -06:00
parent a77a28c029
commit 251ae9c138
7 changed files with 748 additions and 1 deletions

View File

@@ -53,10 +53,109 @@
The sort order for this composition layer. Higher numbers will be shown in front of lower numbers. The sort order for this composition layer. Higher numbers will be shown in front of lower numbers.
[b]Note:[/b] This will have no effect if a fallback mesh is being used. [b]Note:[/b] This will have no effect if a fallback mesh is being used.
</member> </member>
<member name="swapchain_state_alpha_swizzle" type="int" setter="set_alpha_swizzle" getter="get_alpha_swizzle" enum="OpenXRCompositionLayer.Swizzle" default="3">
The swizzle value for the alpha channel of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_blue_swizzle" type="int" setter="set_blue_swizzle" getter="get_blue_swizzle" enum="OpenXRCompositionLayer.Swizzle" default="2">
The swizzle value for the blue channel of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_border_color" type="Color" setter="set_border_color" getter="get_border_color" default="Color(0, 0, 0, 0)">
The border color of the swapchain state that is used when the wrap mode clamps to the border.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_green_swizzle" type="int" setter="set_green_swizzle" getter="get_green_swizzle" enum="OpenXRCompositionLayer.Swizzle" default="1">
The swizzle value for the green channel of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_horizontal_wrap" type="int" setter="set_horizontal_wrap" getter="get_horizontal_wrap" enum="OpenXRCompositionLayer.Wrap" default="0">
The horizontal wrap mode of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_mag_filter" type="int" setter="set_mag_filter" getter="get_mag_filter" enum="OpenXRCompositionLayer.Filter" default="1">
The magnification filter of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_max_anisotropy" type="float" setter="set_max_anisotropy" getter="get_max_anisotropy" default="1.0">
The max anisotropy of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_min_filter" type="int" setter="set_min_filter" getter="get_min_filter" enum="OpenXRCompositionLayer.Filter" default="1">
The minification filter of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_mipmap_mode" type="int" setter="set_mipmap_mode" getter="get_mipmap_mode" enum="OpenXRCompositionLayer.MipmapMode" default="2">
The mipmap mode of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_red_swizzle" type="int" setter="set_red_swizzle" getter="get_red_swizzle" enum="OpenXRCompositionLayer.Swizzle" default="0">
The swizzle value for the red channel of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="swapchain_state_vertical_wrap" type="int" setter="set_vertical_wrap" getter="get_vertical_wrap" enum="OpenXRCompositionLayer.Wrap" default="0">
The vertical wrap mode of the swapchain state.
[b]Note:[/b] This property only has an effect on devices that support the OpenXR XR_FB_swapchain_update_state OpenGLES/Vulkan extensions.
</member>
<member name="use_android_surface" type="bool" setter="set_use_android_surface" getter="get_use_android_surface" default="false"> <member name="use_android_surface" type="bool" setter="set_use_android_surface" getter="get_use_android_surface" default="false">
If enabled, an Android surface will be created (with the dimensions from [member android_surface_size]) which will provide the 2D content for the composition layer, rather than using [member layer_viewport]. If enabled, an Android surface will be created (with the dimensions from [member android_surface_size]) which will provide the 2D content for the composition layer, rather than using [member layer_viewport].
See [method get_android_surface] for information about how to get the surface so that your application can draw to it. See [method get_android_surface] for information about how to get the surface so that your application can draw to it.
[b]Note:[/b] This will only work in Android builds. [b]Note:[/b] This will only work in Android builds.
</member> </member>
</members> </members>
<constants>
<constant name="FILTER_NEAREST" value="0" enum="Filter">
Perform nearest-neighbor filtering when sampling the texture.
</constant>
<constant name="FILTER_LINEAR" value="1" enum="Filter">
Perform linear filtering when sampling the texture.
</constant>
<constant name="FILTER_CUBIC" value="2" enum="Filter">
Perform cubic filtering when sampling the texture.
</constant>
<constant name="MIPMAP_MODE_DISABLED" value="0" enum="MipmapMode">
Disable mipmapping.
[b]Note:[/b] Mipmapping can only be disabled in the compatibility renderer.
</constant>
<constant name="MIPMAP_MODE_NEAREST" value="1" enum="MipmapMode">
Use the mipmap of the nearest resolution.
</constant>
<constant name="MIPMAP_MODE_LINEAR" value="2" enum="MipmapMode">
Use linear interpolation of the two mipmaps of the nearest resolution.
</constant>
<constant name="WRAP_CLAMP_TO_BORDER" value="0" enum="Wrap">
Clamp the texture to its specified border color.
</constant>
<constant name="WRAP_CLAMP_TO_EDGE" value="1" enum="Wrap">
Clamp the texture to its edge color.
</constant>
<constant name="WRAP_REPEAT" value="2" enum="Wrap">
Repeat the texture infinitely.
</constant>
<constant name="WRAP_MIRRORED_REPEAT" value="3" enum="Wrap">
Repeat the texture infinitely, mirroring it on each repeat.
</constant>
<constant name="WRAP_MIRROR_CLAMP_TO_EDGE" value="4" enum="Wrap">
Mirror the texture once and then clamp the texture to its edge color.
[b]Note:[/b] This wrap mode is not available in the compatibility renderer.
</constant>
<constant name="SWIZZLE_RED" value="0" enum="Swizzle">
Maps a color channel to the value of the red channel.
</constant>
<constant name="SWIZZLE_GREEN" value="1" enum="Swizzle">
Maps a color channel to the value of the green channel.
</constant>
<constant name="SWIZZLE_BLUE" value="2" enum="Swizzle">
Maps a color channel to the value of the blue channel.
</constant>
<constant name="SWIZZLE_ALPHA" value="3" enum="Swizzle">
Maps a color channel to the value of the alpha channel.
</constant>
<constant name="SWIZZLE_ZERO" value="4" enum="Swizzle">
Maps a color channel to the value of zero.
</constant>
<constant name="SWIZZLE_ONE" value="5" enum="Swizzle">
Maps a color channel to the value of one.
</constant>
</constants>
</class> </class>

View File

@@ -35,6 +35,7 @@
#include <openxr/openxr_platform.h> #include <openxr/openxr_platform.h>
#endif #endif
#include "openxr_fb_update_swapchain_extension.h"
#include "platform/android/api/java_class_wrapper.h" #include "platform/android/api/java_class_wrapper.h"
#include "servers/rendering/rendering_server_globals.h" #include "servers/rendering/rendering_server_globals.h"
@@ -227,6 +228,13 @@ void OpenXRViewportCompositionLayerProvider::set_viewport(RID p_viewport, Size2i
void OpenXRViewportCompositionLayerProvider::set_use_android_surface(bool p_use_android_surface, Size2i p_size) { void OpenXRViewportCompositionLayerProvider::set_use_android_surface(bool p_use_android_surface, Size2i p_size) {
#ifdef ANDROID_ENABLED #ifdef ANDROID_ENABLED
if (p_use_android_surface == use_android_surface) { if (p_use_android_surface == use_android_surface) {
if (use_android_surface && swapchain_size != p_size) {
OpenXRFBUpdateSwapchainExtension *fb_update_swapchain_ext = OpenXRFBUpdateSwapchainExtension::get_singleton();
if (fb_update_swapchain_ext && fb_update_swapchain_ext->is_android_ext_enabled()) {
swapchain_size = p_size;
fb_update_swapchain_ext->update_swapchain_surface_size(android_surface.swapchain, swapchain_size);
}
}
return; return;
} }
@@ -280,6 +288,8 @@ void OpenXRViewportCompositionLayerProvider::create_android_surface() {
jobject surface; jobject surface;
composition_layer_extension->create_android_surface_swapchain(&info, &android_surface.swapchain, &surface); composition_layer_extension->create_android_surface_swapchain(&info, &android_surface.swapchain, &surface);
swapchain_state.dirty = true;
if (surface) { if (surface) {
android_surface.surface.instantiate(JavaClassWrapper::get_singleton()->wrap("android.view.Surface"), surface); android_surface.surface.instantiate(JavaClassWrapper::get_singleton()->wrap("android.view.Surface"), surface);
} }
@@ -327,6 +337,11 @@ void OpenXRViewportCompositionLayerProvider::on_pre_render() {
} }
} }
} }
if (swapchain_state.dirty) {
update_swapchain_state();
swapchain_state.dirty = false;
}
} }
XrCompositionLayerBaseHeader *OpenXRViewportCompositionLayerProvider::get_composition_layer() { XrCompositionLayerBaseHeader *OpenXRViewportCompositionLayerProvider::get_composition_layer() {
@@ -393,6 +408,34 @@ XrCompositionLayerBaseHeader *OpenXRViewportCompositionLayerProvider::get_compos
return composition_layer; return composition_layer;
} }
void OpenXRViewportCompositionLayerProvider::update_swapchain_state() {
OpenXRFBUpdateSwapchainExtension *fb_update_swapchain_ext = OpenXRFBUpdateSwapchainExtension::get_singleton();
if (!fb_update_swapchain_ext) {
return;
}
#ifdef ANDROID_ENABLED
if (use_android_surface) {
if (android_surface.swapchain == XR_NULL_HANDLE) {
return;
}
fb_update_swapchain_ext->update_swapchain_state(android_surface.swapchain, &swapchain_state);
} else
#endif
{
if (subviewport.swapchain_info.get_swapchain() == XR_NULL_HANDLE) {
return;
}
fb_update_swapchain_ext->update_swapchain_state(subviewport.swapchain_info.get_swapchain(), &swapchain_state);
}
}
OpenXRViewportCompositionLayerProvider::SwapchainState *OpenXRViewportCompositionLayerProvider::get_swapchain_state() {
return &swapchain_state;
}
void OpenXRViewportCompositionLayerProvider::update_swapchain_sub_image(XrSwapchainSubImage &r_subimage) { void OpenXRViewportCompositionLayerProvider::update_swapchain_sub_image(XrSwapchainSubImage &r_subimage) {
#ifdef ANDROID_ENABLED #ifdef ANDROID_ENABLED
if (use_android_surface) { if (use_android_surface) {
@@ -451,6 +494,8 @@ bool OpenXRViewportCompositionLayerProvider::update_and_acquire_swapchain(bool p
return false; return false;
} }
swapchain_state.dirty = true;
// Acquire our image so we can start rendering into it, // Acquire our image so we can start rendering into it,
// we can ignore should_render here, ret will be false. // we can ignore should_render here, ret will be false.
bool should_render = true; bool should_render = true;

View File

@@ -96,6 +96,56 @@ private:
}; };
class OpenXRViewportCompositionLayerProvider { class OpenXRViewportCompositionLayerProvider {
public:
// Must be identical to Filter enum definition in OpenXRCompositionLayer.
enum Filter {
FILTER_NEAREST,
FILTER_LINEAR,
FILTER_CUBIC,
};
// Must be identical to MipmapMode enum definition in OpenXRCompositionLayer.
enum MipmapMode {
MIPMAP_MODE_DISABLED,
MIPMAP_MODE_NEAREST,
MIPMAP_MODE_LINEAR,
};
// Must be identical to Wrap enum definition in OpenXRCompositionLayer.
enum Wrap {
WRAP_CLAMP_TO_BORDER,
WRAP_CLAMP_TO_EDGE,
WRAP_REPEAT,
WRAP_MIRRORED_REPEAT,
WRAP_MIRROR_CLAMP_TO_EDGE,
};
// Must be identical to Swizzle enum definition in OpenXRCompositionLayer.
enum Swizzle {
SWIZZLE_RED,
SWIZZLE_GREEN,
SWIZZLE_BLUE,
SWIZZLE_ALPHA,
SWIZZLE_ZERO,
SWIZZLE_ONE,
};
struct SwapchainState {
Filter min_filter = Filter::FILTER_LINEAR;
Filter mag_filter = Filter::FILTER_LINEAR;
MipmapMode mipmap_mode = MipmapMode::MIPMAP_MODE_LINEAR;
Wrap horizontal_wrap = Wrap::WRAP_CLAMP_TO_BORDER;
Wrap vertical_wrap = Wrap::WRAP_CLAMP_TO_BORDER;
Swizzle red_swizzle = Swizzle::SWIZZLE_RED;
Swizzle green_swizzle = Swizzle::SWIZZLE_GREEN;
Swizzle blue_swizzle = Swizzle::SWIZZLE_BLUE;
Swizzle alpha_swizzle = Swizzle::SWIZZLE_ALPHA;
float max_anisotropy = 1.0;
Color border_color = { 0.0, 0.0, 0.0, 0.0 };
bool dirty = false;
};
private:
XrCompositionLayerBaseHeader *composition_layer = nullptr; XrCompositionLayerBaseHeader *composition_layer = nullptr;
int sort_order = 1; int sort_order = 1;
bool alpha_blend = false; bool alpha_blend = false;
@@ -129,6 +179,8 @@ class OpenXRViewportCompositionLayerProvider {
void update_swapchain_sub_image(XrSwapchainSubImage &r_swapchain_sub_image); void update_swapchain_sub_image(XrSwapchainSubImage &r_swapchain_sub_image);
void free_swapchain(); void free_swapchain();
SwapchainState swapchain_state;
#ifdef ANDROID_ENABLED #ifdef ANDROID_ENABLED
void create_android_surface(); void create_android_surface();
#endif #endif
@@ -155,6 +207,9 @@ public:
void on_pre_render(); void on_pre_render();
XrCompositionLayerBaseHeader *get_composition_layer(); XrCompositionLayerBaseHeader *get_composition_layer();
void update_swapchain_state();
SwapchainState *get_swapchain_state();
OpenXRViewportCompositionLayerProvider(XrCompositionLayerBaseHeader *p_composition_layer); OpenXRViewportCompositionLayerProvider(XrCompositionLayerBaseHeader *p_composition_layer);
~OpenXRViewportCompositionLayerProvider(); ~OpenXRViewportCompositionLayerProvider();
}; };

View File

@@ -33,6 +33,19 @@
// Always include this as late as possible. // Always include this as late as possible.
#include "../openxr_platform_inc.h" #include "../openxr_platform_inc.h"
#ifndef GL_CUBIC_IMG
#define GL_CUBIC_IMG 0x9139
#endif
#ifndef GL_CUBIC_MIPMAP_LINEAR_IMG
#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B
#endif
#ifndef GL_CUBIC_MIPMAP_NEAREST_IMG
#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A
#endif
#ifndef GL_CLAMP_TO_BORDER
#define GL_CLAMP_TO_BORDER 0x812D
#endif
OpenXRFBUpdateSwapchainExtension *OpenXRFBUpdateSwapchainExtension::singleton = nullptr; OpenXRFBUpdateSwapchainExtension *OpenXRFBUpdateSwapchainExtension::singleton = nullptr;
OpenXRFBUpdateSwapchainExtension *OpenXRFBUpdateSwapchainExtension::get_singleton() { OpenXRFBUpdateSwapchainExtension *OpenXRFBUpdateSwapchainExtension::get_singleton() {
@@ -63,6 +76,10 @@ HashMap<String, bool *> OpenXRFBUpdateSwapchainExtension::get_requested_extensio
#endif #endif
} }
#ifdef ANDROID_ENABLED
request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_ANDROID_SURFACE_EXTENSION_NAME] = &fb_swapchain_update_state_android_ext;
#endif
return request_extensions; return request_extensions;
} }
@@ -100,3 +117,231 @@ bool OpenXRFBUpdateSwapchainExtension::is_enabled() const {
return false; return false;
} }
bool OpenXRFBUpdateSwapchainExtension::is_android_ext_enabled() const {
return fb_swapchain_update_state_android_ext;
}
void OpenXRFBUpdateSwapchainExtension::update_swapchain_state(XrSwapchain p_swapchain, const OpenXRViewportCompositionLayerProvider::SwapchainState *p_swapchain_state) {
if (!p_swapchain_state) {
return;
}
if (rendering_driver == "vulkan") {
#ifdef XR_USE_GRAPHICS_API_VULKAN
if (!fb_swapchain_update_state_ext || !fb_swapchain_update_state_vulkan_ext) {
return;
}
Color border_color = p_swapchain_state->border_color;
XrSwapchainStateSamplerVulkanFB swapchain_state = {
XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB, // type
nullptr, // next
(VkFilter)filter_to_vk(p_swapchain_state->min_filter), // minFilter
(VkFilter)filter_to_vk(p_swapchain_state->mag_filter), // magFilter
(VkSamplerMipmapMode)mipmap_mode_to_vk(p_swapchain_state->mipmap_mode), // mipmapMode
(VkSamplerAddressMode)wrap_to_vk(p_swapchain_state->horizontal_wrap), // wrapModeS;
(VkSamplerAddressMode)wrap_to_vk(p_swapchain_state->vertical_wrap), // wrapModeT
(VkComponentSwizzle)swizzle_to_vk(p_swapchain_state->red_swizzle), // swizzleRed
(VkComponentSwizzle)swizzle_to_vk(p_swapchain_state->green_swizzle), // swizzleGreen
(VkComponentSwizzle)swizzle_to_vk(p_swapchain_state->blue_swizzle), // swizzleBlue
(VkComponentSwizzle)swizzle_to_vk(p_swapchain_state->alpha_swizzle), // swizzleAlpha
p_swapchain_state->max_anisotropy, // maxAnisotropy
{ border_color.r, border_color.g, border_color.b, border_color.a } // borderColor
};
XrResult result = xrUpdateSwapchainFB(p_swapchain, (XrSwapchainStateBaseHeaderFB *)&swapchain_state);
if (XR_FAILED(result)) {
print_error(vformat("OpenXR: Failed to update swapchain [%s]", OpenXRAPI::get_singleton()->get_error_string(result)));
return;
}
#endif
} else if (rendering_driver == "opengl3") {
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
if (!fb_swapchain_update_state_ext || !fb_swapchain_update_state_opengles_ext) {
return;
}
Color border_color = p_swapchain_state->border_color;
XrSwapchainStateSamplerOpenGLESFB swapchain_state = {
XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB, // type
nullptr, // next
filter_to_gl(p_swapchain_state->min_filter, p_swapchain_state->mipmap_mode), // minFilter
filter_to_gl(p_swapchain_state->mag_filter), // magFilter
wrap_to_gl(p_swapchain_state->horizontal_wrap), // wrapModeS;
wrap_to_gl(p_swapchain_state->vertical_wrap), // wrapModeT
swizzle_to_gl(p_swapchain_state->red_swizzle), // swizzleRed
swizzle_to_gl(p_swapchain_state->green_swizzle), // swizzleGreen
swizzle_to_gl(p_swapchain_state->blue_swizzle), // swizzleBlue
swizzle_to_gl(p_swapchain_state->alpha_swizzle), // swizzleAlpha
p_swapchain_state->max_anisotropy, // maxAnisotropy
{ border_color.r, border_color.g, border_color.b, border_color.a } // borderColor
};
XrResult result = xrUpdateSwapchainFB(p_swapchain, (XrSwapchainStateBaseHeaderFB *)&swapchain_state);
if (XR_FAILED(result)) {
print_error(vformat("OpenXR: Failed to update swapchain [%s]", OpenXRAPI::get_singleton()->get_error_string(result)));
return;
}
#endif
}
}
void OpenXRFBUpdateSwapchainExtension::update_swapchain_surface_size(XrSwapchain p_swapchain, const Size2i &p_size) {
#ifdef ANDROID_ENABLED
if (!fb_swapchain_update_state_ext || !fb_swapchain_update_state_android_ext) {
return;
}
XrSwapchainStateAndroidSurfaceDimensionsFB swapchain_state = {
XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB, // type
nullptr, // next
(uint32_t)p_size.width, // width
(uint32_t)p_size.height // height
};
XrResult result = xrUpdateSwapchainFB(p_swapchain, (XrSwapchainStateBaseHeaderFB *)&swapchain_state);
if (XR_FAILED(result)) {
print_error(vformat("OpenXR: Failed to update swapchain surface size [%s]", OpenXRAPI::get_singleton()->get_error_string(result)));
}
#endif
}
uint32_t OpenXRFBUpdateSwapchainExtension::filter_to_gl(OpenXRViewportCompositionLayerProvider::Filter p_filter, OpenXRViewportCompositionLayerProvider::MipmapMode p_mipmap_mode) {
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
switch (p_mipmap_mode) {
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_DISABLED:
switch (p_filter) {
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_NEAREST:
return GL_NEAREST;
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_LINEAR:
return GL_LINEAR;
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_CUBIC:
return GL_CUBIC_IMG;
}
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_NEAREST:
switch (p_filter) {
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_NEAREST:
return GL_NEAREST_MIPMAP_NEAREST;
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_LINEAR:
return GL_LINEAR_MIPMAP_NEAREST;
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_CUBIC:
return GL_CUBIC_MIPMAP_NEAREST_IMG;
}
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_LINEAR:
switch (p_filter) {
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_NEAREST:
return GL_NEAREST_MIPMAP_LINEAR;
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_LINEAR:
return GL_LINEAR_MIPMAP_LINEAR;
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_CUBIC:
return GL_CUBIC_MIPMAP_LINEAR_IMG;
}
}
#endif
return 0;
}
uint32_t OpenXRFBUpdateSwapchainExtension::wrap_to_gl(OpenXRViewportCompositionLayerProvider::Wrap p_wrap) {
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
switch (p_wrap) {
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_CLAMP_TO_BORDER:
return GL_CLAMP_TO_BORDER;
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_CLAMP_TO_EDGE:
return GL_CLAMP_TO_EDGE;
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_REPEAT:
return GL_REPEAT;
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_MIRRORED_REPEAT:
return GL_MIRRORED_REPEAT;
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_MIRROR_CLAMP_TO_EDGE:
return GL_CLAMP_TO_EDGE;
}
#endif
return 0;
}
uint32_t OpenXRFBUpdateSwapchainExtension::swizzle_to_gl(OpenXRViewportCompositionLayerProvider::Swizzle p_swizzle) {
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
switch (p_swizzle) {
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_RED:
return GL_RED;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_GREEN:
return GL_GREEN;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_BLUE:
return GL_BLUE;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ALPHA:
return GL_ALPHA;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ZERO:
return GL_ZERO;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ONE:
return GL_ONE;
}
#endif
return 0;
}
uint32_t OpenXRFBUpdateSwapchainExtension::filter_to_vk(OpenXRViewportCompositionLayerProvider::Filter p_filter) {
#ifdef XR_USE_GRAPHICS_API_VULKAN
switch (p_filter) {
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_NEAREST:
return VK_FILTER_NEAREST;
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_LINEAR:
return VK_FILTER_LINEAR;
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_CUBIC:
return VK_FILTER_CUBIC_EXT;
}
#endif
return 0;
}
uint32_t OpenXRFBUpdateSwapchainExtension::mipmap_mode_to_vk(OpenXRViewportCompositionLayerProvider::MipmapMode p_mipmap_mode) {
#ifdef XR_USE_GRAPHICS_API_VULKAN
switch (p_mipmap_mode) {
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_DISABLED:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
}
#endif
return 0;
}
uint32_t OpenXRFBUpdateSwapchainExtension::wrap_to_vk(OpenXRViewportCompositionLayerProvider::Wrap p_wrap) {
#ifdef XR_USE_GRAPHICS_API_VULKAN
switch (p_wrap) {
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_CLAMP_TO_BORDER:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_MIRRORED_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_MIRROR_CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
}
#endif
return 0;
}
uint32_t OpenXRFBUpdateSwapchainExtension::swizzle_to_vk(OpenXRViewportCompositionLayerProvider::Swizzle p_swizzle) {
#ifdef XR_USE_GRAPHICS_API_VULKAN
switch (p_swizzle) {
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_RED:
return VK_COMPONENT_SWIZZLE_R;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_GREEN:
return VK_COMPONENT_SWIZZLE_G;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_BLUE:
return VK_COMPONENT_SWIZZLE_B;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ALPHA:
return VK_COMPONENT_SWIZZLE_A;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ZERO:
return VK_COMPONENT_SWIZZLE_ZERO;
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ONE:
return VK_COMPONENT_SWIZZLE_ONE;
}
#endif
return 0;
}

View File

@@ -37,6 +37,7 @@
#include "../openxr_api.h" #include "../openxr_api.h"
#include "../util.h" #include "../util.h"
#include "openxr_composition_layer_extension.h"
#include "openxr_extension_wrapper.h" #include "openxr_extension_wrapper.h"
class OpenXRFBUpdateSwapchainExtension : public OpenXRExtensionWrapper { class OpenXRFBUpdateSwapchainExtension : public OpenXRExtensionWrapper {
@@ -54,6 +55,11 @@ public:
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;
bool is_enabled() const; bool is_enabled() const;
bool is_android_ext_enabled() const;
void update_swapchain_state(XrSwapchain p_swapchain, const OpenXRViewportCompositionLayerProvider::SwapchainState *p_swapchain_state);
void update_swapchain_surface_size(XrSwapchain p_swapchain, const Size2i &p_size);
private: private:
static OpenXRFBUpdateSwapchainExtension *singleton; static OpenXRFBUpdateSwapchainExtension *singleton;
@@ -63,6 +69,16 @@ private:
bool fb_swapchain_update_state_ext = false; bool fb_swapchain_update_state_ext = false;
bool fb_swapchain_update_state_vulkan_ext = false; bool fb_swapchain_update_state_vulkan_ext = false;
bool fb_swapchain_update_state_opengles_ext = false; bool fb_swapchain_update_state_opengles_ext = false;
bool fb_swapchain_update_state_android_ext = false;
uint32_t filter_to_gl(OpenXRViewportCompositionLayerProvider::Filter p_filter, OpenXRViewportCompositionLayerProvider::MipmapMode p_mipmap_mode = OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_DISABLED);
uint32_t wrap_to_gl(OpenXRViewportCompositionLayerProvider::Wrap p_wrap);
uint32_t swizzle_to_gl(OpenXRViewportCompositionLayerProvider::Swizzle p_swizzle);
uint32_t filter_to_vk(OpenXRViewportCompositionLayerProvider::Filter p_filter);
uint32_t mipmap_mode_to_vk(OpenXRViewportCompositionLayerProvider::MipmapMode p_mipmap);
uint32_t wrap_to_vk(OpenXRViewportCompositionLayerProvider::Wrap p_wrap);
uint32_t swizzle_to_vk(OpenXRViewportCompositionLayerProvider::Swizzle p_swizzle);
// OpenXR API call wrappers // OpenXR API call wrappers
EXT_PROTO_XRRESULT_FUNC2(xrUpdateSwapchainFB, (XrSwapchain), swapchain, (const XrSwapchainStateBaseHeaderFB *), state); EXT_PROTO_XRRESULT_FUNC2(xrUpdateSwapchainFB, (XrSwapchain), swapchain, (const XrSwapchainStateBaseHeaderFB *), state);

View File

@@ -30,7 +30,6 @@
#include "openxr_composition_layer.h" #include "openxr_composition_layer.h"
#include "../extensions/openxr_composition_layer_extension.h"
#include "../openxr_api.h" #include "../openxr_api.h"
#include "../openxr_interface.h" #include "../openxr_interface.h"
@@ -52,6 +51,7 @@ static const char *HOLE_PUNCH_SHADER_CODE =
OpenXRCompositionLayer::OpenXRCompositionLayer(XrCompositionLayerBaseHeader *p_composition_layer) { OpenXRCompositionLayer::OpenXRCompositionLayer(XrCompositionLayerBaseHeader *p_composition_layer) {
composition_layer_base_header = p_composition_layer; composition_layer_base_header = p_composition_layer;
openxr_layer_provider = memnew(OpenXRViewportCompositionLayerProvider(composition_layer_base_header)); openxr_layer_provider = memnew(OpenXRViewportCompositionLayerProvider(composition_layer_base_header));
swapchain_state = openxr_layer_provider->get_swapchain_state();
openxr_api = OpenXRAPI::get_singleton(); openxr_api = OpenXRAPI::get_singleton();
composition_layer_extension = OpenXRCompositionLayerExtension::get_singleton(); composition_layer_extension = OpenXRCompositionLayerExtension::get_singleton();
@@ -113,6 +113,39 @@ void OpenXRCompositionLayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_android_surface"), &OpenXRCompositionLayer::get_android_surface); ClassDB::bind_method(D_METHOD("get_android_surface"), &OpenXRCompositionLayer::get_android_surface);
ClassDB::bind_method(D_METHOD("is_natively_supported"), &OpenXRCompositionLayer::is_natively_supported); ClassDB::bind_method(D_METHOD("is_natively_supported"), &OpenXRCompositionLayer::is_natively_supported);
ClassDB::bind_method(D_METHOD("set_min_filter", "mode"), &OpenXRCompositionLayer::set_min_filter);
ClassDB::bind_method(D_METHOD("get_min_filter"), &OpenXRCompositionLayer::get_min_filter);
ClassDB::bind_method(D_METHOD("set_mag_filter", "mode"), &OpenXRCompositionLayer::set_mag_filter);
ClassDB::bind_method(D_METHOD("get_mag_filter"), &OpenXRCompositionLayer::get_mag_filter);
ClassDB::bind_method(D_METHOD("set_mipmap_mode", "mode"), &OpenXRCompositionLayer::set_mipmap_mode);
ClassDB::bind_method(D_METHOD("get_mipmap_mode"), &OpenXRCompositionLayer::get_mipmap_mode);
ClassDB::bind_method(D_METHOD("set_horizontal_wrap", "mode"), &OpenXRCompositionLayer::set_horizontal_wrap);
ClassDB::bind_method(D_METHOD("get_horizontal_wrap"), &OpenXRCompositionLayer::get_horizontal_wrap);
ClassDB::bind_method(D_METHOD("set_vertical_wrap", "mode"), &OpenXRCompositionLayer::set_vertical_wrap);
ClassDB::bind_method(D_METHOD("get_vertical_wrap"), &OpenXRCompositionLayer::get_vertical_wrap);
ClassDB::bind_method(D_METHOD("set_red_swizzle", "mode"), &OpenXRCompositionLayer::set_red_swizzle);
ClassDB::bind_method(D_METHOD("get_red_swizzle"), &OpenXRCompositionLayer::get_red_swizzle);
ClassDB::bind_method(D_METHOD("set_green_swizzle", "mode"), &OpenXRCompositionLayer::set_green_swizzle);
ClassDB::bind_method(D_METHOD("get_green_swizzle"), &OpenXRCompositionLayer::get_green_swizzle);
ClassDB::bind_method(D_METHOD("set_blue_swizzle", "mode"), &OpenXRCompositionLayer::set_blue_swizzle);
ClassDB::bind_method(D_METHOD("get_blue_swizzle"), &OpenXRCompositionLayer::get_blue_swizzle);
ClassDB::bind_method(D_METHOD("set_alpha_swizzle", "mode"), &OpenXRCompositionLayer::set_alpha_swizzle);
ClassDB::bind_method(D_METHOD("get_alpha_swizzle"), &OpenXRCompositionLayer::get_alpha_swizzle);
ClassDB::bind_method(D_METHOD("set_max_anisotropy", "value"), &OpenXRCompositionLayer::set_max_anisotropy);
ClassDB::bind_method(D_METHOD("get_max_anisotropy"), &OpenXRCompositionLayer::get_max_anisotropy);
ClassDB::bind_method(D_METHOD("set_border_color", "color"), &OpenXRCompositionLayer::set_border_color);
ClassDB::bind_method(D_METHOD("get_border_color"), &OpenXRCompositionLayer::get_border_color);
ClassDB::bind_method(D_METHOD("intersects_ray", "origin", "direction"), &OpenXRCompositionLayer::intersects_ray); ClassDB::bind_method(D_METHOD("intersects_ray", "origin", "direction"), &OpenXRCompositionLayer::intersects_ray);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "layer_viewport", PROPERTY_HINT_NODE_TYPE, "SubViewport"), "set_layer_viewport", "get_layer_viewport"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "layer_viewport", PROPERTY_HINT_NODE_TYPE, "SubViewport"), "set_layer_viewport", "get_layer_viewport");
@@ -121,6 +154,41 @@ void OpenXRCompositionLayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "sort_order", PROPERTY_HINT_NONE, ""), "set_sort_order", "get_sort_order"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sort_order", PROPERTY_HINT_NONE, ""), "set_sort_order", "get_sort_order");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "alpha_blend", PROPERTY_HINT_NONE, ""), "set_alpha_blend", "get_alpha_blend"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "alpha_blend", PROPERTY_HINT_NONE, ""), "set_alpha_blend", "get_alpha_blend");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_hole_punch", PROPERTY_HINT_NONE, ""), "set_enable_hole_punch", "get_enable_hole_punch"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_hole_punch", PROPERTY_HINT_NONE, ""), "set_enable_hole_punch", "get_enable_hole_punch");
ADD_GROUP("Swapchain State", "swapchain_state_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_min_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Cubic"), "set_min_filter", "get_min_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_mag_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Cubic"), "set_mag_filter", "get_mag_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_mipmap_mode", PROPERTY_HINT_ENUM, "Disabled,Nearest,Linear"), "set_mipmap_mode", "get_mipmap_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_horizontal_wrap", PROPERTY_HINT_ENUM, "Clamp to Border,Clamp to Edge,Repeat,Mirrored Repeat,Mirror Clamp to Edge"), "set_horizontal_wrap", "get_horizontal_wrap");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_vertical_wrap", PROPERTY_HINT_ENUM, "Clamp to Border,Clamp to Edge,Repeat,Mirrored Repeat,Mirror Clamp to Edge"), "set_vertical_wrap", "get_vertical_wrap");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_red_swizzle", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Zero,One"), "set_red_swizzle", "get_red_swizzle");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_green_swizzle", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Zero,One"), "set_green_swizzle", "get_green_swizzle");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_blue_swizzle", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Zero,One"), "set_blue_swizzle", "get_blue_swizzle");
ADD_PROPERTY(PropertyInfo(Variant::INT, "swapchain_state_alpha_swizzle", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Zero,One"), "set_alpha_swizzle", "get_alpha_swizzle");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "swapchain_state_max_anisotropy", PROPERTY_HINT_RANGE, "1.0,16.0,0.001"), "set_max_anisotropy", "get_max_anisotropy");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "swapchain_state_border_color"), "set_border_color", "get_border_color");
ADD_GROUP("", "");
BIND_ENUM_CONSTANT(FILTER_NEAREST);
BIND_ENUM_CONSTANT(FILTER_LINEAR);
BIND_ENUM_CONSTANT(FILTER_CUBIC);
BIND_ENUM_CONSTANT(MIPMAP_MODE_DISABLED);
BIND_ENUM_CONSTANT(MIPMAP_MODE_NEAREST);
BIND_ENUM_CONSTANT(MIPMAP_MODE_LINEAR);
BIND_ENUM_CONSTANT(WRAP_CLAMP_TO_BORDER);
BIND_ENUM_CONSTANT(WRAP_CLAMP_TO_EDGE);
BIND_ENUM_CONSTANT(WRAP_REPEAT);
BIND_ENUM_CONSTANT(WRAP_MIRRORED_REPEAT);
BIND_ENUM_CONSTANT(WRAP_MIRROR_CLAMP_TO_EDGE);
BIND_ENUM_CONSTANT(SWIZZLE_RED);
BIND_ENUM_CONSTANT(SWIZZLE_GREEN);
BIND_ENUM_CONSTANT(SWIZZLE_BLUE);
BIND_ENUM_CONSTANT(SWIZZLE_ALPHA);
BIND_ENUM_CONSTANT(SWIZZLE_ZERO);
BIND_ENUM_CONSTANT(SWIZZLE_ONE);
} }
bool OpenXRCompositionLayer::_should_use_fallback_node() { bool OpenXRCompositionLayer::_should_use_fallback_node() {
@@ -337,6 +405,149 @@ bool OpenXRCompositionLayer::is_natively_supported() const {
return false; return false;
} }
void OpenXRCompositionLayer::set_min_filter(Filter p_mode) {
if (swapchain_state->min_filter == (OpenXRViewportCompositionLayerProvider::Filter)p_mode) {
return;
}
swapchain_state->min_filter = (OpenXRViewportCompositionLayerProvider::Filter)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::Filter OpenXRCompositionLayer::get_min_filter() const {
return (OpenXRCompositionLayer::Filter)swapchain_state->min_filter;
}
void OpenXRCompositionLayer::set_mag_filter(Filter p_mode) {
if (swapchain_state->mag_filter == (OpenXRViewportCompositionLayerProvider::Filter)p_mode) {
return;
}
swapchain_state->mag_filter = (OpenXRViewportCompositionLayerProvider::Filter)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::Filter OpenXRCompositionLayer::get_mag_filter() const {
return (OpenXRCompositionLayer::Filter)swapchain_state->mag_filter;
}
void OpenXRCompositionLayer::set_mipmap_mode(MipmapMode p_mode) {
if (swapchain_state->mipmap_mode == (OpenXRViewportCompositionLayerProvider::MipmapMode)p_mode) {
return;
}
swapchain_state->mipmap_mode = (OpenXRViewportCompositionLayerProvider::MipmapMode)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::MipmapMode OpenXRCompositionLayer::get_mipmap_mode() const {
return (OpenXRCompositionLayer::MipmapMode)swapchain_state->mipmap_mode;
}
void OpenXRCompositionLayer::set_horizontal_wrap(Wrap p_mode) {
if (swapchain_state->horizontal_wrap == (OpenXRViewportCompositionLayerProvider::Wrap)p_mode) {
return;
}
swapchain_state->horizontal_wrap = (OpenXRViewportCompositionLayerProvider::Wrap)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::Wrap OpenXRCompositionLayer::get_horizontal_wrap() const {
return (OpenXRCompositionLayer::Wrap)swapchain_state->horizontal_wrap;
}
void OpenXRCompositionLayer::set_vertical_wrap(Wrap p_mode) {
if (swapchain_state->vertical_wrap == (OpenXRViewportCompositionLayerProvider::Wrap)p_mode) {
return;
}
swapchain_state->vertical_wrap = (OpenXRViewportCompositionLayerProvider::Wrap)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::Wrap OpenXRCompositionLayer::get_vertical_wrap() const {
return (OpenXRCompositionLayer::Wrap)swapchain_state->vertical_wrap;
}
void OpenXRCompositionLayer::set_red_swizzle(Swizzle p_mode) {
if (swapchain_state->red_swizzle == (OpenXRViewportCompositionLayerProvider::Swizzle)p_mode) {
return;
}
swapchain_state->red_swizzle = (OpenXRViewportCompositionLayerProvider::Swizzle)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::Swizzle OpenXRCompositionLayer::get_red_swizzle() const {
return (OpenXRCompositionLayer::Swizzle)swapchain_state->red_swizzle;
}
void OpenXRCompositionLayer::set_green_swizzle(Swizzle p_mode) {
if (swapchain_state->green_swizzle == (OpenXRViewportCompositionLayerProvider::Swizzle)p_mode) {
return;
}
swapchain_state->green_swizzle = (OpenXRViewportCompositionLayerProvider::Swizzle)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::Swizzle OpenXRCompositionLayer::get_green_swizzle() const {
return (OpenXRCompositionLayer::Swizzle)swapchain_state->green_swizzle;
}
void OpenXRCompositionLayer::set_blue_swizzle(Swizzle p_mode) {
if (swapchain_state->blue_swizzle == (OpenXRViewportCompositionLayerProvider::Swizzle)p_mode) {
return;
}
swapchain_state->blue_swizzle = (OpenXRViewportCompositionLayerProvider::Swizzle)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::Swizzle OpenXRCompositionLayer::get_blue_swizzle() const {
return (OpenXRCompositionLayer::Swizzle)swapchain_state->blue_swizzle;
}
void OpenXRCompositionLayer::set_alpha_swizzle(Swizzle p_mode) {
if (swapchain_state->alpha_swizzle == (OpenXRViewportCompositionLayerProvider::Swizzle)p_mode) {
return;
}
swapchain_state->alpha_swizzle = (OpenXRViewportCompositionLayerProvider::Swizzle)p_mode;
swapchain_state->dirty = true;
}
OpenXRCompositionLayer::Swizzle OpenXRCompositionLayer::get_alpha_swizzle() const {
return (OpenXRCompositionLayer::Swizzle)swapchain_state->alpha_swizzle;
}
void OpenXRCompositionLayer::set_max_anisotropy(float p_value) {
if (swapchain_state->max_anisotropy == p_value) {
return;
}
swapchain_state->max_anisotropy = p_value;
swapchain_state->dirty = true;
}
float OpenXRCompositionLayer::get_max_anisotropy() const {
return swapchain_state->max_anisotropy;
}
void OpenXRCompositionLayer::set_border_color(Color p_color) {
if (swapchain_state->border_color == p_color) {
return;
}
swapchain_state->border_color = p_color;
swapchain_state->dirty = true;
}
Color OpenXRCompositionLayer::get_border_color() const {
return swapchain_state->border_color;
}
Ref<JavaObject> OpenXRCompositionLayer::get_android_surface() { Ref<JavaObject> OpenXRCompositionLayer::get_android_surface() {
return openxr_layer_provider->get_android_surface(); return openxr_layer_provider->get_android_surface();
} }

View File

@@ -32,6 +32,7 @@
#include <openxr/openxr.h> #include <openxr/openxr.h>
#include "../extensions/openxr_composition_layer_extension.h"
#include "scene/3d/node_3d.h" #include "scene/3d/node_3d.h"
class JavaObject; class JavaObject;
@@ -45,6 +46,41 @@ class SubViewport;
class OpenXRCompositionLayer : public Node3D { class OpenXRCompositionLayer : public Node3D {
GDCLASS(OpenXRCompositionLayer, Node3D); GDCLASS(OpenXRCompositionLayer, Node3D);
public:
// Must be identical to Filter enum definition in OpenXRViewportCompositionLayerProvider.
enum Filter {
FILTER_NEAREST,
FILTER_LINEAR,
FILTER_CUBIC,
};
// Must be identical to MipmapMode enum definition in OpenXRViewportCompositionLayerProvider.
enum MipmapMode {
MIPMAP_MODE_DISABLED,
MIPMAP_MODE_NEAREST,
MIPMAP_MODE_LINEAR,
};
// Must be identical to Wrap enum definition in OpenXRViewportCompositionLayerProvider.
enum Wrap {
WRAP_CLAMP_TO_BORDER,
WRAP_CLAMP_TO_EDGE,
WRAP_REPEAT,
WRAP_MIRRORED_REPEAT,
WRAP_MIRROR_CLAMP_TO_EDGE,
};
// Must be identical to Swizzle enum definition in OpenXRViewportCompositionLayerProvider.
enum Swizzle {
SWIZZLE_RED,
SWIZZLE_GREEN,
SWIZZLE_BLUE,
SWIZZLE_ALPHA,
SWIZZLE_ZERO,
SWIZZLE_ONE,
};
private:
XrCompositionLayerBaseHeader *composition_layer_base_header = nullptr; XrCompositionLayerBaseHeader *composition_layer_base_header = nullptr;
OpenXRViewportCompositionLayerProvider *openxr_layer_provider = nullptr; OpenXRViewportCompositionLayerProvider *openxr_layer_provider = nullptr;
@@ -56,6 +92,8 @@ class OpenXRCompositionLayer : public Node3D {
bool should_update_fallback_mesh = false; bool should_update_fallback_mesh = false;
bool openxr_session_running = false; bool openxr_session_running = false;
OpenXRViewportCompositionLayerProvider::SwapchainState *swapchain_state = nullptr;
Dictionary extension_property_values; Dictionary extension_property_values;
bool _should_use_fallback_node(); bool _should_use_fallback_node();
@@ -114,9 +152,47 @@ public:
Ref<JavaObject> get_android_surface(); Ref<JavaObject> get_android_surface();
bool is_natively_supported() const; bool is_natively_supported() const;
void set_min_filter(Filter p_mode);
Filter get_min_filter() const;
void set_mag_filter(Filter p_mode);
Filter get_mag_filter() const;
void set_mipmap_mode(MipmapMode p_mode);
MipmapMode get_mipmap_mode() const;
void set_horizontal_wrap(Wrap p_mode);
Wrap get_horizontal_wrap() const;
void set_vertical_wrap(Wrap p_mode);
Wrap get_vertical_wrap() const;
void set_red_swizzle(Swizzle p_mode);
Swizzle get_red_swizzle() const;
void set_green_swizzle(Swizzle p_mode);
Swizzle get_green_swizzle() const;
void set_blue_swizzle(Swizzle p_mode);
Swizzle get_blue_swizzle() const;
void set_alpha_swizzle(Swizzle p_mode);
Swizzle get_alpha_swizzle() const;
void set_max_anisotropy(float p_value);
float get_max_anisotropy() const;
void set_border_color(Color p_color);
Color get_border_color() const;
virtual PackedStringArray get_configuration_warnings() const override; virtual PackedStringArray get_configuration_warnings() const override;
virtual Vector2 intersects_ray(const Vector3 &p_origin, const Vector3 &p_direction) const; virtual Vector2 intersects_ray(const Vector3 &p_origin, const Vector3 &p_direction) const;
~OpenXRCompositionLayer(); ~OpenXRCompositionLayer();
}; };
VARIANT_ENUM_CAST(OpenXRCompositionLayer::Filter)
VARIANT_ENUM_CAST(OpenXRCompositionLayer::MipmapMode)
VARIANT_ENUM_CAST(OpenXRCompositionLayer::Wrap)
VARIANT_ENUM_CAST(OpenXRCompositionLayer::Swizzle)