Compare commits

...

19 Commits

Author SHA1 Message Date
mitchellhansen c0b1c2e135 petgraph
4 years ago
mitchellhansen 165a90eba1 .
4 years ago
mitchellhansen aaef25f710 how do I make eventing extensible without cluttering this file with standalone functions
4 years ago
mitchellhansen 84999130bb eventing will be slightly harder
4 years ago
mitchellhansen e7bbf1f1db comes together fast when you actually use the library correctly. compute works
4 years ago
mitchellhansen 34b5d7b3d0 rendering works in pure ECS. This is actually pretty sweet. broke compu rendering though
4 years ago
mitchellhansen 76c75c349b This consolidation is not the way to go
4 years ago
mitchellhansen 369a305817 this is a week or so worth of brainstorming. Looking at pulling everything sprite related into it's own little struct. And also doing a message everything arch
4 years ago
mitchellhansen a42d23e5f9 sync
5 years ago
mitchellhansen 28565652c0 events are coming in. But my dual box thingy is not gonna be the way to go here. I guess it copied the data and they no longer link. Bummer
5 years ago
mitchellhansen 9719675465 added event translation
5 years ago
mitchellhansen 2e33c9c75e event system needs some thinkin
5 years ago
mitchellhansen 9eed836083 moves
5 years ago
mitchellhansen f781c76e7e renders
5 years ago
mitchellhansen ccbd21d90b compiles, slowly moving everything over to spec stuff
5 years ago
mitchellhansen c52bdc1441 hulk smashing all these states together for da world
5 years ago
mitchellhansen c10115e7b9 added hello-world example + modified vkproccessor to live inside specs
5 years ago
mitchellhansen b070a7dd32 .
5 years ago
mitchellhansen eac4f8d233 ,
5 years ago

@ -18,6 +18,7 @@ vulkano-win = "0.19.0"
#shade_runner = {version = "0.1.1", git = "https://github.com/MitchellHansen/shade_runner"}
shade_runner = {path = "../shade_runner"}
specs = "0.16.1"
gilrs = "0.7.2"
cgmath = "0.17.0"
simple-stopwatch="0.1.4"
@ -30,4 +31,5 @@ winit = "0.22.0"
#criterion = "0.3.0"
hprof = "0.1.3"
rusttype = { version = "0.7.0", features = ["gpu_cache"] }
vulkano_text = "0.12.0"
vulkano_text = "0.12.0"
petgraph = "0.5.1"

@ -0,0 +1,53 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2020-08-06T21:51:48-07:00
====== MakingAnActualThing ======
Created Thursday 06 August 2020
So, I need to figure out how to determine which objects will :
* Be rendered
* Be notified
* Get batched
* And initialized
Looks like it could possibly be specs...
Sprites currently are just a container for the meta-information needed in order to return a VertexTypeContainer.
{{{code: lang="rust" linenumbers="True"
pub enum VertexTypeContainer {
TextureType(Vec<TextureVertex3D>, Arc<CanvasTextureHandle>),
ImageType(Vec<ImageVertex3D>, Arc<CanvasImageHandle>),
ColorType(Vec<ColorVertex3D>),
ThreeDType(Vec<Vertex3D>),
TextType(Vec<ColorVertex3D>),
}
}}}
So for a sprite, which is a generic texture and position/size combo
Images are similar, but instead of a "sprite" I made a computsprite because that's the only thing that uses them.
Now if I had to shove these into a component / a set of components... I could have a component of the vertex type even?
===== Sep 2020 =====
Lets think about this for a minute...
* We have components which are purely data...
* But can also have structs that impl functionality
* The data can be contained within traits. But it has to do all IO through the trait interface. ALL
* Problem, for example I have primitives like textured sprites, and also complex widgets which also have additional IO they they need. Like text input or buttons. I suppose This could all be made message based. So when the text input receives a focus, and then key presses it would update. When the enter key is pressed it could create a customer event for which another component is the listener...
* Maybe this is the way to go... Have some generic structure that has a render(params), notify(event), update(delta) -> VEvent
* So if I had a textbox sprite it could notify(key events) render
* We can split up components in order to have sharable sets of data for shared functionality. e.g rendering
[[paste]]
So that article more or less talked about what I was thinking with the ECS. But they didn't really go into the separation of components.

@ -0,0 +1,40 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2020-09-09T22:41:18-07:00
====== paste ======
Created Wednesday 09 September 2020
// If I were to have multiple systems
/*
One for rendering
One for updating
One for eventing
Rendering is easy enough. It needs all the components necessary in order
to generate the vertices. This includes the position, size, and vertex generator
Updating can probably be multiple types, I imagine something that implemented an Updatable
trait could then be used.
So the big problem here is that I have two traits that I want to expose, BUT
I have to put the concrete value in both containers... I don't think this is something
that specs will like since it wants to be the only owner. No use in RefCell'ing it
because that's just stupid
What if I turn this on it's head and really embrace the systems. So for example I could have
the User system. Ooof this is a big question actually...
// Components that want to be updated
Move
// want to be drawn
Drawable
Geom
Notifyable
*/

