updated documentation and resources
This commit is contained in:
@@ -4,8 +4,9 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["vulkan"]
|
default = ["vulkan", "passthrough"]
|
||||||
vulkan = ["dep:ash"]
|
vulkan = ["dep:ash"]
|
||||||
|
passthrough = []
|
||||||
|
|
||||||
# bevy can't be placed behind target or proc macros won't work properly
|
# bevy can't be placed behind target or proc macros won't work properly
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
2
crates/bevy_openxr/src/openxr/features/mod.rs
Normal file
2
crates/bevy_openxr/src/openxr/features/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#[cfg(feature = "passthrough")]
|
||||||
|
pub mod passthrough;
|
||||||
59
crates/bevy_openxr/src/openxr/features/passthrough.rs
Normal file
59
crates/bevy_openxr/src/openxr/features/passthrough.rs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use openxr::sys::SystemPassthroughProperties2FB;
|
||||||
|
use openxr::PassthroughCapabilityFlagsFB;
|
||||||
|
|
||||||
|
use crate::resources::*;
|
||||||
|
use crate::types::*;
|
||||||
|
|
||||||
|
pub struct OxrPassthroughPlugin;
|
||||||
|
|
||||||
|
impl Plugin for OxrPassthroughPlugin {
|
||||||
|
fn build(&self, _app: &mut App) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_passthrough(
|
||||||
|
session: &OxrSession,
|
||||||
|
flags: openxr::PassthroughFlagsFB,
|
||||||
|
purpose: openxr::PassthroughLayerPurposeFB,
|
||||||
|
) -> Result<(OxrPassthrough, OxrPassthroughLayer)> {
|
||||||
|
let passthrough = session.create_passthrough(flags)?;
|
||||||
|
|
||||||
|
let passthrough_layer = session.create_passthrough_layer(&passthrough, purpose)?;
|
||||||
|
|
||||||
|
Ok((passthrough, passthrough_layer))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn supports_passthrough(instance: &OxrInstance, system: OxrSystemId) -> Result<bool> {
|
||||||
|
unsafe {
|
||||||
|
let mut hand = openxr::sys::SystemPassthroughProperties2FB {
|
||||||
|
ty: SystemPassthroughProperties2FB::TYPE,
|
||||||
|
next: std::ptr::null(),
|
||||||
|
capabilities: PassthroughCapabilityFlagsFB::PASSTHROUGH_CAPABILITY,
|
||||||
|
};
|
||||||
|
let mut p = openxr::sys::SystemProperties::out(&mut hand as *mut _ as _);
|
||||||
|
cvt((instance.fp().get_system_properties)(
|
||||||
|
instance.as_raw(),
|
||||||
|
system.0,
|
||||||
|
p.as_mut_ptr(),
|
||||||
|
))?;
|
||||||
|
bevy::log::info!(
|
||||||
|
"From supports_passthrough: Passthrough capabilities: {:?}",
|
||||||
|
hand.capabilities
|
||||||
|
);
|
||||||
|
Ok(
|
||||||
|
(hand.capabilities & PassthroughCapabilityFlagsFB::PASSTHROUGH_CAPABILITY)
|
||||||
|
== PassthroughCapabilityFlagsFB::PASSTHROUGH_CAPABILITY,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cvt(x: openxr::sys::Result) -> openxr::Result<openxr::sys::Result> {
|
||||||
|
if x.into_raw() >= 0 {
|
||||||
|
Ok(x)
|
||||||
|
} else {
|
||||||
|
Err(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ use std::mem;
|
|||||||
use openxr::{sys, CompositionLayerFlags, Fovf, Posef, Rect2Di, Space};
|
use openxr::{sys, CompositionLayerFlags, Fovf, Posef, Rect2Di, Space};
|
||||||
|
|
||||||
use crate::graphics::graphics_match;
|
use crate::graphics::graphics_match;
|
||||||
use crate::resources::OxrSwapchain;
|
use crate::resources::{OxrPassthroughLayer, OxrSwapchain};
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct SwapchainSubImage<'a> {
|
pub struct SwapchainSubImage<'a> {
|
||||||
@@ -105,7 +105,7 @@ impl<'a> Default for CompositionLayerProjectionView<'a> {
|
|||||||
}
|
}
|
||||||
pub unsafe trait CompositionLayer<'a> {
|
pub unsafe trait CompositionLayer<'a> {
|
||||||
fn swapchain(&self) -> Option<&'a OxrSwapchain>;
|
fn swapchain(&self) -> Option<&'a OxrSwapchain>;
|
||||||
fn header(&self) -> &'a sys::CompositionLayerBaseHeader;
|
fn header(&self) -> &sys::CompositionLayerBaseHeader;
|
||||||
}
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CompositionLayerProjection<'a> {
|
pub struct CompositionLayerProjection<'a> {
|
||||||
@@ -158,8 +158,8 @@ unsafe impl<'a> CompositionLayer<'a> for CompositionLayerProjection<'a> {
|
|||||||
self.swapchain
|
self.swapchain
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header(&self) -> &'a sys::CompositionLayerBaseHeader {
|
fn header(&self) -> &sys::CompositionLayerBaseHeader {
|
||||||
unsafe { std::mem::transmute(&self.inner) }
|
unsafe { mem::transmute(&self.inner) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> Default for CompositionLayerProjection<'a> {
|
impl<'a> Default for CompositionLayerProjection<'a> {
|
||||||
@@ -167,3 +167,36 @@ impl<'a> Default for CompositionLayerProjection<'a> {
|
|||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub struct CompositionLayerPassthrough {
|
||||||
|
inner: sys::CompositionLayerPassthroughFB,
|
||||||
|
}
|
||||||
|
impl CompositionLayerPassthrough {
|
||||||
|
#[inline]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: openxr::sys::CompositionLayerPassthroughFB {
|
||||||
|
ty: openxr::sys::CompositionLayerPassthroughFB::TYPE,
|
||||||
|
..unsafe { mem::zeroed() }
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn layer_handle(mut self, layer_handle: &OxrPassthroughLayer) -> Self {
|
||||||
|
self.inner.layer_handle = *layer_handle.inner();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn layer_flags(mut self, value: CompositionLayerFlags) -> Self {
|
||||||
|
self.inner.flags = value;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe impl<'a> CompositionLayer<'a> for CompositionLayerPassthrough {
|
||||||
|
fn swapchain(&self) -> Option<&'a OxrSwapchain> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn header(&self) -> &sys::CompositionLayerBaseHeader {
|
||||||
|
unsafe { mem::transmute(&self.inner) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use render::OxrRenderPlugin;
|
|||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod exts;
|
mod exts;
|
||||||
|
pub mod features;
|
||||||
pub mod graphics;
|
pub mod graphics;
|
||||||
pub mod init;
|
pub mod init;
|
||||||
pub mod layer_builder;
|
pub mod layer_builder;
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ use crate::graphics::*;
|
|||||||
use crate::layer_builder::CompositionLayer;
|
use crate::layer_builder::CompositionLayer;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
/// Wrapper around the entry point to the OpenXR API
|
/// Wrapper around an [`Entry`](openxr::Entry) with some methods overridden to use bevy types.
|
||||||
|
///
|
||||||
|
/// See [`openxr::Entry`] for other available methods.
|
||||||
#[derive(Deref, Clone)]
|
#[derive(Deref, Clone)]
|
||||||
pub struct OxrEntry(pub openxr::Entry);
|
pub struct OxrEntry(pub openxr::Entry);
|
||||||
|
|
||||||
@@ -20,6 +22,9 @@ impl OxrEntry {
|
|||||||
Ok(self.0.enumerate_extensions().map(Into::into)?)
|
Ok(self.0.enumerate_extensions().map(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an [`OxrInstance`].
|
||||||
|
///
|
||||||
|
/// Calls [`create_instance`](openxr::Entry::create_instance) internally.
|
||||||
pub fn create_instance(
|
pub fn create_instance(
|
||||||
&self,
|
&self,
|
||||||
app_info: AppInfo,
|
app_info: AppInfo,
|
||||||
@@ -49,6 +54,7 @@ impl OxrEntry {
|
|||||||
Ok(OxrInstance(instance, backend, app_info))
|
Ok(OxrInstance(instance, backend, app_info))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a list of all of the backends the OpenXR runtime supports.
|
||||||
pub fn available_backends(&self) -> Result<Vec<GraphicsBackend>> {
|
pub fn available_backends(&self) -> Result<Vec<GraphicsBackend>> {
|
||||||
Ok(GraphicsBackend::available_backends(
|
Ok(GraphicsBackend::available_backends(
|
||||||
&self.enumerate_extensions()?,
|
&self.enumerate_extensions()?,
|
||||||
@@ -56,20 +62,48 @@ impl OxrEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper around [openxr::Instance] with additional data for safety.
|
/// Wrapper around [`openxr::Instance`] with additional data for safety and some methods overriden to use bevy types.
|
||||||
|
///
|
||||||
|
/// See [`openxr::Instance`] for other available methods.
|
||||||
#[derive(Resource, Deref, Clone)]
|
#[derive(Resource, Deref, Clone)]
|
||||||
pub struct OxrInstance(
|
pub struct OxrInstance(
|
||||||
#[deref] pub openxr::Instance,
|
#[deref] pub(crate) openxr::Instance,
|
||||||
|
/// [`GraphicsBackend`] is stored here to let us know what graphics API the current instance wants to target.
|
||||||
pub(crate) GraphicsBackend,
|
pub(crate) GraphicsBackend,
|
||||||
pub(crate) AppInfo,
|
pub(crate) AppInfo,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl OxrInstance {
|
impl OxrInstance {
|
||||||
|
/// Creates an [`OxrInstance`] from an [`openxr::Instance`] if needed.
|
||||||
|
/// In the majority of cases, you should use [`create_instance`](OxrEntry::create_instance) instead.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The OpenXR instance passed in *must* have support for the backend specified.
|
||||||
|
pub unsafe fn from_inner(
|
||||||
|
instance: openxr::Instance,
|
||||||
|
backend: GraphicsBackend,
|
||||||
|
info: AppInfo,
|
||||||
|
) -> Self {
|
||||||
|
Self(instance, backend, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consumes self and returns the inner [`openxr::Instance`]
|
||||||
pub fn into_inner(self) -> openxr::Instance {
|
pub fn into_inner(self) -> openxr::Instance {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize graphics. This is used to create [WgpuGraphics] for the bevy app and to get the [SessionCreateInfo] to make an XR session.
|
/// Returns the current backend being used by this instance.
|
||||||
|
pub fn backend(&self) -> GraphicsBackend {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the [`AppInfo`] being used by this instance.
|
||||||
|
pub fn app_info(&self) -> &AppInfo {
|
||||||
|
&self.2
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialize graphics. This is used to create [WgpuGraphics] for the bevy app and to get the [SessionCreateInfo] needed to make an XR session.
|
||||||
pub fn init_graphics(
|
pub fn init_graphics(
|
||||||
&self,
|
&self,
|
||||||
system_id: openxr::SystemId,
|
system_id: openxr::SystemId,
|
||||||
@@ -86,6 +120,8 @@ impl OxrInstance {
|
|||||||
|
|
||||||
/// Creates an [OxrSession]
|
/// Creates an [OxrSession]
|
||||||
///
|
///
|
||||||
|
/// Calls [`create_session`](openxr::Instance::create_session) internally.
|
||||||
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// `info` must contain valid handles for the graphics api
|
/// `info` must contain valid handles for the graphics api
|
||||||
@@ -111,11 +147,18 @@ impl OxrInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Graphics agnostic wrapper around [openxr::Session]
|
/// Graphics agnostic wrapper around [openxr::Session].
|
||||||
|
///
|
||||||
|
/// See [`openxr::Session`] for other available methods.
|
||||||
#[derive(Resource, Deref, Clone)]
|
#[derive(Resource, Deref, Clone)]
|
||||||
pub struct OxrSession(
|
pub struct OxrSession(
|
||||||
#[deref] pub openxr::Session<AnyGraphics>,
|
/// A session handle with [`AnyGraphics`].
|
||||||
pub GraphicsWrap<Self>,
|
/// Having this here allows the majority of [`Session`](openxr::Session)'s methods to work without having to rewrite them.
|
||||||
|
#[deref]
|
||||||
|
pub(crate) openxr::Session<AnyGraphics>,
|
||||||
|
/// A [`GraphicsWrap`] with [`openxr::Session<G>`] as the inner type.
|
||||||
|
/// This is so that we can still operate on functions that don't take [`AnyGraphics`] as the generic.
|
||||||
|
pub(crate) GraphicsWrap<Self>,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl GraphicsType for OxrSession {
|
impl GraphicsType for OxrSession {
|
||||||
@@ -124,16 +167,27 @@ impl GraphicsType for OxrSession {
|
|||||||
|
|
||||||
impl<G: GraphicsExt> From<openxr::Session<G>> for OxrSession {
|
impl<G: GraphicsExt> From<openxr::Session<G>> for OxrSession {
|
||||||
fn from(session: openxr::Session<G>) -> Self {
|
fn from(session: openxr::Session<G>) -> Self {
|
||||||
Self::new(session)
|
Self::from_inner(session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OxrSession {
|
impl OxrSession {
|
||||||
pub fn new<G: GraphicsExt>(session: openxr::Session<G>) -> Self {
|
/// Creates a new [`OxrSession`] from an [`openxr::Session`].
|
||||||
|
/// In the majority of cases, you should use [`create_session`](OxrInstance::create_session) instead.
|
||||||
|
pub fn from_inner<G: GraphicsExt>(session: openxr::Session<G>) -> Self {
|
||||||
Self(session.clone().into_any_graphics(), G::wrap(session))
|
Self(session.clone().into_any_graphics(), G::wrap(session))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enumerate all available swapchain formats.
|
/// Returns [`GraphicsWrap`] with [`openxr::Session<G>`] as the inner type.
|
||||||
|
///
|
||||||
|
/// This can be useful if you need access to the original [`openxr::Session`] with the graphics API still specified.
|
||||||
|
pub fn typed_session(&self) -> &GraphicsWrap<Self> {
|
||||||
|
&self.1
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enumerates all available swapchain formats and converts them to wgpu's [`TextureFormat`](wgpu::TextureFormat).
|
||||||
|
///
|
||||||
|
/// Calls [`enumerate_swapchain_formats`](openxr::Session::enumerate_swapchain_formats) internally.
|
||||||
pub fn enumerate_swapchain_formats(&self) -> Result<Vec<wgpu::TextureFormat>> {
|
pub fn enumerate_swapchain_formats(&self) -> Result<Vec<wgpu::TextureFormat>> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&self.1;
|
&self.1;
|
||||||
@@ -142,14 +196,75 @@ impl OxrSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an [OxrSwapchain].
|
/// Creates an [OxrSwapchain].
|
||||||
|
///
|
||||||
|
/// Calls [`create_swapchain`](openxr::Session::create_swapchain) internally.
|
||||||
pub fn create_swapchain(&self, info: SwapchainCreateInfo) -> Result<OxrSwapchain> {
|
pub fn create_swapchain(&self, info: SwapchainCreateInfo) -> Result<OxrSwapchain> {
|
||||||
Ok(OxrSwapchain(graphics_match!(
|
Ok(OxrSwapchain(graphics_match!(
|
||||||
&self.1;
|
&self.1;
|
||||||
session => session.create_swapchain(&info.try_into()?)? => OxrSwapchain
|
session => session.create_swapchain(&info.try_into()?)? => OxrSwapchain
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a passthrough.
|
||||||
|
///
|
||||||
|
/// Requires [`XR_FB_passthrough`](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_FB_passthrough).
|
||||||
|
///
|
||||||
|
/// Calls [`create_passthrough`](openxr::Session::create_passthrough) internally.
|
||||||
|
pub fn create_passthrough(&self, flags: openxr::PassthroughFlagsFB) -> Result<OxrPassthrough> {
|
||||||
|
Ok(OxrPassthrough(
|
||||||
|
graphics_match! {
|
||||||
|
&self.1;
|
||||||
|
session => session.create_passthrough(flags)?
|
||||||
|
},
|
||||||
|
flags,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a passthrough layer that can be used to make a [`CompositionLayerPassthrough`](crate::layer_builder::CompositionLayerPassthrough) for frame submission.
|
||||||
|
///
|
||||||
|
/// Requires [`XR_FB_passthrough`](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_FB_passthrough).
|
||||||
|
///
|
||||||
|
/// Calls [`create_passthrough_layer`](openxr::Session::create_passthrough_layer) internally.
|
||||||
|
pub fn create_passthrough_layer(
|
||||||
|
&self,
|
||||||
|
passthrough: &OxrPassthrough,
|
||||||
|
purpose: openxr::PassthroughLayerPurposeFB,
|
||||||
|
) -> Result<OxrPassthroughLayer> {
|
||||||
|
Ok(OxrPassthroughLayer(graphics_match! {
|
||||||
|
&self.1;
|
||||||
|
session => session.create_passthrough_layer(&passthrough.0, passthrough.1, purpose)?
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper around [`openxr::Passthrough`].
|
||||||
|
///
|
||||||
|
/// Used to [`start`](openxr::Passthrough::start) or [`pause`](openxr::Passthrough::pause) passthrough on the physical device.
|
||||||
|
///
|
||||||
|
/// See [`openxr::Passthrough`] for available methods.
|
||||||
|
#[derive(Resource, Deref, DerefMut)]
|
||||||
|
pub struct OxrPassthrough(
|
||||||
|
#[deref] pub openxr::Passthrough,
|
||||||
|
/// The flags are stored here so that they don't need to be passed in again when creating an [`OxrPassthroughLayer`].
|
||||||
|
openxr::PassthroughFlagsFB,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl OxrPassthrough {
|
||||||
|
/// This function can create an [`OxrPassthrough`] from raw openxr types if needed.
|
||||||
|
/// In the majority of cases, you should use [`create_passthrough`](OxrSession::create_passthrough) instead.
|
||||||
|
pub fn from_inner(passthrough: openxr::Passthrough, flags: openxr::PassthroughFlagsFB) -> Self {
|
||||||
|
Self(passthrough, flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper around [`openxr::Passthrough`].
|
||||||
|
///
|
||||||
|
/// Used to create a [`CompositionLayerPassthrough`](crate::layer_builder::CompositionLayerPassthrough), and to [`pause`](openxr::PassthroughLayer::pause) or [`resume`](openxr::PassthroughLayer::resume) rendering of the passthrough layer.
|
||||||
|
///
|
||||||
|
/// See [`openxr::PassthroughLayer`] for available methods.
|
||||||
|
#[derive(Resource, Deref, DerefMut)]
|
||||||
|
pub struct OxrPassthroughLayer(pub openxr::PassthroughLayer);
|
||||||
|
|
||||||
/// Graphics agnostic wrapper around [openxr::FrameStream]
|
/// Graphics agnostic wrapper around [openxr::FrameStream]
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct OxrFrameStream(pub GraphicsWrap<Self>);
|
pub struct OxrFrameStream(pub GraphicsWrap<Self>);
|
||||||
@@ -159,7 +274,15 @@ impl GraphicsType for OxrFrameStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OxrFrameStream {
|
impl OxrFrameStream {
|
||||||
|
/// Creates a new [`OxrFrameStream`] from an [`openxr::FrameStream`].
|
||||||
|
/// In the majority of cases, you should use [`create_session`](OxrInstance::create_session) instead.
|
||||||
|
pub fn from_inner<G: GraphicsExt>(frame_stream: openxr::FrameStream<G>) -> Self {
|
||||||
|
Self(G::wrap(frame_stream))
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicate that graphics device work is beginning.
|
/// Indicate that graphics device work is beginning.
|
||||||
|
///
|
||||||
|
/// Calls [`begin`](openxr::FrameStream::begin) internally.
|
||||||
pub fn begin(&mut self) -> openxr::Result<()> {
|
pub fn begin(&mut self) -> openxr::Result<()> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&mut self.0;
|
&mut self.0;
|
||||||
@@ -169,8 +292,8 @@ impl OxrFrameStream {
|
|||||||
|
|
||||||
/// Indicate that all graphics work for the frame has been submitted
|
/// Indicate that all graphics work for the frame has been submitted
|
||||||
///
|
///
|
||||||
/// `layers` is an array of references to any type of composition layer,
|
/// `layers` is an array of references to any type of composition layer that implements [`CompositionLayer`],
|
||||||
/// e.g. [`CompositionLayerProjection`](crate::oxr::layer_builder::CompositionLayerProjection)
|
/// e.g. [`CompositionLayerProjection`](crate::layer_builder::CompositionLayerProjection)
|
||||||
pub fn end(
|
pub fn end(
|
||||||
&mut self,
|
&mut self,
|
||||||
display_time: openxr::Time,
|
display_time: openxr::Time,
|
||||||
@@ -202,7 +325,9 @@ impl OxrFrameStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle for waiting to render a frame. Check [`FrameWaiter`](openxr::FrameWaiter) for available methods.
|
/// Handle for waiting to render a frame.
|
||||||
|
///
|
||||||
|
/// See [`FrameWaiter`](openxr::FrameWaiter) for available methods.
|
||||||
#[derive(Resource, Deref, DerefMut)]
|
#[derive(Resource, Deref, DerefMut)]
|
||||||
pub struct OxrFrameWaiter(pub openxr::FrameWaiter);
|
pub struct OxrFrameWaiter(pub openxr::FrameWaiter);
|
||||||
|
|
||||||
@@ -215,7 +340,15 @@ impl GraphicsType for OxrSwapchain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OxrSwapchain {
|
impl OxrSwapchain {
|
||||||
/// Determine the index of the next image to render to in the swapchain image array
|
/// Creates a new [`OxrSwapchain`] from an [`openxr::Swapchain`].
|
||||||
|
/// In the majority of cases, you should use [`create_swapchain`](OxrSession::create_swapchain) instead.
|
||||||
|
pub fn from_inner<G: GraphicsExt>(swapchain: openxr::Swapchain<G>) -> Self {
|
||||||
|
Self(G::wrap(swapchain))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine the index of the next image to render to in the swapchain image array.
|
||||||
|
///
|
||||||
|
/// Calls [`acquire_image`](openxr::Swapchain::acquire_image) internally.
|
||||||
pub fn acquire_image(&mut self) -> Result<u32> {
|
pub fn acquire_image(&mut self) -> Result<u32> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&mut self.0;
|
&mut self.0;
|
||||||
@@ -223,7 +356,9 @@ impl OxrSwapchain {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for the compositor to finish reading from the oldest unwaited acquired image
|
/// Wait for the compositor to finish reading from the oldest unwaited acquired image.
|
||||||
|
///
|
||||||
|
/// Calls [`wait_image`](openxr::Swapchain::wait_image) internally.
|
||||||
pub fn wait_image(&mut self, timeout: openxr::Duration) -> Result<()> {
|
pub fn wait_image(&mut self, timeout: openxr::Duration) -> Result<()> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&mut self.0;
|
&mut self.0;
|
||||||
@@ -231,7 +366,9 @@ impl OxrSwapchain {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Release the oldest acquired image
|
/// Release the oldest acquired image.
|
||||||
|
///
|
||||||
|
/// Calls [`release_image`](openxr::Swapchain::release_image) internally.
|
||||||
pub fn release_image(&mut self) -> Result<()> {
|
pub fn release_image(&mut self) -> Result<()> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&mut self.0;
|
&mut self.0;
|
||||||
@@ -240,6 +377,8 @@ impl OxrSwapchain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enumerates swapchain images and converts them to wgpu [`Texture`](wgpu::Texture)s.
|
/// Enumerates swapchain images and converts them to wgpu [`Texture`](wgpu::Texture)s.
|
||||||
|
///
|
||||||
|
/// Calls [`enumerate_images`](openxr::Swapchain::enumerate_images) internally.
|
||||||
pub fn enumerate_images(
|
pub fn enumerate_images(
|
||||||
&self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
|
|||||||
Reference in New Issue
Block a user