Compare commits

..

1 commit

Author SHA1 Message Date
2b82f556f7 Update Rust crate openvr to 0.7.0 2025-02-28 18:02:33 +00:00
10 changed files with 120 additions and 213 deletions

View file

@ -25,7 +25,7 @@ use std::time::{Duration, Instant};
pub struct Context { pub struct Context {
core: VulkanCore, core: VulkanCore,
pub(crate) presentation: PresentationCore, pub(crate) presentation: PresentationCore,
render_core: Arc<RwLock<RenderCore>>, render_core: Arc<RwLock<Box<dyn RenderCore>>>,
#[cfg(feature = "sound")] #[cfg(feature = "sound")]
sound_handler: SoundHandler, sound_handler: SoundHandler,
@ -89,11 +89,11 @@ impl Context {
Ok(true) Ok(true)
} }
pub fn render_core(&self) -> impl Deref<Target = RenderCore> + '_ { pub fn render_core(&self) -> impl Deref<Target = Box<dyn RenderCore>> + '_ {
self.render_core.read().unwrap() self.render_core.read().unwrap()
} }
pub fn render_core_mut(&self) -> impl DerefMut<Target = RenderCore> + '_ { pub fn render_core_mut(&self) -> impl DerefMut<Target = Box<dyn RenderCore>> + '_ {
self.render_core.write().unwrap() self.render_core.write().unwrap()
} }

View file

