rework stereo mode
This commit is contained in:
@@ -24,6 +24,7 @@ use wgui::gfx::WGfx;
|
||||
use wlx_common::overlays::{BackendAttrib, BackendAttribValue};
|
||||
|
||||
use crate::backend::input::{HoverResult, PointerHit};
|
||||
use crate::graphics::ExtentExt;
|
||||
use crate::state::AppState;
|
||||
use crate::subsystem::hid::WheelDelta;
|
||||
use crate::windowing::Z_ORDER_LINES;
|
||||
@@ -200,7 +201,7 @@ impl OverlayBackend for LineBackend {
|
||||
}
|
||||
fn frame_meta(&mut self) -> Option<FrameMeta> {
|
||||
Some(FrameMeta {
|
||||
extent: self.view.image().extent(),
|
||||
extent: self.view.extent_u32arr(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use vulkano::{
|
||||
};
|
||||
use wgui::gfx::WGfx;
|
||||
|
||||
use crate::{state::AppState, windowing::window::OverlayWindowData};
|
||||
use crate::{graphics::ExtentExt, state::AppState, windowing::window::OverlayWindowData};
|
||||
|
||||
use super::helpers::Affine3AConvert;
|
||||
|
||||
@@ -65,10 +65,10 @@ impl OverlayWindowData<OpenVrOverlayData> {
|
||||
pub(super) fn ensure_staging_image(
|
||||
&mut self,
|
||||
app: &mut AppState,
|
||||
extent: [u32; 3],
|
||||
extent: [u32; 2],
|
||||
) -> anyhow::Result<Arc<ImageView>> {
|
||||
if let Some(image_view) = self.data.image_view.as_ref()
|
||||
&& image_view.image().extent() == extent
|
||||
&& image_view.extent_u32arr() == extent
|
||||
{
|
||||
return Ok(image_view.clone());
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ impl LinePool {
|
||||
&Default::default(),
|
||||
)?;
|
||||
|
||||
let srd = create_swapchain(xr, app.gfx.clone(), [1, 1, 1], SwapchainOpts::new())?;
|
||||
let srd = create_swapchain(xr, app.gfx.clone(), [1, 1], 1, SwapchainOpts::new())?;
|
||||
self.lines.insert(
|
||||
id,
|
||||
LineContainer {
|
||||
|
||||
@@ -10,7 +10,7 @@ use input::OpenXrInputSource;
|
||||
use openxr as xr;
|
||||
use skybox::create_skybox;
|
||||
use vulkano::{Handle, VulkanObject};
|
||||
use wlx_common::overlays::ToastTopic;
|
||||
use wlx_common::overlays::{StereoMode, ToastTopic};
|
||||
|
||||
use crate::{
|
||||
FRAME_COUNTER, RUNNING,
|
||||
@@ -391,7 +391,8 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
|
||||
if should_render {
|
||||
log::trace!("{}: render new frame", o.config.name);
|
||||
let meta = o.config.backend.frame_meta().unwrap(); // want panic
|
||||
let wsi = o.ensure_swapchain_acquire(&app, &xr_state, meta.extent)?;
|
||||
let stereo = !matches!(meta.stereo, StereoMode::None);
|
||||
let wsi = o.ensure_swapchain_acquire(&app, &xr_state, meta.extent, stereo)?;
|
||||
let tgt = RenderTarget { views: wsi.views };
|
||||
let mut rdr = RenderResources::new(app.gfx.clone(), tgt, &meta, alpha)?;
|
||||
o.render(&mut app, &mut rdr)?;
|
||||
|
||||
@@ -25,10 +25,14 @@ impl OverlayWindowData<OpenXrOverlayData> {
|
||||
&'a mut self,
|
||||
app: &AppState,
|
||||
xr: &'a XrState,
|
||||
extent: [u32; 3],
|
||||
extent: [u32; 2],
|
||||
stereo: bool,
|
||||
) -> anyhow::Result<WlxSwapchainImage> {
|
||||
let array_size = if stereo { 2 } else { 1 };
|
||||
|
||||
if let Some(swapchain) = self.data.swapchain.as_mut()
|
||||
&& swapchain.extent == extent
|
||||
&& swapchain.array_size == array_size
|
||||
{
|
||||
return swapchain.acquire_wait_image();
|
||||
}
|
||||
@@ -38,9 +42,15 @@ impl OverlayWindowData<OpenXrOverlayData> {
|
||||
self.config.name,
|
||||
extent[0],
|
||||
extent[1],
|
||||
extent[2],
|
||||
array_size,
|
||||
);
|
||||
let mut swapchain = create_swapchain(xr, app.gfx.clone(), extent, SwapchainOpts::new())?;
|
||||
let mut swapchain = create_swapchain(
|
||||
xr,
|
||||
app.gfx.clone(),
|
||||
extent,
|
||||
array_size,
|
||||
SwapchainOpts::new(),
|
||||
)?;
|
||||
let tgt = swapchain.acquire_wait_image()?;
|
||||
self.data.swapchain = Some(swapchain);
|
||||
Ok(tgt)
|
||||
@@ -65,7 +75,7 @@ impl OverlayWindowData<OpenXrOverlayData> {
|
||||
// overlays without active_state don't get queued for present
|
||||
let state = self.config.active_state.as_ref().unwrap();
|
||||
|
||||
let sub_images: SmallVec<[_; 2]> = if swapchain.extent[2] > 1 {
|
||||
let sub_images: SmallVec<[_; 2]> = if swapchain.array_size > 1 {
|
||||
smallvec![
|
||||
(swapchain.get_subimage(0), EyeVisibility::LEFT),
|
||||
(swapchain.get_subimage(1), EyeVisibility::RIGHT),
|
||||
|
||||
@@ -92,8 +92,8 @@ impl Skybox {
|
||||
}
|
||||
let opts = SwapchainOpts::new().immutable();
|
||||
|
||||
let extent = self.view.image().extent();
|
||||
let mut swapchain = create_swapchain(xr, app.gfx.clone(), extent, opts)?;
|
||||
let extent = self.view.extent_u32arr();
|
||||
let mut swapchain = create_swapchain(xr, app.gfx.clone(), extent, 1, opts)?;
|
||||
let tgt = swapchain
|
||||
.acquire_wait_image()?
|
||||
.views
|
||||
@@ -141,11 +141,12 @@ impl Skybox {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let extent = [1024, 1024, 1];
|
||||
let extent = [1024, 1024];
|
||||
let mut swapchain = create_swapchain(
|
||||
xr,
|
||||
app.gfx.clone(),
|
||||
extent,
|
||||
1,
|
||||
SwapchainOpts::new().immutable(),
|
||||
)?;
|
||||
let pipeline = app.gfx.create_pipeline(
|
||||
|
||||
@@ -35,7 +35,8 @@ impl SwapchainOpts {
|
||||
pub(super) fn create_swapchain(
|
||||
xr: &XrState,
|
||||
gfx: Arc<WGfx>,
|
||||
extent: [u32; 3],
|
||||
extent: [u32; 2],
|
||||
array_size: u32,
|
||||
opts: SwapchainOpts,
|
||||
) -> anyhow::Result<WlxSwapchain> {
|
||||
let create_flags = if opts.immutable {
|
||||
@@ -52,7 +53,7 @@ pub(super) fn create_swapchain(
|
||||
width: extent[0],
|
||||
height: extent[1],
|
||||
face_count: 1,
|
||||
array_size: extent[2],
|
||||
array_size,
|
||||
mip_count: 1,
|
||||
})?;
|
||||
|
||||
@@ -69,7 +70,7 @@ pub(super) fn create_swapchain(
|
||||
ImageCreateInfo {
|
||||
format: gfx.surface_format as _,
|
||||
extent: [extent[0], extent[1], 1],
|
||||
array_layers: extent[2],
|
||||
array_layers: array_size,
|
||||
usage: ImageUsage::COLOR_ATTACHMENT,
|
||||
..Default::default()
|
||||
},
|
||||
@@ -78,7 +79,7 @@ pub(super) fn create_swapchain(
|
||||
// SAFETY: OpenXR guarantees that the image is a swapchain image, thus has memory backing it.
|
||||
let image = Arc::new(unsafe { raw_image.assume_bound() });
|
||||
let mut wsi = WlxSwapchainImage::default();
|
||||
for d in 0..extent[2] {
|
||||
for d in 0..array_size {
|
||||
let mut create_info = ImageViewCreateInfo::from_image(&image);
|
||||
create_info.subresource_range.array_layers = d..d + 1;
|
||||
wsi.views.push(ImageView::new(image.clone(), create_info)?);
|
||||
@@ -93,6 +94,7 @@ pub(super) fn create_swapchain(
|
||||
swapchain,
|
||||
images,
|
||||
extent,
|
||||
array_size,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -105,7 +107,8 @@ pub(super) struct WlxSwapchain {
|
||||
acquired: bool,
|
||||
pub(super) ever_acquired: bool,
|
||||
pub(super) swapchain: xr::Swapchain<xr::Vulkan>,
|
||||
pub(super) extent: [u32; 3],
|
||||
pub(super) extent: [u32; 2],
|
||||
pub(super) array_size: u32,
|
||||
pub(super) images: SmallVec<[WlxSwapchainImage; 4]>,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use anyhow::Context;
|
||||
use button::setup_custom_button;
|
||||
@@ -353,7 +353,6 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
|
||||
extent: [
|
||||
self.max_size.x.min(self.layout.content_size.x) as _,
|
||||
self.max_size.y.min(self.layout.content_size.y) as _,
|
||||
1,
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
|
||||
@@ -185,7 +185,7 @@ impl OverlayBackend for DashFrontend {
|
||||
fn frame_meta(&mut self) -> Option<FrameMeta> {
|
||||
Some(FrameMeta {
|
||||
clear: WGfxClearMode::Clear([0., 0., 0., 0.]),
|
||||
extent: [DASH_RES_U32A[0], DASH_RES_U32A[1], 1],
|
||||
extent: [DASH_RES_U32A[0], DASH_RES_U32A[1]],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ use crate::{
|
||||
XrBackend,
|
||||
input::{HoverResult, PointerHit, PointerMode},
|
||||
},
|
||||
graphics::ExtentExt,
|
||||
overlays::screen::capture::MyFirstDmaExporter,
|
||||
state::AppState,
|
||||
subsystem::hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, WheelDelta},
|
||||
@@ -208,31 +207,22 @@ impl OverlayBackend for ScreenBackend {
|
||||
}
|
||||
|
||||
if let Some(frame) = self.capture.receive() {
|
||||
let mut meta = frame.get_frame_meta(&app.session.config);
|
||||
let stereo = self.stereo.unwrap_or(StereoMode::None);
|
||||
let meta = frame.get_frame_meta(&app.session.config, stereo);
|
||||
|
||||
if let Some(pipeline) = self.pipeline.as_mut() {
|
||||
meta.extent[2] = pipeline.get_depth();
|
||||
if self
|
||||
.meta
|
||||
.is_some_and(|old| old.extent[..2] != meta.extent[..2])
|
||||
{
|
||||
if self.meta.is_some_and(|old| old.extent != meta.extent) {
|
||||
pipeline.set_extent(
|
||||
app,
|
||||
[meta.extent[0] as _, meta.extent[1] as _],
|
||||
[0., 0.],
|
||||
)?;
|
||||
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
||||
self.interaction_transform = Some(ui_transform(meta.extent));
|
||||
}
|
||||
} else {
|
||||
let pipeline = ScreenPipeline::new(
|
||||
&meta,
|
||||
app,
|
||||
self.stereo.unwrap_or(StereoMode::None),
|
||||
[0., 0.],
|
||||
)?;
|
||||
meta.extent[2] = pipeline.get_depth();
|
||||
let pipeline = ScreenPipeline::new(&meta, app, stereo, [0., 0.])?;
|
||||
self.pipeline = Some(pipeline);
|
||||
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
||||
self.interaction_transform = Some(ui_transform(meta.extent));
|
||||
}
|
||||
|
||||
self.meta = Some(meta);
|
||||
@@ -344,14 +334,14 @@ impl OverlayBackend for ScreenBackend {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn set_attrib(&mut self, app: &mut AppState, value: BackendAttribValue) -> bool {
|
||||
fn set_attrib(&mut self, _app: &mut AppState, value: BackendAttribValue) -> bool {
|
||||
match value {
|
||||
BackendAttribValue::Stereo(new) => {
|
||||
if let Some(stereo) = self.stereo.as_mut() {
|
||||
log::debug!("{}: stereo: {stereo:?} → {new:?}", self.name);
|
||||
*stereo = new;
|
||||
if let Some(pipeline) = self.pipeline.as_mut() {
|
||||
pipeline.set_stereo(app, new).unwrap(); // only panics if gfx is dead
|
||||
pipeline.ensure_stereo(new);
|
||||
}
|
||||
true
|
||||
} else {
|
||||
|
||||
@@ -101,20 +101,21 @@ impl ScreenPipeline {
|
||||
buf_alpha,
|
||||
stereo,
|
||||
};
|
||||
me.set_stereo(app, stereo)?;
|
||||
me.ensure_stereo(stereo);
|
||||
Ok(me)
|
||||
}
|
||||
|
||||
pub fn set_stereo(&mut self, app: &mut AppState, stereo: StereoMode) -> anyhow::Result<()> {
|
||||
pub fn ensure_stereo(&mut self, stereo: StereoMode) {
|
||||
if self.stereo == stereo {
|
||||
return;
|
||||
}
|
||||
|
||||
self.stereo = stereo;
|
||||
self.pass.clear(); // ensure_depth will repopulate
|
||||
}
|
||||
|
||||
let depth = if matches!(stereo, StereoMode::None) {
|
||||
1
|
||||
} else {
|
||||
2
|
||||
};
|
||||
|
||||
if self.pass.len() < depth {
|
||||
fn ensure_depth(&mut self, app: &mut AppState, depth: usize) -> anyhow::Result<()> {
|
||||
while self.pass.len() < depth {
|
||||
self.pass.push(Self::create_pass(
|
||||
app,
|
||||
self.pipeline.clone(),
|
||||
@@ -124,21 +125,17 @@ impl ScreenPipeline {
|
||||
)?);
|
||||
}
|
||||
|
||||
if self.pass.len() > depth {
|
||||
while self.pass.len() > depth {
|
||||
self.pass.pop();
|
||||
}
|
||||
|
||||
for (eye, current) in self.pass.iter_mut().enumerate() {
|
||||
let verts = stereo_mode_to_verts(stereo, eye);
|
||||
let verts = stereo_mode_to_verts(self.stereo, eye);
|
||||
current.buf_vert.write()?.copy_from_slice(&verts);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_depth(&self) -> u32 {
|
||||
self.pass.len() as _
|
||||
}
|
||||
|
||||
pub fn set_extent(
|
||||
&mut self,
|
||||
app: &mut AppState,
|
||||
@@ -147,18 +144,7 @@ impl ScreenPipeline {
|
||||
) -> anyhow::Result<()> {
|
||||
self.extentf = extentf;
|
||||
self.offsetf = offsetf;
|
||||
|
||||
for (eye, pass) in self.pass.iter_mut().enumerate() {
|
||||
*pass = Self::create_pass(
|
||||
app,
|
||||
self.pipeline.clone(),
|
||||
extentf,
|
||||
offsetf,
|
||||
self.buf_alpha.clone(),
|
||||
)?;
|
||||
let verts = stereo_mode_to_verts(self.stereo, eye);
|
||||
pass.buf_vert.write()?.copy_from_slice(&verts);
|
||||
}
|
||||
self.pass.clear();
|
||||
|
||||
self.mouse = Self::create_mouse_pass(
|
||||
app,
|
||||
@@ -251,6 +237,8 @@ impl ScreenPipeline {
|
||||
app: &mut AppState,
|
||||
rdr: &mut RenderResources,
|
||||
) -> anyhow::Result<()> {
|
||||
self.ensure_depth(app, rdr.cmd_bufs.len())?;
|
||||
|
||||
self.buf_alpha.write()?[0] = rdr.alpha;
|
||||
|
||||
for (eye, cmd_buf) in rdr.cmd_bufs.iter_mut().enumerate() {
|
||||
@@ -503,12 +491,13 @@ pub(super) struct WlxCaptureOut {
|
||||
}
|
||||
|
||||
impl WlxCaptureOut {
|
||||
pub(super) fn get_frame_meta(&self, config: &GeneralConfig) -> FrameMeta {
|
||||
pub(super) fn get_frame_meta(&self, config: &GeneralConfig, stereo: StereoMode) -> FrameMeta {
|
||||
FrameMeta {
|
||||
clear: WGfxClearMode::DontCare,
|
||||
extent: extent_from_format(self.format, config),
|
||||
transform: affine_from_format(&self.format),
|
||||
format: self.image.format(),
|
||||
stereo,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -721,7 +710,7 @@ const fn receive_callback_dummy(_: &DummyDrmExporter, frame: WlxFrame) -> Option
|
||||
Some(frame)
|
||||
}
|
||||
|
||||
fn extent_from_format(fmt: FrameFormat, config: &GeneralConfig) -> [u32; 3] {
|
||||
fn extent_from_format(fmt: FrameFormat, config: &GeneralConfig) -> [u32; 2] {
|
||||
// screens above a certain resolution will have severe aliasing
|
||||
let height_limit = if config.screen_render_down {
|
||||
u32::from(config.screen_max_height.min(2560))
|
||||
@@ -731,7 +720,7 @@ fn extent_from_format(fmt: FrameFormat, config: &GeneralConfig) -> [u32; 3] {
|
||||
|
||||
let h = fmt.height.min(height_limit);
|
||||
let w = (fmt.width as f32 / fmt.height as f32 * h as f32) as u32;
|
||||
[w, h, 1]
|
||||
[w, h]
|
||||
}
|
||||
|
||||
fn affine_from_format(format: &FrameFormat) -> Affine3A {
|
||||
|
||||
@@ -49,7 +49,7 @@ pub struct MirrorBackend {
|
||||
name: Arc<str>,
|
||||
renderer: Option<ScreenBackend>,
|
||||
selector: Option<PinnedSelectorFuture>,
|
||||
last_extent: [u32; 3],
|
||||
last_extent: [u32; 2],
|
||||
interaction_transform: Option<Affine2>,
|
||||
}
|
||||
impl MirrorBackend {
|
||||
@@ -59,7 +59,7 @@ impl MirrorBackend {
|
||||
name,
|
||||
renderer: None,
|
||||
selector: Some(selector),
|
||||
last_extent: [0; 3],
|
||||
last_extent: [0; 2],
|
||||
interaction_transform: None,
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ impl OverlayBackend for MirrorBackend {
|
||||
let extent = meta.extent;
|
||||
if self.last_extent != extent {
|
||||
self.last_extent = extent;
|
||||
self.interaction_transform = Some(ui_transform([extent[0], extent[1]]));
|
||||
self.interaction_transform = Some(ui_transform(extent));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ pub struct WvrWindowBackend {
|
||||
stereo: Option<StereoMode>,
|
||||
cur_image: Option<Arc<ImageView>>,
|
||||
panel: GuiPanel<WindowHandle>,
|
||||
inner_extent: [u32; 3],
|
||||
inner_extent: [u32; 2],
|
||||
mouse_transform: Affine2,
|
||||
uv_range: RangeInclusive<f32>,
|
||||
panel_hovered: bool,
|
||||
@@ -208,7 +208,7 @@ impl WvrWindowBackend {
|
||||
None
|
||||
},
|
||||
cur_image: None,
|
||||
inner_extent: [0, 0, 1],
|
||||
inner_extent: [0, 0],
|
||||
panel,
|
||||
mouse_transform: Affine2::ZERO,
|
||||
uv_range: 0.0..=1.0,
|
||||
@@ -217,7 +217,7 @@ impl WvrWindowBackend {
|
||||
}
|
||||
|
||||
fn apply_extent(&mut self, app: &mut AppState, meta: &FrameMeta) -> anyhow::Result<()> {
|
||||
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
||||
self.interaction_transform = Some(ui_transform(meta.extent));
|
||||
|
||||
let scale = vec2(
|
||||
((meta.extent[0] + BORDER_SIZE * 2) as f32) / (meta.extent[0] as f32),
|
||||
@@ -300,7 +300,7 @@ impl OverlayBackend for WvrWindowBackend {
|
||||
with_states(toplevel.wl_surface(), |states| {
|
||||
if let Some(surf) = SurfaceBufWithImage::get_from_surface(states) {
|
||||
let mut meta = FrameMeta {
|
||||
extent: surf.image.image().extent(),
|
||||
extent: surf.image.extent_u32arr(),
|
||||
format: surf.image.format(),
|
||||
clear: WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.0]),
|
||||
..Default::default()
|
||||
@@ -310,8 +310,7 @@ impl OverlayBackend for WvrWindowBackend {
|
||||
meta.extent[1] += BORDER_SIZE * 2 + BAR_SIZE;
|
||||
|
||||
if let Some(pipeline) = self.pipeline.as_mut() {
|
||||
meta.extent[2] = pipeline.get_depth();
|
||||
if self.inner_extent[..2] != inner_extent[..2] {
|
||||
if self.inner_extent != inner_extent {
|
||||
pipeline.set_extent(
|
||||
app,
|
||||
[inner_extent[0] as _, inner_extent[1] as _],
|
||||
@@ -327,7 +326,6 @@ impl OverlayBackend for WvrWindowBackend {
|
||||
self.stereo.unwrap_or(StereoMode::None),
|
||||
[BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _],
|
||||
)?;
|
||||
meta.extent[2] = pipeline.get_depth();
|
||||
self.apply_extent(app, &meta)?;
|
||||
self.pipeline = Some(pipeline);
|
||||
}
|
||||
@@ -388,7 +386,8 @@ impl OverlayBackend for WvrWindowBackend {
|
||||
.render(image, self.mouse.as_ref(), app, rdr)?;
|
||||
|
||||
for (popup_img, point) in &self.popups {
|
||||
let extentf = self.meta.as_ref().unwrap().extent.extent_f32();
|
||||
let meta = self.meta.as_ref().unwrap();
|
||||
let extentf = [meta.extent[0] as f32, meta.extent[1] as f32];
|
||||
let popup_extentf = popup_img.extent_f32();
|
||||
let mut buf_vert = app
|
||||
.gfx
|
||||
@@ -551,14 +550,14 @@ impl OverlayBackend for WvrWindowBackend {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn set_attrib(&mut self, app: &mut AppState, value: BackendAttribValue) -> bool {
|
||||
fn set_attrib(&mut self, _app: &mut AppState, value: BackendAttribValue) -> bool {
|
||||
match value {
|
||||
BackendAttribValue::Stereo(new) => {
|
||||
if let Some(stereo) = self.stereo.as_mut() {
|
||||
log::debug!("{}: stereo: {stereo:?} → {new:?}", self.name);
|
||||
*stereo = new;
|
||||
if let Some(pipeline) = self.pipeline.as_mut() {
|
||||
pipeline.set_stereo(app, new).unwrap(); // only panics if gfx is dead
|
||||
pipeline.ensure_stereo(new);
|
||||
}
|
||||
true
|
||||
} else {
|
||||
|
||||
@@ -7,7 +7,7 @@ use wgui::gfx::{
|
||||
cmd::{GfxCommandBuffer, WGfxClearMode},
|
||||
};
|
||||
use wlx_common::{
|
||||
overlays::{BackendAttrib, BackendAttribValue},
|
||||
overlays::{BackendAttrib, BackendAttribValue, StereoMode},
|
||||
windowing::Positioning,
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::{
|
||||
input::{HoverResult, PointerHit},
|
||||
task::ModifyPanelCommand,
|
||||
},
|
||||
graphics::{ExtentExt, RenderResult},
|
||||
graphics::RenderResult,
|
||||
overlays::wayvr::WvrCommand,
|
||||
state::AppState,
|
||||
subsystem::hid::WheelDelta,
|
||||
@@ -25,10 +25,11 @@ use crate::{
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct FrameMeta {
|
||||
pub extent: [u32; 3],
|
||||
pub extent: [u32; 2],
|
||||
pub transform: Affine3A,
|
||||
pub format: Format,
|
||||
pub clear: WGfxClearMode,
|
||||
pub stereo: StereoMode,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -70,7 +71,7 @@ impl RenderResources {
|
||||
Ok(Self {
|
||||
cmd_bufs,
|
||||
alpha,
|
||||
extent: meta.extent.extent_u32arr(),
|
||||
extent: meta.extent,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ pub enum BackendAttribValue {
|
||||
Icon(Arc<str>),
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
|
||||
pub enum StereoMode {
|
||||
#[default]
|
||||
None,
|
||||
|
||||
Reference in New Issue
Block a user