diff --git a/src/canvas/canvas_frame.rs b/src/canvas/canvas_frame.rs index 1afce6f4..25fb919b 100644 --- a/src/canvas/canvas_frame.rs +++ b/src/canvas/canvas_frame.rs @@ -6,12 +6,18 @@ use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef; use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, Handle}; use vulkano::pipeline::vertex::Vertex; use std::any::Any; -use crate::VertexTypeContainer; +use crate::{VertexTypeContainer, Move, Geom}; use winit::event::Event; /// Trait which may be inherited by objects that wish to be drawn to the screen pub trait Drawable { - fn get(&self, window_size: (u32, u32)) -> Vec; + fn get(&self, + window_size: (u32, u32), + position: (f32, f32), + rotation: f32, + size: (f32, f32), + depth: f32, + ) -> Vec; } /// Trait which may be inherited by objects that wish to receive events @@ -32,7 +38,6 @@ pub struct CanvasFrame { } impl CanvasFrame { - pub fn new(window_size: (u32, u32)) -> CanvasFrame { CanvasFrame { map: vec![], @@ -42,14 +47,20 @@ impl CanvasFrame { /// Push this drawable onto the back of the accumulator pub fn add(&mut self, drawable: Vec) { - for i in drawable{ + for i in drawable { self.map.push(i); } } /// Push this drawable onto the back of the accumulator - pub fn draw(&mut self, drawable: &dyn Drawable) { - for i in drawable.get(self.window_size) { + pub fn draw(&mut self, drawable: &dyn Drawable, mv: Move, geom: Geom) { + for i in drawable.get( + self.window_size, + (mv.pos_x, mv.pos_y), + geom.rotation, + (geom.size_x, geom.size_y), + geom.depth + ) { self.map.push(i); } } diff --git a/src/canvas/compu_frame.rs b/src/canvas/compu_frame.rs index 0b8743dc..90a1b063 100644 --- a/src/canvas/compu_frame.rs +++ b/src/canvas/compu_frame.rs @@ -4,6 +4,7 @@ use crate::canvas::managed::handles::{CompuKernelHandle}; use crate::drawables::compu_sprite::CompuSprite; use crate::canvas::canvas_frame::Drawable; use crate::util::vertex::VertexTypeContainer; +use crate::{Move, Geom}; #[derive(Default)] pub struct CompuFrame { @@ -56,15 +57,22 @@ impl CompuFrame { pub fn add_with_image_swap(&mut self, buffer: Arc, kernel: Arc, - sprite: &CompuSprite) { - - let compu_sprites = sprite.get(self.window_size); + sprite: &CompuSprite, + mv: Move, + geom: Geom, + ) { + let compu_sprites = sprite.get( + self.window_size, + (mv.pos_x, mv.pos_y), + geom.rotation, + (geom.size_x, geom.size_y), + geom.depth, + ); if compu_sprites.len() == 1 { if let VertexTypeContainer::ImageType(a, b) = compu_sprites.first().unwrap() { self.swapped_to_image.push((buffer, b.clone(), kernel)) }; } - } } \ No newline at end of file diff --git a/src/drawables/compu_sprite.rs b/src/drawables/compu_sprite.rs index 56f490bb..414a2554 100644 --- a/src/drawables/compu_sprite.rs +++ b/src/drawables/compu_sprite.rs @@ -53,7 +53,13 @@ impl CompuSprite { } impl Drawable for CompuSprite { - fn get(&self, window_size: (u32, u32)) -> Vec { + fn get(&self, + window_size: (u32, u32), + position: (f32, f32), + rotation: f32, + size: (f32, f32), + depth: f32, + ) -> Vec { vec![self.verts.clone()] } } \ No newline at end of file diff --git a/src/drawables/polygon.rs b/src/drawables/polygon.rs index c62d9178..f4979595 100644 --- a/src/drawables/polygon.rs +++ b/src/drawables/polygon.rs @@ -61,7 +61,13 @@ impl Polygon { } } impl Drawable for Polygon { - fn get(&self, window_size: (u32, u32)) -> Vec { + fn get(&self, + window_size: (u32, u32), + position: (f32, f32), + rotation: f32, + size: (f32, f32), + depth: f32, + ) -> Vec { vec![self.verts.clone()] } diff --git a/src/drawables/rect.rs b/src/drawables/rect.rs index fb8b4c78..caffb660 100644 --- a/src/drawables/rect.rs +++ b/src/drawables/rect.rs @@ -73,7 +73,13 @@ impl Rect { } impl Drawable for Rect { - fn get(&self, window_size: (u32, u32)) -> Vec { + fn get(&self, + window_size: (u32, u32), + position: (f32, f32), + rotation: f32, + size: (f32, f32), + depth: f32, + ) -> Vec { vec![ VertexTypeContainer::ColorType( Rect::generate_vertices(window_size, self.position, self.size, self.depth, self.color) diff --git a/src/drawables/slider.rs b/src/drawables/slider.rs index cd59f060..eb1f2c2f 100644 --- a/src/drawables/slider.rs +++ b/src/drawables/slider.rs @@ -7,6 +7,7 @@ use crate::drawables::rect::Rect; use crate::drawables::sprite::Sprite; use crate::util::vertex::VertexTypeContainer; +#[derive(Debug, Clone)] pub struct Slider { handle: Rect, guide: Vec, @@ -28,7 +29,7 @@ impl Slider { let left_guide_bar = Rect::new((position.0, position.1), (2.0, size.1), 1, red); let right_guide_bar = Rect::new((position.0 + size.0, position.1), (2.0, size.1), 1, blue); - let line = Rect::new((position.0, position.1 - (size.1 / 2.0) ), (size.0, 2.0), 1, green); + let line = Rect::new((position.0, position.1 - (size.1 / 2.0)), (size.0, 2.0), 1, green); let scale = value as f32 / u16::max_value() as f32; let handle = Rect::new((position.0 + (size.0 * scale), position.1), (15.0, size.1), 1, rg); @@ -45,18 +46,40 @@ impl Slider { } impl Drawable for Slider { - fn get(&self, window_size: (u32, u32)) -> Vec { - let mut vertices = self.handle.get(window_size).clone(); + fn get(&self, + window_size: (u32, u32), + position: (f32, f32), + rotation: f32, + size: (f32, f32), + depth: f32, + ) -> Vec { + let mut vertices = self.handle.get( + window_size, + position, + rotation, + size, + depth, + ).clone(); vertices.extend_from_slice( self.guide.iter() - .map(|x| x.get(window_size)) - .flatten() + .map(|x| x.get(window_size, + position, + rotation, + size, + depth, + )).flatten() .collect::>() .as_slice() ); - vertices.extend_from_slice(self.guide[0].get(window_size).as_slice()); + vertices.extend_from_slice( + self.guide[0].get(window_size, + position, + rotation, + size, + depth, + ).as_slice()); vertices } } diff --git a/src/drawables/sprite.rs b/src/drawables/sprite.rs index ea6495de..9780cd19 100644 --- a/src/drawables/sprite.rs +++ b/src/drawables/sprite.rs @@ -8,16 +8,17 @@ use winit::event::{DeviceEvent, MouseButton, ElementState, Event, WindowEvent}; /// #[derive(Debug, Clone)] pub struct Sprite { - pub position: (f32, f32), - pub size: (f32, f32), - depth: f32, texture_handle: Arc, } /// Container class which implements drawable. impl Sprite { - fn generate_verts(window_size: (u32, u32), position: (f32, f32), size: (f32, f32), depth: f32) -> Vec { - + fn generate_verts( + window_size: (u32, u32), + position: (f32, f32), + size: (f32, f32), + depth: f32, + ) -> Vec { let ss_position = ( position.0 / window_size.0 as f32 - 1.0, position.1 / window_size.1 as f32 - 1.0 @@ -57,28 +58,27 @@ impl Sprite { } /// - pub fn new(position: (f32, f32), - size: (f32, f32), - depth: u32, - texture_handle: Arc) -> Sprite { - let normalized_depth = (depth as f32 / 255.0); - + pub fn new(texture_handle: Arc) -> Sprite { Sprite { - position: position, - size: size, - depth: normalized_depth, texture_handle: texture_handle.clone(), } } } - impl Drawable for Sprite { - fn get(&self, window_size: (u32, u32)) -> Vec { + fn get(&self, + window_size: (u32, u32), + position: (f32, f32), + rotation: f32, + size: (f32, f32), + depth: f32, + ) -> Vec { + let normalized_depth = (depth / 255.0); + vec![ VertexTypeContainer::TextureType( - Sprite::generate_verts(window_size, self.position, self.size, self.depth), + Sprite::generate_verts(window_size, position, size, normalized_depth), self.texture_handle.clone()) ] } @@ -91,7 +91,7 @@ impl Eventable for Sprite { match button { MouseButton::Left => { if *state == ElementState::Pressed { - self.position = (self.position.0, self.position.1 + 0.1); + } } _ => {} @@ -103,7 +103,5 @@ impl Eventable for Sprite { } impl Updatable for Sprite { - fn update(&mut self, delta_time: f32) -> () { - - } + fn update(&mut self, delta_time: f32) -> () {} } diff --git a/src/drawables/text.rs b/src/drawables/text.rs index b1a0928b..fbe8bebe 100644 --- a/src/drawables/text.rs +++ b/src/drawables/text.rs @@ -137,7 +137,13 @@ impl Text { } impl Drawable for Text { - fn get(&self, window_size: (u32, u32)) -> Vec { + fn get(&self, + window_size: (u32, u32), + position: (f32, f32), + rotation: f32, + size: (f32, f32), + depth: f32, + ) -> Vec { vec![self.verts.clone()] } } diff --git a/src/main.rs b/src/main.rs index 9c9ccd14..4423209b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,27 +53,31 @@ use specs::prelude::*; use vulkano::swapchain::Surface; -struct Draws(Sprite); +struct Draws(Box, Box + Sync + Send>); impl Component for Draws { type Storage = VecStorage; } -struct Vel { - x: f32, - y: f32, +pub struct Move { + vel_x: f32, + vel_y: f32, + pos_x: f32, + pos_y: f32, } -impl Component for Vel { +impl Component for Move { type Storage = VecStorage; } -struct Pos { - x: f32, - y: f32 +pub struct Geom { + size_x: f32, + size_y: f32, + rotation: f32, + depth: f32, } -impl Component for Pos { +impl Component for Geom { type Storage = VecStorage; } @@ -91,34 +95,37 @@ struct RenderSystem; impl<'a> System<'a> for RenderSystem { type SystemData = ( - WriteStorage<'a, Pos>, - WriteStorage<'a, Vel>, + WriteStorage<'a, Move>, + WriteStorage<'a, Geom>, WriteStorage<'a, Draws>, Write<'a, PersistentState>, Write<'a, VkProcessor>, ); - fn run(&mut self, (mut pos, vel, mut draw, mut state, mut vk_processor): Self::SystemData) { + fn run(&mut self, (mut mv, mut geom, mut draw, mut state, mut vk_processor): Self::SystemData) { state.canvas_frame = CanvasFrame::new(state.window_size); state.compu_frame = CompuFrame::new(state.window_size); // compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1); // compu_frame.add(compute_buffer.clone(), compute_kernel.clone()); - - - for (vel, pos, draw) in (&vel, &mut pos, &mut draw).join() { - pos.x += vel.x * state.delta_time; - pos.y += vel.y * state.delta_time; - - draw.0.position = (pos.x, pos.y); - + for (mv, geom, draw) in (&mut mv, &mut geom, &mut draw).join() { + mv.pos_x += mv.vel_x * state.delta_time; + mv.pos_y += mv.vel_y * state.delta_time; + + let window_size = state.window_size.clone(); + state.canvas_frame.add(draw.0.get( + window_size, + (mv.pos_x, mv.pos_y), + geom.rotation, + (geom.size_x, geom.size_y), + geom.depth, + )); } - for draw_data in (&draw).join() { let size = state.window_size.clone(); - state.canvas_frame.add(draw_data.0.get(size)) + } vk_processor.run(&state.surface.clone().unwrap(), @@ -128,10 +135,28 @@ impl<'a> System<'a> for RenderSystem { } +struct EventSystem; + +impl<'a> System<'a> for EventSystem { + type SystemData = ( + WriteStorage<'a, Draws>, + Write<'a, PersistentState>, + Write<'a, VkProcessor>, + ); + + fn run(&mut self, (mut draw, mut state, mut vk_processor): Self::SystemData) { + + for draw_data in (&draw).join() { + draw_data.1.notify() + } + } +} + + pub fn main() { - hprof::start_frame(); + //hprof::start_frame(); + //let g = hprof::enter("vulkan preload"); - let q1 = hprof::enter("setup"); let instance = { let extensions = vulkano_win::required_extensions(); @@ -149,17 +174,12 @@ pub fn main() { .build_vk_surface(&events_loop, instance.clone()).unwrap(); let mut processor = VkProcessor::new(instance.clone(), surface.clone()); + processor.create_swapchain(instance.clone(), surface.clone()); + processor.preload_kernels(); + processor.preload_shaders(); + processor.preload_textures(); + processor.preload_fonts(); - { - let g = hprof::enter("vulkan preload"); - processor.create_swapchain(instance.clone(), surface.clone()); - processor.preload_kernels(); - processor.preload_shaders(); - processor.preload_textures(); - processor.preload_fonts(); - } - - let q2 = hprof::enter("Game Objects"); let mut timer = Timer::new(); let mut frame_future: Box = @@ -175,12 +195,13 @@ pub fn main() { let image_data = load_raw(String::from("ford2.jpg")); let image_dimensions_f: (f32, f32) = ((image_data.1).clone().0 as f32, (image_data.1).clone().1 as f32); let image_dimensions_u: (u32, u32) = image_data.1; + + let compu_sprite1: CompuSprite = CompuSprite::new((-1.0, -1.0), (1.0, 1.0), 0, image_dimensions_f, // Swap image to render the result to. Must match dimensions processor.new_swap_image(image_dimensions_u)); - // Need to let compute_buffer: Arc = processor.new_compute_buffer(image_data.0.clone(), image_data.1, 4); @@ -196,25 +217,10 @@ pub fn main() { processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap(); let sfml_handle: Arc = processor.get_texture_handle(String::from("sfml.png")).unwrap(); - //let font_handle : Arc = - // processor.get_font_handle(String::from("sansation.ttf")).unwrap(); - - - // So I would have to go full in on the ECS in order to do rendering... - - // That would probably look like a canvasFrame and compuFrame component which would - // be added to the world. - - // Though canvasFrame and compuFrame have to share the command_buffer - // which means I should just keep the vk processor lol - - // The `World` is our - // container for components - // and other resources. let mut world = World::new(); - world.register::(); - world.register::(); + world.register::(); + world.register::(); world.register::(); world.insert::(processor); world.insert::(PersistentState { @@ -225,31 +231,35 @@ pub fn main() { compu_frame: CompuFrame::new((0, 0)), }); + + let thing = Box::new(Sprite::new(funky_handle.clone())); + // An entity may or may not contain some component. world.create_entity() - .with(Vel { x: 0.0, y: 0.0 }) - .with(Pos{ x: 0.0, y: 0.0 }) - .with(Draws( - Sprite::new( - (200.0, 200.0), - (100.0, 150.0), 10, funky_handle.clone()))) + .with(Move { vel_x: 0.0, vel_y: 0.0, pos_x: 100.0, pos_y: 400.0 }) + .with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0 }) + .with(Draws(thing.clone(), thing.clone())) .build(); - let mut dispatcher = DispatcherBuilder::new() - // .with(SysA, "sys_a", &[]) - .with(RenderSystem, "render_s", &[]).build(); - - - let sfml_sprite = Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone()); - - let slider = Slider::new((300.0, 50.0), (550.0, 100.0), 30000); + world.create_entity() + .with(Move { vel_x: 0.0, vel_y: 0.0, pos_x: 100.0, pos_y: 400.0 }) + .with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0 }) + .with(Draws(thing.clone(), thing)) + .build(); + let thing2 = Box::new(Slider::new((300.0, 50.0), (550.0, 100.0), 30000)); - drop(q2); - drop(q1); + world.create_entity() + .with(Move { vel_x: 0.0, vel_y: 0.0, pos_x: 100.0, pos_y: 400.0 }) + .with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0 }) + .with(Draws(thing2.clone(), thing2)) + .build(); - let l = hprof::enter("Loop"); + // call the run method for the following systems & deps + let mut dispatcher = DispatcherBuilder::new() + // .with(SysA, "sys_a", &[]) + .with(RenderSystem, "render_s", &[]).build(); let event_loop_proxy = events_loop.create_proxy(); @@ -286,47 +296,16 @@ pub fn main() { }); - // What would the component for a sprite be... - // Drawable with the vertex format in one rendering system - // position + velocity could then be two more in one system - // maybe some sort of input system - - // - // let mut big_container = vec![ - // Box::new(Slider::new((0.1, 0.1), (0.9, 0.9), 5000)), - // Box::new(Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone())), - // ]; - //container.push(Sprite::new((0.1))); - - // Events loop is borrowed from the surface events_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Poll; - // for eventable in &mut big_container { - // eventable.notify(&event); - // } - // - // for drawable in &mut big_container { - // canvas_frame.draw(&drawable); - // } - match event { Event::NewEvents(cause) => { if cause == StartCause::Init { world.write_resource::() .window_size = surface.window().inner_size().into(); } - elapsed_time = timer.elap_time(); - delta_time = elapsed_time - current_time; - current_time = elapsed_time; - if delta_time > 0.02 { - delta_time = 0.02; - } - accumulator_time += delta_time; - // This dispatches all the systems in parallel (but blocking). - world.write_resource::().delta_time = delta_time; - dispatcher.dispatch(&mut world); } Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { *control_flow = ControlFlow::Exit @@ -334,7 +313,8 @@ pub fn main() { Event::WindowEvent { event: WindowEvent::Resized(new_size), .. } => { world.write_resource::() .swapchain_recreate_needed = true; - let size = (new_size.width, new_size.height); + world.write_resource::() + .window_size = (new_size.width, new_size.height); } Event::WindowEvent { event: WindowEvent::MouseInput { @@ -368,6 +348,17 @@ pub fn main() { } Event::MainEventsCleared => { + elapsed_time = timer.elap_time(); + delta_time = elapsed_time - current_time; + current_time = elapsed_time; + if delta_time > 0.02 { + delta_time = 0.02; + } + accumulator_time += delta_time; + + // This dispatches all the systems in parallel (but blocking). + world.write_resource::().delta_time = delta_time; + dispatcher.dispatch(&mut world); // while (accumulator_time - step_size) >= step_size { // accumulator_time -= step_size; @@ -392,22 +383,12 @@ pub fn main() { // } }); - drop(l); - hprof::end_frame(); - hprof::profiler().print_timing(); + // hprof::end_frame(); + // hprof::profiler().print_timing(); } -pub fn click_test(event_loop_proxy: EventLoopProxy, canvas_state: &CanvasState) { - // for i in canvas_state. { - // event_loop_proxy.send_event(TrEvent::MouseClickEvent { - // position: (0.0, 0.0), - // button: MouseButton::Left, - // }).ok(); - // } -} -