@ -13,29 +13,23 @@ use crate::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
pub struct GuiHandlerRenderer { struct GuiPostProcess(Arc<GuiHandler>);
pub gui_handler: Arc<GuiHandler>,
}
impl TScene for GuiHandlerRenderer { impl context::prelude::PostProcess for GuiPostProcess {
fn process( fn priority(&self) -> u32 {
&mut self, 50
buffer_recorder: &mut CommandBufferRecorder<'_>,
_images: &TargetMode<Vec<Arc<Image>>>,
indices: &TargetMode<usize>,
_world: &World,
) -> Result<()> {
self.gui_handler.process(buffer_recorder, indices)
} }
fn resize( fn process(
&mut self, &self,
window_width: f32, buffer_recorder: &mut CommandBufferRecorder<'_>,
window_height: f32, indices: &TargetMode<usize>,
images: &TargetMode<Vec<Arc<Image>>>,
) -> Result<()> { ) -> Result<()> {
self.gui_handler self.0.process(buffer_recorder, indices)
.resize(window_width as u32, window_height as u32, images) }
fn resize(&self, width: u32, height: u32, images: &TargetMode<Vec<Arc<Image>>>) -> Result<()> {
self.0.resize(width, height, images)
} }
} }
@ -172,13 +166,11 @@ impl Engine {
let asset_manager = AssetManager::new(&engine_settings)?; let asset_manager = AssetManager::new(&engine_settings)?;
let gui_handler = GuiHandlerRenderer { let gui_handler = GuiHandler::new(create_info.gui_info, &context)?;
gui_handler: GuiHandler::new(create_info.gui_info, &context)?, let gui_post_process = Arc::new(GuiPostProcess(gui_handler.clone()));
};
context context
.render_core_mut() .render_core()
.add_render_routine::<GuiHandlerRenderer>(10_000_000); .add_post_processing_routine(gui_post_process.clone());
world.resources.insert(gui_handler); world.resources.insert(gui_handler);
@ -257,25 +249,23 @@ impl Engine {
impl Engine { impl Engine {
fn main_system<T: EventConsumer>(world: &mut World) -> Result<bool> { fn main_system<T: EventConsumer>(world: &mut World) -> Result<bool> {
let gui_handler = world.resources.get_unchecked::<GuiHandlerRenderer>(); world
.resources
.get::<Arc<GuiHandler>>()
.process_callbacks()?;
let gui_handler = world.resources.get_unchecked::<Arc<GuiHandler>>();
let input_map = world.resources.get_unchecked::<InputMap>(); let input_map = world.resources.get_unchecked::<InputMap>();
let context = world.resources.get_unchecked::<Context>(); let context = world.resources.get_unchecked::<Context>();
let res = world.resources.get_mut_unchecked::<Context>().next_frame( let res = world.resources.get_mut_unchecked::<Context>().next_frame(
world, world,
|world, consumer: &mut T, event| { |world, consumer: &mut T, event| {
Self::event( Self::event(world, context, gui_handler, input_map, consumer, event)
world,
context,
&gui_handler.gui_handler,
input_map,
consumer,
event,
)
}, },
)?; )?;
gui_handler.gui_handler.process_callbacks()?; gui_handler.process_callbacks()?;
Ok(res) Ok(res)
} }

View file

@ -54,7 +54,7 @@ impl<'a> Default for EngineCreateInfo<'a> {
enable_game_mode: true, enable_game_mode: true,
}, },
vulkan_debug_info: VulkanDebugInfo { vulkan_debug_info: VulkanDebugInfo {
debugging: true, debugging: false,
steam_layer: false, steam_layer: false,
verbose: false, verbose: false,
renderdoc: false, renderdoc: false,

View file

@ -9,6 +9,7 @@ vulkan-rs = { workspace = true }
ui = { workspace = true } ui = { workspace = true }
sdl2 = { workspace = true } sdl2 = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
destructure_traitobject = { workspace = true }
openxr = { workspace = true, optional = true } openxr = { workspace = true, optional = true }
openvr = { workspace = true, optional = true } openvr = { workspace = true, optional = true }

View file

@ -34,25 +34,25 @@ pub fn create_render_core<S: TScene + 'static>(
device: &Arc<Device>, device: &Arc<Device>,
queue: &Arc<Mutex<Queue>>, queue: &Arc<Mutex<Queue>>,
create_info: RenderCoreCreateInfo, create_info: RenderCoreCreateInfo,
) -> Result<(RenderCore, TargetMode<()>)> { ) -> Result<(Box<dyn RenderCore>, TargetMode<()>)> {
match presentation_core.backend() { match presentation_core.backend() {
PresentationBackend::Window(wsi) => { PresentationBackend::Window(wsi) => {
let (render_core, target_mode) = let (render_core, target_mode) =
VulkanWindowRenderCore::new(wsi.clone(), device, queue, create_info)?; VulkanWindowRenderCore::<S>::new(wsi.clone(), device, queue, create_info)?;
Ok((render_core.into(), target_mode)) Ok((Box::new(render_core), target_mode))
} }
PresentationBackend::OpenXR(xri) => { PresentationBackend::OpenXR(xri) => {
let (render_core, target_mode) = let (render_core, target_mode) =
xri::openxrrendercore::OpenXRRenderCore::new(xri, device, queue, create_info)?; xri::openxrrendercore::OpenXRRenderCore::new(xri, device, queue, create_info)?;
Ok((render_core.into(), target_mode)) Ok((Box::new(render_core), target_mode))
} }
PresentationBackend::OpenVR(vri) => { PresentationBackend::OpenVR(vri) => {
let (render_core, target_mode) = let (render_core, target_mode) =
vri::openvrrendercore::OpenVRRenderCore::new(vri, device, queue, create_info)?; vri::openvrrendercore::OpenVRRenderCore::new(vri, device, queue, create_info)?;
Ok((render_core.into(), target_mode)) Ok((Box::new(render_core), target_mode))
} }
} }
} }

View file

@ -169,8 +169,12 @@ impl RenderBackend {
// make a call to the connected scenes // make a call to the connected scenes
self.render_routines self.render_routines
.iter_mut() .iter_mut()
.try_for_each(|(_, type_id)| -> Result<()> { .try_for_each(|(_, type_id)| {
let scene: &mut dyn TScene = world.resources.get_mut_by_type_id_untyped(*type_id); let scene: &mut dyn TScene = unsafe {
std::mem::transmute(destructure_traitobject::data_mut(
world.resources.get_mut_by_type_id_untyped(*type_id),
))
};
scene.process( scene.process(
&mut buffer_recorder, &mut buffer_recorder,
@ -178,8 +182,6 @@ impl RenderBackend {
&image_indices, &image_indices,
world, world,
)?; )?;
Ok(())
})?; })?;
Ok(&self.command_buffer) Ok(&self.command_buffer)
@ -205,10 +207,14 @@ impl RenderBackend {
self.render_routines self.render_routines
.iter_mut() .iter_mut()
.try_for_each(|(_, type_id)| -> Result<()> { .try_for_each(|(_, type_id)| {
let scene: &mut dyn TScene = world.resources.get_mut_by_type_id_untyped(*type_id); let scene: &mut dyn TScene = unsafe {
std::mem::transmute(destructure_traitobject::data_mut(
world.resources.get_mut_by_type_id_untyped(*type_id),
))
};
scene.resize(width as f32, height as f32, &images) scene.resize(width, height, &images)
})?; })?;
Ok(()) Ok(())
@ -221,12 +227,12 @@ impl RenderBackend {
} }
pub fn remove_render_routine<T: TScene>(&mut self) { pub fn remove_render_routine<T: TScene>(&mut self) {
if let Some(&(index, _)) = self if let Some(index) = self
.render_routines .render_routines
.iter() .iter()
.find(|(_, type_id)| *type_id == TypeId::of::<T>()) .find(|(_, type_id)| *type_id == TypeId::of::<T>())
{ {
self.render_routines.remove(index as usize); self.render_routines.remove(index)
} }
} }

View file

@ -2,10 +2,7 @@ use ecs::World;
use ui::prelude::*; use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
use crate::{ use crate::Result;
Result, vri::openvrrendercore::OpenVRRenderCore,
wsi::vulkanwindowrendercore::VulkanWindowRenderCore, xri::openxrrendercore::OpenXRRenderCore,
};
use std::sync::Arc; use std::sync::Arc;
@ -28,123 +25,26 @@ pub trait TScene: Send + Sync + 'static {
) -> Result<()>; ) -> Result<()>;
} }
#[derive(Debug)] pub trait RenderCore: std::fmt::Debug + Send + Sync {
pub enum RenderCore { fn next_frame(&mut self, world: &mut World) -> Result<bool>;
Wsi(VulkanWindowRenderCore),
OpenVR(OpenVRRenderCore),
OpenXR(OpenXRRenderCore),
}
impl RenderCore { fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()>;
pub fn next_frame(&mut self, world: &mut World) -> Result<bool> {
match self {
RenderCore::Wsi(rc) => rc.next_frame(world),
RenderCore::OpenVR(rc) => rc.next_frame(world),
RenderCore::OpenXR(rc) => rc.next_frame(world),
}
}
pub fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> { fn format(&self) -> VkFormat;
match self { fn image_layout(&self) -> VkImageLayout {
RenderCore::Wsi(rc) => rc.resize(world, w, h),
RenderCore::OpenVR(rc) => rc.resize(world, w, h),
RenderCore::OpenXR(rc) => rc.resize(world, w, h),
}
}
pub fn format(&self) -> VkFormat {
match self {
RenderCore::Wsi(rc) => rc.format(),
RenderCore::OpenVR(rc) => rc.format(),
RenderCore::OpenXR(rc) => rc.format(),
}
}
pub fn image_layout(&self) -> VkImageLayout {
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
} }
/// lower priority means it is more important // render routines
pub fn add_render_routine<T: TScene>(&mut self, priority: u32) { fn add_render_routine<T: TScene>(&mut self, priority: u32);
match self { fn remove_render_routine<T: TScene>(&mut self);
RenderCore::Wsi(rc) => rc.add_render_routine::<T>(priority),
RenderCore::OpenVR(rc) => rc.add_render_routine::<T>(priority),
RenderCore::OpenXR(rc) => rc.add_render_routine::<T>(priority),
}
}
pub fn remove_render_routine<T: TScene>(&mut self) { fn set_clear_color(&self, color: [f32; 4]);
match self {
RenderCore::Wsi(rc) => rc.remove_render_routine::<T>(),
RenderCore::OpenVR(rc) => rc.remove_render_routine::<T>(),
RenderCore::OpenXR(rc) => rc.remove_render_routine::<T>(),
}
}
pub fn set_clear_color(&self, color: [f32; 4]) {
match self {
RenderCore::Wsi(rc) => rc.set_clear_color(color),
RenderCore::OpenVR(rc) => rc.set_clear_color(color),
RenderCore::OpenXR(rc) => rc.set_clear_color(color),
}
}
// getter // getter
pub fn image_count(&self) -> usize { fn image_count(&self) -> usize;
match self { fn images(&self) -> TargetMode<Vec<Arc<Image>>>;
RenderCore::Wsi(rc) => rc.image_count(), fn width(&self) -> u32;
RenderCore::OpenVR(rc) => rc.image_count(), fn height(&self) -> u32;
RenderCore::OpenXR(rc) => rc.image_count(), fn transformations(&self) -> Option<(VRTransformations, VRTransformations)>;
}
}
pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
match self {
RenderCore::Wsi(rc) => rc.images(),
RenderCore::OpenVR(rc) => rc.images(),
RenderCore::OpenXR(rc) => rc.images(),
}
}
pub fn width(&self) -> u32 {
match self {
RenderCore::Wsi(rc) => rc.width(),
RenderCore::OpenVR(rc) => rc.width(),
RenderCore::OpenXR(rc) => rc.width(),
}
}
pub fn height(&self) -> u32 {
match self {
RenderCore::Wsi(rc) => rc.height(),
RenderCore::OpenVR(rc) => rc.height(),
RenderCore::OpenXR(rc) => rc.height(),
}
}
pub fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
match self {
RenderCore::Wsi(rc) => rc.transformations(),
RenderCore::OpenVR(rc) => rc.transformations(),
RenderCore::OpenXR(rc) => rc.transformations(),
}
}
}
impl From<VulkanWindowRenderCore> for RenderCore {
fn from(value: VulkanWindowRenderCore) -> Self {
Self::Wsi(value)
}
}
impl From<OpenXRRenderCore> for RenderCore {
fn from(value: OpenXRRenderCore) -> Self {
Self::OpenXR(value)
}
}
impl From<OpenVRRenderCore> for RenderCore {
fn from(value: OpenVRRenderCore) -> Self {
Self::OpenVR(value)
}
} }

