Compare commits

..

2 commits

Author SHA1 Message Date
ef23b93c95 Update Rust crate itertools to 0.14.0 2025-02-28 21:02:29 +00:00
0daf0a858a Simplify render backend 2025-02-28 20:42:07 +01:00
10 changed files with 210 additions and 117 deletions

View file

@ -25,7 +25,7 @@ use std::time::{Duration, Instant};
pub struct Context {
core: VulkanCore,
pub(crate) presentation: PresentationCore,
render_core: Arc<RwLock<Box<dyn RenderCore>>>,
render_core: Arc<RwLock<RenderCore>>,
#[cfg(feature = "sound")]
sound_handler: SoundHandler,
@ -89,11 +89,11 @@ impl Context {
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()
}
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()
}

View file

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

View file

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

View file

@ -9,7 +9,6 @@ vulkan-rs = { workspace = true }
ui = { workspace = true }
sdl2 = { workspace = true }
anyhow = { workspace = true }
destructure_traitobject = { workspace = true }
openxr = { 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>,
queue: &Arc<Mutex<Queue>>,
create_info: RenderCoreCreateInfo,
) -> Result<(Box<dyn RenderCore>, TargetMode<()>)> {
) -> Result<(RenderCore, TargetMode<()>)> {
match presentation_core.backend() {
PresentationBackend::Window(wsi) => {
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) => {
let (render_core, target_mode) =
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) => {
let (render_core, target_mode) =
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
self.render_routines
.iter_mut()
.try_for_each(|(_, 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),
))
};
.try_for_each(|(_, type_id)| -> Result<()> {
let scene: &mut dyn TScene = world.resources.get_mut_by_type_id_untyped(*type_id);
scene.process(
&mut buffer_recorder,
@ -182,6 +178,8 @@ impl RenderBackend {
&image_indices,
world,
)?;
Ok(())
})?;
Ok(&self.command_buffer)
@ -207,14 +205,10 @@ impl RenderBackend {
self.render_routines
.iter_mut()
.try_for_each(|(_, 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),
))
};
.try_for_each(|(_, type_id)| -> Result<()> {
let scene: &mut dyn TScene = 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(())
@ -227,12 +221,12 @@ impl RenderBackend {
}
pub fn remove_render_routine<T: TScene>(&mut self) {
if let Some(index) = self
if let Some(&(index, _)) = self
.render_routines
.iter()
.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 vulkan_rs::prelude::*;
use crate::Result;
use crate::{
Result, vri::openvrrendercore::OpenVRRenderCore,
wsi::vulkanwindowrendercore::VulkanWindowRenderCore, xri::openxrrendercore::OpenXRRenderCore,
};
use std::sync::Arc;
@ -25,26 +28,123 @@ pub trait TScene: Send + Sync + 'static {
) -> Result<()>;
}
pub trait RenderCore: std::fmt::Debug + Send + Sync {
fn next_frame(&mut self, world: &mut World) -> Result<bool>;
#[derive(Debug)]
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;
fn image_layout(&self) -> VkImageLayout {
pub fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> {
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
}
// render routines
fn add_render_routine<T: TScene>(&mut self, priority: u32);
fn remove_render_routine<T: TScene>(&mut self);
/// lower priority means it is more important
pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
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
fn image_count(&self) -> usize;
fn images(&self) -> TargetMode<Vec<Arc<Image>>>;
fn width(&self) -> u32;
fn height(&self) -> u32;
fn transformations(&self) -> Option<(VRTransformations, VRTransformations)>;
pub fn image_count(&self) -> usize {
match self {
RenderCore::Wsi(rc) => rc.image_count(),
RenderCore::OpenVR(rc) => rc.image_count(),
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 {
fn format(&self) -> VkFormat {
impl OpenVRRenderCore {
pub fn format(&self) -> VkFormat {
unimplemented!()
}
fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
pub fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
unimplemented!()
}
fn next_frame(&mut self, _: &mut World) -> Result<bool> {
pub fn next_frame(&mut self, _: &mut World) -> Result<bool> {
unimplemented!()
}
fn set_clear_color(&self, _: [f32; 4]) {
pub fn set_clear_color(&self, _: [f32; 4]) {
unimplemented!()
}
// post process handling
fn add_render_routine<T: TScene>(&mut self, priority: u32) {
todo!()
pub fn add_render_routine<T: TScene>(&mut self, _priority: u32) {
unimplemented!()
}
fn remove_render_routine<T: TScene>(&mut self) {
todo!()
pub fn remove_render_routine<T: TScene>(&mut self) {
unimplemented!()
}
// getter
fn image_count(&self) -> usize {
pub fn image_count(&self) -> usize {
unimplemented!()
}
fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
unimplemented!()
}
fn width(&self) -> u32 {
pub fn width(&self) -> u32 {
unimplemented!()
}
fn height(&self) -> u32 {
pub fn height(&self) -> u32 {
unimplemented!()
}
fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
pub fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
unimplemented!()
}
}

View file

@ -14,7 +14,7 @@ use std::sync::{
use std::time::Duration;
use std::u64;
pub struct VulkanWindowRenderCore<S: TScene + 'static> {
pub struct VulkanWindowRenderCore {
device: Arc<Device>,
// driver provided images
@ -27,14 +27,14 @@ pub struct VulkanWindowRenderCore<S: TScene + 'static> {
render_finished_sem: Arc<Semaphore>,
render_fence: Arc<Fence>,
render_backend: RenderBackend<S>,
render_backend: RenderBackend,
current_image_index: AtomicUsize,
wsi: Arc<WindowSystemIntegration>,
}
impl<S: TScene + 'static> VulkanWindowRenderCore<S> {
impl VulkanWindowRenderCore {
pub fn new(
wsi: Arc<WindowSystemIntegration>,
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
let swapchain = Swapchain::new(
@ -140,12 +140,12 @@ impl<S: TScene + 'static> VulkanWindowRenderCore<S> {
}
}
impl<S: TScene + 'static> RenderCore for VulkanWindowRenderCore<S> {
fn format(&self) -> VkFormat {
impl VulkanWindowRenderCore {
pub fn format(&self) -> VkFormat {
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))?;
let swapchain_images = self.swapchain.wrap_images(
@ -164,7 +164,7 @@ impl<S: TScene + 'static> RenderCore for VulkanWindowRenderCore<S> {
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)?;
let command_buffer = self.render_backend.render(
@ -208,48 +208,42 @@ impl<S: TScene + 'static> RenderCore for VulkanWindowRenderCore<S> {
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);
}
// post process handling
fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) {
self.render_backend
.add_post_processing_routine(post_process);
pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
self.render_backend.add_render_routine::<T>(priority);
}
fn remove_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) {
self.render_backend
.remove_post_processing_routine(post_process);
}
fn clear_post_processing_routines(&self) {
self.render_backend.clear_post_processing_routines();
pub fn remove_render_routine<T: TScene>(&mut self) {
self.render_backend.remove_render_routine::<T>();
}
// getter
fn image_count(&self) -> usize {
pub fn image_count(&self) -> usize {
self.render_backend.image_count()
}
fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
pub fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
self.render_backend.images()
}
fn width(&self) -> u32 {
pub fn width(&self) -> u32 {
self.swapchain.width()
}
fn height(&self) -> u32 {
pub fn height(&self) -> u32 {
self.swapchain.height()
}
fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
pub fn transformations(&self) -> Option<(VRTransformations, VRTransformations)> {
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 {
write!(f, "VulkanWindowRenderCore {{ }}")
}

View file

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