From de5fa84ac78c50e6acc9101c95d4ff4c9c43853f Mon Sep 17 00:00:00 2001 From: Till Date: Sat, 27 Jul 2019 03:49:02 +0200 Subject: [PATCH] input --- shaders/triangle.frag | 2 +- src/input.rs | 97 +++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 29 ++++++++++--- 3 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 src/input.rs diff --git a/shaders/triangle.frag b/shaders/triangle.frag index 6fe3cef..9c7d850 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -5,5 +5,5 @@ layout(location = 0) in vec3 pos; layout(location = 0) out vec4 f_color; void main() { - f_color = vec4(.3, .1, .8, 1.0); + f_color = vec4(.3, (pos.y + 5.) / 10., .8, 1.0); } \ No newline at end of file diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 0000000..9598942 --- /dev/null +++ b/src/input.rs @@ -0,0 +1,97 @@ +use winit::{ScanCode, ModifiersState, MouseButton, ElementState}; +use std::collections::{HashMap}; + +pub struct VirtualButton { + pub digital_inputs: Vec +} + +pub struct VirtualAxis { + pub analog_inputs: Vec +} + +pub struct InputState { + pub virtual_buttons: HashMap, + pub virtual_axes: HashMap, + pressed_digital: HashMap +} + +impl InputState { + pub fn new() -> InputState { + InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(), pressed_digital: HashMap::new() } + } + + pub fn button_down(self: &Self, button_code: &str) -> bool { + if let Some(input) = self.virtual_buttons.get(button_code) { + self.pressed_digital.iter().any(|(registered_input, _)| input.digital_inputs.iter().any(|digital_input| digital_input == registered_input)) + } else { + false + } + } + + pub fn button_just_pressed(self: &Self, input: VirtualButton) -> bool { + false + } + + pub fn button_just_released(self: &Self, input: VirtualButton) -> bool { + false + } + + pub fn on_keyboard_event(self: &mut Self, state: ElementState, scancode: ScanCode, modifiers: ModifiersState) { + match state { + ElementState::Pressed => { + self.pressed_digital.insert(DigitalInput::Keyboard(KeyboardInput { scancode, modifiers }), (true, false)); + }, + ElementState::Released => { + if let Some((_, recent_release)) = self.pressed_digital.get_mut(&DigitalInput::Keyboard(KeyboardInput { scancode, modifiers })) { + *recent_release = true; + } + }, + } + } + + pub fn finish_update(self: &mut Self) { + self.pressed_digital.iter_mut().for_each(|(_, (recent_press, _))| { + if *recent_press { *recent_press = false } + }); + self.pressed_digital.retain(|_, (recent_press, recent_release)| *recent_release == false); + } +} + +pub enum AxisInput { + Analog(AnalogInput), + Digital(DigitalInput, DigitalInput), +} + +#[derive(Debug, Eq, PartialEq, Hash)] +pub enum DigitalInput { + Keyboard(KeyboardInput), + Mouse(MouseInput) +} + +impl DigitalInput { + pub fn simple_key(scancode: ScanCode) -> DigitalInput { + DigitalInput::Keyboard(KeyboardInput { scancode, modifiers: ModifiersState { + shift: false, + ctrl: false, + alt: false, + logo: false + } }) + } +} + +#[derive(Debug, Eq, PartialEq, Hash)] +pub struct KeyboardInput { + scancode: ScanCode, + modifiers: ModifiersState +} + +#[derive(Debug, Eq, PartialEq, Hash)] +pub struct MouseInput { + button: MouseButton, + modifiers: ModifiersState +} + +#[derive(Debug, Eq, PartialEq)] +pub struct AnalogInput { + +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 05890ad..f204222 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,12 +2,17 @@ use crate::vulkan::{GameData, Game, LinePoint}; use winit::{Event, WindowEvent, ElementState}; use std::iter::FromIterator; use cgmath::{Matrix4, Rad, Point3, Vector3, Deg}; +use crate::input::{InputState, VirtualButton, DigitalInput, VirtualAxis, AxisInput}; mod vulkan; +mod input; const PRINT_KEYBOARD_INPUT: bool = false; -struct TestGame {} +struct TestGame { + input: InputState, + cam_pos: Point3 +} impl Game for TestGame { fn update(self: &mut Self, game_data: &mut GameData) { @@ -16,7 +21,7 @@ impl Game for TestGame { let model = Matrix4::from_angle_z(Rad::from(Deg(game_data.push_constants.time * 100.0))); let view = Matrix4::look_at( - Point3::new(2.0, 2.0, 2.0), + self.cam_pos, Point3::new(0.0, 0.0, 0.0), Vector3::new(0.0, 0.0, 1.0) ); @@ -53,22 +58,34 @@ impl Game for TestGame { } } + self.input.on_keyboard_event(input.state, input.scancode, input.modifiers); + if input.state == ElementState::Released && input.modifiers.ctrl && input.scancode == 19 { game_data.recreate_pipeline = true; } - if input.state == ElementState::Released && input.scancode == 1 { + if self.input.button_down("QUIT") { game_data.shutdown = true; } - } + }, +// Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => { +// +// } _ => {} } } } fn main() { - let mut game = TestGame {}; + let mut game = TestGame { + input: InputState::new(), + cam_pos: Point3::new(2.0, 2.0, 2.0) + }; + + game.input.virtual_buttons.insert("QUIT".to_string(), VirtualButton { digital_inputs: vec![DigitalInput::simple_key(1)] }); + game.input.virtual_axes.insert("FORWARD_CAM_AXIS".to_string(), VirtualAxis { analog_inputs: vec![AxisInput::Digital(DigitalInput::simple_key(87), DigitalInput::simple_key(83))] }); + vulkan::init( - "models/box.obj", + "models/iski51.obj", (-10..10) .flat_map(|it| vec![ LinePoint { position: [it as f32, -10., 0.] },