diff --git a/src/canvas.rs b/src/canvas.rs index 781d0806..442cd43b 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -2,7 +2,7 @@ use crate::vertex_2d::{ColoredVertex2D, Vertex2D}; use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState}; use crate::Sprite; use std::collections::HashMap; -use vulkano::buffer::{BufferAccess, CpuAccessibleBuffer, BufferUsage}; +use vulkano::buffer::{BufferAccess, CpuAccessibleBuffer, BufferUsage, ImmutableBuffer}; use std::sync::Arc; use vulkano::format::{ClearValue, Format}; use vulkano::framebuffer::FramebufferAbstract; @@ -111,13 +111,14 @@ pub trait Drawable { // Need three types of shaders. Solid, Textured, Compute -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, Clone)] pub enum ShaderType { SOLID = 0, TEXTURED = 1, COMPUTE = 2 } +#[derive(Clone)] pub struct Canvas { colored_drawables : Vec, @@ -126,9 +127,6 @@ pub struct Canvas { textured_drawables: HashMap>, textured_vertex_buffer: HashMap>, - - vertex_buffers: Vec>, - shader_kernels: HashMap, texture_store: HashMap>>, @@ -161,8 +159,6 @@ impl Canvas { textured_drawables: Default::default(), textured_vertex_buffer: Default::default(), - vertex_buffers: vec![], - shader_kernels: shader_kernels, texture_store: Default::default(), @@ -235,8 +231,15 @@ impl Canvas { match drawable.get_texture_id() { Some(id) => { - // This dont work - self.textured_drawables.get(&id).unwrap(); + self.textured_drawables + .entry(id) + .or_insert(Vec::new()) + .extend(drawable.get_vertices().iter().map(|n| + Vertex2D { + position: [n.0, n.1], + } + )); + }, None => { let colors = drawable.get_color(); @@ -254,74 +257,58 @@ impl Canvas { } - fn get_texture(&mut self, texture_id: String) -> Arc> { + fn get_texture(&self, texture_id: String) -> Arc> { if let Some(i) = self.texture_store.get(&texture_id) { return i.clone(); } else { - self.load_texture_from_filename(texture_id) + panic!("{} : Texture not loaded", texture_id); } } + pub fn allocate_vertex_buffers(&mut self, device: Arc) { - pub fn allocate_colored_vertex_buffers(&mut self, device: Arc) { - - self.vertex_buffers.clear(); self.colored_vertex_buffer.clear(); - - self.vertex_buffers.push( - CpuAccessibleBuffer::from_iter( - device.clone(), - BufferUsage::vertex_buffer(), - self.colored_drawables.iter().cloned() - ).unwrap() - ); + self.textured_vertex_buffer.clear(); self.colored_vertex_buffer.push( - CpuAccessibleBuffer::from_iter( - device.clone(), + ImmutableBuffer::from_iter( + self.colored_drawables.iter().cloned(), BufferUsage::vertex_buffer(), - self.colored_drawables.iter().cloned() - ).unwrap() + self.queue.clone(), + ).unwrap().0 ); + + for (k, v) in self.textured_drawables.iter() { + self.textured_vertex_buffer.insert( + k.clone(), + ImmutableBuffer::from_iter( + self.textured_drawables.get(k).iter().cloned(), + BufferUsage::vertex_buffer(), + self.queue.clone(), + ).unwrap().0 + ); + } } - // I guess these go out as an array. So I can add multiple descriptor sets + fn get_solid_color_descriptor_set(&self) -> Box { + let o: Box = Box::new( + PersistentDescriptorSet::start( + self.shader_kernels.get(&ShaderType::SOLID).unwrap().clone().get_pipeline().clone(), 0 + ).build().unwrap()); + o + } - // So probably needs to know which shaders are for textures - // needs to associate this descriptor set to a texture (key-pair, tuple) - // - - // So this is fine for now. But I want to be able to: - // Choose which texture I want to add to this descriptor set. - // Add multiple textures - // Choose which shader and pipeline it should run on - - fn get_descriptor_set(&mut self, - shader_type: &ShaderType, - texture_id: String) -> Box { - - match shader_type { - ShaderType::SOLID => { - let o: Box = Box::new( - PersistentDescriptorSet::start( - self.shader_kernels.get(&shader_type).unwrap().clone().get_pipeline().clone(), 0 - ).build().unwrap()); - o - }, - ShaderType::TEXTURED => { - let o: Box = Box::new( - PersistentDescriptorSet::start( - self.shader_kernels.get(&shader_type).unwrap().clone().get_pipeline().clone(), 0 - ) - .add_sampled_image(self.get_texture(texture_id), self.sampler.clone()).unwrap() - .build().unwrap()); - o - }, - ShaderType::COMPUTE => { - unimplemented!("Compute dont work here"); - }, - } + fn get_textured_descriptor_set(&self, texture_id: String) + -> Box { + + let o: Box = Box::new( + PersistentDescriptorSet::start( + self.shader_kernels.get(&ShaderType::TEXTURED).unwrap().clone().get_pipeline().clone(), 0 + ) + .add_sampled_image(self.get_texture(texture_id), self.sampler.clone()).unwrap() + .build().unwrap()); + o } // This is the image which is written to by the write compute buffer @@ -345,10 +332,7 @@ impl Canvas { } - /* - - So I need the image set in order to get my texture or compute texture Done @@ -369,14 +353,13 @@ impl Canvas { I just need to add a third option on sprite and allow it to have a swap buffer - */ - pub fn draw_commands(&mut self, - command_buffer: AutoCommandBufferBuilder, + pub fn draw_commands(&self, + command_buffer: &mut AutoCommandBufferBuilder, framebuffers: Vec>, - image_num: usize) -> AutoCommandBufferBuilder { + image_num: usize) { // Specify the color to clear the framebuffer with i.e. blue let clear_values = vec!(ClearValue::Float([0.0, 0.0, 1.0, 1.0])); @@ -388,34 +371,29 @@ impl Canvas { ).unwrap(); - // So I need to do this without borrowing self from the shader_kernels.... - // Maybe self referential struct issue cropping up - // - // - // - // - // - // - // - // - - for (shader_type, kernel) in self.shader_kernels.iter() { - command_buffer = command_buffer.draw( - kernel.clone().get_pipeline().clone(), - &dynamic_state.clone(), self.vertex_buffers.clone(), - vec![self.get_descriptor_set(shader_type, String::from("texture"))], () - ).unwrap(); + for (shader_type, kernel) in self.shader_kernels.clone().iter() { + match shader_type { + ShaderType::SOLID => { + command_buffer = command_buffer.draw( + kernel.clone().get_pipeline().clone(), + &dynamic_state.clone(), self.colored_vertex_buffer.clone(), + vec![self.get_solid_color_descriptor_set()], () + ).unwrap(); + }, + ShaderType::TEXTURED => { + command_buffer = command_buffer.draw( + kernel.clone().get_pipeline().clone(), + &dynamic_state.clone(), self.colored_vertex_buffer.clone(), + vec![self.get_textured_descriptor_set(String::from("funky-bird"))], () + ).unwrap(); + }, + ShaderType::COMPUTE => {}, + } } -// -// .draw(self.shader_kernels.clone().unwrap().get_pipeline(), -// &dynamic_state.clone(), self.vertex_buffers, -// vec![self.get_gui_image_set()], ()) -// .unwrap(); -// - command_buffer + command_buffer = command_buffer .end_render_pass() - .unwrap() + .unwrap(); } } diff --git a/src/main.rs b/src/main.rs index 0b1c325f..fe37b217 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,6 +46,7 @@ use winit::{EventsLoop, WindowBuilder, WindowEvent, Event, DeviceEvent, VirtualK use winit::dpi::LogicalSize; use vulkano_win::VkSurfaceBuild; use sprite::Sprite; +use crate::canvas::Canvas; mod util; @@ -138,7 +139,7 @@ fn main() { } - frame_future = processor.run(&surface, frame_future); + (frame_future) = processor.run(&surface, frame_future); } } diff --git a/src/vkprocessor.rs b/src/vkprocessor.rs index ebe6ce47..e0d445d3 100644 --- a/src/vkprocessor.rs +++ b/src/vkprocessor.rs @@ -45,7 +45,8 @@ use crate::util::compute_image::ComputeImage; use vulkano::descriptor::descriptor::DescriptorDesc; use crate::vertex_2d::ColoredVertex2D; - +use crate::canvas::Canvas; +use std::mem; /// This method is called once during initialization, then again whenever the window is resized @@ -99,7 +100,8 @@ pub struct VkProcessor<'a> { swapchain_recreate_needed: bool, - capabilities: Capabilities + capabilities: Capabilities, + canvas: Canvas, } @@ -107,8 +109,6 @@ impl<'a> VkProcessor<'a> { pub fn new(instance: &'a Arc, surface: &'a Arc>) -> VkProcessor<'a> { - - let physical = PhysicalDevice::enumerate(instance).next().unwrap(); let queue_family = physical.queue_families().find(|&q| { @@ -126,11 +126,13 @@ impl<'a> VkProcessor<'a> { [(queue_family, 0.5)].iter().cloned()).unwrap(); let queue = queues.next().unwrap(); + let capabilities = surface.capabilities(physical).unwrap(); + VkProcessor { instance: instance.clone(), physical: physical.clone(), device: device.clone(), - queue: queue, + queue: queue.clone(), queues: queues, dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None }, shader_kernels: None, @@ -142,7 +144,8 @@ impl<'a> VkProcessor<'a> { swapchain: None, swapchain_images: None, swapchain_recreate_needed: false, - capabilities: surface.capabilities(physical).unwrap() + capabilities: capabilities.clone(), + canvas: Canvas::new(queue, device, physical, capabilities) } } @@ -346,7 +349,10 @@ impl<'a> VkProcessor<'a> { - pub fn run(&mut self, surface: &'a Arc>, mut frame_future: Box) -> Box { + pub fn run(&mut self, + surface: &'a Arc>, + mut frame_future: Box, + ) -> Box { let mut framebuffers = window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone(), self.shader_kernels.clone().unwrap().render_pass.clone(), @@ -397,26 +403,20 @@ impl<'a> VkProcessor<'a> { .get_descriptor_set(self.compute_kernel.clone().unwrap().clone().get_pipeline()).clone(), ()).unwrap() .copy_buffer_to_image(self.compute_image.clone().unwrap().clone().rw_buffers.get(0).unwrap().clone(), - self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap() + self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap(); - .begin_render_pass(framebuffers[image_num].clone(), false, clear_values.clone()) - .unwrap() - .draw(self.shader_kernels.clone().unwrap().get_pipeline(), - &self.dynamic_state.clone(), v, - vec![self.get_image_set()], ()) - .unwrap(); + /* + Fuck. So this is a problem... - command_buffer = command_buffer.draw(self.shader_kernels.clone().unwrap().get_pipeline(), - &self.dynamic_state.clone(), v2, - vec![self.get_gui_image_set()], ()) - .unwrap(); + I can't replace canvas. + */ - let command_buffer = command_buffer - .end_render_pass() - .unwrap() + self.canvas.draw_commands(&mut command_buffer, framebuffers, image_num); + + //self.canvas = mem::replace(&mut self.canvas, - .build().unwrap(); + let command_buffer = command_buffer.build().unwrap(); // Wait on the previous frame, then execute the command buffer and present the image let future = frame_future.join(acquire_future)