From c5b3c29ad478e9dc5b093a50dd3568a9ab35b030 Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Tue, 6 Aug 2019 23:23:36 -0700 Subject: [PATCH] in the midst of a very messy refactor of the way i build the command buffer --- resources/images/button.png | Bin 0 -> 10502 bytes src/canvas.rs | 281 +++++++++++++++++++- src/main.rs | 6 +- src/sprite.rs | 94 ++++++- src/util.rs | 34 --- src/{vkprocessor => util}/compute_image.rs | 0 src/{vkprocessor => util}/compute_kernel.rs | 0 src/util/mod.rs | 3 + src/{vkprocessor => util}/shader_kernels.rs | 0 src/vertex_2d.rs | 11 +- src/vertex_3d.rs | 6 +- src/vkprocessor.rs | 50 ++-- 12 files changed, 400 insertions(+), 85 deletions(-) create mode 100644 resources/images/button.png delete mode 100644 src/util.rs rename src/{vkprocessor => util}/compute_image.rs (100%) rename src/{vkprocessor => util}/compute_kernel.rs (100%) create mode 100644 src/util/mod.rs rename src/{vkprocessor => util}/shader_kernels.rs (100%) diff --git a/resources/images/button.png b/resources/images/button.png new file mode 100644 index 0000000000000000000000000000000000000000..fe1cd4aaf72d68b947cb1d7d6f337c64e2031d52 GIT binary patch literal 10502 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

