From 9561a6ce0cce7ffa97de738313666329afb1083c Mon Sep 17 00:00:00 2001 From: Till Date: Mon, 19 Aug 2019 00:29:33 +0200 Subject: [PATCH] update UBOs --- shaders/triangle.vert | 5 +--- src/main.rs | 29 +++++++++--------- src/vulkan.rs | 68 ++++++++++++++++++++----------------------- 3 files changed, 47 insertions(+), 55 deletions(-) diff --git a/shaders/triangle.vert b/shaders/triangle.vert index e6e49c0..5ebdd6c 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -14,12 +14,9 @@ layout(location = 0) out vec2 tex_coords; layout(push_constant) uniform PushConstants { mat4 model; - mat4 view; - mat4 projection; - float time; } push; void main() { - gl_Position = push.projection * push.view * push.model * vec4(position, 1.0); + gl_Position = ubo.projection * ubo.view * push.model * vec4(position, 1.0); tex_coords = uv; } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index f022117..9479570 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,8 @@ use winit::{Event}; use cgmath::{Matrix4, Rad, Vector3, Deg, Quaternion, Rotation3, One, Rotation}; mod vulkan; -use crate::vulkan::{Game, LinePoint, GameObject, VulkanRenderer, RenderLoopResult, MeshHandle, GameObjectHandle}; +use crate::vulkan::{Game, LinePoint, GameObject, VulkanRenderer, RenderResult, MeshHandle, GameObjectHandle}; +use crate::vulkan::vs::ty::UniformBufferObject; mod input; use crate::input::{InputState}; @@ -41,12 +42,9 @@ impl TestGame { println!("Game loaded!"); } - fn update(self: &mut Self, renderer: &mut VulkanRenderer) { + fn update(self: &mut Self, renderer: &mut VulkanRenderer) -> UniformBufferObject { self.input.frame_start(); - - let new_time = (renderer.game_data.start_time.elapsed().unwrap().as_micros() as f64 / 1000000.0) as f32; -// let frame_time = new_time - renderer.game_data.uniform_buffers.iter().map(|ubo| ubo.time).max_by(|a,b| if a > b {Ordering::Greater} else {Ordering::Less} ).unwrap(); -// renderer.uniform_buffers.iter_mut().for_each(|ubo| ubo.time = new_time); + let time = (renderer.game_data.start_time.elapsed().unwrap().as_micros() as f64 / 1000000.0) as f32; // User interaction if self.input.button_just_released("quit") { @@ -85,14 +83,16 @@ impl TestGame { proj.y.y *= -1.0; - renderer.game_data.push_constants.view = view.into(); - renderer.game_data.push_constants.projection = proj.into(); -// renderer.uniform_buffers.iter_mut().for_each(|ubo| ubo.view = view.into()); -// renderer.uniform_buffers.iter_mut().for_each(|ubo| ubo.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(); + + UniformBufferObject { + view: view.into(), + projection: proj.into(), + time, + } } } @@ -123,12 +123,13 @@ fn main() { game.game_start(&mut renderer); let mut continue_rendering = true; + let mut ubo = game.update(&mut renderer); while continue_rendering { - match renderer.render_loop(&mut game) { - RenderLoopResult::Ok => game.update(&mut renderer), - RenderLoopResult::Reload => println!("Render loop reloaded..."), - RenderLoopResult::Quit => continue_rendering = false, + match renderer.render_loop(&mut game, ubo) { + RenderResult::Ok => ubo = game.update(&mut renderer), + RenderResult::Reload => println!("Render loop reloaded..."), + RenderResult::Quit => continue_rendering = false, } } } \ No newline at end of file diff --git a/src/vulkan.rs b/src/vulkan.rs index a44bb9a..f92b05b 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -35,7 +35,6 @@ use shaderc; use vs::ty::PushConstants; use line_vs::ty::LinePushConstants; use crate::mesh::{CPUMesh}; -use crate::vulkan::RenderLoopResult::Quit; use image::{ImageFormat, ConvertBuffer, ImageBuffer, Rgb, Rgba}; @@ -113,7 +112,8 @@ pub struct VulkanRenderer { pub descriptor_sets: Vec, } -pub enum RenderLoopResult { +pub enum RenderResult { + /// Contains buffer index and swapchain future Ok, Reload, Quit, @@ -123,10 +123,7 @@ impl VulkanRenderer { pub fn init(line_vertices: Vec, enable_validation_layers: bool) -> VulkanRenderer { let mut data = GameData { push_constants: PushConstants { - time: 0.0, model: Matrix4::identity().into(), - view: Matrix4::identity().into(), - projection: Matrix4::identity().into(), }, line_push_constants: LinePushConstants { model: Matrix4::identity().into(), @@ -334,35 +331,32 @@ impl VulkanRenderer { recreate_swapchain: false, debug_callback, previous_frame_end } } - fn create_command_buffers(self: &mut Self) -> Vec> { - let mut buffers = Vec::new(); - for fb_index in 0..self.framebuffers.len() { - let mut cbb = AutoCommandBufferBuilder::primary_simultaneous_use(self.device.clone(), self.queue.family()).unwrap() - .update_buffer(self.uniform_buffers[fb_index].clone(), vs::ty::UniformBufferObject { view: Matrix4::identity().into(), projection: Matrix4::identity().into(), time: 0.0 }).unwrap() - .begin_render_pass(self.framebuffers[fb_index].clone(), false, vec![ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap(); + fn create_command_buffer(self: &mut Self, fb_index: usize, ubo: vs::ty::UniformBufferObject) -> Arc { + let mut cbb = AutoCommandBufferBuilder::primary_simultaneous_use(self.device.clone(), self.queue.family()).unwrap() + .update_buffer(self.uniform_buffers[fb_index].clone(), ubo).unwrap() + .begin_render_pass(self.framebuffers[fb_index].clone(), false, vec![ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap(); - for i in 0..self.game_data.game_objects.len() { - let game_object = &self.game_data.game_objects[i]; - let mesh = &self.game_data.meshes[game_object.mesh_index]; - self.game_data.push_constants.model = game_object.model_matrix.into(); - cbb = cbb.draw_indexed( - self.pipeline.clone(), - &self.dynamic_state, - vec![mesh.vertex_buffer.clone()], - mesh.index_buffer.clone(), - self.descriptor_sets[fb_index].clone(), - self.game_data.push_constants.clone()).unwrap() - } - - cbb = cbb.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap() - .end_render_pass().unwrap(); - - buffers.push(Arc::new(cbb.build().unwrap())); + for i in 0..self.game_data.game_objects.len() { + let game_object = &self.game_data.game_objects[i]; + let mesh = &self.game_data.meshes[game_object.mesh_index]; + self.game_data.push_constants.model = game_object.model_matrix.into(); + cbb = cbb.draw_indexed( + self.pipeline.clone(), + &self.dynamic_state, + vec![mesh.vertex_buffer.clone()], + mesh.index_buffer.clone(), + self.descriptor_sets[fb_index].clone(), + self.game_data.push_constants.clone()).unwrap() } - buffers + + cbb = cbb.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap() + .end_render_pass().unwrap(); + + Arc::new(cbb.build().unwrap()) } - pub fn render_loop(self: &mut Self, game: &mut dyn Game) -> RenderLoopResult { + /// Returns false if rendering should stop + pub fn render_loop(self: &mut Self, game: &mut dyn Game, new_ubo: vs::ty::UniformBufferObject) -> RenderResult { // It is important to call this function from time to time, otherwise resources will keep // accumulating and you will eventually reach an out of memory error. // Calling this function polls various fences in order to determine what the GPU has @@ -384,7 +378,7 @@ impl VulkanRenderer { // Simply restarting the loop is the easiest way to fix this issue. Err(SwapchainCreationError::UnsupportedDimensions) => { println!("Swapchain rejected: UnsupportedDimensions"); - return RenderLoopResult::Reload; + return RenderResult::Reload; } Err(err) => panic!("{:?}", err), }; @@ -414,20 +408,20 @@ impl VulkanRenderer { // // This function can block if no image is available. The parameter is an optional timeout // after which the function call will return an error. - let (image_num, acquire_future) = match swapchain::acquire_next_image(self.swapchain.clone(), None) { + let (fb_index, acquire_future) = match swapchain::acquire_next_image(self.swapchain.clone(), None) { Ok(r) => r, Err(AcquireError::OutOfDate) => { self.recreate_swapchain = true; - return RenderLoopResult::Reload; + return RenderResult::Reload; }, Err(err) => panic!("{:?}", err) }; - let command_buffer = self.create_command_buffers()[image_num].clone(); + let command_buffer = self.create_command_buffer(fb_index, new_ubo).clone(); let future = self.previous_frame_end.take().unwrap().join(acquire_future) .then_execute(self.queue.clone(), command_buffer).unwrap() - .then_swapchain_present(self.queue.clone(), self.swapchain.clone(), image_num) + .then_swapchain_present(self.queue.clone(), self.swapchain.clone(), fb_index) .then_signal_fence_and_flush(); match future { @@ -463,9 +457,9 @@ impl VulkanRenderer { } }); if resized { self.recreate_swapchain = true } - if self.game_data.shutdown || window_closed { return Quit; } + if self.game_data.shutdown || window_closed { return RenderResult::Quit; } - RenderLoopResult::Ok + RenderResult::Ok } pub fn upload_mesh(self: &mut Self, mesh: CPUMesh) -> usize {