View file

@ -74,50 +74,50 @@ pub mod openvrrendercore {
} }
} }
impl OpenVRRenderCore { impl RenderCore for OpenVRRenderCore {
pub fn format(&self) -> VkFormat { fn format(&self) -> VkFormat {
unimplemented!() unimplemented!()
} }
pub fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> { fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
unimplemented!() unimplemented!()
} }
pub fn next_frame(&mut self, _: &mut World) -> Result<bool> { fn next_frame(&mut self, _: &mut World) -> Result<bool> {
unimplemented!() unimplemented!()
} }
pub fn set_clear_color(&self, _: [f32; 4]) { fn set_clear_color(&self, _: [f32; 4]) {
unimplemented!() unimplemented!()
} }
// post process handling // post process handling
pub fn add_render_routine<T: TScene>(&mut self, _priority: u32) { fn add_render_routine<T: TScene>(&mut self, priority: u32) {
unimplemented!() todo!()
} }
pub fn remove_render_routine<T: TScene>(&mut self) { fn remove_render_routine<T: TScene>(&mut self) {
unimplemented!() todo!()
} }
// getter // getter
pub fn image_count(&self) -> usize { fn image_count(&self) -> usize {
unimplemented!() unimplemented!()
} }
pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> { fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
unimplemented!() unimplemented!()
} }
pub fn width(&self) -> u32 { fn width(&self) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn height(&self) -> u32 { fn height(&self) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> { fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
unimplemented!() unimplemented!()
} }
} }

