Compare commits

...

2 commits

Author SHA1 Message Date
87c9e79d05 Update Rust crate hostname to 0.4.0 2025-02-28 21:02:26 +00:00
0daf0a858a Simplify render backend 2025-02-28 20:42:07 +01:00
11 changed files with 211 additions and 118 deletions

View file

@ -48,7 +48,7 @@ public-ip = { version = "0.2.2", default-features = false, features = [
] } ] }
async-std = { version = "1.12.0" } async-std = { version = "1.12.0" }
if-addrs = { version = "0.13.0" } if-addrs = { version = "0.13.0" }
hostname = { version = "0.3.1" } hostname = { version = "0.4.0" }
trust-dns-resolver = { version = "0.23.2" } trust-dns-resolver = { version = "0.23.2" }
openxr = { version = "0.19.0", default-features = false, features = ["static"] } openxr = { version = "0.19.0", default-features = false, features = ["static"] }
openvr = { version = "0.6.0" } openvr = { version = "0.6.0" }

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<Box<dyn RenderCore>>>, render_core: Arc<RwLock<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 = Box<dyn RenderCore>> + '_ { pub fn render_core(&self) -> impl Deref<Target = RenderCore> + '_ {
self.render_core.read().unwrap() self.render_core.read().unwrap()
} }
pub fn render_core_mut(&self) -> impl DerefMut<Target = Box<dyn RenderCore>> + '_ { pub fn render_core_mut(&self) -> impl DerefMut<Target = RenderCore> + '_ {
self.render_core.write().unwrap() self.render_core.write().unwrap()
} }

View file

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

View file

@ -9,7 +9,6 @@ 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<(Box<dyn RenderCore>, TargetMode<()>)> { ) -> Result<(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::<S>::new(wsi.clone(), device, queue, create_info)?; VulkanWindowRenderCore::new(wsi.clone(), device, queue, create_info)?;
Ok((Box::new(render_core), target_mode)) Ok((render_core.into(), 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((Box::new(render_core), target_mode)) Ok((render_core.into(), 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((Box::new(render_core), target_mode)) Ok((render_core.into(), target_mode))
} }
} }
} }

View file

@ -169,12 +169,8 @@ 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)| { .try_for_each(|(_, type_id)| -> Result<()> {
let scene: &mut dyn TScene = unsafe { let scene: &mut dyn TScene = world.resources.get_mut_by_type_id_untyped(*type_id);
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,
@ -182,6 +178,8 @@ impl RenderBackend {
&image_indices, &image_indices,
world, world,
)?; )?;
Ok(())
})?; })?;
Ok(&self.command_buffer) Ok(&self.command_buffer)
@ -207,14 +205,10 @@ impl RenderBackend {
self.render_routines self.render_routines
.iter_mut() .iter_mut()
.try_for_each(|(_, type_id)| { .try_for_each(|(_, type_id)| -> Result<()> {
let scene: &mut dyn TScene = unsafe { let scene: &mut dyn TScene = world.resources.get_mut_by_type_id_untyped(*type_id);
std::mem::transmute(destructure_traitobject::data_mut(
world.resources.get_mut_by_type_id_untyped(*type_id),
))
};
scene.resize(width, height, &images) scene.resize(width as f32, height as f32, &images)
})?; })?;
Ok(()) Ok(())
@ -227,12 +221,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) self.render_routines.remove(index as usize);
} }
} }

View file

