fixed judder

This commit is contained in:
awtterpip
2024-06-02 04:57:44 -05:00
parent 72f2e7174e
commit e17262ab46
8 changed files with 322 additions and 325 deletions

View File

@@ -4,76 +4,142 @@ use bevy::{
render::{
camera::{ManualTextureView, ManualTextureViewHandle, ManualTextureViews, RenderTarget},
extract_resource::ExtractResourcePlugin,
renderer::render_system,
pipelined_rendering::PipelinedRenderingPlugin,
view::ExtractedView,
Render, RenderApp, RenderSet,
},
transform::TransformSystem,
};
use bevy_xr::{
camera::{XrCamera, XrCameraBundle, XrProjection},
session::session_running,
};
use bevy_xr::camera::{XrCamera, XrCameraBundle, XrProjection};
use openxr::ViewStateFlags;
use crate::{
init::{session_started, OxrPreUpdateSet, OxrTrackingRoot},
init::{session_started, OxrHandleEvents, OxrLast, OxrTrackingRoot},
layer_builder::ProjectionLayer,
};
use crate::{reference_space::OxrPrimaryReferenceSpace, resources::*};
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, SystemSet)]
pub struct OxrRenderBegin;
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, SystemSet)]
pub struct OxrRenderEnd;
pub struct OxrRenderPlugin;
impl Plugin for OxrRenderPlugin {
fn build(&self, app: &mut App) {
app.add_plugins((ExtractResourcePlugin::<OxrViews>::default(),))
.add_systems(
PreUpdate,
(
init_views.run_if(resource_added::<OxrGraphicsInfo>),
locate_views.run_if(session_running),
update_views.run_if(session_running),
)
.chain()
.after(OxrPreUpdateSet::UpdateNonCriticalComponents),
if app.is_plugin_added::<PipelinedRenderingPlugin>() {
app.init_resource::<Pipelined>();
}
app.add_plugins((
ExtractResourcePlugin::<OxrFrameState>::default(),
ExtractResourcePlugin::<OxrRootTransform>::default(),
ExtractResourcePlugin::<OxrGraphicsInfo>::default(),
ExtractResourcePlugin::<OxrSwapchainImages>::default(),
ExtractResourcePlugin::<OxrViews>::default(),
))
.add_systems(
PreUpdate,
(locate_views, update_views)
.chain()
// .run_if(should_render)
.run_if(session_started),
)
.add_systems(
OxrLast,
(
wait_frame.run_if(session_started),
update_cameras.run_if(session_started),
init_views.run_if(resource_added::<OxrSession>),
apply_deferred,
)
.add_systems(
PostUpdate,
(locate_views, update_views)
.chain()
.run_if(session_running)
.before(TransformSystem::TransformPropagate),
.chain()
.after(OxrHandleEvents),
)
.init_resource::<OxrViews>();
let render_app = app.sub_app_mut(RenderApp);
render_app
.configure_sets(
Render,
OxrRenderBegin
.after(RenderSet::ExtractCommands)
.before(RenderSet::PrepareAssets)
.before(RenderSet::ManageViews),
)
.configure_sets(
Render,
OxrRenderEnd
.after(RenderSet::Render)
.before(RenderSet::Cleanup),
)
.add_systems(Last, wait_frame.run_if(session_started));
app.sub_app_mut(RenderApp)
.add_systems(
Render,
(
(
insert_texture_views,
locate_views.run_if(resource_exists::<OxrPrimaryReferenceSpace>),
update_views_render_world,
)
.chain()
.in_set(RenderSet::PrepareAssets),
begin_frame
.before(RenderSet::Queue)
.before(insert_texture_views),
wait_image.in_set(RenderSet::Render).before(render_system),
(release_image, end_frame)
.chain()
.in_set(RenderSet::Cleanup),
begin_frame,
insert_texture_views,
locate_views,
update_views_render_world,
wait_image,
)
.run_if(session_started),
.chain()
.run_if(session_started)
.in_set(OxrRenderBegin),
)
.add_systems(
Render,
(release_image, end_frame)
.chain()
.run_if(session_started)
.in_set(OxrRenderEnd),
)
.insert_resource(OxrRenderLayers(vec![Box::new(ProjectionLayer)]));
// app.add_systems(
// PreUpdate,
// (
// init_views.run_if(resource_added::<OxrGraphicsInfo>),
// locate_views.run_if(session_running),
// update_views.run_if(session_running),
// )
// .chain(), // .after(OxrPreUpdateSet::UpdateNonCriticalComponents),
// )
// .add_systems(
// PostUpdate,
// (locate_views, update_views)
// .chain()
// .run_if(session_running)
// .before(TransformSystem::TransformPropagate),
// )
// .add_systems(Last, wait_frame.run_if(session_started));
// app.sub_app_mut(RenderApp)
// .add_systems(
// Render,
// (
// (
// insert_texture_views,
// locate_views.run_if(resource_exists::<OxrPrimaryReferenceSpace>),
// update_views_render_world,
// )
// .chain()
// .in_set(RenderSet::PrepareAssets),
// begin_frame
// .before(RenderSet::Queue)
// .before(insert_texture_views),
// wait_image.in_set(RenderSet::Render).before(render_system),
// (release_image, end_frame)
// .chain()
// .in_set(RenderSet::Cleanup),
// )
// .run_if(session_started),
// )
// .insert_resource(OxrRenderLayers(vec![Box::new(ProjectionLayer)]));
}
}
pub const XR_TEXTURE_INDEX: u32 = 3383858418;
// TODO: have cameras initialized externally and then recieved by this function.
/// This is needed to properly initialize the texture views so that bevy will set them to the correct resolution despite them being updated in the render world.
pub fn init_views(
graphics_info: Res<OxrGraphicsInfo>,
mut manual_texture_views: ResMut<ManualTextureViews>,
@@ -84,7 +150,6 @@ pub fn init_views(
let _span = info_span!("xr_init_views");
let temp_tex = swapchain_images.first().unwrap();
// this for loop is to easily add support for quad or mono views in the future.
let mut views = Vec::with_capacity(2);
for index in 0..2 {
info!("{}", graphics_info.resolution);
let view_handle =
@@ -115,10 +180,7 @@ pub fn init_views(
warn!("Multiple OxrTrackingRoots! this is not allowed");
}
}
views.push(default());
}
commands.insert_resource(OxrViews(views));
}
pub fn wait_frame(mut frame_waiter: ResMut<OxrFrameWaiter>, mut commands: Commands) {
@@ -126,26 +188,43 @@ pub fn wait_frame(mut frame_waiter: ResMut<OxrFrameWaiter>, mut commands: Comman
let state = frame_waiter.wait().expect("Failed to wait frame");
// Here we insert the predicted display time for when this frame will be displayed.
// TODO: don't add predicted_display_period if pipelined rendering plugin not enabled
commands.insert_resource(OxrTime(state.predicted_display_time));
commands.insert_resource(OxrFrameState(state));
}
pub fn update_cameras(
frame_state: Res<OxrFrameState>,
mut cameras: Query<&mut Camera, With<XrCamera>>,
) {
if frame_state.is_changed() {
for mut camera in &mut cameras {
camera.is_active = frame_state.should_render
}
}
}
pub fn locate_views(
session: Res<OxrSession>,
ref_space: Res<OxrPrimaryReferenceSpace>,
time: Res<OxrTime>,
frame_state: Res<OxrFrameState>,
mut openxr_views: ResMut<OxrViews>,
pipelined: Option<Res<Pipelined>>,
) {
let _span = info_span!("xr_locate_views");
let time = if pipelined.is_some() {
openxr::Time::from_nanos(
frame_state.predicted_display_time.as_nanos()
+ frame_state.predicted_display_period.as_nanos(),
)
} else {
frame_state.predicted_display_time
};
let (flags, xr_views) = session
.locate_views(
openxr::ViewConfigurationType::PRIMARY_STEREO,
**time,
time,
&ref_space,
)
.expect("Failed to locate views");
if openxr_views.len() != xr_views.len() {
openxr_views.resize(xr_views.len(), default());
}
match (
flags & ViewStateFlags::ORIENTATION_VALID == ViewStateFlags::ORIENTATION_VALID,
flags & ViewStateFlags::POSITION_VALID == ViewStateFlags::POSITION_VALID,
@@ -153,12 +232,18 @@ pub fn locate_views(
(true, true) => *openxr_views = OxrViews(xr_views),
(true, false) => {
for (i, view) in openxr_views.iter_mut().enumerate() {
view.pose.orientation = xr_views[i].pose.orientation;
let Some(xr_view) = xr_views.get(i) else {
break;
};
view.pose.orientation = xr_view.pose.orientation;
}
}
(false, true) => {
for (i, view) in openxr_views.iter_mut().enumerate() {
view.pose.position = xr_views[i].pose.position;
let Some(xr_view) = xr_views.get(i) else {
break;
};
view.pose.position = xr_view.pose.position;
}
}
(false, false) => {}
@@ -372,64 +457,21 @@ pub fn end_frame(world: &mut World) {
}
world.resource_scope::<OxrFrameStream, ()>(|world, mut frame_stream| {
let mut layers = vec![];
for layer in world.resource::<OxrRenderLayers>().iter() {
layers.push(layer.get(world));
let frame_state = world.resource::<OxrFrameState>();
if frame_state.should_render {
for layer in world.resource::<OxrRenderLayers>().iter() {
if let Some(layer) = layer.get(world) {
layers.push(layer);
}
}
}
let layers: Vec<_> = layers.iter().map(Box::as_ref).collect();
frame_stream
.end(
**world.resource::<OxrTime>(),
frame_state.predicted_display_time,
world.resource::<OxrGraphicsInfo>().blend_mode,
&layers,
)
.expect("Failed to end frame");
});
}
// pub fn end_frame(
// mut frame_stream: ResMut<OxrFrameStream>,
// mut swapchain: ResMut<OxrSwapchain>,
// stage: Res<OxrStage>,
// display_time: Res<OxrTime>,
// graphics_info: Res<OxrGraphicsInfo>,
// openxr_views: Res<OxrViews>,
// ) {
// let _span = info_span!("xr_end_frame");
// swapchain.release_image().unwrap();
// let rect = openxr::Rect2Di {
// offset: openxr::Offset2Di { x: 0, y: 0 },
// extent: openxr::Extent2Di {
// width: graphics_info.resolution.x as _,
// height: graphics_info.resolution.y as _,
// },
// };
// frame_stream
// .end(
// **display_time,
// graphics_info.blend_mode,
// &[&CompositionLayerProjection::new()
// .layer_flags(CompositionLayerFlags::BLEND_TEXTURE_SOURCE_ALPHA)
// .space(&stage)
// .views(&[
// CompositionLayerProjectionView::new()
// .pose(openxr_views.0[0].pose)
// .fov(openxr_views.0[0].fov)
// .sub_image(
// SwapchainSubImage::new()
// .swapchain(&swapchain)
// .image_array_index(0)
// .image_rect(rect),
// ),
// CompositionLayerProjectionView::new()
// .pose(openxr_views.0[1].pose)
// .fov(openxr_views.0[1].fov)
// .sub_image(
// SwapchainSubImage::new()
// .swapchain(&swapchain)
// .image_array_index(1)
// .image_rect(rect),
// ),
// ])],
// )
// .expect("Failed to end frame");
// }