View file

@ -14,7 +14,7 @@ use std::sync::{
use std::time::Duration; use std::time::Duration;
use std::u64; use std::u64;
pub struct VulkanWindowRenderCore { pub struct VulkanWindowRenderCore<S: TScene + 'static> {
device: Arc<Device>, device: Arc<Device>,
// driver provided images // driver provided images
@ -27,14 +27,14 @@ pub struct VulkanWindowRenderCore {
render_finished_sem: Arc<Semaphore>, render_finished_sem: Arc<Semaphore>,
render_fence: Arc<Fence>, render_fence: Arc<Fence>,
render_backend: RenderBackend, render_backend: RenderBackend<S>,
current_image_index: AtomicUsize, current_image_index: AtomicUsize,
wsi: Arc<WindowSystemIntegration>, wsi: Arc<WindowSystemIntegration>,
} }
impl VulkanWindowRenderCore { impl<S: TScene + 'static> VulkanWindowRenderCore<S> {
pub fn new( pub fn new(
wsi: Arc<WindowSystemIntegration>, wsi: Arc<WindowSystemIntegration>,
device: &Arc<Device>, device: &Arc<Device>,
@ -57,7 +57,7 @@ impl VulkanWindowRenderCore {
))); )));
} }
let usage = create_info.usage | RenderBackend::required_image_usage(); let usage = create_info.usage | RenderBackend::<S>::required_image_usage();
// create swapchain // create swapchain
let swapchain = Swapchain::new( let swapchain = Swapchain::new(
@ -140,12 +140,12 @@ impl VulkanWindowRenderCore {
} }
} }
impl VulkanWindowRenderCore { impl<S: TScene + 'static> RenderCore for VulkanWindowRenderCore<S> {
pub fn format(&self) -> VkFormat { fn format(&self) -> VkFormat {
self.format self.format
} }
pub fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> { fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> {
self.swapchain.recreate((w, h))?; self.swapchain.recreate((w, h))?;
let swapchain_images = self.swapchain.wrap_images( let swapchain_images = self.swapchain.wrap_images(
@ -164,7 +164,7 @@ impl VulkanWindowRenderCore {
Ok(()) Ok(())
} }
pub fn next_frame(&mut self, world: &mut World) -> Result<bool> { fn next_frame(&mut self, world: &mut World) -> Result<bool> {
self.aquire_next_image_index(world)?; self.aquire_next_image_index(world)?;
let command_buffer = self.render_backend.render( let command_buffer = self.render_backend.render(
@ -208,42 +208,48 @@ impl VulkanWindowRenderCore {
Ok(true) Ok(true)
} }
pub fn set_clear_color(&self, color: [f32; 4]) { fn set_clear_color(&self, color: [f32; 4]) {
self.render_backend.set_clear_color(color); self.render_backend.set_clear_color(color);
} }
// post process handling // post process handling
pub fn add_render_routine<T: TScene>(&mut self, priority: u32) { fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) {
self.render_backend.add_render_routine::<T>(priority); self.render_backend
.add_post_processing_routine(post_process);
} }
pub fn remove_render_routine<T: TScene>(&mut self) { fn remove_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) {
self.render_backend.remove_render_routine::<T>(); self.render_backend
.remove_post_processing_routine(post_process);
}
fn clear_post_processing_routines(&self) {
self.render_backend.clear_post_processing_routines();
} }
// getter // getter
pub fn image_count(&self) -> usize { fn image_count(&self) -> usize {
self.render_backend.image_count() self.render_backend.image_count()
} }
pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> { fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
self.render_backend.images() self.render_backend.images()
} }
pub fn width(&self) -> u32 { fn width(&self) -> u32 {
self.swapchain.width() self.swapchain.width()
} }
pub fn height(&self) -> u32 { fn height(&self) -> u32 {
self.swapchain.height() self.swapchain.height()
} }
pub fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> { fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
None None
} }
} }
impl std::fmt::Debug for VulkanWindowRenderCore { impl<S: TScene + 'static> std::fmt::Debug for VulkanWindowRenderCore<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "VulkanWindowRenderCore {{ }}") write!(f, "VulkanWindowRenderCore {{ }}")
} }