File diff suppressed because one or more lines are too long

@ -6,45 +6,64 @@ use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef;
use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, Handle};
use vulkano::pipeline::vertex::Vertex;
use std::any::Any;
use crate::VertexType;
use crate::{VertexTypeContainer};
use winit::event::Event;
use crate::util::tr_event::{TrEvent, TrUIEvent};
use crate::render_system::Position;
enum CustomEvent {
}
/// Trait which may be inherited by objects that wish to be drawn to the screen
pub trait Drawable {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexType>;
}
/// Trait which may be inherited by objects that wish to receive events
pub trait Eventable<T> {
fn notify(&mut self, event: &Event<T>) -> ();
}
// Render expects the implementer to create custom render logic based on interior data within
// the struct. This data as of right now, will *only* be mutatable via events & update
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer>;
/// Trait which may be inherited by objects that wish to be updated
pub trait Updatable {
fn update(&mut self, delta_time: f32) -> ();
}
/// Accumulator for Vectors of VertexTypes
#[derive(Default)]
pub struct CanvasFrame {
pub map: Vec<VertexType>,
pub map: Vec<VertexTypeContainer>,
window_size: (u32, u32),
}
impl CanvasFrame {
pub fn new(window_size: (u32, u32)) -> CanvasFrame {
CanvasFrame {
map: vec![],
window_size: window_size,
}
}
/// Push this drawable onto the back of the accumulator
pub fn draw(&mut self, drawable: &dyn Drawable) {
for i in drawable.get(self.window_size) {
pub fn add(&mut self, drawable: Vec<VertexTypeContainer>) {
for i in drawable {
self.map.push(i);
}
}
// /// Push this drawable onto the back of the accumulator
// pub fn draw(&mut self, drawable: &dyn Drawable, pos: Position, geom: Geometry) {
// for i in drawable.render(
// self.window_size,
// (mv.pos_x, mv.pos_y),
// geom.rotation,
// (geom.size_x, geom.size_y),
// geom.depth
// ) {
// self.map.push(i);
// }
// }
}

@ -27,24 +27,27 @@ use std::io::Read;
use rusttype::{Font, PositionedGlyph, Scale, Rect, point, GlyphId, Line, Curve, Segment};
use vulkano::pipeline::vertex::{VertexDefinition, Vertex};
use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef;
use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, CompiledShaderHandle, Handle, DrawableHandle};
use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, CompiledShaderHandle, Handle, DrawableHandle, CompuBufferHandle, CompuKernelHandle};
use crate::canvas::managed::gpu_buffers::{CanvasImage, CanvasTexture, CanvasFont};
use crate::canvas::managed::shader::shader_common::CompiledShader;
use crate::canvas::managed::shader::generic_shader::GenericShader;
use crate::VertexType;
use crate::VertexTypeContainer;
use crate::util::vertex::{TextVertex3D, TextureVertex3D, ImageVertex3D, ColorVertex3D, CanvasFrameAllocation};
use shade_runner::Input;
use winit::window::Window;
use crate::canvas::managed::compu_buffer::CompuBuffers;
use crate::canvas::managed::compu_kernel::CompuKernel;
use crate::canvas::compu_frame::CompuFrame;
/// Canvas state is used for storage of texture and image buffers in addition to vertex buffers
/// Canvas state also contains logic for writing the stored buffers to the command_buffer
#[derive(Clone)]
#[derive(Clone, Default)]
pub struct CanvasState {
/// Generated during new()
dynamic_state: DynamicState,
/// Generated during new()
sampler: Arc<Sampler>,
sampler: Option<Arc<Sampler>>,
/// hold the image, texture, and Fonts the same was as we do CompuState
image_buffers: Vec<Arc<CanvasImage>>,
@ -52,12 +55,15 @@ pub struct CanvasState {
font_buffers: Vec<Arc<CanvasFont>>,
/// Compiled Graphics pipelines have a handle which self describe their position in this vector
shader_buffers: Vec<Arc<Box<dyn CompiledShader>>>,
shader_buffers: Vec<Arc<Box<dyn CompiledShader + Send + Sync>>>,
/// Looks like we gotta hold onto the queue for managing textures
queue: Arc<Queue>,
device: Arc<Device>,
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
queue: Option<Arc<Queue>>,
device: Option<Arc<Device>>,
render_pass: Option<Arc<dyn RenderPassAbstract + Send + Sync>>,
compute_buffers: Vec<CompuBuffers>,
kernels: Vec<CompuKernel>,
}
@ -75,11 +81,11 @@ impl CanvasState {
}]);
let dimensions = [dimensions.width(), dimensions.height()];
let depth_buffer = AttachmentImage::transient(self.device.clone(), dimensions, Format::D32Sfloat_S8Uint).unwrap();
let depth_buffer = AttachmentImage::transient(self.device.clone().unwrap(), dimensions, Format::D32Sfloat_S8Uint).unwrap();
images.iter().map(|image| {
Arc::new(
Framebuffer::start(self.render_pass.clone())
Framebuffer::start(self.render_pass.clone().unwrap())
.add(image.clone()).unwrap()
.add(depth_buffer.clone()).unwrap()
.build().unwrap()
@ -133,6 +139,9 @@ impl CanvasState {
CanvasState {
compute_buffers: vec![],
kernels: vec![],
// TODO: Might need to move this
dynamic_state: DynamicState {
line_width: None,
@ -151,20 +160,147 @@ impl CanvasState {
value: 0xFF,
}),
},
sampler: Sampler::new(device.clone(),
sampler: Some(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(),
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap()),
image_buffers: vec![],
texture_buffers: vec![],
shader_buffers: vec![],
font_buffers: vec![],
queue: queue.clone(),
device: device.clone(),
render_pass: render_pass.clone(),
queue: Some(queue.clone()),
device: Some(device.clone()),
render_pass: Some(render_pass.clone()),
}
}
pub fn read_compute_buffer(&mut self, handle: Arc<CompuBufferHandle>) -> Vec<u8> {
let mut buffer : &CompuBuffers = self.compute_buffers.get(handle.handle as usize).unwrap();
let v = buffer.read_output_buffer();
v.into_vec()
}
/// Write to the compute buffer, ostensibly overwriting what's already there
pub fn write_compute_buffer(&self, handle: Arc<CompuBufferHandle>, data: Vec<u8>) {
unimplemented!("read_compute_buffer is not implemented")
}
pub fn new_kernel(&mut self,
filename: String,
device: Arc<Device>) -> Arc<CompuKernelHandle> {
let handle = Arc::new(CompuKernelHandle {
handle: self.kernels.len() as u32
});
self.kernels.push((CompuKernel::new(filename, device.clone(), handle.clone())));
handle
}
pub fn get_kernel_handle(&self, kernel_name: String) -> Option<Arc<CompuKernelHandle>> {
for i in self.kernels.clone() {
if i.get_name() == kernel_name {
return Some(i.get_handle());
}
}
None
}
pub fn compute_commands(&mut self,
compute_frame: &CompuFrame,
mut command_buffer: &mut AutoCommandBufferBuilder) {
// i = (Buffer, Kernel)
for i in &compute_frame.pure_compute {
let buffer_id = (*i.0).clone().get_handle() as usize;
let kernel_id = (*i.1).clone().get_handle() as usize;
let buffer = self.compute_buffers.get(buffer_id).unwrap();
let kernel = self.kernels.get(kernel_id).unwrap();
let pipeline = kernel.clone().get_pipeline();
let descriptorset = buffer.get_descriptor_set(kernel.clone().get_pipeline());
let size = buffer.get_size();
command_buffer = command_buffer
.dispatch([size.0 / 8, size.1 / 8, 1], pipeline, descriptorset, ()).unwrap()
}
// i = (Buffer, Image, Kernel)
for i in &compute_frame.swapped_to_image {
let buffer_id = (*i.0).clone().get_handle() as usize;
let image_id = i.1.clone();
let kernel_id = (*i.2).clone().handle as usize;
let buffer = self.compute_buffers.get(buffer_id).unwrap();
let image = self.get_image(image_id);
let kernel = self.kernels.get(kernel_id).unwrap();
let p = kernel.clone().get_pipeline();
let d = buffer.get_descriptor_set(kernel.clone().get_pipeline());
let dimensions = image.dimensions();
let dimensions = (dimensions.width(), dimensions.height());
if dimensions != buffer.get_size() {
panic!("Buffer sizes not the same");
}
let size = buffer.get_size();
command_buffer = command_buffer
.dispatch([size.0 / 8, size.1 / 8, 1], p, d, ()).unwrap()
.copy_buffer_to_image(buffer.get_output_buffer(), image).unwrap();
}
// i = (Input Buffer, Output Buffer, Kernel)
// Input buffer -> Kernel -> Output buffer
for i in &compute_frame.swapped_to_buffer {
let input_buffer_id = (*i.0).clone().get_handle() as usize;
let output_buffer_id = (*i.1).clone().get_handle() as usize;
let kernel_id = (*i.2).clone().handle as usize;
let input_buffer = self.compute_buffers.get(input_buffer_id).unwrap();
let output_buffer = self.compute_buffers.get(output_buffer_id).unwrap();
let kernel = self.kernels.get(kernel_id).unwrap();
let pipeline = kernel.clone().get_pipeline();
let descriptor_set = input_buffer.get_descriptor_set(kernel.clone().get_pipeline());
if input_buffer.get_size() != output_buffer.get_size() {
panic!("Buffer sizes not the same");
}
let size = input_buffer.get_size();
command_buffer = command_buffer
// .dispatch([size.0/8, size.1/8,1], pipeline, descriptor_set, ()).unwrap()
.copy_buffer(
input_buffer.get_output_buffer(),
output_buffer.get_input_buffer()).unwrap();
}
}
/// Creates a 2d compute buffer from incoming data
pub fn new_compute_buffer(&mut self,
data: Vec<u8>,
dimensions: (u32, u32),
stride: u32,
device: Arc<Device>) -> Arc<CompuBufferHandle> {
let handle = Arc::new(CompuBufferHandle {
handle: self.compute_buffers.len() as u32
});
self.compute_buffers.push(
(CompuBuffers::new(device.clone(), data, dimensions, stride, handle.clone())));
handle
}
/// Using the dimensions and suggested usage, load a CanvasImage and return it's handle
@ -174,7 +310,7 @@ impl CanvasState {
let image = CanvasImage {
handle: handle.clone(),
buffer: AttachmentImage::with_usage(
self.device.clone(),
self.device.clone().unwrap(),
[dimensions.0, dimensions.1],
Format::R8G8B8A8Uint,
usage).unwrap(),
@ -228,7 +364,7 @@ impl CanvasState {
image_buffer.iter().cloned(),
Dimensions::Dim2d { width: xy.0, height: xy.1 },
Format::R8G8B8A8Srgb,
self.queue.clone(),
self.queue.clone().unwrap(),
).unwrap();
texture
@ -254,19 +390,19 @@ impl CanvasState {
/// Load and Compile a shader with the filename at resources/shaders
/// Takes physical and capabilities as we don't store that in Canvas
pub fn load_shader<T: 'static, V>(&mut self,
filename: String,
capabilities: Capabilities) -> Option<Arc<CompiledShaderHandle>>
where T: CompiledShader, V: Vertex {
pub fn load_shader<T, V>(&mut self,
filename: String) -> Option<Arc<CompiledShaderHandle>>
where T: CompiledShader + Send + Sync + 'static, V: Vertex {
let handle = Arc::new(CompiledShaderHandle {
handle: self.shader_buffers.len() as u32
});
let shader: Box<dyn CompiledShader> = Box::new(T::new::<V>(
let shader: Box<dyn CompiledShader + Send + Sync> = Box::new(T::new::<V>(
filename.clone(),
self.device.clone(),
self.device.clone().unwrap(),
handle.clone(),
self.render_pass.clone(),
self.render_pass.clone().unwrap(),
));
self.shader_buffers.push(Arc::new(shader));
@ -324,7 +460,7 @@ impl CanvasState {
name: name,
buffer: ImmutableBuffer::from_iter(
accumulator.iter().cloned(),
BufferUsage::vertex_buffer(), self.queue.clone()).unwrap().0,
BufferUsage::vertex_buffer(), self.queue.clone().unwrap()).unwrap().0,
}
}));
@ -396,19 +532,19 @@ impl CanvasState {
// separate the mux of vertex containers back out
for value in &canvas_frame.map {
match value {
VertexType::TextureType(vertices, handle) => {
VertexTypeContainer::TextureType(vertices, handle) => {
textured_vertex_buffer.entry(handle.clone()).or_insert(vertices.clone()).extend(vertices);
}
VertexType::ImageType(vertices, handle) => {
VertexTypeContainer::ImageType(vertices, handle) => {
image_vertex_buffer.entry(handle.clone()).or_insert(vertices.clone()).extend(vertices);
}
VertexType::ColorType(vertices) => {
VertexTypeContainer::ColorType(vertices) => {
colored_vertex_buffer.extend(vertices);
}
VertexType::ThreeDType(vertices) => {
VertexTypeContainer::ThreeDType(vertices) => {
}
VertexType::TextType(vertices) => {
VertexTypeContainer::TextType(vertices) => {
text_vertex_buffer.extend(vertices);
}
};
@ -419,7 +555,7 @@ impl CanvasState {
allocated_colored_buffer.push(ImmutableBuffer::from_iter(
colored_vertex_buffer.iter().cloned(),
BufferUsage::vertex_buffer(),
self.queue.clone(),
self.queue.clone().unwrap(),
).unwrap().0);
}
@ -428,7 +564,7 @@ impl CanvasState {
allocated_text_buffer.push(ImmutableBuffer::from_iter(
text_vertex_buffer.iter().cloned(),
BufferUsage::vertex_buffer(),
self.queue.clone(),
self.queue.clone().unwrap(),
).unwrap().0);
}
@ -439,7 +575,7 @@ impl CanvasState {
ImmutableBuffer::from_iter(
v.iter().cloned(),
BufferUsage::vertex_buffer(),
self.queue.clone(),
self.queue.clone().unwrap(),
).unwrap().0 as Arc<(dyn BufferAccess + Send + Sync)>)
}).collect(),
image_vertex_buffer: image_vertex_buffer.into_iter().map(|(k, v)| {
@ -447,7 +583,7 @@ impl CanvasState {
ImmutableBuffer::from_iter(
v.iter().cloned(),
BufferUsage::vertex_buffer(),
self.queue.clone(),
self.queue.clone().unwrap(),
).unwrap().0 as Arc<(dyn BufferAccess + Send + Sync)>)
}).collect(),
text_instances: Default::default(),
@ -532,7 +668,7 @@ impl CanvasState {
for (texture_handle, vertex_buffer) in allocated_buffers.textured_vertex_buffer.clone() {
let handle = texture_handle.clone().get_handle() as usize;
let descriptor_set = self.texture_buffers.get(handle).clone().unwrap().clone()
.get_descriptor_set(shader.get_pipeline(), self.sampler.clone());
.get_descriptor_set(shader.get_pipeline(), self.sampler.clone().unwrap());
command_buffer = command_buffer.draw(
shader.get_pipeline().clone(),

@ -1,10 +1,12 @@
use std::sync::Arc;
use crate::canvas::managed::handles::{CanvasImageHandle};
use crate::compute::managed::handles::{CompuKernelHandle, CompuBufferHandle};
use crate::canvas::managed::handles::{CanvasImageHandle, CompuBufferHandle};
use crate::canvas::managed::handles::{CompuKernelHandle};
use crate::drawables::compu_sprite::CompuSprite;
use crate::canvas::canvas_frame::Drawable;
use crate::util::vertex::VertexType;
use crate::util::vertex::VertexTypeContainer;
use crate::render_system::{Images, Geometry};
#[derive(Default)]
pub struct CompuFrame {
// Vec<(Buffer, Kernel)>
pub pure_compute: Vec<(
@ -55,15 +57,9 @@ impl CompuFrame {
pub fn add_with_image_swap(&mut self,
buffer: Arc<CompuBufferHandle>,
kernel: Arc<CompuKernelHandle>,
sprite: &CompuSprite) {
let compu_sprites = sprite.get(self.window_size);
if compu_sprites.len() == 1 {
if let VertexType::ImageType(a, b) = compu_sprites.first().unwrap() {
self.swapped_to_image.push((buffer, b.clone(), kernel))
};
}
images: &Images,
) {
self.swapped_to_image.push((buffer, images.images.get(0).unwrap().clone(), kernel))
}
}

@ -7,8 +7,8 @@ use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, PersistentDes
use image::ImageBuffer;
use image::Rgba;
use shade_runner::Layout;
use crate::compute::managed::handles::CompuBufferHandle;
use vulkano::descriptor::PipelineLayoutAbstract;
use crate::canvas::managed::handles::CompuBufferHandle;
#[derive(Clone)]

@ -8,7 +8,7 @@ use vulkano::descriptor::pipeline_layout::PipelineLayout;
use shade_runner::{CompileError, Layout, Input, Output, CompiledShaders, Entry, CompiledShader};
use shaderc::CompileOptions;
use vulkano::pipeline::shader::{ShaderModule, GraphicsEntryPoint, SpecializationConstants, SpecializationMapEntry};
use crate::compute::managed::handles::CompuKernelHandle;
use crate::canvas::managed::handles::CompuKernelHandle;
#[derive(Clone)]

@ -57,4 +57,31 @@ impl Handle for CompiledShaderHandle {
}
}
/// Typed wrapper for a u32 handle
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CompuBufferHandle {
pub(in crate::canvas) handle: u32,
}
impl Handle for CompuBufferHandle {
fn get_handle(&self) -> u32 {
self.handle
}
}
/// Typed wrapper for a u32 handle
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CompuKernelHandle {
pub(in crate::canvas) handle: u32,
}
impl Handle for CompuKernelHandle {
fn get_handle(&self) -> u32 {
self.handle
}
}

@ -3,6 +3,8 @@ pub mod shader;
pub mod handles;
pub mod canvas_text;
pub mod gpu_buffers;
pub mod compu_buffer;
pub mod compu_kernel;
use vulkano::pipeline::shader::{SpecializationConstants, SpecializationMapEntry};

@ -18,7 +18,7 @@ use crate::canvas::managed::shader::shader_common::{ShaderType, CompiledShaderRe
use crate::canvas::managed::handles::CompiledShaderHandle;
use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef;
use crate::canvas::managed::ShaderSpecializationConstants;
use crate::util::vertex::{VertexType, ColorVertex3D};
use crate::util::vertex::{VertexTypeContainer, ColorVertex3D};
/// CanvasShader holds the pipeline and render pass for the input shader source
#[derive(Clone)]

@ -98,19 +98,18 @@ pub trait CompiledShaderResources {
}
}
pub trait CompiledShader {
fn new<V>(filename: String,
fn new<V: Vertex + Send>(filename: String,
device: Arc<Device>,
handle: Arc<CompiledShaderHandle>,
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> Self where Self: Sized, V: Vertex,;
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>)
-> Self where Self: Sized + Send + Sync;
fn get_name(&self) -> String;
fn get_handle(&self) -> Arc<CompiledShaderHandle>;
fn get_pipeline(&self) -> Arc<dyn GraphicsPipelineAbstract + Sync + Send>;
fn get_renderpass(&self) -> Arc<dyn RenderPassAbstract + Send + Sync>;
fn recompile<V: Vertex>(self, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>)
-> Self where Self: Sized;
fn recompile<V: Vertex + Send>(self, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>)
-> Self where Self: Sized + Send;
}
/// Legacy ShaderType enum for single type shaders.

@ -2,5 +2,6 @@
pub mod canvas_state;
pub mod canvas_frame;
pub mod managed;
pub mod compu_frame;

@ -0,0 +1,58 @@
use std::sync::Arc;
use specs::{Component, Join, System, VecStorage, Write, WriteStorage};
use crate::canvas::canvas_frame::CanvasFrame;
use crate::canvas::compu_frame::CompuFrame;
use crate::canvas::managed::handles::{CanvasImageHandle, CanvasTextureHandle, CompuBufferHandle, CompuKernelHandle};
use crate::PersistentState;
use crate::render_system::{Geometry, Images, Position, Textures};
use crate::util::vertex::{ImageVertex3D, TextureVertex3D, VertexTypeContainer};
use crate::vkprocessor::VkProcessor;
pub struct Compu {
pub kernels: Vec<Arc<CompuKernelHandle>>,
pub buffers: Vec<Arc<CompuBufferHandle>>,
}
impl Component for Compu {
type Storage = VecStorage<Self>;
}
pub struct CompuSystem;
impl<'a> System<'a> for CompuSystem {
type SystemData = (
WriteStorage<'a, Compu>,
WriteStorage<'a, Images>,
Write<'a, PersistentState>, // delta_time, window size, etc.
Write<'a, VkProcessor>, // Renderer
);
fn run(&mut self, (
mut compu_list,
mut image_list,
mut state,
mut vk_processor
): Self::SystemData) {
state.compu_frame = CompuFrame::new(state.window_size);
// compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1);
// compu_frame.add(compute_buffer.clone(), compute_kernel.clone());
for (compute_item, image) in (&mut compu_list, &mut image_list).join() {
state.compu_frame.add_with_image_swap(
compute_item.buffers.get(0).unwrap().clone(),
compute_item.kernels.get(0).unwrap().clone(),
image,
);
}
for (compute_item) in (&mut compu_list).join() {
state.compu_frame.add(
compute_item.buffers.get(0).unwrap().clone(),
compute_item.kernels.get(0).unwrap().clone(),
);
}
}
}

@ -1,169 +0,0 @@
use std::ffi::CStr;
use vulkano::buffer::{CpuAccessibleBuffer, BufferUsage};
use std::sync::Arc;
use vulkano::framebuffer::RenderPassAbstract;
use vulkano::pipeline::{GraphicsPipelineAbstract, ComputePipeline};
use vulkano::device::Device;
use image::ImageBuffer;
use image::GenericImageView;
use vulkano::image::{ImageUsage, AttachmentImage};
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSetBuf, PersistentDescriptorSet};
use vulkano::format::Format;
use vulkano::descriptor::pipeline_layout::PipelineLayout;
use std::borrow::Borrow;
use image::Rgba;
use vulkano::command_buffer::AutoCommandBufferBuilder;
use std::path::PathBuf;
use shade_runner::{CompiledShaders, Entry, CompileError};
use vulkano::pipeline::shader::ShaderModule;
use shaderc::CompileOptions;
use crate::compute::compu_frame::CompuFrame;
use crate::canvas::managed::handles::Handle;
use crate::compute::managed::compu_buffer::CompuBuffers;
use crate::compute::managed::handles::{CompuKernelHandle, CompuBufferHandle};
use crate::compute::managed::compu_kernel::CompuKernel;
use crate::canvas::canvas_state::CanvasState;
/// State holding the compute buffers for computation and the kernels which will compute them
pub struct CompuState {
compute_buffers: Vec<CompuBuffers>,
kernels: Vec<CompuKernel>,
}
impl CompuState {
pub fn new() -> CompuState {
CompuState {
compute_buffers: vec![],
kernels: vec![],
}
}
/// Creates a 2d compute buffer from incoming data
pub fn new_compute_buffer(&mut self,
data: Vec<u8>,
dimensions: (u32, u32),
stride: u32,
device: Arc<Device>) -> Arc<CompuBufferHandle> {
let handle = Arc::new(CompuBufferHandle {
handle: self.compute_buffers.len() as u32
});
self.compute_buffers.push(
(CompuBuffers::new(device.clone(), data, dimensions, stride, handle.clone())));
handle
}
pub fn read_compute_buffer(&mut self, handle: Arc<CompuBufferHandle>) -> Vec<u8> {
let mut buffer : &CompuBuffers = self.compute_buffers.get(handle.handle as usize).unwrap();
let v = buffer.read_output_buffer();
v.into_vec()
}
/// Write to the compute buffer, ostensibly overwriting what's already there
pub fn write_compute_buffer(&self, handle: Arc<CompuBufferHandle>, data: Vec<u8>) {
unimplemented!("read_compute_buffer is not implemented")
}
pub fn new_kernel(&mut self,
filename: String,
device: Arc<Device>) -> Arc<CompuKernelHandle> {
let handle = Arc::new(CompuKernelHandle {
handle: self.kernels.len() as u32
});
self.kernels.push((CompuKernel::new(filename, device.clone(), handle.clone())));
handle
}
pub fn get_kernel_handle(&self, kernel_name: String) -> Option<Arc<CompuKernelHandle>> {
for i in self.kernels.clone() {
if i.get_name() == kernel_name {
return Some(i.get_handle());
}
}
None
}
pub fn compute_commands(&mut self,
compute_frame: &CompuFrame,
mut command_buffer: &mut AutoCommandBufferBuilder,
canvas: &CanvasState) {
// i = (Buffer, Kernel)
for i in &compute_frame.pure_compute {
let buffer_id = (*i.0).clone().get_handle() as usize;
let kernel_id = (*i.1).clone().get_handle() as usize;
let buffer = self.compute_buffers.get(buffer_id).unwrap();
let kernel = self.kernels.get(kernel_id).unwrap();
let pipeline = kernel.clone().get_pipeline();
let descriptorset = buffer.get_descriptor_set(kernel.clone().get_pipeline());
let size = buffer.get_size();
command_buffer = command_buffer
.dispatch([size.0 / 8, size.1 / 8, 1], pipeline, descriptorset, ()).unwrap()
}
// i = (Buffer, Image, Kernel)
for i in &compute_frame.swapped_to_image {
let buffer_id = (*i.0).clone().get_handle() as usize;
let image_id = i.1.clone();
let kernel_id = (*i.2).clone().handle as usize;
let buffer = self.compute_buffers.get(buffer_id).unwrap();
let image = canvas.get_image(image_id);
let kernel = self.kernels.get(kernel_id).unwrap();
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");
}
let size = buffer.get_size();
command_buffer = command_buffer
.dispatch([size.0 / 8, size.1 / 8, 1], p, d, ()).unwrap()
.copy_buffer_to_image(buffer.get_output_buffer(), image).unwrap();
}
// i = (Input Buffer, Output Buffer, Kernel)
// Input buffer -> Kernel -> Output buffer
for i in &compute_frame.swapped_to_buffer {
let input_buffer_id = (*i.0).clone().get_handle() as usize;
let output_buffer_id = (*i.1).clone().get_handle() as usize;
let kernel_id = (*i.2).clone().handle as usize;
let input_buffer = self.compute_buffers.get(input_buffer_id).unwrap();
let output_buffer = self.compute_buffers.get(output_buffer_id).unwrap();
let kernel = self.kernels.get(kernel_id).unwrap();
let pipeline = kernel.clone().get_pipeline();
let descriptor_set = input_buffer.get_descriptor_set(kernel.clone().get_pipeline());
if input_buffer.get_size() != output_buffer.get_size() {
panic!("Buffer sizes not the same");
}
let size = input_buffer.get_size();
command_buffer = command_buffer
// .dispatch([size.0/8, size.1/8,1], pipeline, descriptor_set, ()).unwrap()
.copy_buffer(
input_buffer.get_output_buffer(),
output_buffer.get_input_buffer()).unwrap();
}
}
}

@ -1,29 +0,0 @@
use crate::canvas::managed::handles::Handle;
/// Typed wrapper for a u32 handle
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CompuBufferHandle {
pub(in crate::compute) handle: u32,
}
impl Handle for CompuBufferHandle {
fn get_handle(&self) -> u32 {
self.handle
}
}
/// Typed wrapper for a u32 handle
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CompuKernelHandle {
pub(in crate::compute) handle: u32,
}
impl Handle for CompuKernelHandle {
fn get_handle(&self) -> u32 {
self.handle
}
}

@ -1,4 +0,0 @@
pub mod compu_buffer;
pub mod compu_kernel;
pub mod handles;

@ -1,6 +0,0 @@
pub mod compu_frame;
pub mod compu_state;
pub mod managed;
use crate::compute::compu_state::CompuState;
use crate::compute::compu_frame::CompuFrame;

@ -1,11 +1,12 @@
use std::sync::Arc;
use crate::canvas::managed::handles::{CanvasImageHandle, CanvasTextureHandle};
use crate::canvas::canvas_frame::Drawable;
use crate::util::vertex::{VertexType, ImageVertex3D};
use crate::util::vertex::{VertexTypeContainer, ImageVertex3D};
use crate::util::tr_event::{TrUIEvent, TrEvent};
pub struct CompuSprite {
pub verts: VertexType,
pub verts: VertexTypeContainer,
position: (f32, f32),
size: (f32, f32),
@ -44,7 +45,7 @@ impl CompuSprite {
];
CompuSprite {
verts: VertexType::ImageType(verts, image_handle.clone()),
verts: VertexTypeContainer::ImageType(verts, image_handle.clone()),
position: position,
size: size,
color: (0.0, 0.0, 0.0, 0.0),
@ -53,7 +54,21 @@ impl CompuSprite {
}
impl Drawable for CompuSprite {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexType> {
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![self.verts.clone()]
}
// fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
// Vec::new()
// }
//
// fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
// Vec::new()
// }
}

@ -2,14 +2,15 @@ use std::sync::Arc;
use crate::canvas::*;
use crate::canvas::managed::handles::{CanvasFontHandle, CanvasImageHandle, CanvasTextureHandle, Handle};
use crate::canvas::canvas_frame::{Drawable};
use crate::util::vertex::{VertexType, TextureVertex3D, Vertex3D, ColorVertex3D};
use crate::util::vertex::{VertexTypeContainer, TextureVertex3D, Vertex3D, ColorVertex3D};
use crate::drawables::sprite::Sprite;
use crate::util::tr_event::{TrUIEvent, TrEvent};
/// Convex multi verticy polygon
#[derive(Debug, Clone)]
pub struct Polygon {
pub verts: VertexType,
pub verts: VertexTypeContainer,
position: (f32, f32),
size: (f32, f32),
@ -54,17 +55,30 @@ impl Polygon {
Polygon {
verts: VertexType::ColorType(verts),
verts: VertexTypeContainer::ColorType(verts),
position: position,
size: size,
}
}
}
impl Drawable for Polygon {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexType> {
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![self.verts.clone()]
}
// fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
// Vec::new()
// }
//
// fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
// Vec::new()
// }
}

@ -1,5 +1,6 @@
use crate::canvas::canvas_frame::Drawable;
use crate::util::vertex::{VertexType, ColorVertex3D};
use crate::util::vertex::{VertexTypeContainer, ColorVertex3D};
use crate::util::tr_event::{TrUIEvent, TrEvent};
///
#[derive(Debug, Clone)]
@ -73,11 +74,25 @@ impl Rect {
}
impl Drawable for Rect {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexType> {
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![
VertexType::ColorType(
VertexTypeContainer::ColorType(
Rect::generate_vertices(window_size, self.position, self.size, self.depth, self.color)
)
]
}
// fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
// Vec::new()
// }
//
// fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
// Vec::new()
// }
}

@ -1,12 +1,14 @@
use std::collections::HashSet;
use winit::event::Event;
use winit::event::{Event, ElementState, MouseButton};
use crate::canvas::canvas_frame::{Drawable, Eventable};
use crate::canvas::canvas_frame::{Drawable};
use crate::drawables::rect::Rect;
use crate::drawables::sprite::Sprite;
use crate::util::vertex::VertexType;
use crate::util::vertex::VertexTypeContainer;
use crate::util::tr_event::{TrEvent, TrWindowEvent, TrUIEvent};
#[derive(Debug, Clone)]
pub struct Slider {
handle: Rect,
guide: Vec<Rect>,
@ -28,7 +30,7 @@ impl Slider {
let left_guide_bar = Rect::new((position.0, position.1), (2.0, size.1), 1, red);
let right_guide_bar = Rect::new((position.0 + size.0, position.1), (2.0, size.1), 1, blue);
let line = Rect::new((position.0, position.1 - (size.1 / 2.0) ), (size.0, 2.0), 1, green);
let line = Rect::new((position.0, position.1 - (size.1 / 2.0)), (size.0, 2.0), 1, green);
let scale = value as f32 / u16::max_value() as f32;
let handle = Rect::new((position.0 + (size.0 * scale), position.1), (15.0, size.1), 1, rg);
@ -42,27 +44,88 @@ impl Slider {
value,
}
}
pub fn update(&mut self) {
// render the guide first
let red = (1.0, 0.0, 0.0, 0.0);
let green = (0.0, 1.0, 0.0, 0.0);
let blue = (0.0, 1.0, 1.0, 0.0);
let rg = (1.0, 1.0, 0.0, 0.0);
let left_guide_bar = Rect::new((self.position.0, self.position.1), (2.0, self.size.1), 1, red);
let right_guide_bar = Rect::new((self.position.0 + self.size.0, self.position.1), (2.0, self.size.1), 1, blue);
let line = Rect::new((self.position.0, self.position.1 - (self.size.1 / 2.0)), (self.size.0, 2.0), 1, green);
let scale = self.value as f32 / u16::max_value() as f32;
let handle = Rect::new((self.position.0 + (self.size.0 * scale), self.position.1), (15.0, self.size.1), 1, rg);
self.handle = handle;
self.guide = vec![left_guide_bar, right_guide_bar, line];
self.scaler = 255;
}
}
impl Drawable for Slider {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexType> {
let mut vertices = self.handle.get(window_size).clone();
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
let mut vertices = self.handle.render(
window_size,
position,
rotation,
size,
depth,
).clone();
vertices.extend_from_slice(
self.guide.iter()
.map(|x| x.get(window_size))
.flatten()
.collect::<Vec<VertexType>>()
.map(|x| x.render(window_size,
position,
rotation,
size,
depth,
)).flatten()
.collect::<Vec<VertexTypeContainer>>()
.as_slice()
);
vertices.extend_from_slice(self.guide[0].get(window_size).as_slice());
vertices.extend_from_slice(
self.guide[0].render(window_size,
position,
rotation,
size,
depth,
).as_slice());
vertices
}
}
impl<T> Eventable<T> for Slider {
fn notify(&mut self, event: &Event<T>) -> () {
unimplemented!()
}
// fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
// Vec::new()
// }
//
// fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
// match tr_event {
// TrEvent::WindowEvent { event: TrWindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
//
//
// match button {
// MouseButton::Left => {
// if *state == ElementState::Pressed {
// self.position.0 += 30.0;
// self.value += 10;
// self.update()
// }
// }
// _ => {}
// }
// }
// _ => {}
// }