From 3f14555c992454fe9ff6538a457eb697b75ff8c7 Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Fri, 30 Aug 2019 00:50:45 -0700 Subject: [PATCH] texturing works, next will be images --- resources/shaders/simple_texture.fragment | 2 + src/canvas.rs | 49 +++++++-- src/canvas_shader.rs | 121 +++++++++++++++++++++- src/compu_state.rs | 10 +- src/main.rs | 8 +- src/sprite.rs | 2 +- src/vkprocessor.rs | 2 +- 7 files changed, 178 insertions(+), 16 deletions(-) diff --git a/resources/shaders/simple_texture.fragment b/resources/shaders/simple_texture.fragment index d38a0c5e..e8ead073 100644 --- a/resources/shaders/simple_texture.fragment +++ b/resources/shaders/simple_texture.fragment @@ -15,4 +15,6 @@ void main() { // f_color.rgb = pow(f_color.rgb, vec3(1.0/gamma)); f_color = texture(tex, tex_coords); + float gamma = 0.5; + f_color.rgb = pow(f_color.rgb, vec3(1.0/gamma)); } \ No newline at end of file diff --git a/src/canvas.rs b/src/canvas.rs index 1f3df7d3..d6f79370 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -112,7 +112,7 @@ pub struct CanvasTexture { } impl CanvasTexture { - fn get_descriptor_set(&mut self, + fn get_descriptor_set(&self, shader: Arc, sampler: Arc) -> Box { let o: Box = Box::new( @@ -153,7 +153,7 @@ pub struct CanvasState { // hold the image, texture, and shader buffers the same was as we do CompuState image_buffers: Vec>, texture_buffers: Vec>, - shader_buffers: HashMap, + shader_buffers: HashMap>, // Hold onto the vertices we get from the Compu and Canvas Frames // When the run comes around, push the vertices to the GPU @@ -211,17 +211,17 @@ impl CanvasState { image_buffers: vec![], texture_buffers: vec![], shader_buffers: HashMap::from_iter(vec![ - (solid_color_kernel.clone(), CanvasShader::new(solid_color_kernel.clone(), + (solid_color_kernel.clone(), Arc::new(CanvasShader::new_colored(solid_color_kernel.clone(), capabilities.clone(), queue.clone(), physical.clone(), - device.clone()) + device.clone())) ), - (texture_kernel.clone(), CanvasShader::new(texture_kernel.clone(), + (texture_kernel.clone(), Arc::new(CanvasShader::new_textured(texture_kernel.clone(), capabilities.clone(), queue.clone(), physical.clone(), - device.clone()) + device.clone())) ), ]), @@ -313,7 +313,7 @@ impl CanvasState { let texture = Arc::new(CanvasTexture { handle: handle.clone(), buffer: self.get_texture_from_file(filename.clone()), - name: "".to_string(), + name: filename.clone(), size: (0, 0), }); @@ -322,7 +322,18 @@ impl CanvasState { Some(handle) } - fn get_texture(&self, texture_handle: Arc) + pub fn get_texture_handle(&self, texture_name: String) + -> Option> { + + for i in self.texture_buffers.clone() { + if i.name == texture_name { + return Some(i.handle.clone()); + } + } + None + } + + pub fn get_texture(&self, texture_handle: Arc) -> Arc> { let handle = texture_handle.handle as usize; @@ -367,10 +378,11 @@ impl CanvasState { ); for (k, v) in self.textured_drawables.drain() { + println!("{:?}", v.len()); self.textured_vertex_buffer.insert( k.clone(), ImmutableBuffer::from_iter( - v.iter().cloned(), + v.first().unwrap().iter().cloned(), BufferUsage::vertex_buffer(), self.queue.clone(), ).unwrap().0, @@ -409,6 +421,25 @@ impl CanvasState { (), (), ).unwrap(); + + // Images + let mut shader = self.shader_buffers.get("simple_texture").unwrap().clone(); + + + let handle = self.get_texture_handle(String::from("funky-bird.jpg")).unwrap().clone(); + + let descriptor_set = self.texture_buffers.first().clone().unwrap().clone() + .get_descriptor_set(shader.clone(), self.sampler.clone()); + + let vertex_buffer = self.textured_vertex_buffer.get(&handle).unwrap().clone(); + + println!("{:?}", self.texture_buffers.len()); + command_buffer = command_buffer.draw( + shader.get_pipeline().clone(), + &self.dynamic_state.clone(), vec![vertex_buffer], + vec![descriptor_set], () + ).unwrap(); + /*for (shader_type, kernel) in self.shader_kernels.clone().iter() { match shader_type { ShaderType::SOLID => { diff --git a/src/canvas_shader.rs b/src/canvas_shader.rs index c2baee17..9ff3475c 100644 --- a/src/canvas_shader.rs +++ b/src/canvas_shader.rs @@ -8,7 +8,7 @@ use shade_runner as sr; use vulkano::framebuffer::{Subpass, RenderPassAbstract, Framebuffer, FramebufferAbstract}; use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, SpecializationConstants, SpecializationMapEntry}; use vulkano::swapchain::{Capabilities}; -use crate::vertex_2d::ColoredVertex2D; +use crate::vertex_2d::{ColoredVertex2D, Vertex2D}; /* @@ -51,7 +51,7 @@ impl CanvasShader { self.graphics_pipeline.clone().unwrap() } - pub fn new(filename: String, + pub fn new_colored(filename: String, capabilities: Capabilities, queue: Arc, physical: PhysicalDevice, @@ -168,6 +168,123 @@ impl CanvasShader { } } + pub fn new_textured(filename: String, + capabilities: Capabilities, + queue: Arc, + physical: PhysicalDevice, + device: Arc) -> CanvasShader { + + let format = capabilities.supported_formats[0].0; + + let filenames = CanvasShader::get_path(filename.clone()); + + // TODO: better compile message, run til successful compile + let shader = sr::load(filenames.0, filenames.1) + .expect("Shader didn't compile"); + + let vulkano_entry = + sr::parse(&shader) + .expect("failed to parse"); + + let fragment_shader_module: Arc = unsafe { + let filenames1 = CanvasShader::get_path(filename.clone()); + let shader1 = sr::load(filenames1.0, filenames1.1) + .expect("Shader didn't compile"); + vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &shader1.fragment.clone()) + }.unwrap(); + + let vertex_shader_module: Arc = unsafe { + let filenames1 = CanvasShader::get_path(filename.clone()); + let shader1 = sr::load(filenames1.0, filenames1.1) + .expect("Shader didn't compile"); + vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &shader1.vertex.clone()) + }.unwrap(); + + let filenames = CanvasShader::get_path(filename.clone()); + + + let frag_entry_point = unsafe { + Some(fragment_shader_module.graphics_entry_point(CStr::from_bytes_with_nul_unchecked(b"main\0"), + vulkano_entry.frag_input, + vulkano_entry.frag_output, + vulkano_entry.frag_layout, + GraphicsShaderType::Fragment)) + }; + + let vertex_entry_point = unsafe { + Some(vertex_shader_module.graphics_entry_point(CStr::from_bytes_with_nul_unchecked(b"main\0"), + vulkano_entry.vert_input, + vulkano_entry.vert_output, + vulkano_entry.vert_layout, + GraphicsShaderType::Vertex)) + }; + + + let render_pass = Arc::new(vulkano::single_pass_renderpass!( + device.clone(), + + // Attachments are outgoing like f_color + attachments: { + // `color` is a custom name we give to the first and only attachment. + color: { + // `load: Clear` means that we ask the GPU to clear the content of this + // attachment at the start of the drawing. + load: Clear, + // `store: Store` means that we ask the GPU to store the output of the draw + // in the actual image. We could also ask it to discard the result. + store: Store, + // `format: ` indicates the type of the format of the image. This has to + // be one of the types of the `vulkano::format` module (or alternatively one + // of your structs that implements the `FormatDesc` trait). Here we use the + // same format as the swapchain. + format: format, + // TODO: + samples: 1, + } + }, + pass: { + // We use the attachment named `color` as the one and only color attachment. + color: [color], + //color: [], + // No depth-stencil attachment is indicated with empty brackets. + depth_stencil: {} + } + ).unwrap()); + + + CanvasShader { + + graphics_pipeline: Some(Arc::new(GraphicsPipeline::start() + + .vertex_input_single_buffer::() + + .vertex_shader(vertex_entry_point.clone().unwrap(), ShaderSpecializationConstants { + first_constant: 0, + second_constant: 0, + third_constant: 0.0, + }) + + .triangle_list() + // Use a resizable viewport set to draw over the entire window + .viewports_dynamic_scissors_irrelevant(1) + + .fragment_shader(frag_entry_point.clone().unwrap(), ShaderSpecializationConstants { + first_constant: 0, + second_constant: 0, + third_constant: 0.0, + }) + // We have to indicate which subpass of which render pass this pipeline is going to be used + // in. The pipeline will only be usable from this particular subpass. + .render_pass(Subpass::from(render_pass.clone(), 0).unwrap()) + + .build(device.clone()) + .unwrap())), + + device: device, + render_pass: render_pass, + } + } + } #[repr(C)] diff --git a/src/compu_state.rs b/src/compu_state.rs index d47eb91a..d1be3203 100644 --- a/src/compu_state.rs +++ b/src/compu_state.rs @@ -101,8 +101,10 @@ impl CompuState { let p = kernel.clone().get_pipeline(); let d = buffer.get_descriptor_set(kernel.clone().get_pipeline()); + let size = buffer.get_size(); + command_buffer = command_buffer - .dispatch([100,100,1], p, d, ()).unwrap() + .dispatch([size.0,size.1,1], p, d, ()).unwrap() } // i = (Buffer, Image, Kernel) @@ -118,6 +120,12 @@ impl CompuState { let p = kernel.clone().get_pipeline(); let d = buffer.get_descriptor_set(kernel.clone().get_pipeline()); + let dimensions = image.dimensions(); + let dimensions = (dimensions[0], dimensions[1]); + if dimensions != buffer.get_size() { + panic!("Buffer sizes not the same"); + } + command_buffer = command_buffer .dispatch([100,100,1], p, d, ()).unwrap() .copy_buffer_to_image(buffer.get_input_buffer(), image).unwrap(); diff --git a/src/main.rs b/src/main.rs index 2d0d7a2a..0d37a8fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,7 +91,9 @@ fn main() { let sprite = Sprite::new_with_color((0.,0.), (0.1,0.1), (1.,0.,0.,1.)); let sprite2 = Sprite::new_with_color((-1.,-0.5), (0.1,0.1), (0.,1.,0.,1.)); - let compu_sprite1 = CompuSprite::new((-1.,-0.5), (0.1,0.1), processor.new_swap_image((300, 300))); + let compu_sprite1 = CompuSprite::new((-1.,-0.5), (0.1,0.1), + // This swap image needs to match the size of the compute + processor.new_swap_image((720, 756))); let image_data = load_raw(String::from("funky-bird.jpg")); let compute_buffer = processor.new_compute_buffer(image_data.0, image_data.1, 4); @@ -99,8 +101,9 @@ fn main() { let compute_kernel = processor.get_kernel_handle(String::from("simple-edge.compute")) .expect("Can't find that kernel"); + let handle = processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap(); - + let sprite3 = Sprite::new_with_texture((0.3, 0.5), (0.1,0.1), handle.clone()); while let Some(p) = window.get_position() { @@ -158,6 +161,7 @@ fn main() { let mut canvas = CanvasFrame::new(); canvas.draw(&sprite); canvas.draw(&sprite2); + canvas.draw(&sprite3); canvas.draw(&compu_sprite1); (frame_future) = processor.run(&surface, frame_future, diff --git a/src/sprite.rs b/src/sprite.rs index 154123ec..480ffc91 100644 --- a/src/sprite.rs +++ b/src/sprite.rs @@ -60,7 +60,7 @@ impl Sprite { position: position, size: size, color: (0.0, 0.0, 0.0, 0.0), - textured: false, + textured: true, texture_handle: Some(texture_handle.clone()) } } diff --git a/src/vkprocessor.rs b/src/vkprocessor.rs index 15f43196..df046fca 100644 --- a/src/vkprocessor.rs +++ b/src/vkprocessor.rs @@ -146,7 +146,7 @@ impl<'a> VkProcessor<'a> { } pub fn get_texture_handle(&self, texture_name: String) -> Option> { - None + self.canvas.get_texture_handle(texture_name) } pub fn get_kernel_handle(&self, kernel_name: String) -> Option> { self.compute_state.get_kernel_handle(kernel_name)