use winit::{Event, WindowEvent, DeviceEvent}; use cgmath::{Matrix4, Rad, Vector3, Deg, Quaternion, Rotation3, One, Rotation}; mod vulkan; use crate::vulkan::{GameData, Game, LinePoint}; mod input; use crate::input::{InputState, mods_to_string}; mod config; use crate::config::LogConfig; struct TestGame { input: InputState, cam_position: Vector3, cam_rotation: Quaternion, log_config: LogConfig, } impl Game for TestGame { fn validation_layers_enabled(self: &Self) -> bool { self.log_config.vulkan_validation_layers } fn update(self: &mut Self, game_data: &mut GameData) { game_data.push_constants.time = game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0; // User interaction if self.input.button_just_released("QUIT") { game_data.shutdown = true; } if self.input.button_just_pressed("RELOAD_SHADERS") { game_data.recreate_pipeline = true; } self.cam_rotation = self.cam_rotation * Quaternion::from_angle_z(Deg(self.input.get_axis("look_horizontal") * 0.05)); self.cam_rotation = Quaternion::from_angle_x(Deg(self.input.get_axis("look_vertical") * 0.05)) * self.cam_rotation; self.cam_position += self.cam_rotation.invert().rotate_vector(Vector3::new( self.input.get_axis("move_sideways") * -0.05, 0.0, self.input.get_axis("move_forward") * 0.05)); // Move game objects let model = Matrix4::from_angle_z(Rad::from(Deg(game_data.push_constants.time * 100.0))); let view = Matrix4::from(self.cam_rotation) * Matrix4::from_translation(self.cam_position); let mut proj = cgmath::perspective( Rad::from(Deg(45.0)), game_data.dimensions[0] as f32 / game_data.dimensions[1] as f32, 0.1, 100.0 ); proj.y.y *= -1.0; game_data.push_constants.model = model.into(); game_data.push_constants.view = view.into(); game_data.push_constants.projection = proj.into(); game_data.line_push_constants.view = view.into(); game_data.line_push_constants.projection = proj.into(); self.input.frame_end(); } fn on_window_event(self: &mut Self, event: &Event) { match event { Event::WindowEvent { event: WindowEvent::KeyboardInput { device_id, input }, .. } => { if self.log_config.input { let mods = mods_to_string(&input.modifiers); if mods.len() > 0 { println!("Keyboard {:?} {:?} {:?} + {:?}", device_id, input.state, &mods, input.scancode) } else { println!("Keyboard {:?} {:?} {:?}", device_id, input.state, input.scancode) } } self.input.on_keyboard_event(input.state, input.scancode, input.modifiers); }, Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => { if self.log_config.input { let mods = mods_to_string(modifiers); if mods.len() > 0 { println!("Mouse {:?} {:?} {:?} + {:?}", device_id, state, &mods, button) } else { println!("Mouse {:?} {:?} {:?}", device_id, state, button) } } self.input.on_mouse_event(state, button, modifiers); }, Event::WindowEvent { event: WindowEvent::MouseWheel { device_id, delta, phase, modifiers }, .. } => { if self.log_config.input { let mods = mods_to_string(modifiers); if mods.len() > 0 { println!("Scroll {:?} {:?} {:?} + {:?}", device_id, phase, &mods, delta) } else { println!("Scroll {:?} {:?} {:?}", device_id, phase, delta) } } self.input.on_mouse_wheel_event(&delta, &modifiers); }, Event::DeviceEvent { device_id, event: DeviceEvent::MouseMotion { delta: (delta_x, delta_y) } } => { if self.log_config.input { println!("MouseMotion {:?}, ({:?},{:?})", device_id, delta_x, delta_y); } self.input.mouse_delta_x += *delta_x; self.input.mouse_delta_y += *delta_y; } _ => {} } } } fn main() { let mut game = TestGame { input: InputState::new("config/input.toml"), cam_rotation: Quaternion::one(), cam_position: Vector3::new(0.0, 0.0, -10.0), log_config: LogConfig::from_file("config/log.toml"), }; let line_count = 30; vulkan::init( "models/iski51.obj", (-line_count..=line_count) .flat_map(|it| vec![ LinePoint { position: [it as f32, -line_count as f32, 0.] }, LinePoint { position: [it as f32, line_count as f32, 0.] }, LinePoint { position: [-line_count as f32, it as f32, 0.] }, LinePoint { position: [line_count as f32, it as f32, 0.] }, ]).collect(), &mut game ); }