From 7dc22f026eee9a4fc442d0dd9385b50eadd61673 Mon Sep 17 00:00:00 2001 From: Steins7 Date: Tue, 28 Jul 2020 11:18:13 +0200 Subject: [PATCH] Got input system to work + added changing color depending on mouse pos + started refactoring HalState * Vsync may not be working --- src/bin/main.rs | 2 +- src/lib.rs | 75 +++++++++++++------ src/renderer.rs | 42 +++++++++++ src/{hal.rs => renderer/init.rs} | 123 +++++-------------------------- src/{hal => renderer}/render.rs | 15 ++-- 5 files changed, 120 insertions(+), 137 deletions(-) create mode 100644 src/renderer.rs rename src/{hal.rs => renderer/init.rs} (77%) rename src/{hal => renderer}/render.rs (92%) diff --git a/src/bin/main.rs b/src/bin/main.rs index 71ae510..ebf4501 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -16,7 +16,7 @@ fn setup_logger() -> Result<(), fern::InitError> { message )) }) - .level(log::LevelFilter::Warn) + .level(log::LevelFilter::Debug) .chain(std::io::stdout()) .chain(fern::log_file("output.log")?) .apply()?; diff --git a/src/lib.rs b/src/lib.rs index 8671f82..4086d54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,6 @@ use std::{ thread, collections::HashMap, cell::RefCell, - time, }; mod winit_state; @@ -21,15 +20,29 @@ use winit::{ event_loop::ControlFlow, }; -mod hal; -use hal::HalState; +mod renderer; +use renderer::Renderer; //mod local_state; //use local_state::LocalState; pub enum Command { - Draw, + NoCommand, Stop, + Color{ + r: f32, + g: f32, + b: f32, + a: f32, + }, +} + +pub enum Input { + Close, + Mouse{ + x: f64, + y: f64, + }, } @@ -39,7 +52,7 @@ pub enum Command { /// The main function of the library pub fn run() -> Result<(), &'static str> { let winit_state = WinitState::default(); - let mut hal_state = HalState::new(&winit_state.window)?; + let mut renderer = Renderer::new(&winit_state.window)?; //let local_state = LocalState::default(); let (input_tx, input_rx) = mpsc::channel(); @@ -55,39 +68,46 @@ pub fn run() -> Result<(), &'static str> { #[allow(unused_imports)] use log::{debug, error, info, trace, warn}; - + let mut color = [0.0, 0.0, 0.0, 0.0]; loop { - match cmd_rx.try_recv().unwrap_or(None) { - None => (), - Some(Command::Draw) => { - //TODO manage errors - let _ = hal_state.draw_clear_frame([0.0, 255.0, 0.0, 0.0]); - }, - Some(Command::Stop) => { + + //TODO manage errors + let _ = renderer.draw_clear_frame(color); + + match cmd_rx.try_recv().unwrap_or(Command::NoCommand) { + Command::NoCommand => (), + Command::Stop => { warn!("Stop render thread"); return; }, - }; + Command::Color{r, g, b, a} => { + color = [r, g, b, a]; + }, + } } }); loop { - match input_rx.try_recv().unwrap_or(false) { - false => (), - true => { - cmd_tx.send(Some(Command::Stop)).unwrap(); + match input_rx.recv().unwrap() { + Input::Close => { + cmd_tx.send(Command::Stop).unwrap(); //TODO stop event_loop warn!("wait for render thread"); render_thread.join().unwrap(); warn!("Stop control thread"); return; }, - }; - - cmd_tx.send(Some(Command::Draw)).unwrap(); - thread::sleep(time::Duration::from_millis(100)); - + Input::Mouse{x, y} => { + let pos = Command::Color{ + r: (x/1280.0) as f32, + g: (y/720.0) as f32, + b: ((x/1280.0 + y/720.0)/2.0) as f32, + a: 1.0, + }; + cmd_tx.send(pos).unwrap(); + }, + } } }))); @@ -102,13 +122,20 @@ pub fn run() -> Result<(), &'static str> { match event { Event::WindowEvent{window_id: _, event} => match event { WindowEvent::CloseRequested => { - input_tx.send(true).unwrap(); + input_tx.send(Input::Close).unwrap(); let handle = control_thread.replace(None).unwrap(); warn!("Wait for control thread"); handle.join().unwrap(); warn!("Stop input thread"); *control_flow = ControlFlow::Exit; }, + WindowEvent::CursorMoved{position, ..} => { + input_tx + .send(Input::Mouse{ + x: position.x, + y: position.y}) + .unwrap(); + }, _ => (), } _ => (), diff --git a/src/renderer.rs b/src/renderer.rs new file mode 100644 index 0000000..a734acb --- /dev/null +++ b/src/renderer.rs @@ -0,0 +1,42 @@ +use std::mem::ManuallyDrop; + +use gfx_hal::{ + queue::QueueGroup, + Backend, + pso::Rect, +}; + +use gfx_backend_vulkan as vk_back; + +pub mod init; +pub mod render; + +#[derive(Debug)] +pub struct Renderer { + //items need to communicate with the GPU + instance: ManuallyDrop<::Instance>, + surface: ManuallyDrop<::Surface>, + adapter: ManuallyDrop>, + device: vk_back::Device, + queue_group: ManuallyDrop>, + render_pass: ManuallyDrop<::RenderPass>, + swapchain: ManuallyDrop<::Swapchain>, + extent: gfx_hal::window::Extent2D, + format: gfx_hal::format::Format, + render_area: Rect, + + //items needed to render the images + sems_image_available: Vec<::Semaphore>, + sems_render_finished: Vec<::Semaphore>, + fences: Vec<::Fence>, + image_views: Vec<::ImageView>, + framebuffers: Vec<::Framebuffer>, + + command_pool: ManuallyDrop<::CommandPool>, + command_buffers: Vec<::CommandBuffer>, + + //items needed to keep track of the images + image_count: usize, + current_image: usize, +} + diff --git a/src/hal.rs b/src/renderer/init.rs similarity index 77% rename from src/hal.rs rename to src/renderer/init.rs index 2ebca6e..9e5e85c 100644 --- a/src/hal.rs +++ b/src/renderer/init.rs @@ -3,7 +3,6 @@ use log::{debug, error, info, trace, warn}; use std::{ mem::ManuallyDrop, - iter, }; use core::ptr::read; @@ -11,7 +10,6 @@ use core::ptr::read; use gfx_hal::{ Instance, device::Device, - queue::QueueGroup, Backend, pool::CommandPool, pso::Rect, @@ -21,38 +19,9 @@ use gfx_backend_vulkan as vk_back; use winit::window::Window; -pub mod render; +use crate::renderer::Renderer; -#[derive(Debug)] -pub struct HalState { - //items need to communicate with the GPU - instance: ManuallyDrop<::Instance>, - surface: ManuallyDrop<::Surface>, - adapter: ManuallyDrop>, - device: vk_back::Device, - queue_group: ManuallyDrop>, - render_pass: ManuallyDrop<::RenderPass>, - swapchain: ManuallyDrop<::Swapchain>, - extent: gfx_hal::window::Extent2D, - format: gfx_hal::format::Format, - render_area: Rect, - - //items needed to render the images - sems_image_available: Vec<::Semaphore>, - sems_render_finished: Vec<::Semaphore>, - fences: Vec<::Fence>, - image_views: Vec<::ImageView>, - framebuffers: Vec<::Framebuffer>, - - command_pool: ManuallyDrop<::CommandPool>, - command_buffers: Vec<::CommandBuffer>, - - //items needed to keep track of the images - image_count: usize, - current_image: usize, -} - -impl core::ops::Drop for HalState { +impl core::ops::Drop for Renderer { //---------------------------------------------------------------------------------------------- fn drop(&mut self) { @@ -60,7 +29,7 @@ impl core::ops::Drop for HalState { let _ = self.device.wait_idle(); //destroy all underlying ressources - debug!("Destroying HAL ressources"); + debug!("Destroying Renderer ressources"); unsafe { self.command_pool.free(self.command_buffers.drain(..)); self.device.destroy_command_pool( @@ -87,95 +56,43 @@ impl core::ops::Drop for HalState { self.instance.destroy_surface(ManuallyDrop::into_inner(read(&mut self.surface))); ManuallyDrop::drop(&mut self.instance); } - info!("HAL ressources destroyed"); + info!("Renderer ressources destroyed"); } } -impl HalState { +impl Renderer { //---------------------------------------------------------------------------------------------- - pub fn recreate_swapchain(&mut self) -> Result<(), &'static str> { + pub fn update_swapchain(&mut self) -> Result<(), &'static str> { use gfx_hal::window::{ SwapchainConfig, Surface, + PresentationSurface, }; - debug!("Recreating swapchain"); + debug!("Updating swapchain"); - //destroying previous swapchain - unsafe { - for buffer in self.framebuffers.drain(..) { - self.device.destroy_framebuffer(buffer); - } - for view in self.image_views.drain(..) { - self.device.destroy_image_view(view); - } - - self.device.destroy_swapchain(ManuallyDrop::into_inner(read(&mut self.swapchain))); - } + //creating new swapchain config let capabilities = self.surface.capabilities(&self.adapter.physical_device); - info!("{:#?}", capabilities); - - //creating new swapchain let swapchain_config = SwapchainConfig::from_caps(&capabilities, self.format, self.extent); info!("{:?}", swapchain_config); - let (swapchain, backbuffer) = unsafe { - self.device - .create_swapchain(&mut self.surface, swapchain_config, None) - .map_err(|_| "Failed to create swapchain and backbuffer")? - }; + self.device + .wait_idle() + .map_err(|_| "Failed to to wait for device to be idle")?; - let image_views : Vec<_> = { - use gfx_hal::{ - image::{ViewKind, SubresourceRange}, - format::{Swizzle, Aspects}, - }; + unsafe { + self.surface + .configure_swapchain(&self.device, swapchain_config) + .map_err(|_| "Failed to updtate swapchain")?; + debug!("update succesfull !"); + } - backbuffer - .iter() - .map(|img| unsafe { - self.device - .create_image_view( - &img, - ViewKind::D2, - self.format, - Swizzle::NO, - SubresourceRange { - aspects : Aspects::COLOR, - levels : 0..1, - layers : 0..1, - }, - ) - .map_err(|_| "Could not create ImageViews") - }) - .collect::, &str>>()? - }; - - let framebuffers: Vec<_> = { - - image_views - .iter() - .map(|image_view| - unsafe { - self.device - .create_framebuffer(&self.render_pass, - iter::once(image_view), - self.extent.to_extent()) - .map_err(|_| "Could not create FrameBuffer") - }, - ) - .collect::, &str>>()? - }; - - self.swapchain = ManuallyDrop::new(swapchain); - self.image_views = image_views; - self.framebuffers = framebuffers; Ok(()) } //---------------------------------------------------------------------------------------------- - pub fn new(window: &Window) -> Result { + pub fn new(window: &Window) -> Result { use gfx_hal::adapter::Gpu; // create top level @@ -469,7 +386,7 @@ impl HalState { info!("HAL successfully initialized"); Ok( - HalState { + Renderer { instance: ManuallyDrop::new(instance), surface: ManuallyDrop::new(surface), adapter: ManuallyDrop::new(adapter), diff --git a/src/hal/render.rs b/src/renderer/render.rs similarity index 92% rename from src/hal/render.rs rename to src/renderer/render.rs index 1ca8ac1..86b244c 100644 --- a/src/hal/render.rs +++ b/src/renderer/render.rs @@ -9,9 +9,9 @@ use gfx_hal::{ command::CommandBuffer, }; -use crate::hal::HalState; +use crate::renderer::Renderer; -impl HalState { +impl Renderer { //---------------------------------------------------------------------------------------------- pub fn draw_clear_frame(&mut self, color: [f32; 4]) -> Result<(), &'static str> { @@ -20,7 +20,7 @@ impl HalState { queue::{Submission, CommandQueue}, pso::PipelineStage, }; - + // get current frame fence let fence = &self.fences[self.current_image]; @@ -43,13 +43,13 @@ impl HalState { match self.swapchain.acquire_image(core::u64::MAX, Some(sem_image_available), None) { Ok((swp_image_id, suboptimal)) => match suboptimal { Some(_) => { - return self.recreate_swapchain() + return self.update_swapchain() .map_err(|_| "Could not recreate swpachain"); }, None => swp_image_id, } Err(_) => { - return self.recreate_swapchain() + return self.update_swapchain() .map_err(|_| "Could not recreate swpachain"); }, } @@ -73,7 +73,6 @@ impl HalState { SubpassContents::Inline, ); command_buffer.end_render_pass(); - command_buffer.finish(); } @@ -91,15 +90,13 @@ impl HalState { unsafe { - debug!("Submiting"); queue.submit(submission, Some(fence)); - debug!("Presenting into swapchain"); let result = self.swapchain.present(&mut queue, swp_image_id, Some(sem_render_finished)) .map_err(|_| "Failed to present into the swapchain")?; if result.is_some() { - self.recreate_swapchain() + self.update_swapchain() .map_err(|_| "Could not recreate swapchain")?; } }