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:
parent
ebc9299f33
commit
7dc22f026e
@ -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()?;
|
||||
|
||||
75
src/lib.rs
75
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();
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
_ => (),
|
||||
|
||||
42
src/renderer.rs
Normal file
42
src/renderer.rs
Normal 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,
|
||||
}
|
||||
|
||||
@ -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),
|
||||
@ -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")?;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user