Got input system to work

+ added changing color depending on mouse pos
+ started refactoring HalState
* Vsync may not be working
This commit is contained in:
Steins7 2020-07-28 11:18:13 +02:00
parent ebc9299f33
commit 7dc22f026e
5 changed files with 120 additions and 137 deletions

View File

@ -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()?;

View File

@ -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();
},
_ => (),
}
_ => (),

42
src/renderer.rs Normal file
View File

@ -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<<vk_back::Backend as Backend>::Instance>,
surface: ManuallyDrop<<vk_back::Backend as Backend>::Surface>,
adapter: ManuallyDrop<gfx_hal::adapter::Adapter<vk_back::Backend>>,
device: vk_back::Device,
queue_group: ManuallyDrop<QueueGroup<vk_back::Backend>>,
render_pass: ManuallyDrop<<vk_back::Backend as Backend>::RenderPass>,
swapchain: ManuallyDrop<<vk_back::Backend as Backend>::Swapchain>,
extent: gfx_hal::window::Extent2D,
format: gfx_hal::format::Format,
render_area: Rect,
//items needed to render the images
sems_image_available: Vec<<vk_back::Backend as Backend>::Semaphore>,
sems_render_finished: Vec<<vk_back::Backend as Backend>::Semaphore>,
fences: Vec<<vk_back::Backend as Backend>::Fence>,
image_views: Vec<<vk_back::Backend as Backend>::ImageView>,
framebuffers: Vec<<vk_back::Backend as Backend>::Framebuffer>,
command_pool: ManuallyDrop<<vk_back::Backend as Backend>::CommandPool>,
command_buffers: Vec<<vk_back::Backend as Backend>::CommandBuffer>,
//items needed to keep track of the images
image_count: usize,
current_image: usize,
}

View File

@ -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<<vk_back::Backend as Backend>::Instance>,
surface: ManuallyDrop<<vk_back::Backend as Backend>::Surface>,
adapter: ManuallyDrop<gfx_hal::adapter::Adapter<vk_back::Backend>>,
device: vk_back::Device,
queue_group: ManuallyDrop<QueueGroup<vk_back::Backend>>,
render_pass: ManuallyDrop<<vk_back::Backend as Backend>::RenderPass>,
swapchain: ManuallyDrop<<vk_back::Backend as Backend>::Swapchain>,
extent: gfx_hal::window::Extent2D,
format: gfx_hal::format::Format,
render_area: Rect,
//items needed to render the images
sems_image_available: Vec<<vk_back::Backend as Backend>::Semaphore>,
sems_render_finished: Vec<<vk_back::Backend as Backend>::Semaphore>,
fences: Vec<<vk_back::Backend as Backend>::Fence>,
image_views: Vec<<vk_back::Backend as Backend>::ImageView>,
framebuffers: Vec<<vk_back::Backend as Backend>::Framebuffer>,
command_pool: ManuallyDrop<<vk_back::Backend as Backend>::CommandPool>,
command_buffers: Vec<<vk_back::Backend as Backend>::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::<Result<Vec<_>, &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::<Result<Vec<_>, &str>>()?
};
self.swapchain = ManuallyDrop::new(swapchain);
self.image_views = image_views;
self.framebuffers = framebuffers;
Ok(())
}
//----------------------------------------------------------------------------------------------
pub fn new(window: &Window) -> Result<HalState, &'static str> {
pub fn new(window: &Window) -> Result<Renderer, &'static str> {
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),

View File

@ -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> {
@ -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")?;
}
}