diff --git a/Cargo.toml b/Cargo.toml index d8c162f..09a9242 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ chrono = { version = "0.4.35", features = ["serde"] } anyhow = { version = "1.0.86", features = ["backtrace"] } indexmap = { version = "2.2.6", features = ["rayon"] } shaderc = { version = "0.8.3", features = ["build-from-source"] } -rusqlite = { version = "0.32.0", features = ["bundled"] } +rusqlite = { version = "0.33.0", features = ["bundled"] } cgmath = "0.18.0" http = "1.1.0" iterchunks = "0.5.0" diff --git a/context/src/core/context.rs b/context/src/core/context.rs index 1a22959..fae29df 100644 --- a/context/src/core/context.rs +++ b/context/src/core/context.rs @@ -60,7 +60,7 @@ impl Context { pub fn next_frame<C, F>(&mut self, world: &mut World, mut f: F) -> Result<bool> where C: Send + Sync + 'static, - F: FnMut(&mut World, &mut C, Event) -> Result<()> + Send + Sync + 'static, + F: FnMut(&mut World, &mut C, Event<'_>) -> Result<()> + Send + Sync + 'static, { let render_core = self.render_core.clone(); let consumer = world.resources.get_mut_unchecked::<C>(); @@ -72,6 +72,7 @@ impl Context { ) { Ok(res) => { if !res { + self.device().wait_idle()?; return Ok(false); } } @@ -116,18 +117,12 @@ impl Context { self.core.queue() } - pub fn controllers(&self) -> &[Arc<RwLock<Controller>>] { + pub fn controllers(&self) -> impl Iterator<Item = &Controller> { self.presentation.event_system().controllers() } - pub fn active_controller(&self) -> &Option<Arc<RwLock<Controller>>> { - self.presentation.event_system().active_controller() - } - - pub fn set_active_controller(&mut self, controller: &Arc<RwLock<Controller>>) { - self.presentation - .event_system_mut() - .set_active_controller(controller) + pub fn joysticks(&self) -> impl Iterator<Item = &Joystick> { + self.presentation.event_system().joysticks() } } diff --git a/ecs/src/type_map.rs b/ecs/src/type_map.rs index d0aa76d..3dfb1a1 100644 --- a/ecs/src/type_map.rs +++ b/ecs/src/type_map.rs @@ -229,7 +229,7 @@ pub enum ComponentRequestType { #[derive(Debug)] pub struct ComponentNotFoundError { - request_type: ComponentRequestType, + pub request_type: ComponentRequestType, } impl ComponentNotFoundError { diff --git a/ecs/src/updates.rs b/ecs/src/updates.rs index 7b80fc4..638b324 100644 --- a/ecs/src/updates.rs +++ b/ecs/src/updates.rs @@ -341,7 +341,7 @@ pub struct ArchetypeInfo { } impl ArchetypeInfo { - pub(crate) fn new(entities: Vec<(Entity, Option<String>)>) -> Self { + pub fn new(entities: Vec<(Entity, Option<String>)>) -> Self { Self { entities } } @@ -388,7 +388,7 @@ impl Archetype { Ok(()) } - pub(crate) fn entities( + pub fn entities( &self, ) -> &IndexMap<Entity, Box<dyn Fn(Entity, &mut World) -> Result<()> + Send + Sync>> { &self.entities @@ -572,12 +572,12 @@ impl Updates { } } - pub(crate) fn clear(&mut self) { - self.updates.clear(); + // pub(crate) fn clear(&mut self) { + // self.updates.clear(); - #[cfg(feature = "timings")] - self.timings.clear(); - } + // #[cfg(feature = "timings")] + // self.timings.clear(); + // } pub(crate) fn add(&mut self, name: &str, priority: u32, update: Update) -> Result<()> { #[cfg(feature = "timings")] diff --git a/engine/src/engine/engine.rs b/engine/src/engine/engine.rs index 5060d30..6ad4a52 100644 --- a/engine/src/engine/engine.rs +++ b/engine/src/engine/engine.rs @@ -13,9 +13,7 @@ use crate::prelude::*; use std::collections::HashMap; use std::sync::Arc; -pub struct GuiHandlerRenderer { - pub gui_handler: Arc<GuiHandler>, -} +pub struct GuiHandlerRenderer; impl TScene for GuiHandlerRenderer { fn process( @@ -23,9 +21,12 @@ impl TScene for GuiHandlerRenderer { buffer_recorder: &mut CommandBufferRecorder<'_>, _images: &TargetMode<Vec<Arc<Image>>>, indices: &TargetMode<usize>, - _world: &World, + world: &World, ) -> Result<()> { - self.gui_handler.process(buffer_recorder, indices) + world + .resources + .get::<Arc<GuiHandler>>() + .process(buffer_recorder, indices) } fn resize( @@ -33,16 +34,17 @@ impl TScene for GuiHandlerRenderer { window_width: f32, window_height: f32, images: &TargetMode<Vec<Arc<Image>>>, + world: &World, ) -> Result<()> { - self.gui_handler - .resize(window_width as u32, window_height as u32, images) + world.resources.get::<Arc<GuiHandler>>().resize( + window_width as u32, + window_height as u32, + images, + ) } } pub struct Engine { - // loads and keeps track of raw data - asset_manager: AssetManager, - pub(crate) resource_base_path: String, } @@ -171,16 +173,7 @@ impl Engine { )?; let asset_manager = AssetManager::new(&engine_settings)?; - - let gui_handler = GuiHandlerRenderer { - gui_handler: GuiHandler::new(create_info.gui_info, &context)?, - }; - - let engine = Engine { - asset_manager, - - resource_base_path: create_info.resource_base_path, - }; + let gui_handler = GuiHandler::new(create_info.gui_info, &context)?; context .render_core_mut() @@ -189,7 +182,7 @@ impl Engine { world.resources.insert(context); - let scene = Scene::new( + Scene::new( create_info.rasterizer_info, create_info.raytracing_info, create_info.graphics_info, @@ -204,11 +197,13 @@ impl Engine { direction_mapping.insert(Keycode::Down, GuiDirection::Down); world.resources.insert(gui_handler); + world.resources.insert(GuiHandlerRenderer); world.resources.insert(InputMap { direction_mapping }); - - world.resources.insert(engine); + world.resources.insert(asset_manager); + world.resources.insert(Engine { + resource_base_path: create_info.resource_base_path, + }); world.resources.insert(engine_settings); - world.resources.insert(scene); world.add_system(Self::main_system::<T>); @@ -254,25 +249,18 @@ impl Engine { impl Engine { fn main_system<T: EventConsumer>(world: &mut World) -> Result<bool> { - let gui_handler = world.resources.get_unchecked::<GuiHandlerRenderer>(); + let gui_handler = world.resources.get_unchecked::<Arc<GuiHandler>>(); 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.gui_handler, - input_map, - consumer, - event, - ) + Self::event(world, context, gui_handler, input_map, consumer, event) }, )?; - gui_handler.gui_handler.process_callbacks()?; + gui_handler.process_callbacks()?; Ok(res) } diff --git a/engine/src/engine/engine_event_handling.rs b/engine/src/engine/engine_event_handling.rs index cecc6d3..a0b79fb 100644 --- a/engine/src/engine/engine_event_handling.rs +++ b/engine/src/engine/engine_event_handling.rs @@ -1,14 +1,9 @@ use crate::prelude::*; - use anyhow::Result; - use std::collections::HashMap; -use std::sync::{Arc, RwLock}; - -// use super::engine_object_data::{EngineObjectAccess, EngineObjectDataHandle}; #[derive(Debug)] -pub enum EngineEvent { +pub enum EngineEvent<'a> { MouseMotion(u32, u32), MouseButtonDown(MouseButton), MouseButtonUp(MouseButton), @@ -17,18 +12,23 @@ pub enum EngineEvent { KeyDown(Keycode), KeyUp(Keycode), - ButtonDown(ControllerButton), - ButtonUp(ControllerButton), - ControllerAxis(ControllerAxis), + ControllerButtonDown(&'a Controller, ControllerButton), + ControllerButtonUp(&'a Controller, ControllerButton), + ControllerAxis(&'a Controller, ControllerAxis), + ControllerAdded(&'a Controller), + ControllerRemoved(&'a Controller), - ControllerAdded(Arc<RwLock<Controller>>), - ControllerRemoved(Arc<RwLock<Controller>>), + JoystickButtonDown(&'a Joystick), + JoystickButtonUp(&'a Joystick), + JoystickAxis(&'a Joystick), + JoystickAdded(&'a Joystick), + JoystickRemoved(&'a Joystick), FileDrop(String), } pub trait EventConsumer: Send + Sync + 'static { - fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()>; + fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()>; } pub struct InputMap { @@ -42,7 +42,7 @@ impl Engine { gui_handler: &GuiHandler, input: &InputMap, consumer: &mut T, - event: Event, + event: Event<'_>, ) -> anyhow::Result<()> { match event { Event::MouseMotion(x, y) => { @@ -71,15 +71,13 @@ impl Engine { Event::TextInput(text) => { Self::text_input(gui_handler, text)?; } - Event::ControllerButtonDown(button) => { - Self::button_down_event(world, gui_handler, consumer, button)?; + Event::ControllerButtonDown(controller, button) => { + Self::button_down_event(world, gui_handler, consumer, controller, button)?; } - Event::ControllerButtonUp(button) => { - Self::button_up_event(world, consumer, button)?; + Event::ControllerButtonUp(controller, button) => { + Self::button_up_event(world, consumer, controller, button)?; } Event::ControllerAxis(controller) => { - let controller = controller.read().unwrap(); - if !gui_handler.check_navigatable()? { Self::axis_event(world, consumer, &controller)? } else { @@ -92,6 +90,23 @@ impl Engine { Event::ControllerRemoved(controller) => { Self::controller_removed(world, consumer, controller)? } + + Event::JoystickAxis(joystick) => { + consumer.event(world, EngineEvent::JoystickAxis(joystick))? + } + Event::JoystickButtonDown(joystick) => { + consumer.event(world, EngineEvent::JoystickButtonDown(joystick))? + } + Event::JoystickButtonUp(joystick) => { + consumer.event(world, EngineEvent::JoystickButtonUp(joystick))? + } + Event::JoystickAdded(joystick) => { + consumer.event(world, EngineEvent::JoystickAdded(joystick))? + } + Event::JoystickRemoved(joystick) => { + consumer.event(world, EngineEvent::JoystickRemoved(joystick))? + } + Event::FileDrop(filename) => consumer.event(world, EngineEvent::FileDrop(filename))?, } @@ -104,7 +119,7 @@ impl Engine { fn controller_added<T: EventConsumer>( world: &mut World, consumer: &mut T, - controller: Arc<RwLock<Controller>>, + controller: &Controller, ) -> Result<()> { consumer.event(world, EngineEvent::ControllerAdded(controller))?; @@ -115,7 +130,7 @@ impl Engine { fn controller_removed<T: EventConsumer>( world: &mut World, consumer: &mut T, - controller: Arc<RwLock<Controller>>, + controller: &Controller, ) -> Result<()> { consumer.event(world, EngineEvent::ControllerRemoved(controller))?; @@ -192,9 +207,10 @@ impl Engine { fn button_up_event<T: EventConsumer>( world: &mut World, consumer: &mut T, + controller: &Controller, button: ControllerButton, ) -> Result<()> { - consumer.event(world, EngineEvent::ButtonUp(button))?; + consumer.event(world, EngineEvent::ControllerButtonUp(controller, button))?; Ok(()) } @@ -204,12 +220,13 @@ impl Engine { world: &mut World, gui_handler: &GuiHandler, consumer: &mut T, + controller: &Controller, button: ControllerButton, ) -> Result<()> { if gui_handler.check_navigatable()? { - Self::check_button_down(world, gui_handler, consumer, button)?; + Self::check_button_down(world, gui_handler, consumer, controller, button)?; } else { - consumer.event(world, EngineEvent::ButtonDown(button))?; + consumer.event(world, EngineEvent::ControllerButtonDown(controller, button))?; } Ok(()) @@ -223,7 +240,7 @@ impl Engine { ) -> Result<()> { consumer.event( world, - EngineEvent::ControllerAxis(controller.controller_axis()), + EngineEvent::ControllerAxis(controller, controller.controller_axis()), )?; Ok(()) @@ -234,6 +251,7 @@ impl Engine { world: &mut World, gui_handler: &GuiHandler, consumer: &mut T, + controller: &Controller, button: ControllerButton, ) -> Result<()> { match button { @@ -313,7 +331,7 @@ impl Engine { } if !gui_handler.accept_custom_selection(button)? { - consumer.event(world, EngineEvent::ButtonDown(button))?; + consumer.event(world, EngineEvent::ControllerButtonDown(controller, button))?; } Ok(()) diff --git a/engine/src/engine/engine_settings.rs b/engine/src/engine/engine_settings.rs index 34f632e..ec2b9c7 100644 --- a/engine/src/engine/engine_settings.rs +++ b/engine/src/engine/engine_settings.rs @@ -205,7 +205,7 @@ impl EngineSettings { button: ControllerButton, ) -> Result<Option<Arc<Image>>> { // TODO: don't check it every time we request a button - self.check_controller(context)?; + // self.check_controller(context)?; match self.current_controller_type.read().unwrap().as_ref() { Some(controller_type) => Ok(Some(self.controller_button_for( @@ -347,61 +347,61 @@ impl EngineSettings { } } - fn check_controller(&self, context: &Context) -> Result<()> { - let active_controller = context.active_controller(); + // fn check_controller(&self, context: &Context) -> Result<()> { + // let active_controller = context.active_controller(); - match &active_controller { - // there is an controller connected - Some(controller) => { - let controller_name = controller.read().unwrap().name().clone(); + // match &active_controller { + // // there is an controller connected + // Some(controller) => { + // let controller_name = controller.read().unwrap().name().clone(); - // predict controller type from name - let controller_type = if controller_name.contains("PS4") { - ControllerType::PS4 - } else if controller_name.contains("Steam") { - ControllerType::Steam - } else { - ControllerType::XBox - }; + // // predict controller type from name + // let controller_type = if controller_name.contains("PS4") { + // ControllerType::PS4 + // } else if controller_name.contains("Steam") { + // ControllerType::Steam + // } else { + // ControllerType::XBox + // }; - let mut current_controller_type = self.current_controller_type.write().unwrap(); + // let mut current_controller_type = self.current_controller_type.write().unwrap(); - // check if current controller type is set + // // check if current controller type is set - if current_controller_type.is_some() { - // if controller type is set, check if it is different - if *current_controller_type.as_ref().unwrap() != controller_type { - *current_controller_type = Some(controller_type); + // if current_controller_type.is_some() { + // // if controller type is set, check if it is different + // if *current_controller_type.as_ref().unwrap() != controller_type { + // *current_controller_type = Some(controller_type); - let mut map = self.controller_buttons.write().unwrap(); + // let mut map = self.controller_buttons.write().unwrap(); - // clear map if filled - if !map.is_empty() { - map.clear(); - } - } - } else { - // set the controller type - *current_controller_type = Some(controller_type); - } - } - // there is no controller connected - None => { - let mut current_controller_type = self.current_controller_type.write().unwrap(); - let mut map = self.controller_buttons.write().unwrap(); + // // clear map if filled + // if !map.is_empty() { + // map.clear(); + // } + // } + // } else { + // // set the controller type + // *current_controller_type = Some(controller_type); + // } + // } + // // there is no controller connected + // None => { + // let mut current_controller_type = self.current_controller_type.write().unwrap(); + // let mut map = self.controller_buttons.write().unwrap(); - // clear current type if set - if current_controller_type.is_some() { - *current_controller_type = None; - } + // // clear current type if set + // if current_controller_type.is_some() { + // *current_controller_type = None; + // } - // clear map if filled - if !map.is_empty() { - map.clear(); - } - } - } + // // clear map if filled + // if !map.is_empty() { + // map.clear(); + // } + // } + // } - Ok(()) - } + // Ok(()) + // } } diff --git a/engine/src/scene/general/light.rs b/engine/src/scene/general/light.rs index 2f9ac57..bb89d1c 100644 --- a/engine/src/scene/general/light.rs +++ b/engine/src/scene/general/light.rs @@ -5,7 +5,7 @@ use crate::prelude::*; use anyhow::Result; use utilities::{ impl_reprc, - prelude::cgmath::{vec3, InnerSpace, Rad, Vector3, Zero}, + prelude::cgmath::{InnerSpace, Rad, Vector3, Zero, vec3}, }; use utilities::prelude::cgmath::{Matrix4, SquareMatrix}; @@ -127,15 +127,15 @@ pub struct Light { } impl Light { - pub(crate) fn point_light(device: &Arc<Device>) -> Result<Light> { + pub fn point_light(device: &Arc<Device>) -> Result<Light> { Self::new(LightType::Point, device) } - pub(crate) fn directional_light(device: &Arc<Device>) -> Result<Light> { + pub fn directional_light(device: &Arc<Device>) -> Result<Light> { Self::new(LightType::Direction, device) } - pub(crate) fn spot_light(device: &Arc<Device>) -> Result<Light> { + pub fn spot_light(device: &Arc<Device>) -> Result<Light> { Self::new(LightType::Spot, device) } diff --git a/engine/src/scene/rendering/rasterizer/traditional/mod.rs b/engine/src/scene/rendering/rasterizer/traditional/mod.rs index 7dcb59e..975d607 100644 --- a/engine/src/scene/rendering/rasterizer/traditional/mod.rs +++ b/engine/src/scene/rendering/rasterizer/traditional/mod.rs @@ -205,7 +205,7 @@ impl TraditionalRasterizer { .add_target_info(depth_target) .set_sample_count(sample_count) // swapchain resolve targets - .add_resolve_targets((images, true)) + .add_resolve_targets((images, false)) // resolved position target .add_resolve_targets(CustomTarget { usage: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT diff --git a/engine/src/scene/scene/scene_base.rs b/engine/src/scene/scene/scene_base.rs index 82c7b29..960f798 100644 --- a/engine/src/scene/scene/scene_base.rs +++ b/engine/src/scene/scene/scene_base.rs @@ -14,7 +14,6 @@ use super::super::timings::Timings; use anyhow::Result; use ecs::*; -use rayon::prelude::*; use utilities::prelude::cgmath::{Matrix4, Vector3, vec3}; use std::sync::Mutex; @@ -28,9 +27,6 @@ pub struct Scene { screen_width: f32, screen_height: f32, - device: Arc<Device>, - queue: Arc<Mutex<Queue>>, - render_type: SceneType, last_frame: Duration, @@ -92,9 +88,6 @@ impl Scene { render_type, - device: device.clone(), - queue: queue.clone(), - frustum_check: None, renderer, @@ -486,6 +479,7 @@ impl TScene for Scene { window_width: f32, window_height: f32, images: &TargetMode<Vec<Arc<Image>>>, + _world: &World, ) -> anyhow::Result<()> { self.screen_width = window_width; self.screen_height = window_height; diff --git a/examples/simple_window/src/main.rs b/examples/simple_window/src/main.rs index 2fbebe9..911ed58 100644 --- a/examples/simple_window/src/main.rs +++ b/examples/simple_window/src/main.rs @@ -3,7 +3,7 @@ use std::path::Path; use anyhow::Result; use ecs::*; -use engine::prelude::*; +use engine::prelude::{cgmath::vec3, *}; use skybox::SkyBox; fn main() -> Result<()> { @@ -14,6 +14,7 @@ fn main() -> Result<()> { world_builder.add_system(GameState::update); world_builder.resources.insert(GameState::Startup); + // let dir = Path::new("C:/Users/M.Huebner/Downloads/Space Skybox Generator/Export"); let dir = Path::new("/home/michaelh/Sync/skybox"); SkyBox::new( &mut world_builder, @@ -28,6 +29,12 @@ fn main() -> Result<()> { .into_iter(), )?; + let view = world_builder.resources.get_mut::<Scene>().view_mut(); + let camera = view.camera_mut(); + + camera.set_eye_offset(vec3(0.0, 1.0, 0.0)); + view.update_buffer()?; + world_builder.build().run() } @@ -52,7 +59,7 @@ impl GameState { } impl EventConsumer for GameState { - fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()> { + fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> { match self { GameState::Startup => (), GameState::Loading => (), @@ -71,7 +78,7 @@ impl Game { Ok(()) } - fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()> { + fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> { Ok(()) } } diff --git a/loading-screen/src/loadingscreen.rs b/loading-screen/src/loadingscreen.rs index 25e3f4d..3bb3e46 100644 --- a/loading-screen/src/loadingscreen.rs +++ b/loading-screen/src/loadingscreen.rs @@ -1,40 +1,60 @@ use context::prelude::*; -use std::{sync::Arc, thread}; +use std::{ + sync::{ + Arc, + mpsc::{Receiver, channel}, + }, + thread, +}; use anyhow::Result; -pub struct LoadingScreen; +pub struct LoadingScreen<T: Send + Sync + 'static> { + result: Option<T>, + receiver: Receiver<T>, +} -impl LoadingScreen { - pub fn load<T, R, L, G>( - context: &Arc<Context>, - gui: Option<Arc<G>>, - loader: L, - on_ready: R, - ) -> Result<()> +impl<T: Send + Sync + 'static> LoadingScreen<T> { + pub fn load<R, L, G>(gui: Arc<G>, loader: L) -> Result<Self> where R: Fn(T) -> Result<()> + Send + Sync + 'static, T: Send + Sync + 'static, L: FnOnce() -> T + Send + Sync + 'static, G: TopLevelGui + TopGui + Send + Sync + 'static, { - if let Some(gui) = &gui { - gui.enable()?; - } + gui.enable()?; - let context = context.clone(); + let (sender, receiver) = channel(); thread::spawn(move || { - let result = loader(); - if let Some(gui) = &gui { - gui.disable().unwrap(); - } - - todo!(); - // context.push_event(move || (on_ready)(result)); + let _ = sender.send(loader()); + let _ = gui.disable(); }); - Ok(()) + Ok(Self { + result: None, + receiver, + }) + } + + pub fn check_ready(&mut self) -> bool { + if self.result.is_some() { + return true; + } + + match self.receiver.try_recv() { + Ok(result) => { + self.result = Some(result); + true + } + Err(_) => false, + } + } + + /// Will panic if there is no result. + /// Use `check_ready` before calling this. + pub fn take_result(mut self) -> T { + self.result.take().unwrap() } } diff --git a/presentation/src/input/controller.rs b/presentation/src/input/controller.rs index f212f1f..3c9e196 100644 --- a/presentation/src/input/controller.rs +++ b/presentation/src/input/controller.rs @@ -3,7 +3,7 @@ use ui::prelude::*; use super::controlleraxis::ControllerAxis; -use sdl2; +use sdl2::{self, GameControllerSubsystem}; #[derive(PartialEq)] enum State { @@ -51,7 +51,7 @@ pub struct Controller { impl Controller { pub fn new( - controller_subsystem: &sdl2::GameControllerSubsystem, + controller_subsystem: &GameControllerSubsystem, id: u32, deadzones: ControllerDeadzones, ) -> Result<Controller> { @@ -199,7 +199,7 @@ impl Controller { } } - pub fn set_left_x(&mut self, x: f32) { + pub(crate) fn set_left_x(&mut self, x: f32) { self.controller_axis.left_stick.x = x; let direction = self.check_direction( @@ -212,7 +212,7 @@ impl Controller { } } - pub fn set_left_y(&mut self, y: f32) { + pub(crate) fn set_left_y(&mut self, y: f32) { self.controller_axis.left_stick.y = y; let direction = self.check_direction( @@ -225,15 +225,15 @@ impl Controller { } } - pub fn set_right_x(&mut self, x: f32) { + pub(crate) fn set_right_x(&mut self, x: f32) { self.controller_axis.right_stick.x = x; } - pub fn set_right_y(&mut self, y: f32) { + pub(crate) fn set_right_y(&mut self, y: f32) { self.controller_axis.right_stick.y = y; } - pub fn set_left_trigger(&mut self, trigger: f32) { + pub(crate) fn set_left_trigger(&mut self, trigger: f32) { self.controller_axis.left_trigger = trigger; let left_trigger = self.check_trigger(trigger, self.last_left_trigger); @@ -244,7 +244,7 @@ impl Controller { } } - pub fn set_right_trigger(&mut self, trigger: f32) { + pub(crate) fn set_right_trigger(&mut self, trigger: f32) { self.controller_axis.right_trigger = trigger; let right_trigger = self.check_trigger(trigger, self.last_right_trigger); diff --git a/presentation/src/input/eventsystem.rs b/presentation/src/input/eventsystem.rs index 803c554..9ab2187 100644 --- a/presentation/src/input/eventsystem.rs +++ b/presentation/src/input/eventsystem.rs @@ -2,7 +2,9 @@ use sdl2; use sdl2::EventPump; use sdl2::EventSubsystem; use sdl2::GameControllerSubsystem; +use sdl2::JoystickSubsystem; use sdl2::Sdl; +use sdl2::controller::Axis; use sdl2::controller::Button; use sdl2::event::{Event as SdlEvent, EventType as SdlEventType, WindowEvent}; use sdl2::keyboard::Keycode; @@ -10,11 +12,12 @@ use sdl2::mouse::{MouseButton as SdlMouseButton, MouseUtil, MouseWheelDirection} use ui::prelude::*; -use std::sync::{Arc, RwLock}; +use std::collections::HashMap; use crate::Result; use super::controller::{Controller, ControllerDeadzones}; +use super::joystick::Joystick; fn convert_button(button: Button) -> ControllerButton { match button { @@ -51,7 +54,7 @@ fn convert_button(button: Button) -> ControllerButton { } #[derive(Debug)] -pub enum Event { +pub enum Event<'a> { // mouse events MouseMotion(u32, u32), MouseButtonDown(MouseButton), @@ -64,11 +67,18 @@ pub enum Event { TextInput(String), // controller events - ControllerAxis(Arc<RwLock<Controller>>), - ControllerButtonDown(ControllerButton), - ControllerButtonUp(ControllerButton), - ControllerAdded(Arc<RwLock<Controller>>), - ControllerRemoved(Arc<RwLock<Controller>>), + ControllerAxis(&'a Controller), + ControllerButtonDown(&'a Controller, ControllerButton), + ControllerButtonUp(&'a Controller, ControllerButton), + ControllerAdded(&'a Controller), + ControllerRemoved(&'a Controller), + + // joystick events + JoystickAxis(&'a Joystick), + JoystickButtonDown(&'a Joystick), + JoystickButtonUp(&'a Joystick), + JoystickAdded(&'a Joystick), + JoystickRemoved(&'a Joystick), // drag'n'drop FileDrop(String), @@ -78,12 +88,13 @@ pub struct EventSystem { event_pump: EventPump, mouse: MouseUtil, controller_subsystem: GameControllerSubsystem, + joystick_subsystem: JoystickSubsystem, event_subsystem: EventSubsystem, controller_deadzones: ControllerDeadzones, - selected_controller: Option<Arc<RwLock<Controller>>>, - connected_controllers: Vec<Arc<RwLock<Controller>>>, + connected_controllers: HashMap<u32, Controller>, + connected_joysticks: HashMap<u32, Joystick>, } impl EventSystem { @@ -96,12 +107,13 @@ impl EventSystem { controller_subsystem: sdl2_context .game_controller() .map_err(|s| anyhow::Error::msg(s))?, + joystick_subsystem: sdl2_context.joystick().map_err(|s| anyhow::Error::msg(s))?, event_subsystem: sdl2_context.event().map_err(|s| anyhow::Error::msg(s))?, controller_deadzones: ControllerDeadzones::default(), - selected_controller: None, - connected_controllers: Vec::new(), + connected_controllers: HashMap::new(), + connected_joysticks: HashMap::new(), }; event_system.disable_mouse(); @@ -180,11 +192,9 @@ impl EventSystem { pub fn poll_events<F, R>(&mut self, mut event_callback: F, mut resize: R) -> Result<bool> where - F: FnMut(Event) -> Result<()>, + F: FnMut(Event<'_>) -> Result<()>, R: FnMut(u32, u32) -> Result<()>, { - let mut controller_axis_changed = false; - for event in self.event_pump.poll_iter() { match event { SdlEvent::Window { win_event, .. } => match win_event { @@ -266,184 +276,78 @@ impl EventSystem { which as u32, self.controller_deadzones.clone(), ) { - let controller = { - if cfg!(debug_assertions) { - println!( - "Controller added: {}({})", - controller.name(), - controller.id() - ); - } + if cfg!(debug_assertions) { + println!( + "Controller added: {}({})", + controller.name(), + controller.id() + ); + } - let arc_controller = Arc::new(RwLock::new(controller)); - self.connected_controllers.push(arc_controller.clone()); - - if self.selected_controller.is_none() { - if cfg!(debug_assertions) { - let contr = arc_controller.read().unwrap(); - - println!( - "New active controller: {}({})", - contr.name(), - contr.id() - ); - } - - self.selected_controller = Some(arc_controller.clone()); - } - - arc_controller - }; - - event_callback(Event::ControllerAdded(controller))?; + event_callback(Event::ControllerAdded(&controller))?; + self.connected_controllers + .insert(controller.id(), controller); } } SdlEvent::ControllerDeviceRemoved { which, .. } => { - let removed_controller = { - if self.selected_controller.is_some() { - if cfg!(debug_assertions) { - let contr = - self.selected_controller.as_ref().unwrap().read().unwrap(); - - println!( - "Remove active controller: {}({})", - contr.name(), - contr.id() - ); - } - - // unwrap is save since we just tested for `is_some()` - if self - .selected_controller - .as_ref() - .unwrap() - .read() - .unwrap() - .id() - == which - { - self.selected_controller = None; - } + if let Some(controller) = self.connected_controllers.remove(&which) { + if cfg!(debug_assertions) { + println!( + "Controller removed: {}({})", + controller.name(), + controller.id() + ); } - self.connected_controllers - .iter() - .position(|controller_cell| { - let controller = controller_cell.read().unwrap(); - controller.id() == which - }) - .map(|remove_index| { - let removed_controller = - self.connected_controllers.swap_remove(remove_index); - - if cfg!(debug_assertions) { - let contr = removed_controller.read().unwrap(); - println!( - "Controller removed: {}({})", - contr.name(), - contr.id() - ); - } - - // if we removed the selected controller, take the controller at the first position if possible - if self.selected_controller.is_none() - && !self.connected_controllers.is_empty() - { - if cfg!(debug_assertions) { - println!( - "Set active controller: {}", - self.connected_controllers[0].read().unwrap().name() - ); - } - - self.selected_controller = - Some(self.connected_controllers[0].clone()); - } - - removed_controller - }) - }; - - if let Some(removed_controller) = removed_controller { - event_callback(Event::ControllerRemoved(removed_controller))?; + event_callback(Event::ControllerRemoved(&controller))?; } } - // maybe make use of `which`, for support of multiple controllers - SdlEvent::ControllerButtonDown { - button, - // which, - .. - } => { - // // only call back if the selected controller pressed a button - // match self.selected_controller.read().unwrap().as_ref() { - // Some(selected_controller) => { - // if selected_controller.read().unwrap().id() != which { - // continue; - // } - // } - // None => continue, - // } - - event_callback(Event::ControllerButtonDown(convert_button(button)))?; + SdlEvent::ControllerButtonDown { button, which, .. } => { + event_callback(Event::ControllerButtonDown( + self.connected_controllers.get(&which).unwrap(), + convert_button(button), + ))?; } - // maybe make use of `which`, for support of multiple controllers - SdlEvent::ControllerButtonUp { - button, - // which, - .. - } => { - // // only call back if the selected controller released a button - // match self.selected_controller.read().unwrap().as_ref() { - // Some(selected_controller) => { - // if selected_controller.read().unwrap().id() != which { - // continue; - // } - // } - // None => continue, - // } - - event_callback(Event::ControllerButtonUp(convert_button(button)))?; + SdlEvent::ControllerButtonUp { button, which, .. } => { + event_callback(Event::ControllerButtonUp( + self.connected_controllers.get(&which).unwrap(), + convert_button(button), + ))?; } SdlEvent::ControllerAxisMotion { - axis, - value, - // which, - .. + axis, value, which, .. } => { - if let Some(controller) = self.selected_controller.as_mut() { - let mut controller = controller.write().unwrap(); + let controller = self.connected_controllers.get_mut(&which).unwrap(); + let normalized = value as f32 * 0.000_030_518; - // // only update axis, when selected controller made the change - // if controller.id() != which { - // continue; - // } - - // 1 / 32768 = 0,000030518 - let normalized = value as f32 * 0.000_030_518; - - match axis { - sdl2::controller::Axis::LeftX => { - controller.set_left_x(normalized); - } - sdl2::controller::Axis::RightX => { - controller.set_right_x(normalized); - } - sdl2::controller::Axis::LeftY => { - controller.set_left_y(-normalized); - } - sdl2::controller::Axis::RightY => { - controller.set_right_y(normalized); - } - sdl2::controller::Axis::TriggerLeft => { - controller.set_left_trigger(normalized); - } - sdl2::controller::Axis::TriggerRight => { - controller.set_right_trigger(normalized); - } + match axis { + Axis::LeftX => { + controller.set_left_x(normalized); + } + Axis::RightX => { + controller.set_right_x(normalized); + } + Axis::LeftY => { + controller.set_left_y(-normalized); + } + Axis::RightY => { + controller.set_right_y(normalized); + } + Axis::TriggerLeft => { + controller.set_left_trigger(normalized); + } + Axis::TriggerRight => { + controller.set_right_trigger(normalized); } - - controller_axis_changed = true; } + + event_callback(Event::ControllerAxis(&*controller))?; + } + SdlEvent::JoyDeviceAdded { which, .. } => { + let joystick = Joystick::new(&self.joystick_subsystem, which)?; + + event_callback(Event::JoystickAdded(&joystick))?; + self.connected_joysticks.insert(joystick.id(), joystick); } SdlEvent::DropFile { filename, .. } => { event_callback(Event::FileDrop(filename))?; @@ -452,58 +356,15 @@ impl EventSystem { } } - if controller_axis_changed { - if let Some(controller) = &self.selected_controller { - let (left_trigger, right_trigger) = { - let mut controller_lock = controller.write().unwrap(); - - ( - controller_lock.left_trigger(), - controller_lock.right_trigger(), - ) - }; - - if let Some(right_trigger) = right_trigger { - if right_trigger { - event_callback(Event::ControllerButtonDown( - ControllerButton::RightTrigger, - ))?; - } else { - event_callback(Event::ControllerButtonUp(ControllerButton::RightTrigger))?; - } - } - - if let Some(left_trigger) = left_trigger { - if left_trigger { - event_callback(Event::ControllerButtonDown(ControllerButton::LeftTrigger))?; - } else { - event_callback(Event::ControllerButtonUp(ControllerButton::LeftTrigger))?; - } - } - - event_callback(Event::ControllerAxis(controller.clone()))?; - } - } - Ok(true) } - pub fn controllers(&self) -> &[Arc<RwLock<Controller>>] { - &self.connected_controllers + pub fn controllers(&self) -> impl Iterator<Item = &Controller> { + self.connected_controllers.values() } - pub fn active_controller(&self) -> &Option<Arc<RwLock<Controller>>> { - &self.selected_controller - } - - pub fn set_active_controller(&mut self, controller: &Arc<RwLock<Controller>>) { - if let Some(res) = self - .connected_controllers - .iter() - .find(|c| Arc::ptr_eq(c, controller)) - { - self.selected_controller = Some(res.clone()); - } + pub fn joysticks(&self) -> impl Iterator<Item = &Joystick> { + self.connected_joysticks.values() } } diff --git a/presentation/src/input/joystick.rs b/presentation/src/input/joystick.rs new file mode 100644 index 0000000..592c822 --- /dev/null +++ b/presentation/src/input/joystick.rs @@ -0,0 +1,40 @@ +use anyhow::Result; +use sdl2::JoystickSubsystem; + +pub struct Joystick { + _sdl2_joystick: sdl2::joystick::Joystick, + id: u32, + name: String, +} + +impl Joystick { + pub fn new(joystick_subsystem: &JoystickSubsystem, id: u32) -> Result<Self> { + let sdl2_joystick = joystick_subsystem.open(id)?; + + Ok(Self { + name: sdl2_joystick.name(), + id, + _sdl2_joystick: sdl2_joystick, + }) + } + + pub fn id(&self) -> u32 { + self.id + } + + pub fn name(&self) -> &str { + &self.name + } +} + +impl std::fmt::Debug for Joystick { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Joystick") + .field("id", &self.id) + .field("name", &self.name) + .finish() + } +} + +unsafe impl Send for Joystick {} +unsafe impl Sync for Joystick {} diff --git a/presentation/src/input/mod.rs b/presentation/src/input/mod.rs index 72bb1a9..c0f7c5f 100644 --- a/presentation/src/input/mod.rs +++ b/presentation/src/input/mod.rs @@ -3,3 +3,4 @@ pub mod controller; pub mod controlleraxis; pub mod eventsystem; +pub mod joystick; diff --git a/presentation/src/prelude.rs b/presentation/src/prelude.rs index 5374ff4..4291c32 100644 --- a/presentation/src/prelude.rs +++ b/presentation/src/prelude.rs @@ -1,6 +1,6 @@ pub use crate::traits::*; -pub use crate::{create_render_core, RenderCoreCreateInfo}; +pub use crate::{RenderCoreCreateInfo, create_render_core}; pub use crate::presentationcore::{ApplicationInfo, PresentationBackend, PresentationCore, VRMode}; @@ -10,6 +10,7 @@ pub use crate::renderbackend::{Eye, VRTransformations}; pub use crate::input::{ controller::{Controller, ControllerDeadzones}, controlleraxis::ControllerAxis, + joystick::Joystick, }; // wsi diff --git a/presentation/src/presentationcore.rs b/presentation/src/presentationcore.rs index 2f86797..b8e87e5 100644 --- a/presentation/src/presentationcore.rs +++ b/presentation/src/presentationcore.rs @@ -113,7 +113,7 @@ impl PresentationCore { pub fn poll_events<F, R>(&mut self, event_callback: F, resize_event: R) -> Result<bool> where - F: FnMut(Event) -> Result<()>, + F: FnMut(Event<'_>) -> Result<()>, R: FnMut(u32, u32) -> Result<()>, { self.event_system.poll_events(event_callback, resize_event) diff --git a/presentation/src/renderbackend.rs b/presentation/src/renderbackend.rs index 74f525a..669335f 100644 --- a/presentation/src/renderbackend.rs +++ b/presentation/src/renderbackend.rs @@ -89,7 +89,7 @@ impl SceneHandle { world .resources .get_mut_unchecked::<T>() - .resize(width, height, images) + .resize(width, height, images, world) }), } } diff --git a/presentation/src/traits.rs b/presentation/src/traits.rs index ab01f9d..9c66da6 100644 --- a/presentation/src/traits.rs +++ b/presentation/src/traits.rs @@ -25,6 +25,7 @@ pub trait TScene: Send + Sync + 'static { window_width: f32, window_height: f32, images: &TargetMode<Vec<Arc<Image>>>, + world: &World, ) -> Result<()>; } diff --git a/skybox/src/lib.rs b/skybox/src/lib.rs index 09c93e8..ba022e7 100644 --- a/skybox/src/lib.rs +++ b/skybox/src/lib.rs @@ -1,6 +1,6 @@ mod vertex; -use std::{path::PathBuf, sync::Arc}; +use std::{path::PathBuf, sync::Arc, time::Duration}; use anyhow::Result; use ecs::*; @@ -37,6 +37,8 @@ impl<T: ExactSizeIterator<Item = PathBuf>> From<T> for SkyBoxImages { } pub struct SkyBox { + enabled: bool, + _cube_map: Arc<Image>, cube_buffer: Arc<Buffer<VertexPoint>>, @@ -94,8 +96,24 @@ impl SkyBox { .add_descriptor_set_layout(&descriptor_set_layout) .build(context.device().clone())?; - let pipeline = - Self::create_pipeline(context, sample_count, &render_target, &pipeline_layout)?; + let vertex_shader = ShaderModule::from_slice( + context.device().clone(), + include_bytes!("../shader/skybox.vert.spv"), + )?; + + let fragment_shader = ShaderModule::from_slice( + context.device().clone(), + include_bytes!("../shader/skybox.frag.spv"), + )?; + + let pipeline = Self::create_pipeline( + context, + sample_count, + &render_target, + &pipeline_layout, + &vertex_shader, + &fragment_shader, + )?; let descriptor_pool = DescriptorPool::builder() .set_layout(descriptor_set_layout) @@ -124,17 +142,34 @@ impl SkyBox { .map(|t| VertexPoint::new(t[0] as f32, t[1] as f32, t[2] as f32)) .collect::<Vec<_>>(); - let cube_buffer = Buffer::builder() - .set_memory_usage(MemoryUsage::GpuOnly) - .set_sharing_mode(VK_SHARING_MODE_EXCLUSIVE) - .set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) - .set_data(&cube_mesh) - .build(context.device().clone())?; + let command_buffer = CommandBuffer::new_primary() + .build(context.device().clone(), context.queue().clone())?; + + let cube_buffer = SingleSubmit::builder(&command_buffer, context.queue(), |recorder| { + Buffer::builder() + .set_memory_usage(MemoryUsage::CpuToGpu) + .set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT) + .set_data(&cube_mesh) + .build(context.device().clone())? + .into_device_local( + recorder, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + ) + }) + .wait_for_timeout(Duration::from_secs(2)) + .submit()?; let me = Self { + enabled: true, + _cube_map: cube_map, cube_buffer, + vertex_shader, + fragment_shader, + render_target, pipeline, descriptor_set, @@ -144,6 +179,14 @@ impl SkyBox { Ok(()) } + pub fn enable(&mut self) { + self.enabled = true; + } + + pub fn disable(&mut self) { + self.enabled = false; + } + fn create_render_target( context: &Context, sample_count: VkSampleCountFlags, @@ -195,11 +238,18 @@ impl SkyBox { sample_count: VkSampleCountFlags, render_target: &TargetMode<RenderTarget>, pipeline_layout: &Arc<PipelineLayout>, + vertex_shader: &Arc<ShaderModule<Vertex>>, + fragment_shader: &Arc<ShaderModule<Fragment>>, ) -> Result<TargetMode<Arc<Pipeline>>> { render_target.execute(|render_target| { Pipeline::new_graphics() + .set_vertex_shader::<VertexPoint>(vertex_shader.clone()) + .set_fragment_shader(fragment_shader.clone()) + .input_assembly(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false) .default_multisample(sample_count) + .default_color_blend(vec![VkPipelineColorBlendAttachmentState::default()]) .default_rasterization(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE) + .whole_area(render_target.width(), render_target.height()) .build( context.device().clone(), pipeline_layout, @@ -218,6 +268,10 @@ impl TScene for SkyBox { indices: &TargetMode<usize>, _world: &World, ) -> Result<()> { + if !self.enabled { + return Ok(()); + } + self.render_target .chain(indices) .chain(&self.pipeline) @@ -241,10 +295,34 @@ impl TScene for SkyBox { fn resize( &mut self, - window_width: f32, - window_height: f32, - images: &TargetMode<Vec<Arc<Image>>>, + _window_width: f32, + _window_height: f32, + _images: &TargetMode<Vec<Arc<Image>>>, + world: &World, ) -> Result<()> { - todo!() + let sample_count = world + .resources + .get::<EngineSettings>() + .graphics_info()? + .sample_count; + + let context = world.resources.get::<Context>(); + + let pipeline_layout = match &self.pipeline { + TargetMode::Mono(p) => p.pipeline_layout().clone(), + TargetMode::Stereo(p, _) => p.pipeline_layout().clone(), + }; + + self.render_target = Self::create_render_target(context, sample_count)?; + self.pipeline = Self::create_pipeline( + context, + sample_count, + &self.render_target, + &pipeline_layout, + &self.vertex_shader, + &self.fragment_shader, + )?; + + Ok(()) } }