lots of refactoring
This commit is contained in:
284
src/canvas.rs
284
src/canvas.rs
@@ -15,11 +15,12 @@ use vulkano::descriptor::DescriptorSet;
|
||||
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
|
||||
use std::path::PathBuf;
|
||||
use image::GenericImageView;
|
||||
use crate::util::compute_image::ComputeImage;
|
||||
use std::iter::FromIterator;
|
||||
use vulkano::swapchain::Capabilities;
|
||||
use winit::Window;
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::descriptor::descriptor::DescriptorDescTy::TexelBuffer;
|
||||
use crate::canvas_frame::CanvasFrame;
|
||||
|
||||
// Canvas is the accumulator of Sprites for drawing
|
||||
|
||||
@@ -85,87 +86,73 @@ pub enum ShaderType {
|
||||
IMAGE = 2,
|
||||
}
|
||||
|
||||
pub struct CanvasFrame {
|
||||
colored_drawables: Vec<ColoredVertex2D>,
|
||||
textured_drawables: HashMap<Arc<u32>, Vec<Vec<Vertex2D>>>,
|
||||
image_drawables: HashMap<Arc<u32>, Vec<Vec<Vertex2D>>>,
|
||||
}
|
||||
|
||||
impl CanvasFrame {
|
||||
|
||||
pub fn new() -> CanvasFrame {
|
||||
CanvasFrame {
|
||||
colored_drawables: vec![],
|
||||
textured_drawables: Default::default(),
|
||||
image_drawables: Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulates the drawables vertices and colors
|
||||
pub fn draw(&mut self, drawable: &dyn Drawable) {
|
||||
|
||||
match drawable.get_texture_handle() {
|
||||
Some(handle) => {
|
||||
self.textured_drawables
|
||||
.entry(handle.clone())
|
||||
.or_insert(Vec::new())
|
||||
.push(drawable.get_vertices().iter().map(|n|
|
||||
Vertex2D {
|
||||
position: [n.0, n.1],
|
||||
}
|
||||
).collect::<Vec<Vertex2D>>());
|
||||
}
|
||||
None => {
|
||||
|
||||
match drawable.get_image_handle() {
|
||||
|
||||
Some(handle) => {
|
||||
self.image_drawables
|
||||
.entry(handle.clone())
|
||||
.or_insert(Vec::new())
|
||||
.push(drawable.get_vertices().iter().map(|n|
|
||||
Vertex2D {
|
||||
position: [n.0, n.1],
|
||||
}
|
||||
).collect());
|
||||
}
|
||||
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],
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Canvas {
|
||||
shader_kernels: HashMap<ShaderType, ShaderKernels>,
|
||||
pub struct TextureHandle {
|
||||
handle: u32
|
||||
}
|
||||
|
||||
texture_store: HashMap<String, Arc<ImmutableImage<Format>>>,
|
||||
#[derive(Clone)]
|
||||
pub struct ImageHandle {
|
||||
handle: u32
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ShaderHandle {
|
||||
handle: u32
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CanvasTexture {
|
||||
handle: Arc<TextureHandle>,
|
||||
buffer: Arc<ImmutableImage<Format>>,
|
||||
name: String,
|
||||
size: (u32, u32),
|
||||
}
|
||||
|
||||
impl CanvasTexture {
|
||||
fn get_descriptor_set(&mut self,
|
||||
shader: Arc<ShaderKernels>,
|
||||
sampler: Arc<Sampler>) -> Box<dyn DescriptorSet + Send + Sync> {
|
||||
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
|
||||
PersistentDescriptorSet::start(
|
||||
shader.clone().get_pipeline().clone(), 0,
|
||||
)
|
||||
.add_sampled_image(self.buffer.clone(), sampler.clone()).unwrap()
|
||||
.build().unwrap());
|
||||
o
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CanvasImage {
|
||||
handle: Arc<ImageHandle>,
|
||||
buffer: Arc<AttachmentImage>,
|
||||
size: (u32, u32),
|
||||
}
|
||||
|
||||
impl CanvasImage {
|
||||
fn get_descriptor_set(&mut self, shader: Arc<ShaderKernels>)
|
||||
-> Box<dyn DescriptorSet + Send + Sync> {
|
||||
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
|
||||
PersistentDescriptorSet::start(
|
||||
shader.clone().get_pipeline().clone(), 0,
|
||||
)
|
||||
.add_image(self.buffer.clone()).unwrap()
|
||||
.build().unwrap());
|
||||
o
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CanvasState {
|
||||
dynamic_state: DynamicState,
|
||||
sampler: Arc<Sampler>,
|
||||
|
||||
// hold the image, texture, and shader buffers the same was as we do CompuState
|
||||
image_buffers: Vec<std::sync::Arc<vulkano::image::attachment::AttachmentImage>>,
|
||||
image_buffer_handles: Vec<Arc<u32>>,
|
||||
|
||||
texture_buffers: Vec<Arc<ImmutableImage<Format>>>,
|
||||
texture_buffer_handles: Vec<Arc<u32>>,
|
||||
|
||||
shader_buffers: HashMap<ShaderType, ShaderKernels>,
|
||||
shader_buffer_handles: Vec<Arc<u32>>,
|
||||
image_buffers: Vec<Arc<CanvasImage>>,
|
||||
texture_buffers: Vec<Arc<CanvasTexture>>,
|
||||
shader_buffers: HashMap<String, ShaderKernels>,
|
||||
|
||||
// Hold onto the vertices we get from the Compu and Canvas Frames
|
||||
// When the run comes around, push the vertices to the GPU
|
||||
@@ -184,11 +171,10 @@ pub struct Canvas {
|
||||
}
|
||||
|
||||
|
||||
impl Canvas {
|
||||
|
||||
impl CanvasState {
|
||||
// This method is called once during initialization, then again whenever the window is resized
|
||||
pub fn window_size_dependent_setup(&mut self, images: &[Arc<SwapchainImage<Window>>])
|
||||
-> Vec<Arc<dyn FramebufferAbstract + Send + Sync>> {
|
||||
-> Vec<Arc<dyn FramebufferAbstract + Send + Sync>> {
|
||||
let dimensions = images[0].dimensions();
|
||||
|
||||
self.dynamic_state.viewports =
|
||||
@@ -200,7 +186,7 @@ impl Canvas {
|
||||
|
||||
images.iter().map(|image| {
|
||||
Arc::new(
|
||||
Framebuffer::start(self.shader_kernels.get(&ShaderType::SOLID).unwrap().render_pass.clone())
|
||||
Framebuffer::start(self.shader_kernels.get(String::from("color-passthrough")).unwrap().render_pass.clone())
|
||||
.add(image.clone()).unwrap()
|
||||
.build().unwrap()
|
||||
) as Arc<dyn FramebufferAbstract + Send + Sync>
|
||||
@@ -211,31 +197,24 @@ impl Canvas {
|
||||
pub fn new(queue: Arc<Queue>,
|
||||
device: Arc<Device>,
|
||||
physical: PhysicalDevice,
|
||||
capabilities: Capabilities) -> Canvas {
|
||||
|
||||
capabilities: Capabilities) -> CanvasState {
|
||||
let solid_color_kernel = String::from("color-passthrough");
|
||||
let texture_kernel = String::from("simple_texture");
|
||||
|
||||
let shader_kernels : HashMap<ShaderType, ShaderKernels> = HashMap::from_iter(vec![
|
||||
let shader_kernels: HashMap<ShaderType, ShaderKernels> = HashMap::from_iter(vec![
|
||||
(ShaderType::SOLID, ShaderKernels::new(solid_color_kernel, capabilities.clone(), queue.clone(), physical.clone(), device.clone())),
|
||||
(ShaderType::TEXTURED, ShaderKernels::new(texture_kernel, capabilities.clone(), queue.clone(), physical.clone(), device.clone()))
|
||||
]);
|
||||
|
||||
|
||||
Canvas {
|
||||
shader_kernels: Default::default(),
|
||||
texture_store: Default::default(),
|
||||
|
||||
CanvasState {
|
||||
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
|
||||
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(),
|
||||
image_buffers: vec![],
|
||||
image_buffer_handles: vec![],
|
||||
texture_buffers: vec![],
|
||||
texture_buffer_handles: vec![],
|
||||
shader_buffers: Default::default(),
|
||||
shader_buffer_handles: vec![],
|
||||
|
||||
colored_drawables: vec![],
|
||||
colored_vertex_buffer: vec![],
|
||||
@@ -249,20 +228,24 @@ impl Canvas {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<u32> {
|
||||
self.image_buffers.push(
|
||||
AttachmentImage::with_usage(
|
||||
pub fn create_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<ImageHandle> {
|
||||
let image = CanvasImage {
|
||||
handle: Arc::new(ImageHandle { handle: self.image_buffers.len() as u32 + 1 }),
|
||||
buffer: AttachmentImage::with_usage(
|
||||
self.device.clone(),
|
||||
[dimensions.0, dimensions.1],
|
||||
Format::R8G8B8A8Uint,
|
||||
usage).unwrap());
|
||||
let id = Arc::new(self.image_buffers.len() as u32);
|
||||
self.image_buffer_handles.push(id.clone());
|
||||
id
|
||||
usage).unwrap(),
|
||||
size: dimensions,
|
||||
};
|
||||
let handle = image.handle.clone();
|
||||
self.image_buffers.push(Arc::new(image));
|
||||
handle
|
||||
}
|
||||
|
||||
pub fn get_image(&self, image_handle: Arc<u32>) -> std::sync::Arc<vulkano::image::attachment::AttachmentImage> {
|
||||
self.image_buffers.get((*image_handle).clone() as usize).unwrap().clone()
|
||||
pub fn get_image(&self, image_handle: Arc<ImageHandle>) -> Arc<AttachmentImage> {
|
||||
self.image_buffers.get((*image_handle).clone() as usize).unwrap()
|
||||
.clone().buffer.clone()
|
||||
}
|
||||
|
||||
// TODO Handle file not found gracefully
|
||||
@@ -307,25 +290,24 @@ impl Canvas {
|
||||
texture
|
||||
}
|
||||
|
||||
pub fn load_texture_from_filename(&mut self, filename: String) -> Arc<ImmutableImage<Format>> {
|
||||
if self.texture_store.contains_key(&filename.clone()) {
|
||||
println!("{} Already exists, not going to replace it.", filename.clone());
|
||||
self.texture_store.get(&filename.clone()).unwrap().clone()
|
||||
} else {
|
||||
let texture = self.get_texture_from_file(filename.clone());
|
||||
self.texture_store.insert(filename, texture.clone());
|
||||
texture
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_texture(&mut self, filename: String) -> Option<Arc<u32>> {
|
||||
pub fn load_texture(&mut self, filename: String) -> Option<Arc<TextureHandle>> {
|
||||
let texture_buffer = self.get_texture_from_file(filename.clone());
|
||||
self.texture_buffers.push(texture_buffer.clone());
|
||||
let id = Arc::new(self.texture_buffers.len() as u32);
|
||||
self.texture_buffer_handles.push(id.clone());
|
||||
Some(id)
|
||||
}
|
||||
|
||||
let handle = Arc::new(TextureHandle {
|
||||
handle: self.texture_buffers.len() as u32 + 1
|
||||
});
|
||||
|
||||
let texture = Arc::new(CanvasTexture {
|
||||
handle: handle.clone(),
|
||||
buffer: self.get_texture_from_file(filename.clone()),
|
||||
name: "".to_string(),
|
||||
size: (0, 0),
|
||||
});
|
||||
|
||||
self.texture_buffers.push(texture);
|
||||
|
||||
Some(handle)
|
||||
}
|
||||
|
||||
// After done using this, need to call allocated vertex buffers
|
||||
pub fn draw(&mut self, canvas_frame: CanvasFrame) {
|
||||
@@ -336,26 +318,20 @@ impl Canvas {
|
||||
self.allocate_vertex_buffers(self.device.clone());
|
||||
}
|
||||
|
||||
fn get_texture(&self, texture_id: String) -> Arc<ImmutableImage<Format>> {
|
||||
if let Some(i) = self.texture_store.get(&texture_id) {
|
||||
return i.clone();
|
||||
} else {
|
||||
panic!("{} : Texture not loaded", texture_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocate_vertex_buffers(&mut self, device: Arc<Device>) {
|
||||
fn allocate_vertex_buffers(&mut self, device: Arc<Device>) {
|
||||
self.colored_vertex_buffer.clear();
|
||||
self.textured_vertex_buffer.clear();
|
||||
self.image_vertex_buffer.clear();
|
||||
|
||||
|
||||
//TODO should probably use cpu accessible buffer instead of recreating immutes each frame
|
||||
// CpuAccessibleBuffer::from_iter(
|
||||
// device.clone(),
|
||||
// BufferUsage::vertex_buffer(),
|
||||
// self.colored_drawables.iter().cloned(),
|
||||
// ).unwrap().0;
|
||||
/*
|
||||
CpuAccessibleBuffer::from_iter(
|
||||
|
||||
device.clone(),
|
||||
BufferUsage::vertex_buffer(),
|
||||
self.colored_drawables.iter().cloned(),
|
||||
).unwrap().0;
|
||||
*/
|
||||
|
||||
self.colored_vertex_buffer.push(
|
||||
ImmutableBuffer::from_iter(
|
||||
@@ -377,46 +353,24 @@ impl Canvas {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_solid_color_descriptor_set(&self) -> Box<dyn DescriptorSet + Send + Sync> {
|
||||
println!("{}", self.shader_kernels.get(&ShaderType::SOLID).unwrap().clone().get_pipeline().clone().num_sets());
|
||||
fn get_texture(&self, texture_id: String) -> Arc<ImmutableImage<Format>> {
|
||||
if let Some(i) = self.texture_store.get(&texture_id) {
|
||||
return i.clone();
|
||||
} else {
|
||||
panic!("{} : Texture not loaded", texture_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_solid_color_descriptor_set(&self, kernel: Arc<ShaderKernels>) -> Box<dyn DescriptorSet + Send + Sync> {
|
||||
|
||||
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
|
||||
PersistentDescriptorSet::start(
|
||||
self.shader_kernels.get(&ShaderType::SOLID).unwrap().clone().get_pipeline().clone(), 0,
|
||||
kernel.clone().get_pipeline().clone(), 0,
|
||||
).build().unwrap());
|
||||
o
|
||||
}
|
||||
|
||||
fn get_textured_descriptor_set(&self, texture_id: String)
|
||||
-> Box<dyn DescriptorSet + Send + Sync> {
|
||||
let o: Box<dyn DescriptorSet + Send + Sync> = 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
|
||||
// I suppose I could just have a general image set maker instead of compue... they are
|
||||
// somewhat similar
|
||||
fn get_compute_swap_descriptor_set(&mut self,
|
||||
device: Arc<Device>,
|
||||
compute_image: &ComputeImage) -> Box<dyn DescriptorSet + Send + Sync> {
|
||||
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<dyn DescriptorSet + Send + Sync> = Box::new(
|
||||
PersistentDescriptorSet::start(
|
||||
self.shader_kernels.get(&ShaderType::IMAGE).clone().unwrap().clone().get_pipeline(), 0,
|
||||
)
|
||||
.add_image(compute_image.clone().get_swap_buffer().clone()).unwrap()
|
||||
.build().unwrap());
|
||||
o
|
||||
}
|
||||
|
||||
pub fn draw_commands(&self,
|
||||
mut command_buffer: AutoCommandBufferBuilder,
|
||||
framebuffers: Vec<Arc<dyn FramebufferAbstract + Send + Sync>>,
|
||||
@@ -447,9 +401,7 @@ impl Canvas {
|
||||
// vec![self.get_textured_descriptor_set(String::from("funky-bird.jpg"))], ()
|
||||
// ).unwrap();
|
||||
}
|
||||
ShaderType::IMAGE => {
|
||||
|
||||
}
|
||||
ShaderType::IMAGE => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,8 +409,6 @@ impl Canvas {
|
||||
.end_render_pass()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user