From 8c42e7b1399e85ec50e390fed805901e9d802ed3 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Tue, 27 May 2025 17:13:22 +0200 Subject: [PATCH] Refactor input --- src/core/{render => }/app.rs | 68 +++++++----------- src/core/input.rs | 75 -------------------- src/core/input/keyboard_state.rs | 46 +++++++++++++ src/core/input/mod.rs | 64 +++++++++++++++++ src/core/input/mouse_state.rs | 22 ++++++ src/core/input/virtual_binding.rs | 24 +++++++ src/core/input/virtual_input.rs | 110 ++++++++++++++++++++++++++++++ src/core/input/virtual_state.rs | 49 +++++++++++++ src/core/mod.rs | 1 + src/core/render/mod.rs | 1 - src/core/render/render_context.rs | 50 +++++++++++--- src/core/scene.rs | 9 ++- src/game/main_scene.rs | 43 +++++------- src/main.rs | 36 +++++++++- 14 files changed, 439 insertions(+), 159 deletions(-) rename src/core/{render => }/app.rs (76%) delete mode 100644 src/core/input.rs create mode 100644 src/core/input/keyboard_state.rs create mode 100644 src/core/input/mod.rs create mode 100644 src/core/input/mouse_state.rs create mode 100644 src/core/input/virtual_binding.rs create mode 100644 src/core/input/virtual_input.rs create mode 100644 src/core/input/virtual_state.rs diff --git a/src/core/render/app.rs b/src/core/app.rs similarity index 76% rename from src/core/render/app.rs rename to src/core/app.rs index 6e08f72..3a7145b 100644 --- a/src/core/render/app.rs +++ b/src/core/app.rs @@ -1,7 +1,9 @@ use std::collections::HashMap; use std::sync::Arc; -use crate::core::input::InputState; +use super::render::render_context::RenderContext; +use super::render::vulkan_context::VulkanContext; +use crate::core::input::InputManager; use crate::core::scene::SceneManager; use crate::core::timer::Timer; use crate::game::main_scene::MainScene; @@ -17,49 +19,46 @@ use vulkano_util::context::VulkanoContext; use vulkano_util::renderer::VulkanoWindowRenderer; use vulkano_util::window::{VulkanoWindows, WindowDescriptor}; use winit::application::ApplicationHandler; -use winit::event::{ElementState, WindowEvent}; +use winit::event::WindowEvent; use winit::event_loop::ActiveEventLoop; use winit::window::WindowId; -use super::render_context::RenderContext; -use super::vulkan_context::VulkanContext; - pub struct App { vulkan_context: Arc, vulkano_windows: Arc, gui: HashMap, clear_color: [f32; 3], - input_state: InputState, + input_manager: InputManager, scene_manager: SceneManager, timer: Timer, } impl From<(&VulkanContext, &VulkanoWindowRenderer)> for RenderContext { fn from((vulkan_context, renderer): (&VulkanContext, &VulkanoWindowRenderer)) -> Self { - RenderContext { - window_size: renderer.resolution(), - aspect_ratio: renderer.aspect_ratio(), - instance: vulkan_context.vulkano_context().instance().clone(), - device: vulkan_context.vulkano_context().device().clone(), - graphics_queue: vulkan_context.vulkano_context().graphics_queue().clone(), - compute_queue: vulkan_context.vulkano_context().compute_queue().clone(), - transfer_queue: vulkan_context.vulkano_context().transfer_queue().cloned(), - memory_allocator: vulkan_context.vulkano_context().memory_allocator().clone(), - command_buffer_allocator: vulkan_context.command_buffer_allocator().clone(), - descriptor_set_allocator: vulkan_context.descriptor_set_allocator().clone(), - swapchain_format: renderer.swapchain_format(), - } + RenderContext::new( + vulkan_context.vulkano_context().instance().clone(), + vulkan_context.vulkano_context().device().clone(), + vulkan_context.vulkano_context().graphics_queue().clone(), + vulkan_context.vulkano_context().compute_queue().clone(), + vulkan_context.vulkano_context().transfer_queue().cloned(), + vulkan_context.vulkano_context().memory_allocator().clone(), + vulkan_context.command_buffer_allocator().clone(), + vulkan_context.descriptor_set_allocator().clone(), + renderer.resolution(), + renderer.aspect_ratio(), + renderer.swapchain_format(), + ) } } -impl From for App { - fn from(vulkano_context: VulkanoContext) -> Self { +impl App { + pub fn new(vulkano_context: VulkanoContext, input_manager: InputManager) -> Self { Self { vulkan_context: Arc::new(VulkanContext::new(vulkano_context)), vulkano_windows: Arc::new(VulkanoWindows::default()), gui: HashMap::new(), clear_color: [0.0, 0.0, 0.0], - input_state: InputState::default(), + input_manager, scene_manager: SceneManager::new(), timer: Timer::new(), } @@ -111,7 +110,7 @@ impl ApplicationHandler for App { let render_context = RenderContext::from((self.vulkan_context.as_ref(), &*renderer)); if !gui.update(&event) { - self.input_state.process_event(&event); + self.input_manager.process_window_event(&event); } match event { @@ -126,11 +125,11 @@ impl ApplicationHandler for App { renderer.resize(); } WindowEvent::RedrawRequested => { - self.input_state.update(); + self.input_manager.update(); self.timer.update(); self.scene_manager.load_scene_if_not_loaded(&render_context); if let Some(scene) = self.scene_manager.current_scene_mut() { - scene.update(&render_context, &self.input_state, &self.timer); + scene.update(&render_context, &self.input_manager, &self.timer); } let acquire_future = renderer.acquire(None, |_| {}).unwrap(); @@ -195,25 +194,10 @@ impl ApplicationHandler for App { .show(&ctx, |ui| { ui.label(format!("Resolution: {:?}", renderer.resolution())); ui.color_edit_button_rgb(&mut self.clear_color); - ui.label(format!( - "Mouse position: {:?}", - self.input_state.get_mouse_state().position - )); - ui.label(format!( - "Mouse delta: {:?}", - self.input_state.get_mouse_state().delta - )); + + ui.label(format!("{:#?}", self.input_manager.get_virtual_input())); ui.label(format!("Delta time: {:?}", self.timer.delta_time())); - - for (key, state) in self - .input_state - .key_states - .iter() - .filter(|(_, state)| *state == &ElementState::Pressed) - { - ui.label(format!("{:?} State: {:?}", key, state)); - } }); }); diff --git a/src/core/input.rs b/src/core/input.rs deleted file mode 100644 index 59e8398..0000000 --- a/src/core/input.rs +++ /dev/null @@ -1,75 +0,0 @@ -use std::collections::HashMap; - -use winit::{ - dpi::PhysicalPosition, - event::{ElementState, KeyEvent, WindowEvent}, - keyboard::PhysicalKey, -}; - -#[derive(Debug, Default)] -pub struct MouseState { - old_position: glam::Vec2, - pub position: glam::Vec2, - pub delta: glam::Vec2, -} - -#[derive(Debug, Default)] -pub struct InputState { - pub key_states: HashMap, - pub mouse_state: MouseState, -} - -impl InputState { - pub fn process_event(&mut self, event: &WindowEvent) { - match event { - WindowEvent::KeyboardInput { event, .. } => { - self.update_key_state(event.physical_key, event); - } - WindowEvent::CursorMoved { position, .. } => { - self.update_mouse_position(position); - } - _ => {} - } - } - - /// Updates deltas before running update - pub fn update(&mut self) { - self.mouse_state.delta = self.mouse_state.position - self.mouse_state.old_position; - self.mouse_state.old_position = self.mouse_state.position; - } - - pub fn get_key_state(&self, key: PhysicalKey) -> &ElementState { - self.key_states.get(&key).unwrap_or(&ElementState::Released) - } - - pub fn get_mouse_state(&self) -> &MouseState { - &self.mouse_state - } - - fn update_key_state(&mut self, key: PhysicalKey, event: &KeyEvent) { - let key_state = self.key_states.get(&event.physical_key); - let new_key_state = match key_state { - Some(key_state) => match event.state { - ElementState::Pressed => match key_state { - ElementState::Released => Some(ElementState::Pressed), - ElementState::Pressed => None, - }, - ElementState::Released => match key_state { - ElementState::Released => None, - ElementState::Pressed => Some(ElementState::Released), - }, - }, - None => match event.state { - ElementState::Pressed => Some(ElementState::Pressed), - ElementState::Released => Some(ElementState::Released), - }, - }; - if let Some(new_key_state) = new_key_state { - self.key_states.insert(key, new_key_state); - } - } - - fn update_mouse_position(&mut self, position: &PhysicalPosition) { - self.mouse_state.position = glam::Vec2::new(position.x as f32, position.y as f32); - } -} diff --git a/src/core/input/keyboard_state.rs b/src/core/input/keyboard_state.rs new file mode 100644 index 0000000..c7b9b3e --- /dev/null +++ b/src/core/input/keyboard_state.rs @@ -0,0 +1,46 @@ +use egui_winit_vulkano::egui::ahash::HashMap; +use winit::{ + event::{ElementState, KeyEvent}, + keyboard::PhysicalKey, +}; + +use super::virtual_input::VirtualInput; + +#[derive(Debug, Default)] +pub struct KeyboardState { + key_states: HashMap, +} + +impl KeyboardState { + pub fn get_key_states(&self) -> &HashMap { + &self.key_states + } + + pub fn get_key_state(&self, key: PhysicalKey) -> &ElementState { + self.key_states.get(&key).unwrap_or(&ElementState::Released) + } + + pub fn process_window_event(&mut self, event: &KeyEvent, virtual_input: &mut VirtualInput) { + let key_state = self.key_states.get(&event.physical_key); + let new_key_state = match key_state { + Some(key_state) => match event.state { + ElementState::Pressed => match key_state { + ElementState::Released => Some(ElementState::Pressed), + ElementState::Pressed => None, + }, + ElementState::Released => match key_state { + ElementState::Released => None, + ElementState::Pressed => Some(ElementState::Released), + }, + }, + None => match event.state { + ElementState::Pressed => Some(ElementState::Pressed), + ElementState::Released => Some(ElementState::Released), + }, + }; + if let Some(new_key_state) = new_key_state { + self.key_states.insert(event.physical_key, new_key_state); + virtual_input.update_key_binding(event.physical_key, new_key_state); + } + } +} diff --git a/src/core/input/mod.rs b/src/core/input/mod.rs new file mode 100644 index 0000000..f29b963 --- /dev/null +++ b/src/core/input/mod.rs @@ -0,0 +1,64 @@ +use std::collections::HashMap; + +use keyboard_state::KeyboardState; +use mouse_state::MouseState; +use virtual_binding::VirtualBinding; +use virtual_input::VirtualInput; +use winit::event::WindowEvent; + +pub mod keyboard_state; +pub mod mouse_state; +pub mod virtual_binding; +pub mod virtual_input; +pub mod virtual_state; + +#[derive(Default)] +pub struct InputManager { + keyboard_state: KeyboardState, + mouse_state: MouseState, + virtual_input: VirtualInput, +} + +impl InputManager { + pub fn process_window_event(&mut self, event: &WindowEvent) { + match event { + WindowEvent::KeyboardInput { event, .. } => { + self.keyboard_state + .process_window_event(event, &mut self.virtual_input); + } + WindowEvent::CursorMoved { position, .. } => { + self.mouse_state.process_window_event(position); + } + _ => {} + } + } + + /// Updates deltas before running update + pub fn update(&mut self) { + self.mouse_state.update(&mut self.virtual_input); + } + + pub fn get_mouse_state(&self) -> &MouseState { + &self.mouse_state + } + + pub fn get_keyboard_state(&self) -> &KeyboardState { + &self.keyboard_state + } + + pub fn get_virtual_input(&self) -> &VirtualInput { + &self.virtual_input + } + + pub fn add_virtual_binding(&mut self, value_name: String, binding: VirtualBinding) { + self.virtual_input.add_binding(value_name, binding); + } + + pub fn add_virtual_bindings(&mut self, value_name: String, bindings: Vec) { + self.virtual_input.add_bindings(value_name, bindings); + } + + pub fn get_virtual_input_state(&self, value_name: &str) -> f32 { + self.virtual_input.get_state(value_name) + } +} diff --git a/src/core/input/mouse_state.rs b/src/core/input/mouse_state.rs new file mode 100644 index 0000000..8cdce4b --- /dev/null +++ b/src/core/input/mouse_state.rs @@ -0,0 +1,22 @@ +use winit::dpi::PhysicalPosition; + +use super::virtual_input::VirtualInput; + +#[derive(Debug, Default)] +pub struct MouseState { + old_position: glam::Vec2, + pub position: glam::Vec2, + pub delta: glam::Vec2, +} + +impl MouseState { + pub fn process_window_event(&mut self, position: &PhysicalPosition) { + self.position = glam::Vec2::new(position.x as f32, position.y as f32); + } + + pub fn update(&mut self, virtual_input: &mut VirtualInput) { + self.delta = self.position - self.old_position; + self.old_position = self.position; + virtual_input.update_mouse_binding(&self.delta); + } +} diff --git a/src/core/input/virtual_binding.rs b/src/core/input/virtual_binding.rs new file mode 100644 index 0000000..9209a78 --- /dev/null +++ b/src/core/input/virtual_binding.rs @@ -0,0 +1,24 @@ +use winit::{event::AxisId, keyboard::PhysicalKey}; + +#[derive(Clone)] +pub enum AxisDirection { + Positive, + Negative, +} + +impl From<&AxisDirection> for f32 { + fn from(direction: &AxisDirection) -> Self { + match direction { + AxisDirection::Positive => 1.0, + AxisDirection::Negative => -1.0, + } + } +} + +#[derive(Clone)] +pub enum VirtualBinding { + Keyboard(PhysicalKey, AxisDirection), + Axis(AxisId, AxisDirection, f32), // f32 deadzone + MouseX(AxisDirection), + MouseY(AxisDirection), +} diff --git a/src/core/input/virtual_input.rs b/src/core/input/virtual_input.rs new file mode 100644 index 0000000..f1ec4a8 --- /dev/null +++ b/src/core/input/virtual_input.rs @@ -0,0 +1,110 @@ +use std::{collections::HashMap, sync::Arc}; + +use egui_winit_vulkano::egui::mutex::Mutex; +use winit::{event::ElementState, keyboard::PhysicalKey}; + +use super::{ + virtual_binding::VirtualBinding, + virtual_state::{VirtualBindingState, VirtualInputState}, +}; + +#[derive(Default)] +pub struct VirtualInput { + states: HashMap>>, + states_by_key: HashMap>>>, + mouse_states: Vec>>, +} + +impl std::fmt::Debug for VirtualInput { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut debug = f.debug_struct("VirtualInput"); + + for (name, state) in &self.states { + debug.field(name, &state.lock().value); + } + + debug.finish() + } +} + +impl VirtualInput { + pub fn get_state(&self, value_name: &str) -> f32 { + self.states + .get(value_name) + .and_then(|state| Some(state.lock().value)) + .unwrap_or(0.0) + } + + pub fn add_bindings(&mut self, value_name: String, new_bindings: Vec) { + add_bindings( + &mut self.states, + &mut self.states_by_key, + &mut self.mouse_states, + value_name, + new_bindings, + ); + } + + pub fn add_binding(&mut self, value_name: String, binding: VirtualBinding) { + self.add_bindings(value_name, vec![binding]); + } + + pub(super) fn update_key_binding(&mut self, key: PhysicalKey, key_state: ElementState) { + let states = self.states_by_key.get_mut(&key); + + if let Some(states) = states { + for state in states { + let mut state = state.lock(); + state.update_from_key(key, key_state); + } + } else { + log::trace!("{}", self.states_by_key.keys().len()); + log::warn!("No states found for key: {key:?}"); + } + } + + pub(super) fn update_mouse_binding(&mut self, delta: &glam::Vec2) { + for state in &mut self.mouse_states { + let mut state = state.lock(); + state.update_from_mouse(delta); + } + } +} + +fn add_bindings( + states: &mut HashMap>>, + states_by_key: &mut HashMap>>>, + mouse_states: &mut Vec>>, + value_name: String, + new_bindings: Vec, +) { + let state = states + .entry(value_name) + .or_insert(Arc::new(Mutex::new(VirtualInputState { + value: 0.0, + bindings: Vec::new(), + }))); + + for binding in &new_bindings { + match binding { + VirtualBinding::Keyboard(key, _) => { + states_by_key + .entry(*key) + .or_insert(Vec::new()) + .push(state.clone()); + } + VirtualBinding::MouseX(_) | VirtualBinding::MouseY(_) => { + mouse_states.push(state.clone()); + } + _ => {} + } + } + + let mut state = state.lock(); + state + .bindings + .extend(new_bindings.iter().map(|b| VirtualBindingState { + value: 0.0, + binding: b.clone(), + })); +} diff --git a/src/core/input/virtual_state.rs b/src/core/input/virtual_state.rs new file mode 100644 index 0000000..47f8b0d --- /dev/null +++ b/src/core/input/virtual_state.rs @@ -0,0 +1,49 @@ +use winit::{event::ElementState, keyboard::PhysicalKey}; + +use super::virtual_binding::VirtualBinding; + +pub struct VirtualBindingState { + pub value: f32, + pub binding: VirtualBinding, +} + +pub struct VirtualInputState { + pub value: f32, + pub bindings: Vec, +} + +impl VirtualInputState { + pub fn update_from_key(&mut self, key: PhysicalKey, key_state: ElementState) { + let mut new_value = 0.0; + for binding in &mut self.bindings { + if let VirtualBinding::Keyboard(binding_key, direction) = &binding.binding { + if binding_key == &key { + if key_state == ElementState::Pressed { + binding.value += f32::from(direction); + } else { + binding.value = 0.0; + } + } + } + new_value += binding.value; + } + self.value = new_value; + } + + pub fn update_from_mouse(&mut self, delta: &glam::Vec2) { + let mut new_value = 0.0; + for binding in &mut self.bindings { + match &binding.binding { + VirtualBinding::MouseX(direction) => { + binding.value = f32::from(direction) * delta.x; + } + VirtualBinding::MouseY(direction) => { + binding.value = f32::from(direction) * delta.y; + } + _ => {} + } + new_value += binding.value; + } + self.value = new_value; + } +} diff --git a/src/core/mod.rs b/src/core/mod.rs index ddaf320..237496d 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,3 +1,4 @@ +pub mod app; pub mod input; pub mod render; pub mod scene; diff --git a/src/core/render/mod.rs b/src/core/render/mod.rs index a074771..c550198 100644 --- a/src/core/render/mod.rs +++ b/src/core/render/mod.rs @@ -1,4 +1,3 @@ -pub mod app; pub mod pipelines; pub mod primitives; pub mod render_context; diff --git a/src/core/render/render_context.rs b/src/core/render/render_context.rs index d1d2be4..e9e34a1 100644 --- a/src/core/render/render_context.rs +++ b/src/core/render/render_context.rs @@ -10,20 +10,48 @@ use vulkano::{ }; pub struct RenderContext { - pub(super) instance: Arc, - pub(super) device: Arc, - pub(super) graphics_queue: Arc, - pub(super) compute_queue: Arc, - pub(super) transfer_queue: Option>, - pub(super) memory_allocator: Arc, - pub(super) command_buffer_allocator: Arc, - pub(super) descriptor_set_allocator: Arc, - pub(super) window_size: [f32; 2], - pub(super) aspect_ratio: f32, - pub(super) swapchain_format: Format, + instance: Arc, + device: Arc, + graphics_queue: Arc, + compute_queue: Arc, + transfer_queue: Option>, + memory_allocator: Arc, + command_buffer_allocator: Arc, + descriptor_set_allocator: Arc, + window_size: [f32; 2], + aspect_ratio: f32, + swapchain_format: Format, } impl RenderContext { + pub fn new( + instance: Arc, + device: Arc, + graphics_queue: Arc, + compute_queue: Arc, + transfer_queue: Option>, + memory_allocator: Arc, + command_buffer_allocator: Arc, + descriptor_set_allocator: Arc, + window_size: [f32; 2], + aspect_ratio: f32, + swapchain_format: Format, + ) -> Self { + Self { + instance, + device, + graphics_queue, + compute_queue, + transfer_queue, + memory_allocator, + command_buffer_allocator, + descriptor_set_allocator, + window_size, + aspect_ratio, + swapchain_format, + } + } + pub fn instance(&self) -> &Arc { &self.instance } diff --git a/src/core/scene.rs b/src/core/scene.rs index e8040f8..9717117 100644 --- a/src/core/scene.rs +++ b/src/core/scene.rs @@ -1,11 +1,16 @@ use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}; -use super::{input::InputState, render::render_context::RenderContext, timer::Timer}; +use super::{input::InputManager, render::render_context::RenderContext, timer::Timer}; pub trait Scene { fn loaded(&self) -> bool; fn load(&mut self, render_context: &RenderContext); - fn update(&mut self, render_context: &RenderContext, input_state: &InputState, timer: &Timer); + fn update( + &mut self, + render_context: &RenderContext, + input_manager: &InputManager, + timer: &Timer, + ); fn render( &self, render_context: &RenderContext, diff --git a/src/game/main_scene.rs b/src/game/main_scene.rs index 54ca089..a759478 100644 --- a/src/game/main_scene.rs +++ b/src/game/main_scene.rs @@ -1,4 +1,4 @@ -use crate::core::input::InputState; +use crate::core::input::InputManager; use crate::core::render::primitives::camera::Camera; use crate::core::render::primitives::vertex::Vertex2D; use crate::core::render::render_context::RenderContext; @@ -115,39 +115,30 @@ impl Scene for MainScene { }) } - fn update(&mut self, render_context: &RenderContext, input_state: &InputState, timer: &Timer) { + fn update( + &mut self, + render_context: &RenderContext, + input_manager: &InputManager, + timer: &Timer, + ) { let state = self.state.as_mut().unwrap(); let speed = 50.0 * timer.delta_time(); let mut rot = Quat::default(); - rot *= Quat::from_rotation_y(input_state.mouse_state.delta.x * speed.to_radians()); - rot *= Quat::from_rotation_x(input_state.mouse_state.delta.y * speed.to_radians()); + rot *= Quat::from_rotation_y( + input_manager.get_virtual_input_state("mouse_x") * speed.to_radians(), + ); + rot *= Quat::from_rotation_x( + input_manager.get_virtual_input_state("mouse_y") * speed.to_radians(), + ); state.camera.get_transform_mut().rotate(rot); - let translation_x = if input_state.get_key_state(PhysicalKey::Code(KeyCode::KeyA)) - == &ElementState::Pressed - { - timer.delta_time() * speed - } else if input_state.get_key_state(PhysicalKey::Code(KeyCode::KeyD)) - == &ElementState::Pressed - { - timer.delta_time() * -speed - } else { - timer.delta_time() * 0.0 - }; + let translation_x = + input_manager.get_virtual_input_state("move_right") * timer.delta_time() * speed; - let translation_z = if input_state.get_key_state(PhysicalKey::Code(KeyCode::KeyW)) - == &ElementState::Pressed - { - timer.delta_time() * speed - } else if input_state.get_key_state(PhysicalKey::Code(KeyCode::KeyS)) - == &ElementState::Pressed - { - timer.delta_time() * -speed - } else { - timer.delta_time() * 0.0 - }; + let translation_z = + input_manager.get_virtual_input_state("move_forward") * timer.delta_time() * speed; state .camera diff --git a/src/main.rs b/src/main.rs index 52ba1f6..d671188 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,14 @@ +use core::input::{ + InputManager, + virtual_binding::{AxisDirection, VirtualBinding}, +}; + use vulkano::device::{DeviceExtensions, DeviceFeatures}; use vulkano_util::context::{VulkanoConfig, VulkanoContext}; -use winit::event_loop::{ControlFlow, EventLoop}; +use winit::{ + event_loop::{ControlFlow, EventLoop}, + keyboard::{KeyCode, PhysicalKey}, +}; mod core; mod game; @@ -8,6 +16,30 @@ mod game; fn main() { env_logger::init(); + let mut input_manager = InputManager::default(); + input_manager.add_virtual_bindings( + "move_forward".to_string(), + vec![ + VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyW), AxisDirection::Positive), + VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyS), AxisDirection::Negative), + ], + ); + input_manager.add_virtual_bindings( + "move_right".to_string(), + vec![ + VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyD), AxisDirection::Positive), + VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyA), AxisDirection::Negative), + ], + ); + input_manager.add_virtual_bindings( + "mouse_x".to_string(), + vec![VirtualBinding::MouseX(AxisDirection::Positive)], + ); + input_manager.add_virtual_bindings( + "mouse_y".to_string(), + vec![VirtualBinding::MouseY(AxisDirection::Positive)], + ); + let device_extensions = DeviceExtensions { khr_swapchain: true, ..Default::default() @@ -30,7 +62,7 @@ fn main() { let event_loop = EventLoop::new().unwrap(); event_loop.set_control_flow(ControlFlow::Poll); - let mut app = core::render::app::App::from(vulkano_context); + let mut app = core::app::App::new(vulkano_context, input_manager); match event_loop.run_app(&mut app) { Ok(_) => {}