@ -17,6 +17,9 @@ use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use std ::path ::PathBuf ;
use std ::path ::PathBuf ;
use image ::GenericImageView ;
use image ::GenericImageView ;
use crate ::util ::compute_image ::ComputeImage ;
use crate ::util ::compute_image ::ComputeImage ;
use std ::iter ::FromIterator ;
use vulkano ::swapchain ::Capabilities ;
use shaderc ::TargetEnv ;
// Canvas is the accumulator of Sprites for drawing
// Canvas is the accumulator of Sprites for drawing
// Needs to know:
// Needs to know:
@ -107,27 +110,8 @@ pub trait Drawable {
/*
OASIJDOQIWEJFOWIEJFOWIEJFOWEIJFOIWEJFOIW
Right now I ' m in the middle of adding texture ownership to the canvas .
I ' m aiming at being able to load them on the fly from what texture name ( String ) the
sprite is requesting . This might be too slow though as I can ' t really avoid a lookup table
somewhere in the code .
* /
// Need three types of shaders. Solid, Textured, Compute
// Need three types of shaders. Solid, Textured, Compute
#[ derive(PartialEq) ]
#[ derive(PartialEq, Eq, Hash) ]
#[ derive(Eq) ]
#[ derive(Hash) ]
pub enum ShaderType {
pub enum ShaderType {
SOLID = 0 ,
SOLID = 0 ,
TEXTURED = 1 ,
TEXTURED = 1 ,
@ -137,31 +121,61 @@ pub enum ShaderType {
pub struct Canvas {
pub struct Canvas {
colored_drawables : Vec < ColoredVertex2D > ,
colored_drawables : Vec < ColoredVertex2D > ,
colored_vertex_buffer : Vec < Arc < ( dyn BufferAccess + std ::marker ::Send + std ::marker ::Sync + ' static ) > > ,
textured_drawables : HashMap < String , Vec < Vertex2D > > ,
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 ) > > ,
vertex_buffers : Vec < Arc < ( dyn BufferAccess + std ::marker ::Send + std ::marker ::Sync + ' static ) > > ,
shader_kernels : HashMap < ShaderType , ShaderKernels > ,
shader_kernels : HashMap < ShaderType , ShaderKernels > ,
textures : Vec < Arc < ImmutableImage < Format > > > ,
texture_store : HashMap < String , Arc < ImmutableImage < Format > > > ,
// Looks like we gotta hold onto the queue for managing textures
queue : Arc < Queue > ,
sampler : Arc < Sampler >
}
}
impl Canvas {
impl Canvas {
// needs to take in the texture list
// needs to take in the texture list
pub fn new ( ) -> Canvas {
pub fn new ( queue : Arc < Queue > ,
device : Arc < Device > ,
physical : PhysicalDevice ,
capabilities : Capabilities ) -> Canvas {
let solid_color_kernel = String ::from ( "color-passthrough" ) ;
let texture_kernel = String ::from ( "simple_texture" ) ;
let shader_kernels = 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 {
Canvas {
colored_drawables : vec ! [ ] ,
colored_drawables : vec ! [ ] ,
colored_vertex_buffer : vec ! [ ] ,
textured_drawables : Default ::default ( ) ,
textured_drawables : Default ::default ( ) ,
textured_vertex_buffer : Default ::default ( ) ,
vertex_buffers : vec ! [ ] ,
vertex_buffers : vec ! [ ] ,
shader_kernels : HashMap ::new ( ) ,
shader_kernels : shader_kernels ,
textures : vec ! [ ]
texture_store : Default ::default ( ) ,
queue : queue . clone ( ) ,
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 ( ) ,
}
}
}
}
fn get_texture_from_file ( image_filename : String , queue : Arc < Queue > ) -> Arc < ImmutableImage < Format > > {
// TODO Handle file not found gracefully
fn get_texture_from_file ( & self , image_filename : String ) -> Arc < ImmutableImage < Format > > {
let project_root =
let project_root =
std ::env ::current_dir ( )
std ::env ::current_dir ( )
@ -197,20 +211,26 @@ impl Canvas {
image_buffer . iter ( ) . cloned ( ) ,
image_buffer . iter ( ) . cloned ( ) ,
Dimensions ::Dim2d { width : xy . 0 , height : xy . 1 } ,
Dimensions ::Dim2d { width : xy . 0 , height : xy . 1 } ,
Format ::R8G8B8A8Srgb ,
Format ::R8G8B8A8Srgb ,
queue . clone ( )
self . queue . clone ( )
) . unwrap ( ) ;
) . unwrap ( ) ;
texture
texture
}
}
pub fn load_texture_from_filename ( & mut self , filename : String , queue : Arc < Queue > ) {
pub fn load_texture_from_filename ( & mut self , filename : String ) -> Arc < ImmutableImage < Format > > {
let texture = Canvas ::get_texture_from_file ( filename . clone ( ) , queue . clone ( ) ) ;
self . textures . push ( texture ) ;
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
}
let texture1 = Canvas ::get_texture_from_file ( String ::from ( "button.png" ) , queue . clone ( ) ) ;
self . textures . push ( texture1 ) ;
}
}
// After done using this, need to call allocated vertex buffers
pub fn draw ( & mut self , drawable : & dyn Drawable ) {
pub fn draw ( & mut self , drawable : & dyn Drawable ) {
match drawable . get_texture_id ( ) {
match drawable . get_texture_id ( ) {
@ -234,8 +254,20 @@ impl Canvas {
}
}
fn get_texture ( & mut 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 )
}
}
pub fn allocate_colored_vertex_buffers ( & mut self , device : Arc < Device > ) {
pub fn allocate_vertex_buffers ( & mut self , device : Arc < Device > ) {
self . vertex_buffers . clear ( ) ;
self . colored_vertex_buffer . clear ( ) ;
self . vertex_buffers . push (
self . vertex_buffers . push (
CpuAccessibleBuffer ::from_iter (
CpuAccessibleBuffer ::from_iter (
@ -244,6 +276,14 @@ impl Canvas {
self . colored_drawables . iter ( ) . cloned ( )
self . colored_drawables . iter ( ) . cloned ( )
) . unwrap ( )
) . unwrap ( )
) ;
) ;
self . colored_vertex_buffer . push (
CpuAccessibleBuffer ::from_iter (
device . clone ( ) ,
BufferUsage ::vertex_buffer ( ) ,
self . colored_drawables . iter ( ) . cloned ( )
) . unwrap ( )
) ;
}
}
// I guess these go out as an array. So I can add multiple descriptor sets
// I guess these go out as an array. So I can add multiple descriptor sets
@ -256,22 +296,37 @@ impl Canvas {
// Choose which texture I want to add to this descriptor set.
// Choose which texture I want to add to this descriptor set.
// Add multiple textures
// Add multiple textures
// Choose which shader and pipeline it should run on
// Choose which shader and pipeline it should run on
fn get_texture_descriptor_set ( & mut self , device : Arc < Device > ) -> Box < dyn DescriptorSet + Send + Sync > {
let sampler = Sampler ::new ( device . clone ( ) , Filter ::Linear , Filter ::Linear ,
fn get_descriptor_set ( & mut self ,
MipmapMode ::Nearest , SamplerAddressMode ::Repeat , SamplerAddressMode ::Repeat ,
shader_type : & ShaderType ,
SamplerAddressMode ::Repeat , 0.0 , 1.0 , 0.0 , 0.0 ) . unwrap ( ) ;
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 (
let o : Box < dyn DescriptorSet + Send + Sync > = Box ::new (
PersistentDescriptorSet ::start (
PersistentDescriptorSet ::start (
self . shader_kernels . get ( & ShaderType ::TEXTURED ) . unwrap ( ) . clone ( ) . get_pipeline ( ) , 0
self . shader_kernels . get ( & shader_type ) . unwrap ( ) . clone ( ) . get_pipeli ne( ) . clo ne( ) , 0
)
)
. add_sampled_image ( self . textures . get ( 0 ) . unwrap ( ) . clone ( ) , sampler . clone ( ) ) . unwrap ( )
. add_sampled_image ( self . get_texture( texture_id ) , self . sampler . clone ( ) ) . unwrap ( )
. build ( ) . unwrap ( ) ) ;
. build ( ) . unwrap ( ) ) ;
o
o
} ,
ShaderType ::COMPUTE = > {
unimplemented! ( "Compute dont work here" ) ;
} ,
}
}
}
// The image set is the containing object for all texture and image hooks.
// 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 ,
fn get_compute_swap_descriptor_set ( & mut self ,
device : Arc < Device > ,
device : Arc < Device > ,
compute_image : & ComputeImage ) -> Box < dyn DescriptorSet + Send + Sync > {
compute_image : & ComputeImage ) -> Box < dyn DescriptorSet + Send + Sync > {
@ -290,6 +345,7 @@ impl Canvas {
}
}
/*
/*
@ -331,13 +387,26 @@ impl Canvas {
framebuffers [ image_num ] . clone ( ) , false , clear_values . clone ( )
framebuffers [ image_num ] . clone ( ) , false , clear_values . clone ( )
) . unwrap ( ) ;
) . unwrap ( ) ;
// for i in self.shader_kernels {
// command_buffer = command_buffer.draw(
// So I need to do this without borrowing self from the shader_kernels....
// i.clone().unwrap().get_pipeline(),
// Maybe self referential struct issue cropping up
// &dynamic_state.clone(), self.vertex_buffers,
//
// vec![self.get_image_set()], ()
//
// ).unwrap();
//
// }
//
//
//
//
//
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 ( ) ;
}
//
//
// .draw(self.shader_kernels.clone().unwrap().get_pipeline(),
// .draw(self.shader_kernels.clone().unwrap().get_pipeline(),
// &dynamic_state.clone(), self.vertex_buffers,
// &dynamic_state.clone(), self.vertex_buffers,
@ -349,3 +418,33 @@ impl Canvas {
. unwrap ( )
. unwrap ( )
}
}
}
}