@ -2,7 +2,10 @@ use ecs::World;
use ui::prelude::*; use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
use crate::Result; use crate::{
Result, vri::openvrrendercore::OpenVRRenderCore,
wsi::vulkanwindowrendercore::VulkanWindowRenderCore, xri::openxrrendercore::OpenXRRenderCore,
};
use std::sync::Arc; use std::sync::Arc;
@ -25,26 +28,123 @@ pub trait TScene: Send + Sync + 'static {
) -> Result<()>; ) -> Result<()>;
} }
pub trait RenderCore: std::fmt::Debug + Send + Sync { #[derive(Debug)]
fn next_frame(&mut self, world: &mut World) -> Result<bool>; pub enum RenderCore {
Wsi(VulkanWindowRenderCore),
OpenVR(OpenVRRenderCore),
OpenXR(OpenXRRenderCore),
}
fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()>; impl RenderCore {
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),
}
}
fn format(&self) -> VkFormat; pub fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> {
fn image_layout(&self) -> VkImageLayout { match self {
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
} }
// render routines /// lower priority means it is more important
fn add_render_routine<T: TScene>(&mut self, priority: u32); pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
fn remove_render_routine<T: TScene>(&mut self); match 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),
}
}
fn set_clear_color(&self, color: [f32; 4]); pub fn remove_render_routine<T: TScene>(&mut self) {
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
fn image_count(&self) -> usize; pub fn image_count(&self) -> usize {
fn images(&self) -> TargetMode<Vec<Arc<Image>>>; match self {
fn width(&self) -> u32; RenderCore::Wsi(rc) => rc.image_count(),
fn height(&self) -> u32; RenderCore::OpenVR(rc) => rc.image_count(),
fn transformations(&self) -> Option<(VRTransformations, VRTransformations)>; RenderCore::OpenXR(rc) => rc.image_count(),
}
}
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 RenderCore for OpenVRRenderCore { impl OpenVRRenderCore {
fn format(&self) -> VkFormat { pub fn format(&self) -> VkFormat {
unimplemented!() unimplemented!()
} }
fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> { pub fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
unimplemented!() unimplemented!()
} }
fn next_frame(&mut self, _: &mut World) -> Result<bool> { pub fn next_frame(&mut self, _: &mut World) -> Result<bool> {
unimplemented!() unimplemented!()
} }
fn set_clear_color(&self, _: [f32; 4]) { pub fn set_clear_color(&self, _: [f32; 4]) {
unimplemented!() unimplemented!()
} }
// post process handling // post process handling
fn add_render_routine<T: TScene>(&mut self, priority: u32) { pub fn add_render_routine<T: TScene>(&mut self, _priority: u32) {
todo!() unimplemented!()
} }
fn remove_render_routine<T: TScene>(&mut self) { pub fn remove_render_routine<T: TScene>(&mut self) {
todo!() unimplemented!()
} }
// getter // getter
fn image_count(&self) -> usize { pub fn image_count(&self) -> usize {
unimplemented!() unimplemented!()
} }
fn images(&self) -> TargetMode<Vec<Arc<Image>>> { pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
unimplemented!() unimplemented!()
} }
fn width(&self) -> u32 { pub fn width(&self) -> u32 {
unimplemented!() unimplemented!()
} }
fn height(&self) -> u32 { pub fn height(&self) -> u32 {
unimplemented!() unimplemented!()
} }
fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> { pub 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<S: TScene + 'static> { pub struct VulkanWindowRenderCore {
device: Arc<Device>, device: Arc<Device>,
// driver provided images // driver provided images
@ -27,14 +27,14 @@ pub struct VulkanWindowRenderCore<S: TScene + 'static> {
render_finished_sem: Arc<Semaphore>, render_finished_sem: Arc<Semaphore>,
render_fence: Arc<Fence>, render_fence: Arc<Fence>,
render_backend: RenderBackend<S>, render_backend: RenderBackend,
current_image_index: AtomicUsize, current_image_index: AtomicUsize,
wsi: Arc<WindowSystemIntegration>, wsi: Arc<WindowSystemIntegration>,
} }
impl<S: TScene + 'static> VulkanWindowRenderCore<S> { impl VulkanWindowRenderCore {
pub fn new( pub fn new(
wsi: Arc<WindowSystemIntegration>, wsi: Arc<WindowSystemIntegration>,
device: &Arc<Device>, device: &Arc<Device>,
@ -57,7 +57,7 @@ impl<S: TScene + 'static> VulkanWindowRenderCore<S> {
))); )));
} }
let usage = create_info.usage | RenderBackend::<S>::required_image_usage(); let usage = create_info.usage | RenderBackend::required_image_usage();
// create swapchain // create swapchain
let swapchain = Swapchain::new( let swapchain = Swapchain::new(
@ -140,12 +140,12 @@ impl<S: TScene + 'static> VulkanWindowRenderCore<S> {
} }
} }
impl<S: TScene + 'static> RenderCore for VulkanWindowRenderCore<S> { impl VulkanWindowRenderCore {
fn format(&self) -> VkFormat { pub fn format(&self) -> VkFormat {
self.format self.format
} }
fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> { pub 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<S: TScene + 'static> RenderCore for VulkanWindowRenderCore<S> {
Ok(()) Ok(())
} }
fn next_frame(&mut self, world: &mut World) -> Result<bool> { pub 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,48 +208,42 @@ impl<S: TScene + 'static> RenderCore for VulkanWindowRenderCore<S> {
Ok(true) Ok(true)
} }
fn set_clear_color(&self, color: [f32; 4]) { pub 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
fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) { pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
self.render_backend self.render_backend.add_render_routine::<T>(priority);
.add_post_processing_routine(post_process);
} }
fn remove_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) { pub fn remove_render_routine<T: TScene>(&mut self) {
self.render_backend self.render_backend.remove_render_routine::<T>();
.remove_post_processing_routine(post_process);
}
fn clear_post_processing_routines(&self) {
self.render_backend.clear_post_processing_routines();
} }
// getter // getter
fn image_count(&self) -> usize { pub fn image_count(&self) -> usize {
self.render_backend.image_count() self.render_backend.image_count()
} }
fn images(&self) -> TargetMode<Vec<Arc<Image>>> { pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
self.render_backend.images() self.render_backend.images()
} }
fn width(&self) -> u32 { pub fn width(&self) -> u32 {
self.swapchain.width() self.swapchain.width()
} }
fn height(&self) -> u32 { pub fn height(&self) -> u32 {
self.swapchain.height() self.swapchain.height()
} }
fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> { pub fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
None None
} }
} }
impl<S: TScene + 'static> std::fmt::Debug for VulkanWindowRenderCore<S> { impl std::fmt::Debug for VulkanWindowRenderCore {
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,54 +72,50 @@ pub mod openxrrendercore {
} }
} }
impl RenderCore for OpenXRRenderCore { impl OpenXRRenderCore {
fn format(&self) -> VkFormat { pub fn format(&self) -> VkFormat {
unimplemented!() unimplemented!()
} }
fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> { pub fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
unimplemented!() unimplemented!()
} }
fn next_frame(&mut self, _: &mut World) -> Result<bool> { pub fn next_frame(&mut self, _: &mut World) -> Result<bool> {
unimplemented!() unimplemented!()
} }
fn set_clear_color(&self, _: [f32; 4]) { pub fn set_clear_color(&self, _: [f32; 4]) {
unimplemented!() unimplemented!()
} }
// post process handling // post process handling
fn add_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) { pub fn add_render_routine<T: TScene>(&mut self, _priority: u32) {
unimplemented!() unimplemented!()
} }
fn remove_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) { pub fn remove_render_routine<T: TScene>(&mut self) {
unimplemented!()
}
fn clear_post_processing_routines(&self) {
unimplemented!() unimplemented!()
} }
// getter // getter
fn image_count(&self) -> usize { pub fn image_count(&self) -> usize {
unimplemented!() unimplemented!()
} }
fn images(&self) -> TargetMode<Vec<Arc<Image>>> { pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
unimplemented!() unimplemented!()
} }
fn width(&self) -> u32 { pub fn width(&self) -> u32 {
unimplemented!() unimplemented!()
} }
fn height(&self) -> u32 { pub fn height(&self) -> u32 {
unimplemented!() unimplemented!()
} }
fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> { pub fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
unimplemented!() unimplemented!()
} }
} }