View file

@ -72,50 +72,54 @@ pub mod openxrrendercore {
} }
} }
impl OpenXRRenderCore { impl RenderCore for OpenXRRenderCore {
pub fn format(&self) -> VkFormat { fn format(&self) -> VkFormat {
unimplemented!() unimplemented!()
} }
pub fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> { fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
unimplemented!() unimplemented!()
} }
pub fn next_frame(&mut self, _: &mut World) -> Result<bool> { fn next_frame(&mut self, _: &mut World) -> Result<bool> {
unimplemented!() unimplemented!()
} }
pub fn set_clear_color(&self, _: [f32; 4]) { fn set_clear_color(&self, _: [f32; 4]) {
unimplemented!() unimplemented!()
} }
// post process handling // post process handling
pub fn add_render_routine<T: TScene>(&mut self, _priority: u32) { fn add_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) {
unimplemented!() unimplemented!()
} }
pub fn remove_render_routine<T: TScene>(&mut self) { fn remove_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) {
unimplemented!()
}
fn clear_post_processing_routines(&self) {
unimplemented!() unimplemented!()
} }
// getter // getter
pub fn image_count(&self) -> usize { fn image_count(&self) -> usize {
unimplemented!() unimplemented!()
} }
pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> { fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
unimplemented!() unimplemented!()
} }
pub fn width(&self) -> u32 { fn width(&self) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn height(&self) -> u32 { fn height(&self) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> { fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
unimplemented!() unimplemented!()
} }
} }