diff --git a/src/main.rs b/src/main.rs index d3da7e5..ac1b3eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ use winit::{Event}; -use cgmath::{Matrix4, Rad, Vector3, Deg, Quaternion, Rotation3, One, Rotation, SquareMatrix}; +use cgmath::{Matrix4, Rad, Vector3, Deg, Quaternion, Rotation3, One, Rotation}; mod vulkan; -use crate::vulkan::{Game, LinePoint, GameObject, VulkanRenderer, RenderLoopResult}; +use crate::vulkan::{Game, LinePoint, GameObject, VulkanRenderer, RenderLoopResult, MeshHandle, GameObjectHandle}; mod input; use crate::input::{InputState}; @@ -16,6 +16,8 @@ struct TestGame<'a> { input: InputState<'a>, cam_position: Vector3, cam_rotation: Quaternion, + cube_mesh: Option, + cubes: Vec, } impl Game for TestGame<'_> { @@ -26,23 +28,22 @@ impl Game for TestGame<'_> { impl TestGame<'_> { fn game_start(self: &mut Self, renderer: &mut VulkanRenderer) { - let player_mesh = renderer.upload_mesh(mesh::load_mesh("models/iski51.dae", true).into_iter().nth(0).unwrap()); + self.cube_mesh = Some(renderer.upload_mesh(mesh::load_mesh("models/cube.dae", true).into_iter().nth(0).unwrap())); println!("Game started."); } fn update(self: &mut Self, renderer: &mut VulkanRenderer) { - let game_data = &mut renderer.game_data; - let new_time = game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0; - let frame_time = new_time - game_data.push_constants.time; - game_data.push_constants.time = new_time; + let new_time = renderer.game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0; + let frame_time = new_time - renderer.game_data.push_constants.time; + renderer.game_data.push_constants.time = new_time; // User interaction if self.input.button_just_released("quit") { - game_data.shutdown = true; + renderer.game_data.shutdown = true; } if self.input.button_just_pressed("reload_shaders") { - game_data.recreate_pipeline = true; + renderer.game_data.recreate_pipeline = true; } if self.input.button_just_pressed("print_framerate") { @@ -50,8 +51,7 @@ impl TestGame<'_> { } if self.input.button_just_pressed("test") { - println!("test"); - game_data.game_objects.push(GameObject { mesh_index: 0, model_matrix: Matrix4::identity() }); + self.cubes.push(renderer.add_game_object(GameObject::new(self.cube_mesh.unwrap()))); } self.cam_rotation = self.cam_rotation * Quaternion::from_angle_z(Deg(self.input.get_axis("look_horizontal") * 0.05)); @@ -66,17 +66,17 @@ impl TestGame<'_> { let mut proj = cgmath::perspective( Rad::from(Deg(45.0)), - game_data.dimensions[0] as f32 / game_data.dimensions[1] as f32, + renderer.game_data.dimensions[0] as f32 / renderer.game_data.dimensions[1] as f32, 0.1, 100.0 ); proj.y.y *= -1.0; - 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(); + renderer.game_data.push_constants.view = view.into(); + renderer.game_data.push_constants.projection = proj.into(); + renderer.game_data.line_push_constants.view = view.into(); + renderer.game_data.line_push_constants.projection = proj.into(); self.input.frame_end(); } @@ -89,6 +89,8 @@ fn main() { input: InputState::new("config/input.toml", &log_config), cam_rotation: Quaternion::one(), cam_position: Vector3::new(0.0, 0.0, -10.0), + cube_mesh: None, + cubes: vec![], }; let line_count = 30; @@ -108,9 +110,9 @@ fn main() { let mut continue_rendering = true; while continue_rendering { - game.update(&mut renderer); match renderer.render_loop(&mut game) { - RenderLoopResult::Ok => {}, + RenderLoopResult::Ok => game.update(&mut renderer), + RenderLoopResult::Reload => println!("Render loop reloaded..."), RenderLoopResult::Quit => continue_rendering = false, } } diff --git a/src/vulkan.rs b/src/vulkan.rs index ef018ec..e4ebf33 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -69,6 +69,9 @@ pub struct GameObject { pub model_matrix: Matrix4, } +pub(crate) type GameObjectHandle = usize; +pub(crate) type MeshHandle = usize; + pub struct GameData { pub start_time: SystemTime, pub line_vertices: Vec, @@ -101,7 +104,8 @@ pub struct VulkanRenderer { pub enum RenderLoopResult { Ok, - Quit + Reload, + Quit, } impl VulkanRenderer { @@ -303,15 +307,15 @@ impl VulkanRenderer { let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into(); [dimensions.0, dimensions.1] } else { - return RenderLoopResult::Ok; + panic!("Window no longer exists!"); }; let (new_swapchain, new_images) = match self.swapchain.recreate_with_dimension(self.game_data.dimensions) { Ok(r) => r, // This error tends to happen when the user is manually resizing the window. // Simply restarting the loop is the easiest way to fix this issue. - Err(SwapchainCreationError::UnsupportedDimensions) => return RenderLoopResult::Ok, - Err(err) => panic!("{:?}", err) + Err(SwapchainCreationError::UnsupportedDimensions) => return RenderLoopResult::Reload, + Err(err) => panic!("{:?}", err), }; self.swapchain = new_swapchain; @@ -343,7 +347,7 @@ impl VulkanRenderer { Ok(r) => r, Err(AcquireError::OutOfDate) => { self.recreate_swapchain = true; - return RenderLoopResult::Ok; + return RenderLoopResult::Reload; }, Err(err) => panic!("{:?}", err) }; @@ -423,6 +427,11 @@ impl VulkanRenderer { self.game_data.meshes.push(Mesh { vertex_buffer, index_buffer }); self.game_data.meshes.len() - 1 } + + pub fn add_game_object(self: &mut Self, game_object: GameObject) -> usize { + self.game_data.game_objects.push(game_object); + self.game_data.game_objects.len() - 1 + } } /// This method is called once during initialization, then again whenever the window is resized @@ -533,6 +542,12 @@ fn create_pipeline(device: Arc, re } } +impl GameObject { + pub fn new(mesh: MeshHandle) -> GameObject { + GameObject { mesh_index: mesh, model_matrix: Matrix4::identity() } + } +} + fn read_shader(vert_path_relative: &str, frag_path_relative: &str) -> Option<(CompiledShaders, Entry)> { let project_root = std::env::current_dir().expect("failed to get root directory");