|
|
|
@ -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<ColoredVertex2D>,
|
|
|
|
@ -126,9 +127,6 @@ pub struct Canvas {
|
|
|
|
|
textured_drawables: HashMap<String, Vec<Vertex2D>>,
|
|
|
|
|
textured_vertex_buffer: HashMap<String, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertex_buffers: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
|
|
|
|
|
|
|
|
|
|
shader_kernels: HashMap<ShaderType, ShaderKernels>,
|
|
|
|
|
|
|
|
|
|
texture_store: HashMap<String, Arc<ImmutableImage<Format>>>,
|
|
|
|
@ -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<ImmutableImage<Format>> {
|
|
|
|
|
fn get_texture(&self, texture_id: String) -> Arc<ImmutableImage<Format>> {
|
|
|
|
|
|
|
|
|
|
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<Device>) {
|
|
|
|
|
|
|
|
|
|
pub fn allocate_colored_vertex_buffers(&mut self, device: Arc<Device>) {
|
|
|
|
|
|
|
|
|
|
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<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
|
|
|
|
|
).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<dyn DescriptorSet + Send + Sync> {
|
|
|
|
|
|
|
|
|
|
match shader_type {
|
|
|
|
|
ShaderType::SOLID => {
|
|
|
|
|
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
|
|
|
|
|
PersistentDescriptorSet::start(
|
|
|
|
|
self.shader_kernels.get(&shader_type).unwrap().clone().get_pipeline().clone(), 0
|
|
|
|
|
).build().unwrap());
|
|
|
|
|
o
|
|
|
|
|
},
|
|
|
|
|
ShaderType::TEXTURED => {
|
|
|
|
|
let o: Box<dyn DescriptorSet + Send + Sync> = 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<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
|
|
|
|
@ -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<Arc<dyn FramebufferAbstract + Send + Sync>>,
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|