VaZ+Y+Y-&W58+a(nXBypbrO z+{w}Q-5k)MJBzPK5}8fxp(}P@*6unYNQJ@;qmSwoC~H_>5ZX6dnIAF$nOhePN6XSr zDpFUkUgh#i0CV@!{27Kz?PWGJ zJA2Fb(w`st(1&`SU<#00c1wpzg1IZ=dcF2NJVjeuRELd?c%~jt(B2+cjO(#&)^z;m zKmRd#vKDoObWInphm&&e)8;jsf}5MN@@h%s$S5@Vg3On+U4SV`xlS_KBpHMRRr;xc ztyZgE6PJ>nIoIuIep^TSJq4uRB6vToji)wA+jSg-GXKWQtOA?hqvH;8<;%a6fDD{L{I@Y-I zVVmNfOm`}+B+QIgoA6yM+GbzRo$k03;)^f7I1EEI_+_WQ*)*$&LO?a!b;7 z5Yiz7Q4qdlu)2UyEEK3#C`NT;m3bcX~p1x#kC6;gba z=!1ieQg5;95+;ffb#whv0Y6WaZv?#kB7xiRxU z{_zh|Dc0dFwFR+Z0#cKh3__=0)@0zClT8fQEXKE!8H6wZBqh2@gj<@`b_ePOLz9Ux zHEE6{cU7gIsNLbDt|V&ug=$Q^gGM`wVi<099#>&2ce^Wz;kXYPx83SPB1XPsmfcPj z{9B&WEC2uqa7jc#RAGL_fELg-XT1q)5n<+eNNZG4Ev5lfq zYnt0(Pmykc8O@Y_gYZqgOBf)JkDKslFTy&sUmJ`{AI0Pu?!3sN*rYzOY%x@9dPE=jaiyT%^|qy zk8Ew~ZN@ca(Y3QVJ24x0Y$iIJ2gIEn)3O-bnKWrLV8@#_gE>vHYqH@sHeJ)UfJcRuXW_ zpgIf>-P+TK*~!Dv$_ok^`7;VGrDQnTDJk(dH#wF2&czkf<`(4ykm3c%M_Ge z7>D}R9(ITtyDUIA6U=ckKiJ|TJkv@i#6>X#N5LxCBry^$s*Dmzl^9e>g}#2cogpz0 zcRY2l^vO#4PNNF)E#>jMi!sIO(zD!I#&{*7; zCjqIpIIlg#$Xz9H;nu=@(be#jHTBv4-+)fW_&8^|!CwYtjl1gMq&(R+JW5f{{#)#j zVQf29ORwhGT;m=aXUL2eFkeMaZ4*u?_NUKfD44!y6g;$!C6ZvAkvhcyh}kvQk`|dP1NetkIy4*%FI4^vS*ZDZ zE>d7`Z?96aDowBQ>dPw}uw6hgs4SkAAf{AVSDDoL&HZzwDQ%L3y(nHRCTZq%CBbcJ zXJmAnp-cwvGH=JsrR}h#5o#wlQ*y@el~}MQl&qwsjM8K?D};Uz!!i^;m5$L>6a&TN z&;#auu~_Wv?9ltO*cP4P0rkPwB1_JomPMT)E?ytjV-uMr-;)T#44IZJO^hL8Vkx4! zCRERfr=H8g^At*=uGGHGTo*|R_b$vJbY`)dfwq7W@hG*j7|P~u@u#FgG zjw{uYMcI-`Z>GRg$&m=`C2UdgNc5AMY9^T_1=>`f%`m*B>`5ren@g%_1jR}yAl(d9 zAMjWv_+r@UuayO4f(^+}IUU7^9q9})jz&Q-RZD3UETv`OeIjhqD}pfG(_{)Vp_EB& z$w6d{x#zl*ZUguWHJe2)*ZL82(XXZ3#3D98X~RmV8Ny=19S03(CUR zk}V-B4Mo3~tY`-xA*xbWb*57P68|c;$VN9Zi)58VpES24%!JbBdbOse<{2=oX~;bj ztW9rOgvv(6HN%bsCQ_7pdjyMwCgWvfsfDG@AEY~pew;7*d{AZ#gL&gUak5U6A|1N{0lf^F(d(rz7cSZV&+`YFk5@2Gt zcP?lyed0&;2+{OwD%gmErw7??IISA>L660QQ;xi>} zhGrx~QZTA+W&BH8T|NN|R~X^p0GiDRnl&@@pUZ%n>&L1_OC+)cR7$gT`I7nIjFQ|k zL)lAa=jQFrYCeYKMSNsC2~p7GimhsmFHn&Z2@S(;mPBd4F#C_zgBFufYBK(Zg@F0aBCyrZS!FjcA7Q^~3`tSXv-fq&8yv?g05CaB^53xNhsF-|{G<^TWy07*qo IM6N<$f;0E5DF6Tf literal 0 HcmV?d00001 diff --git a/src/canvas.rs b/src/canvas.rs index 8c2266d7..fdbb0b90 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -1,5 +1,21 @@ - - +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 std::sync::Arc; +use vulkano::format::{ClearValue, Format}; +use vulkano::framebuffer::FramebufferAbstract; +use vulkano::device::{Device, Queue}; +use vulkano::instance::PhysicalDevice; +use vulkano::image::immutable::ImmutableImage; +use crate::util::shader_kernels::ShaderKernels; +use vulkano::image::{Dimensions, ImageUsage, ImageAccess, ImageDimensions}; +use vulkano::sampler::{Sampler, SamplerAddressMode, MipmapMode, Filter}; +use vulkano::descriptor::DescriptorSet; +use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; +use std::path::PathBuf; +use image::GenericImageView; // Canvas is the accumulator of Sprites for drawing // Needs to know: @@ -12,34 +28,283 @@ If it is textured. It needs to be rendered with the texture shader which requires a separate graphics pipeline. Might as well have a new render pass as well. -Need to pull recreate swapchain out of shader_kernels.rs - I need a second version of shaderkernels +So framebuffer is tied to the swapchains images as well as the renderpass + +it appears that renderpass is tied to the individual shader + + +*/ + +// I want to be able to draw 2d sprites. + +// These sprites might be textured or a single color + +// All of the single colors will be grouped into one batch using colored vertices. +// The rest will be grouped by their texture and run individually + + +/* + +vertex count differing is a big nono + +ColoredVertex2D + Non-Textured + +Vertex2D + Textured + +Colored, vs non-colored: + Calling the color() field or not + + + + +I just wanna + + */ +pub trait Vertex { + fn position(&self) -> (f32, f32) { + (0.0,0.0) + } + + fn color(&self) -> Option<(f32, f32, f32, f32)> { + Some((0.,0.,0.,0.)) + } + + fn textured(&self) -> bool { + false + } +} -trait Drawable { - fn draw() { +impl Vertex for ColoredVertex2D { + + fn position(&self) -> (f32, f32) { + (0.0,0.0) + } + + fn color(&self) -> Option<(f32, f32, f32, f32)> { + Some((0.,0.,0.,0.)) + } + + fn textured(&self) -> bool { + false } } +pub trait Drawable { + fn get_vertices(&self) -> Vec<(f32, f32)>; + fn get_color(&self) -> (f32, f32, f32, f32); + fn get_texture_id(&self) -> Option; +} + + + pub struct Canvas { + colored_drawables : Vec, + + textured_drawables: HashMap>, + + vertex_buffers: Vec>, + + shader_kernels: Vec, + textures: Vec>>, } + impl Canvas { + // needs to take in the texture list pub fn new() -> Canvas { - Canvas { + colored_drawables: vec![], + textured_drawables: Default::default(), + vertex_buffers: vec![], + + shader_kernels: Vec::new(), + textures: vec![] } + } + + fn get_texture_from_file(image_filename: String, queue: Arc) -> Arc> { + let project_root = + std::env::current_dir() + .expect("failed to get root directory"); + + let mut compute_path = project_root.clone(); + compute_path.push(PathBuf::from("resources/images/")); + compute_path.push(PathBuf::from(image_filename)); + + let img = image::open(compute_path).expect("Couldn't find image"); + + let xy = img.dimensions(); + + let data_length = xy.0 * xy.1 * 4; + let pixel_count = img.raw_pixels().len(); + + let mut image_buffer = Vec::new(); + + if pixel_count != data_length as usize { + println!("Creating apha channel..."); + for i in img.raw_pixels().iter() { + if (image_buffer.len() + 1) % 4 == 0 { + image_buffer.push(255); + } + image_buffer.push(*i); + } + image_buffer.push(255); + } else { + image_buffer = img.raw_pixels(); + } + + let (texture, tex_future) = ImmutableImage::from_iter( + image_buffer.iter().cloned(), + Dimensions::Dim2d { width: xy.0, height: xy.1 }, + Format::R8G8B8A8Srgb, + queue.clone() + ).unwrap(); + + texture + } + + pub fn load_texture_from_filename(&mut self, filename: String, queue: Arc) { + let texture = Canvas::get_texture_from_file(filename.clone(), queue.clone()); + self.textures.push(texture); + + let texture1 = Canvas::get_texture_from_file(String::from("button.png"), queue.clone()); + self.textures.push(texture1); } - pub fn draw() -> + pub fn draw(&mut self, drawable: &dyn Drawable) { + + match drawable.get_texture_id() { + Some(id) => { + // This dont work + self.textured_drawables.get(&id).unwrap(); + }, + None => { + let colors = drawable.get_color(); + + self.colored_drawables.extend( + drawable.get_vertices().iter().map(|n| + ColoredVertex2D { + position: [n.0, n.1], + color: [colors.0, colors.1, colors.2, colors.3] + } + ) + ); + } + } + } + + + + pub fn allocate_vertex_buffers(&mut self, device: Arc) { + + self.vertex_buffers.push( + CpuAccessibleBuffer::from_iter( + device.clone(), + BufferUsage::vertex_buffer(), + self.colored_drawables.iter().cloned() + ).unwrap() + ); + } + + // The image set is the containing object for all texture and image hooks. + fn get_texture_set(&mut self, device: Arc) -> Box { + + let sampler = Sampler::new(device.clone(), Filter::Linear, Filter::Linear, + MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, + SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(); + + let o : Box = Box::new( + PersistentDescriptorSet::start( + self.shader_kernels.get(0).unwrap().clone().unwrap().get_pipeline(), 0 + ) + .add_sampled_image(self.textures.get(0).unwrap().clone(), sampler.clone()).unwrap() + .build().unwrap()); + o + } + + // The image set is the containing object for all texture and image hooks. + fn get_compute_swap_set(&mut self, device: Arc) -> Box { + + let sampler = Sampler::new(device.clone(), Filter::Linear, Filter::Linear, + MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, + SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(); + + let o : Box = Box::new( + PersistentDescriptorSet::start( + self.shader_kernels.get(0).unwrap().clone().unwrap().get_pipeline(), 0 + ) + .add_image(self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap() + .build().unwrap()); + o + } + + + /* + + + So I need the image set in order to get my texture or compute texture + + compute image currently holds the set for compute and its swap buffer + + vkprocessor creates the image sets for draw calls + + takes the pipeline from the ShaderKernel + adds vk processor owned texture + adds compute image taken from the ComputeImage + + we have shaderkernel in here so thats fine + Who should own the texture? + I would need to borrow it each time I created an image set... + These are tied very closely to the input output of a shader, which we would own + + + 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, + framebuffers: Vec>, + image_num: usize) -> AutoCommandBufferBuilder { + + // 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])); + + let dynamic_state = DynamicState { line_width: None, viewports: None, scissors: None }; + + let mut command_buffer = command_buffer.begin_render_pass( + framebuffers[image_num].clone(), false, clear_values.clone() + ).unwrap(); + +// for i in self.shader_kernels { +// command_buffer = command_buffer.draw( +// i.clone().unwrap().get_pipeline(), +// &dynamic_state.clone(), self.vertex_buffers, +// vec![self.get_image_set()], () +// ).unwrap(); +// } +// +// .draw(self.shader_kernels.clone().unwrap().get_pipeline(), +// &dynamic_state.clone(), self.vertex_buffers, +// vec![self.get_gui_image_set()], ()) +// .unwrap(); +// + command_buffer + .end_render_pass() + .unwrap() + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 663f2d65..0b1c325f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,15 +47,17 @@ use winit::dpi::LogicalSize; use vulkano_win::VkSurfaceBuild; use sprite::Sprite; +mod util; + mod slider; mod timer; mod input; mod vkprocessor; -mod util; mod button; mod vertex_2d; mod vertex_3d; mod sprite; +mod canvas; fn main() { @@ -87,10 +89,8 @@ fn main() { let mut mouse_xy = Vector2i::new(0,0); - Sprite::new_with_color((0.,0.), (0,0), (0.,0.,0.,0.)); - while let Some(p) = window.get_position() { elapsed_time = timer.elap_time(); diff --git a/src/sprite.rs b/src/sprite.rs index a43ff910..49f376ff 100644 --- a/src/sprite.rs +++ b/src/sprite.rs @@ -1,9 +1,18 @@ use crate::vertex_2d::ColoredVertex2D; +use crate::canvas::Drawable; #[derive(Debug, Clone)] pub struct Sprite { - vertices: [ColoredVertex2D; 6], - color: [f32; 4], + pub vertices: [(f32, f32); 6], + + position: (f32, f32), + size: (u32, u32), + color: (f32, f32, f32, f32), + + textured: bool, + texture_id: i32, + + } impl Sprite { @@ -14,21 +23,80 @@ impl Sprite { pub fn new_with_color(position: (f32, f32), size: (u32, u32), color: (f32, f32, f32, f32)) -> Sprite { - let size = (size.0 as f32, size.1 as f32); - - let color = [color.0, color.1, color.2, color.3]; + let fsize = (size.0 as f32, size.1 as f32); Sprite { vertices: [ - ColoredVertex2D { position: [ position.0, position.1 ], color }, // top left - ColoredVertex2D { position: [ position.0, position.1 + size.1], color }, // bottom left - ColoredVertex2D { position: [ position.0 + size.0, position.1 + size.1 ], color }, // bottom right - - ColoredVertex2D { position: [ position.0, position.1 ], color }, // top left - ColoredVertex2D { position: [ position.0 + size.0, position.1 + size.1 ], color }, // bottom right - ColoredVertex2D { position: [ position.0 + size.0, position.1 ], color }, // top right + (position.0, position.1 ), // top left + (position.0, position.1 + fsize.1), // bottom left + (position.0 + fsize.0, position.1 + fsize.1 ), // bottom right + (position.0, position.1 ), // top left + (position.0 + fsize.0, position.1 + fsize.1 ), // bottom right + (position.0 + fsize.0, position.1 ), // top right ], + + position: position, + size: size, color: color, + textured: false, + texture_id: 0 + } + } + + pub fn new_with_texture(position: (f32, f32), size: (u32, u32), texture_id: i32) -> Sprite { + + let fsize = (size.0 as f32, size.1 as f32); + + Sprite { + vertices: [ + (position.0, position.1 ), // top left + (position.0, position.1 + fsize.1), // bottom left + (position.0 + fsize.0, position.1 + fsize.1 ), // bottom right + (position.0, position.1 ), // top left + (position.0 + fsize.0, position.1 + fsize.1 ), // bottom right + (position.0 + fsize.0, position.1 ), // top right + ], + position, + size, + color: (0.0, 0.0, 0.0, 0.0), + textured: false, + texture_id } } -} \ No newline at end of file + + + +} + +impl Drawable for Sprite { + fn get_vertices(&self) -> Vec<(f32,f32)> { + self.vertices.to_vec() + } + + fn get_color(&self) -> (f32, f32, f32, f32) { + self.color.clone() + } + + fn get_texture_id(&self) -> Option { + match self.textured { + true => { + Some(self.texture_id.clone()) + }, + false => None, + } + } +} + +/* + + let vertex_buffer = { + + CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), [ + ColoredVertex2D { position: [ 1.0, 1.0 ], color }, + ColoredVertex2D { position: [ 1.0, 0.5 ], color }, + ColoredVertex2D { position: [ 0.5, 0.5 ], color }, + ColoredVertex2D { position: [ 0.5, 1.0 ], color }, + ].iter().cloned()).unwrap() + }; + +*/ \ No newline at end of file diff --git a/src/util.rs b/src/util.rs deleted file mode 100644 index e8c2a924..00000000 --- a/src/util.rs +++ /dev/null @@ -1,34 +0,0 @@ -//use crate::error::CompileError; -//use shaderc::{IncludeType, ResolvedInclude}; -//use shaderc::{ShaderKind, CompileOptions}; -//use std::fs::File; -//use std::io::Read; -//use std::path::{Path, PathBuf}; -// -// -// -//pub fn compile(path: T, shader_kind: ShaderKind) -> Result, CompileError> -// where -// T: AsRef, -//{ -// // TODO Probably shouldn't create this every time. -// let mut compiler = shaderc::Compiler::new().ok_or(CompileError::CreateCompiler)?; -// let mut options = CompileOptions::new().ok_or(CompileError::CreateCompiler)?; -// let mut f = File::open(&path).map_err(CompileError::Open)?; -// let mut src = String::new(); -// f.read_to_string(&mut src).map_err(CompileError::Open)?; -// options.set_include_callback(|path, include_type, folder_path, depth| { -// get_include(path, include_type, folder_path, depth) -// }); -// let result = compiler -// .compile_into_spirv( -// src.as_str(), -// shader_kind, -// path.as_ref().to_str().ok_or(CompileError::InvalidPath)?, -// "main", -// Some(&options), -// ) -// .map_err(CompileError::Compile)?; -// let data = result.as_binary(); -// Ok(data.to_owned()) -//} \ No newline at end of file diff --git a/src/vkprocessor/compute_image.rs b/src/util/compute_image.rs similarity index 100% rename from src/vkprocessor/compute_image.rs rename to src/util/compute_image.rs diff --git a/src/vkprocessor/compute_kernel.rs b/src/util/compute_kernel.rs similarity index 100% rename from src/vkprocessor/compute_kernel.rs rename to src/util/compute_kernel.rs diff --git a/src/util/mod.rs b/src/util/mod.rs new file mode 100644 index 00000000..b9d1e648 --- /dev/null +++ b/src/util/mod.rs @@ -0,0 +1,3 @@ +pub mod compute_image; +pub mod compute_kernel; +pub mod shader_kernels; \ No newline at end of file diff --git a/src/vkprocessor/shader_kernels.rs b/src/util/shader_kernels.rs similarity index 100% rename from src/vkprocessor/shader_kernels.rs rename to src/util/shader_kernels.rs diff --git a/src/vertex_2d.rs b/src/vertex_2d.rs index 92996d70..2bee1a0a 100644 --- a/src/vertex_2d.rs +++ b/src/vertex_2d.rs @@ -10,4 +10,13 @@ pub struct ColoredVertex2D { pub color : [f32; 4], } -vulkano::impl_vertex!(ColoredVertex2D, position, color); \ No newline at end of file +vulkano::impl_vertex!(ColoredVertex2D, position, color); +vulkano::impl_vertex!(Vertex2D, position); + + + +impl From<(f32, f32)> for Vertex2D { + fn from(item: (f32, f32)) -> Self { + Vertex2D { position: [item.0, item.1] } + } +} \ No newline at end of file diff --git a/src/vertex_3d.rs b/src/vertex_3d.rs index ac822cfd..b1afc5b5 100644 --- a/src/vertex_3d.rs +++ b/src/vertex_3d.rs @@ -8,4 +8,8 @@ pub struct Vertex3D { pub struct ColoredVertex3D { position: [f32; 3], color : [u8; 4], -} \ No newline at end of file +} + +vulkano::impl_vertex!(ColoredVertex3D, position, color); +vulkano::impl_vertex!(Vertex3D, position); + diff --git a/src/vkprocessor.rs b/src/vkprocessor.rs index b9fa02c6..5a8f229e 100644 --- a/src/vkprocessor.rs +++ b/src/vkprocessor.rs @@ -35,22 +35,19 @@ use vulkano::image::immutable::ImmutableImage; use vulkano::image::attachment::AttachmentImage; use vulkano::image::{Dimensions, ImageUsage, ImageAccess, ImageDimensions}; use vulkano::format::Format; +use vulkano::format::ClearValue; use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode}; use image::flat::NormalForm::ColumnMajorPacked; -mod compute_kernel; -use crate::vkprocessor::compute_kernel::ComputeKernel; - -mod shader_kernels; -use crate::vkprocessor::shader_kernels::ShaderKernels; - -mod compute_image; -use crate::vkprocessor::compute_image::ComputeImage; +use crate::util::compute_kernel::ComputeKernel; +use crate::util::shader_kernels::ShaderKernels; +use crate::util::compute_image::ComputeImage; use vulkano::descriptor::descriptor::DescriptorDesc; use crate::vertex_2d::ColoredVertex2D; + /// This method is called once during initialization, then again whenever the window is resized fn window_size_dependent_setup( images: &[Arc>], @@ -100,6 +97,8 @@ pub struct VkProcessor<'a> { pub swapchain: Option>>, pub swapchain_images: Option>>>, + swapchain_recreate_needed: bool, + } @@ -137,7 +136,8 @@ impl<'a> VkProcessor<'a> { textures: vec![], compute_image: None, swapchain: None, - swapchain_images: None + swapchain_images: None, + swapchain_recreate_needed: false, } } @@ -176,7 +176,7 @@ impl<'a> VkProcessor<'a> { Swapchain::new(self.device.clone(), surface.clone(), - capabilities.min_image_count, + capabilities.min_image_count, // number of attachment images format, initial_dimensions, 1, // Layers @@ -287,6 +287,9 @@ impl<'a> VkProcessor<'a> { ].iter().cloned()).unwrap() }; + + + self.vertex_buffer = Some(vertex_buffer); self.vertex_buffer2 = Some(vertex_buffer2); @@ -344,20 +347,17 @@ impl<'a> VkProcessor<'a> { self.shader_kernels.clone().unwrap().render_pass.clone(), &mut self.dynamic_state); - let mut recreate_swapchain = false; - // The docs said to call this on each loop. frame_future.cleanup_finished(); // Whenever the window resizes we need to recreate everything dependent on the window size. // In this example that includes the swapchain, the framebuffers and the dynamic state viewport. - if recreate_swapchain { + if self.swapchain_recreate_needed { self.recreate_swapchain(surface); framebuffers = window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone(), self.shader_kernels.clone().unwrap().render_pass.clone(), - //self.render_pass.clone().unwrap().clone(), &mut self.dynamic_state); - recreate_swapchain = false; + self.swapchain_recreate_needed = false; } // This function can block if no image is available. The parameter is an optional timeout @@ -365,15 +365,14 @@ impl<'a> VkProcessor<'a> { let (image_num, acquire_future) = match vulkano::swapchain::acquire_next_image(self.swapchain.clone().unwrap().clone(), None) { Ok(r) => r, Err(AcquireError::OutOfDate) => { - recreate_swapchain = true; - //continue; - panic!("Weird thing"); + self.swapchain_recreate_needed = true; + return Box::new(sync::now(self.device.clone())) as Box<_>; } Err(err) => panic!("{:?}", err) }; // Specify the color to clear the framebuffer with i.e. blue - let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into()); + let clear_values = vec!(ClearValue::Float([0.0, 0.0, 1.0, 1.0])); let mut v = Vec::new(); v.push(self.vertex_buffer.clone().unwrap().clone()); @@ -383,7 +382,7 @@ impl<'a> VkProcessor<'a> { let xy = self.compute_image.clone().unwrap().get_size(); - let command_buffer = + let mut command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family()) .unwrap() @@ -395,19 +394,20 @@ impl<'a> VkProcessor<'a> { .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() - .begin_render_pass(framebuffers[image_num].clone(), false, clear_values) + .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() + .unwrap(); - .draw(self.shader_kernels.clone().unwrap().get_pipeline(), + command_buffer = command_buffer.draw(self.shader_kernels.clone().unwrap().get_pipeline(), &self.dynamic_state.clone(), v2, vec![self.get_gui_image_set()], ()) - .unwrap() + .unwrap(); + let command_buffer = command_buffer .end_render_pass() .unwrap() @@ -424,7 +424,7 @@ impl<'a> VkProcessor<'a> { (Box::new(future) as Box<_>) } Err(FlushError::OutOfDate) => { - recreate_swapchain = true; + self.swapchain_recreate_needed = true; (Box::new(sync::now(self.device.clone())) as Box<_>) } Err(e) => {