diff --git a/config/input.toml b/config/input.toml index c2867d4..1b60ca1 100644 --- a/config/input.toml +++ b/config/input.toml @@ -1,3 +1,6 @@ +# Scan codes are in decimal +# See here: https://www.millisecond.com/support/docs/v6/html/language/scancodes.htm + [[button]] name = "quit" scan_code = 1 @@ -8,8 +11,7 @@ scan_code = 59 [[button]] name = "reload_shaders" -scan_code = 19 -ctrl = true +scan_code = 63 [[button]] name = "print_framerate" diff --git a/shaders/triangle.frag b/shaders/triangle.frag index 19b75d0..2290422 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -6,6 +6,7 @@ layout(binding = 0) uniform ObjectUniformData { mat4 projection; float time; vec3 light_position; + vec3 light_directional_rotation; vec3 camera_position; } ubo; @@ -23,7 +24,9 @@ void main() { vec3 normal_cam_u = texture(normal_tex, tex_coords).rgb; normal_cam_u = normal_cam_u * 2.0 - 1.0; normal_cam_u = normalize(tbn * normal_cam_u); - vec3 light_direction_cam_u = normalize(ubo.light_position - position_wld); + + // vec3 light_direction_cam_u = normalize(ubo.light_position - position_wld); + vec3 light_direction_cam_u = normalize(vec3(sin(ubo.time), 1.0, cos(ubo.time))); float ambient_strength = 0.1; vec3 light_color = vec3(1.0, 1.0, 1.0); diff --git a/shaders/triangle.frag.spv b/shaders/triangle.frag.spv index 9b5530c..8b419f3 100644 Binary files a/shaders/triangle.frag.spv and b/shaders/triangle.frag.spv differ diff --git a/shaders/triangle.vert b/shaders/triangle.vert index 875d44a..ee77869 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -10,6 +10,7 @@ layout(binding = 0) uniform ObjectUniformData { mat4 projection; float time; vec3 light_position; + vec3 light_directional_rotation; vec3 camera_position; } ubo; diff --git a/shaders/triangle.vert.spv b/shaders/triangle.vert.spv index c864ac8..7b505f0 100644 Binary files a/shaders/triangle.vert.spv and b/shaders/triangle.vert.spv differ diff --git a/src/game/mod.rs b/src/game/mod.rs index 8640864..46b1318 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,10 +1,11 @@ +use cgmath::{Deg, InnerSpace, Quaternion, Rotation3}; use winit::event::Event; use level::{load_level, save_level}; use player::Player; -use crate::config::{LogConfig}; +use crate::config::LogConfig; use crate::input::InputState; use crate::vulkan::{Game, MeshHandle, VulkanRenderer}; use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable}; @@ -22,6 +23,7 @@ pub struct TestGame { pub texture_index_counter: usize, pub last_time: f32, pub components: Vec>, + pub paused: bool, } impl Game for TestGame { @@ -48,7 +50,7 @@ impl Game for TestGame { } if self.input.button_just_pressed("reload_shaders") { - renderer.game_data.recreate_pipeline = true; + renderer.recreate_swapchain = true; } if self.input.button_just_pressed("quicksave") { @@ -65,17 +67,15 @@ impl Game for TestGame { } if self.input.button_just_pressed("test") { - if renderer.render_config.msaa_samples > 0 { - renderer.render_config.msaa_samples = 0; - } else { - renderer.render_config.msaa_samples = 8; - } - renderer.recreate_swapchain = true; + self.paused = !self.paused; } // Custom game object stuff let light_pos = self.player.camera.position * -1.0; - self.player.update(frame_time, &self.input, renderer); + if !self.paused { + self.player.update(frame_time, &self.input, renderer); + } + self.game_objects[1].get_game_object_mut(renderer).unwrap().rotation = Quaternion::from_angle_y(Deg(time * -20.)).normalize(); // End frame self.last_time = time; @@ -86,9 +86,11 @@ impl Game for TestGame { projection: self.player.camera.proj.into(), time, light_position: light_pos.into(), + light_directional_rotation: [45.0, 45.0, 0.0], camera_position: self.player.camera.position.into(), _dummy0: [0; 12], _dummy1: [0; 4], + _dummy2: [0; 4], } } } @@ -103,6 +105,7 @@ impl TestGame { texture_index_counter: 0, last_time: 0.0, components: vec![], + paused: false, } } diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 38933ff..095a060 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -250,7 +250,7 @@ impl VulkanRenderer { let pipelines: Vec> = vec![ Box::new(DefaultShader::new(device.clone(), render_pass.clone())), - // Box::new(LineShader::new(device.clone(), render_pass.clone(), line_vertex_buffer.clone())), + Box::new(LineShader::new(device.clone(), render_pass.clone(), line_vertex_buffer.clone())), ]; // Dynamic viewports allow us to recreate just the viewport when the window is resized @@ -269,9 +269,11 @@ impl VulkanRenderer { projection: Matrix4::identity().into(), time: 0.0, light_position: [0.0, 0.0, 0.0], + light_directional_rotation: [0.0, 0.0, 0.0], camera_position: [0.0, 0.0, 0.0], _dummy0: [0; 12], _dummy1: [0; 4], + _dummy2: [0; 4], }; for _ in 0..swapchain.num_images() { @@ -347,7 +349,7 @@ impl VulkanRenderer { self.pipelines = vec![ Box::new(DefaultShader::new(self.device.clone(), self.render_pass.clone())), - // Box::new(LineShader::new(self.device.clone(), self.render_pass.clone(), self.line_vertex_buffer.clone())), + Box::new(LineShader::new(self.device.clone(), self.render_pass.clone(), self.line_vertex_buffer.clone())), ]; self.swapchain = new_swapchain; @@ -473,6 +475,11 @@ impl VulkanRenderer { pub fn start_event_loop(mut renderer: VulkanRenderer, mut game: Box, event_loop: EventLoop<()>) { event_loop.run(move |event, _, control_flow| { game.on_window_event(&event); + + if renderer.game_data.shutdown { + *control_flow = ControlFlow::Exit; + } + match event { Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { *control_flow = ControlFlow::Exit; diff --git a/src/vulkan/pipelines.rs b/src/vulkan/pipelines.rs index 361bb8d..2fd00c1 100644 --- a/src/vulkan/pipelines.rs +++ b/src/vulkan/pipelines.rs @@ -1,12 +1,13 @@ use std::{convert::TryInto, io::{Read, Write}, sync::Arc}; -use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}}; +use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::shader::ShaderModule}; use vulkano::command_buffer::DynamicState; use vulkano::device::Device; use vulkano::framebuffer::RenderPassAbstract; use vulkano::framebuffer::Subpass; use vulkano::pipeline::GraphicsPipeline; use vulkano::pipeline::GraphicsPipelineAbstract; +use vulkano::pipeline::shader::GraphicsShaderType; use crate::GameObject; use crate::vulkan::{LinePoint, Vertex}; @@ -42,6 +43,16 @@ pub struct DefaultShader { pipeline: GP, } +fn shader_module_from_file(device: Arc, path: &str) -> Arc { + let mut file = std::fs::File::open(path).unwrap(); + let mut buffer = vec![]; + file.read_to_end(&mut buffer).unwrap(); + let words: Vec = buffer.chunks_exact(4).map(|c| u32::from_ne_bytes(c.try_into().unwrap())).collect(); + unsafe { + ShaderModule::from_words(device.clone(), &words).unwrap() + } +} + impl DefaultShader { pub fn new(device: Arc, render_pass: RP) -> Self { DefaultShader { @@ -51,7 +62,6 @@ impl DefaultShader { fn create_pipeline(device: Arc, render_pass: RP) -> GP { let sub_pass = Subpass::from(render_pass.clone(), 0).unwrap(); - let vertex_shader = vs::Shader::load(device.clone()).unwrap(); #[cfg(debug_assertions)] { @@ -65,22 +75,26 @@ impl DefaultShader { } unsafe { - let mut fs_file = std::fs::File::open("shaders/triangle.frag.spv").unwrap(); - let mut fs_buf = vec![]; - fs_file.read_to_end(&mut fs_buf).unwrap(); - let fs_words: Vec = fs_buf.chunks_exact(4).map(|c| u32::from_ne_bytes(c.try_into().unwrap())).collect(); - let fs_module = vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &fs_words).unwrap(); + static ENTRY_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0]; + let entry_name_c = std::ffi::CStr::from_ptr(ENTRY_NAME.as_ptr() as *const _); + + let fs_module = shader_module_from_file(device.clone(), "shaders/triangle.frag.spv"); let fs_layout = fs::Layout(ShaderStages { fragment: true, ..ShaderStages::none() }); - static FS_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0]; - let fs_name_c = std::ffi::CStr::from_ptr(FS_NAME.as_ptr() as *const _); - let fs_entry = fs_module.graphics_entry_point(fs_name_c, fs::MainInput, fs::MainOutput, fs_layout, vulkano::pipeline::shader::GraphicsShaderType::Fragment); + let fs_entry = fs_module.graphics_entry_point(entry_name_c, fs::MainInput, fs::MainOutput, fs_layout, GraphicsShaderType::Fragment); + + let vs_module = shader_module_from_file(device.clone(), "shaders/triangle.vert.spv"); + let vs_layout = vs::Layout(ShaderStages { + vertex: true, + ..ShaderStages::none() + }); + let vs_entry = vs_module.graphics_entry_point(entry_name_c, vs::MainInput, vs::MainOutput, vs_layout, GraphicsShaderType::Vertex); Arc::new(GraphicsPipeline::start() .vertex_input_single_buffer::() - .vertex_shader(vertex_shader.main_entry_point(), ()) + .vertex_shader(vs_entry, ()) .triangle_list() .viewports_dynamic_scissors_irrelevant(1) .depth_stencil_simple_depth()