From be1d5e6221188e116a7b4ccfe387a797f97b110a Mon Sep 17 00:00:00 2001 From: Asuro Date: Wed, 2 Dec 2020 10:21:33 +0100 Subject: [PATCH] Modules and stuff --- src/config.rs | 6 +- src/{ => game}/level.rs | 4 +- src/game/mod.rs | 155 ++++++++++++++++++++++++++++ src/{ => game}/player.rs | 14 +-- src/input.rs | 11 +- src/main.rs | 169 ++----------------------------- src/{ => vulkan}/gameobject.rs | 8 +- src/{ => vulkan}/mesh.rs | 2 +- src/{vulkan.rs => vulkan/mod.rs} | 24 +++-- src/{ => vulkan}/pipelines.rs | 56 +++++----- 10 files changed, 231 insertions(+), 218 deletions(-) rename src/{ => game}/level.rs (96%) create mode 100644 src/game/mod.rs rename src/{ => game}/player.rs (92%) rename src/{ => vulkan}/gameobject.rs (97%) rename src/{ => vulkan}/mesh.rs (98%) rename src/{vulkan.rs => vulkan/mod.rs} (98%) rename src/{ => vulkan}/pipelines.rs (99%) diff --git a/src/config.rs b/src/config.rs index d181397..bb1560c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,8 @@ -use serde_derive::{Serialize, Deserialize}; -use toml; use std::fs; + +use serde_derive::{Deserialize, Serialize}; +use toml; + #[derive(Debug, Serialize, Deserialize, Clone, Copy)] pub struct LogConfigInput { pub mouse_motion: bool, diff --git a/src/level.rs b/src/game/level.rs similarity index 96% rename from src/level.rs rename to src/game/level.rs index 8364ded..1223bd7 100644 --- a/src/level.rs +++ b/src/game/level.rs @@ -1,8 +1,10 @@ use std::{error::Error, io::{BufReader, BufWriter}}; use std::fs::File; + use serde_derive::{Deserialize, Serialize}; -use crate::{TestGame, gameobject::GameObjectHandle, vulkan::{MeshHandle, VulkanRenderer}}; +use crate::{vulkan::{MeshHandle, VulkanRenderer, gameobject::GameObjectHandle}}; +use crate::game::TestGame; #[derive(Debug, Serialize, Deserialize)] struct MeshJson { diff --git a/src/game/mod.rs b/src/game/mod.rs new file mode 100644 index 0000000..3dd931c --- /dev/null +++ b/src/game/mod.rs @@ -0,0 +1,155 @@ + +use winit::event::Event; + +use level::{load_level, save_level}; +use player::Player; + +use crate::config::{LogConfig}; +use crate::input::InputState; +use crate::vulkan::{Game, MeshHandle, VulkanRenderer}; +use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable}; +use crate::vulkan::mesh; +use crate::vulkan::pipelines::vs::ty::ObjectUniformData; + +pub mod player; +mod level; + +pub struct TestGame { + pub input: InputState, + pub player: Player, + pub game_objects: Vec, + pub log_config: LogConfig, + pub texture_index_counter: usize, + pub last_time: f32, + pub components: Vec>, +} + +impl Game for TestGame { + fn on_window_event(self: &mut Self, event: &Event<()>) { + self.input.on_window_event(event); + } + + fn update(self: &mut Self, renderer: &mut VulkanRenderer) -> ObjectUniformData { + // Input and timing + self.input.frame_start(); + let time = (renderer.game_data.start_time.elapsed().unwrap().as_micros() as f64 / 1000000.0) as f32; + let frame_time = time - self.last_time; + + // Component update + let input = &self.input; + let components = &mut self.components; + components.iter_mut().for_each(|component| { + component.update(frame_time, &input, renderer); + }); + + // User interaction + if self.input.button_just_released("quit") { + renderer.game_data.shutdown = true; + } + + if self.input.button_just_pressed("reload_shaders") { + renderer.game_data.recreate_pipeline = true; + } + + if self.input.button_just_pressed("quicksave") { + save_level("levels/test.lvl", self, renderer).unwrap(); + } + + if self.input.button_just_pressed("quickload") { + self.clear_level(renderer); + load_level("levels/test.lvl", self, renderer).unwrap(); + } + + if self.input.button_down("print_framerate") { + println!("{:.0} ms / {:.0} FPS", frame_time * 1000.0, 1.0 / frame_time); + } + + // Custom game object stuff + let light_pos = self.player.camera.position * -1.0; + self.player.update(frame_time, &self.input, renderer); + + // End frame + self.last_time = time; + self.input.frame_end(); + + ObjectUniformData { + view: self.player.camera.view.into(), + projection: self.player.camera.proj.into(), + time, + light_position: light_pos.into(), + camera_position: self.player.camera.position.into(), + _dummy0: [0; 12], + _dummy1: [0; 4], + } + } +} + +impl TestGame { + pub fn new(toml_path: &str, log_config: LogConfig) -> TestGame { + TestGame { + input: InputState::new(toml_path, log_config), + player: Player::new(), + game_objects: vec![], + log_config, + texture_index_counter: 0, + last_time: 0.0, + components: vec![], + } + } + + pub fn game_start(self: &mut Self, renderer: &mut VulkanRenderer) { + // let plane_mesh = self.load_gltf(renderer, "models/plane.gltf"); + // self.add_game_object(renderer, plane_mesh[0].clone()); + load_level("levels/test.lvl", self, renderer).unwrap(); + println!("Game loaded!"); + } + + pub fn offset_texture_id(&mut self, local_tex_id: Option) -> usize { + match local_tex_id { + Some(local_id) => local_id + self.texture_index_counter, + None => 0, + } + } + + pub fn load_gltf(&mut self, renderer: &mut VulkanRenderer, gltf_path: &str) -> Vec { + let mut mesh_handles = Vec::new(); + + // Load file + let (meshes, textures) = mesh::load_mesh(gltf_path, self.log_config.mesh_load_info).unwrap(); + + for cpu_mesh in meshes.into_iter() { + // Convert file texture id to game texture id + let diffuse_id = self.offset_texture_id(cpu_mesh.local_texture_index); + let normal_id = self.offset_texture_id(cpu_mesh.local_normal_map_index); + + // Upload mesh + let mesh_id = renderer.upload_mesh(cpu_mesh, gltf_path.to_string()); + let mesh_handle = MeshHandle { + index: mesh_id, + diffuse_handle: diffuse_id, + normal_handle: normal_id, + original_path: gltf_path.to_string() + }; + mesh_handles.push(mesh_handle); + } + + textures.iter().for_each(|tex| { + renderer.upload_texture(tex); + self.texture_index_counter += 1; + }); + mesh_handles + } + + pub fn add_game_object(&mut self, renderer: &mut VulkanRenderer, mesh: MeshHandle) -> GameObjectHandle { + let obj = GameObject::new(mesh); + let obj_handle = renderer.add_game_object(obj, 0); + self.game_objects.push(obj_handle); + self.game_objects.last().unwrap().clone() + } + + pub fn clear_level(&mut self, renderer: &mut VulkanRenderer) { + self.game_objects.clear(); + self.texture_index_counter = 0; + renderer.clear_all(); + } +} diff --git a/src/player.rs b/src/game/player.rs similarity index 92% rename from src/player.rs rename to src/game/player.rs index 0bb7bbc..e803740 100644 --- a/src/player.rs +++ b/src/game/player.rs @@ -1,11 +1,13 @@ +use cgmath::{Deg, InnerSpace, Matrix4, One, Quaternion, Rad, Rotation, Rotation3, SquareMatrix, vec3, Vector3}; + +use crate::game::player::PlayerMovementMode::{FirstPerson, Flying}; + +use crate::input::InputState; use crate::MeshHandle; -use cgmath::{vec3, One, SquareMatrix, Deg, Rad, Quaternion, Vector3, Matrix4, Rotation, Rotation3, InnerSpace}; -use crate::{ - VulkanRenderer, - input::InputState, - gameobject::Updatable +use crate::vulkan::{ + gameobject::Updatable, + VulkanRenderer }; -use crate::player::PlayerMovementMode::{FirstPerson, Flying}; pub struct Camera { pub fov_y: f32, diff --git a/src/input.rs b/src/input.rs index e6eb131..2260a34 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,17 +1,14 @@ #![allow(deprecated)] -use winit::event::{ScanCode, MouseButton, ElementState, MouseScrollDelta, Event, WindowEvent, DeviceEvent, ModifiersState}; - use std::collections::{HashMap, HashSet}; use std::fs; use std::iter::FromIterator; -use toml; - -use serde_derive::{Serialize, Deserialize}; - use gilrs; -use gilrs::{Gilrs, EventType}; +use gilrs::{EventType, Gilrs}; +use serde_derive::{Deserialize, Serialize}; +use toml; +use winit::event::{DeviceEvent, ElementState, Event, ModifiersState, MouseButton, MouseScrollDelta, ScanCode, WindowEvent}; use crate::config::LogConfig; diff --git a/src/main.rs b/src/main.rs index 9d470d0..2938716 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,172 +1,19 @@ extern crate serde_json; -use cgmath::{Matrix4, Vector3, Vector4}; -use level::{load_level, save_level}; -use winit::event::Event; + +use vulkan::gameobject::GameObject; + + use crate::config::{LogConfig, RenderConfig}; -use crate::gameobject::{GameObject, GameObjectHandle, Updatable}; -use crate::input::InputState; -use crate::player::Player; -use crate::vulkan::{Game, LinePoint, MeshHandle, VulkanRenderer}; -use crate::pipelines::vs::ty::ObjectUniformData; +use crate::game::TestGame; + +use crate::vulkan::{LinePoint, MeshHandle, VulkanRenderer}; mod vulkan; mod input; mod config; -mod mesh; -mod gameobject; -mod player; -mod pipelines; -mod level; - -pub struct TestGame { - input: InputState, - player: Player, - game_objects: Vec, - log_config: LogConfig, - texture_index_counter: usize, - last_time: f32, - components: Vec>, -} - -impl TestGame { - fn new(toml_path: &str, log_config: LogConfig) -> TestGame { - TestGame { - input: InputState::new(toml_path, log_config), - player: Player::new(), - game_objects: vec![], - log_config, - texture_index_counter: 0, - last_time: 0.0, - components: vec![], - } - } -} - -impl Game for TestGame { - fn on_window_event(self: &mut Self, event: &Event<()>) { - self.input.on_window_event(event); - } - - fn update(self: &mut Self, renderer: &mut VulkanRenderer) -> ObjectUniformData { - // Input and timing - self.input.frame_start(); - let time = (renderer.game_data.start_time.elapsed().unwrap().as_micros() as f64 / 1000000.0) as f32; - let frame_time = time - self.last_time; - - // Component update - let input = &self.input; - let components = &mut self.components; - components.iter_mut().for_each(|component| { - component.update(frame_time, &input, renderer); - }); - - // User interaction - if self.input.button_just_released("quit") { - renderer.game_data.shutdown = true; - } - - if self.input.button_just_pressed("reload_shaders") { - renderer.game_data.recreate_pipeline = true; - } - - if self.input.button_just_pressed("quicksave") { - save_level("levels/test.lvl", self, renderer).unwrap(); - } - - if self.input.button_just_pressed("quickload") { - self.clear_level(renderer); - load_level("levels/test.lvl", self, renderer).unwrap(); - } - - if self.input.button_down("print_framerate") { - println!("{:.0} ms / {:.0} FPS", frame_time * 1000.0, 1.0 / frame_time); - } - - // Custom game object stuff - let light_pos = self.player.camera.position * -1.0; - self.player.update(frame_time, &self.input, renderer); - - // End frame - self.last_time = time; - self.input.frame_end(); - - ObjectUniformData { - view: self.player.camera.view.into(), - projection: self.player.camera.proj.into(), - time, - light_position: light_pos.into(), - camera_position: self.player.camera.position.into(), - _dummy0: [0; 12], - _dummy1: [0; 4], - } - } -} - -fn _matrix_vector_mul(matrix: &Matrix4, vector: &Vector3) -> Vector3 { - let v4 = Vector4::new(vector.x, vector.y, vector.z, 1.0); - let out = matrix * v4; - Vector3::new(out.x, out.y, out.z) -} - -impl TestGame { - fn game_start(self: &mut Self, renderer: &mut VulkanRenderer) { - // let plane_mesh = self.load_gltf(renderer, "models/plane.gltf"); - // self.add_game_object(renderer, plane_mesh[0].clone()); - load_level("levels/test.lvl", self, renderer).unwrap(); - println!("Game loaded!"); - } - - fn offset_texture_id(&mut self, local_tex_id: Option) -> usize { - match local_tex_id { - Some(local_id) => local_id + self.texture_index_counter, - None => 0, - } - } - - fn load_gltf(&mut self, renderer: &mut VulkanRenderer, gltf_path: &str) -> Vec { - let mut mesh_handles = Vec::new(); - - // Load file - let (meshes, textures) = mesh::load_mesh(gltf_path, self.log_config.mesh_load_info).unwrap(); - - for cpu_mesh in meshes.into_iter() { - // Convert file texture id to game texture id - let diffuse_id = self.offset_texture_id(cpu_mesh.local_texture_index); - let normal_id = self.offset_texture_id(cpu_mesh.local_normal_map_index); - - // Upload mesh - let mesh_id = renderer.upload_mesh(cpu_mesh, gltf_path.to_string()); - let mesh_handle = MeshHandle { - index: mesh_id, - diffuse_handle: diffuse_id, - normal_handle: normal_id, - original_path: gltf_path.to_string() - }; - mesh_handles.push(mesh_handle); - } - - textures.iter().for_each(|tex| { - renderer.upload_texture(tex); - self.texture_index_counter += 1; - }); - mesh_handles - } - - fn add_game_object(&mut self, renderer: &mut VulkanRenderer, mesh: MeshHandle) -> GameObjectHandle { - let obj = GameObject::new(mesh); - let obj_handle = renderer.add_game_object(obj, 0); - self.game_objects.push(obj_handle); - self.game_objects.last().unwrap().clone() - } - - fn clear_level(&mut self, renderer: &mut VulkanRenderer) { - self.game_objects.clear(); - self.texture_index_counter = 0; - renderer.clear_all(); - } -} +mod game; fn main() { let log_config = LogConfig::from_file("config/log.toml"); diff --git a/src/gameobject.rs b/src/vulkan/gameobject.rs similarity index 97% rename from src/gameobject.rs rename to src/vulkan/gameobject.rs index 03fac54..8f89481 100644 --- a/src/gameobject.rs +++ b/src/vulkan/gameobject.rs @@ -1,8 +1,10 @@ use std::sync::Arc; -use crate::vulkan::{RendererDescriptorSets, TextureHandle}; -use cgmath::{Matrix4, Vector3, Quaternion, Euler, Deg}; -use crate::vulkan::{MeshHandle, VulkanRenderer}; + +use cgmath::{Deg, Euler, Matrix4, Quaternion, Vector3}; + use crate::input::InputState; +use crate::vulkan::{RendererDescriptorSets, TextureHandle}; +use crate::vulkan::{MeshHandle, VulkanRenderer}; #[derive(Clone)] pub struct GameObject { diff --git a/src/mesh.rs b/src/vulkan/mesh.rs similarity index 98% rename from src/mesh.rs rename to src/vulkan/mesh.rs index 5b866fc..6dd4620 100644 --- a/src/mesh.rs +++ b/src/vulkan/mesh.rs @@ -3,7 +3,7 @@ use std::time::SystemTime; use gltf::Error; use gltf::mesh::util::{ReadJoints, ReadNormals, ReadPositions, ReadTangents, ReadTexCoords, ReadWeights}; -use crate::mesh::LoadError::{GltfError, MeshDataMissing, NoIndices}; +use crate::vulkan::mesh::LoadError::{GltfError, MeshDataMissing, NoIndices}; use crate::vulkan::Vertex; #[derive(Debug)] diff --git a/src/vulkan.rs b/src/vulkan/mod.rs similarity index 98% rename from src/vulkan.rs rename to src/vulkan/mod.rs index 80de15a..248417a 100644 --- a/src/vulkan.rs +++ b/src/vulkan/mod.rs @@ -1,18 +1,16 @@ -use crate::pipelines::{Drawcall, LineShader}; -use crate::pipelines::DefaultShader; use std::sync::Arc; use std::time::SystemTime; use cgmath::{Matrix4, SquareMatrix}; use image::{ImageBuffer, Rgb, Rgba}; use image::buffer::ConvertBuffer; -use vulkano::{command_buffer::CommandBuffer, buffer::{BufferUsage, CpuAccessibleBuffer}, image::{ImageLayout, MipmapsCount}}; +use vulkano::{buffer::{BufferUsage, CpuAccessibleBuffer}, command_buffer::CommandBuffer, image::{ImageLayout, MipmapsCount}}; use vulkano::command_buffer::{AutoCommandBuffer, AutoCommandBufferBuilder, DynamicState}; use vulkano::descriptor::DescriptorSet; use vulkano::device::{Device, DeviceExtensions, Queue}; use vulkano::format::{ClearValue, Format}; use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, RenderPassAbstract}; -use vulkano::image::{AttachmentImage, Dimensions, ImageUsage, ImmutableImage, SwapchainImage, ImageViewAccess}; +use vulkano::image::{AttachmentImage, Dimensions, ImageUsage, ImageViewAccess, ImmutableImage, SwapchainImage}; use vulkano::instance::{ApplicationInfo, Instance, InstanceExtensions, PhysicalDevice, Version}; use vulkano::instance::debug::{DebugCallback, MessageSeverity, MessageType}; use vulkano::pipeline::viewport::Viewport; @@ -26,13 +24,19 @@ use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::{Window, WindowBuilder}; -use crate::pipelines::{line_vs::ty::LinePushConstants}; -use crate::pipelines::vs::ty::PushConstants; +use mesh::CPUMesh; +use pipelines::{Drawcall, LineShader}; +use pipelines::{line_vs::ty::LinePushConstants}; +use pipelines::DefaultShader; +use pipelines::vs; +use pipelines::vs::ty::PushConstants; -use crate::pipelines::vs; -use crate::{gameobject::{GameObject, GameObjectHandle}}; -use crate::mesh::CPUMesh; use crate::config::RenderConfig; +use crate::vulkan::{gameobject::{GameObject, GameObjectHandle}}; + +pub mod pipelines; +pub mod gameobject; +pub mod mesh; const VALIDATION_LAYERS: &[&str] = &[ "VK_LAYER_KHRONOS_validation" @@ -573,4 +577,4 @@ fn window_size_dependent_setup(device: Arc, images: &[Arc; type GP = Arc; @@ -68,8 +70,21 @@ impl DefaultShader { } impl Drawcall for DefaultShader { - fn recreate_pipeline(self: &mut Self, device: Arc, render_pass: RP) { - self.pipeline = Self::create_pipeline(device, render_pass); + fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) { + for i in 0..game_data.game_objects.len() { + let game_object = &game_data.game_objects[i]; + let mesh = &game_data.meshes[game_object.mesh_index]; + let mut push_constants = game_data.push_constants.clone(); + push_constants.model = game_object.get_model_matrix().into(); + + builder.draw_indexed( + self.pipeline.clone(), + dynamic_state, + vec![mesh.vertex_buffer.clone()], + mesh.index_buffer.clone(), + game_object.descriptor_sets[fb_index].clone(), + push_constants).unwrap(); + } } fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer) { @@ -91,21 +106,8 @@ impl Drawcall for DefaultShader { }).collect(); } - fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) { - for i in 0..game_data.game_objects.len() { - let game_object = &game_data.game_objects[i]; - let mesh = &game_data.meshes[game_object.mesh_index]; - let mut push_constants = game_data.push_constants.clone(); - push_constants.model = game_object.get_model_matrix().into(); - - builder.draw_indexed( - self.pipeline.clone(), - dynamic_state, - vec![mesh.vertex_buffer.clone()], - mesh.index_buffer.clone(), - game_object.descriptor_sets[fb_index].clone(), - push_constants).unwrap(); - } + fn recreate_pipeline(self: &mut Self, device: Arc, render_pass: RP) { + self.pipeline = Self::create_pipeline(device, render_pass); } fn get_pipeline(self: &Self) -> &GP {