Compare commits
33 Commits
master
...
looking-at
| Author | SHA1 | Date | |
|---|---|---|---|
| 83688b5246 | |||
| 152a1670c5 | |||
| 8ceb805a52 | |||
| 32ae95b3d0 | |||
| d00f3b06b2 | |||
| 89d42909df | |||
| 280bc4d1a0 | |||
| b80a87dd18 | |||
| 59a945b474 | |||
| bae64b0851 | |||
| 86ce4821a4 | |||
| efb786ca8a | |||
| 846a082f79 | |||
| d1373fc061 | |||
| c0b1c2e135 | |||
| 165a90eba1 | |||
| aaef25f710 | |||
| 84999130bb | |||
| e7bbf1f1db | |||
| 34b5d7b3d0 | |||
| 76c75c349b | |||
| 369a305817 | |||
| a42d23e5f9 | |||
| 28565652c0 | |||
| 9719675465 | |||
| 2e33c9c75e | |||
| 9eed836083 | |||
| f781c76e7e | |||
| ccbd21d90b | |||
| c52bdc1441 | |||
| c10115e7b9 | |||
| b070a7dd32 | |||
| eac4f8d233 |
@@ -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"
|
||||
@@ -31,3 +32,5 @@ winit = "0.22.0"
|
||||
hprof = "0.1.3"
|
||||
rusttype = { version = "0.7.0", features = ["gpu_cache"] }
|
||||
vulkano_text = "0.12.0"
|
||||
petgraph = "0.5.1"
|
||||
nom = "6.0.0-alpha3"
|
||||
@@ -10,14 +10,16 @@ Creation-Date: 2020-02-03T22:11:42-08:00
|
||||
TODO:
|
||||
[X] Text rendering is mocked.
|
||||
[?] Pathfinder vulkan backend implementation
|
||||
* Kinda big meh on this. It's very much oneshot based
|
||||
and not incredibly compatible with vulkano...
|
||||
[ ] Investigate lyon maybe
|
||||
[X] Currently using local copies of a few libraries:
|
||||
* Kinda big meh on this. It's very much oneshot based
|
||||
and not incredibly compatible with vulkano...
|
||||
[ ] Investigate lyon maybe
|
||||
[ ] Event system
|
||||
[ ] HTML like layout scripts
|
||||
[x] Currently using local copies of a few libraries:
|
||||
[x] shade_runner ( not gonna happen, my fork has diverged too far )
|
||||
[ ] Make a toolpath
|
||||
[X] Read from GPU?
|
||||
[ ] Figure out a way to vectorize the simple edge
|
||||
[X] Read from GPU?
|
||||
[ ] Figure out a way to vectorize the simple edge
|
||||
|
||||
|
||||
--------------------
|
||||
|
||||
53
notes/MakingAnActualThing.txt
Normal file
53
notes/MakingAnActualThing.txt
Normal file
@@ -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.
|
||||
95
notes/layout-scripts.txt
Normal file
95
notes/layout-scripts.txt
Normal file
@@ -0,0 +1,95 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2020-10-06T22:33:37-07:00
|
||||
|
||||
====== layout-scripts ======
|
||||
Created Tuesday 06 October 2020
|
||||
|
||||
===== Keywords =====
|
||||
|
||||
***table will need some description of it's requested elements***
|
||||
**Actually I think this could just be done in the parser. Emitting warnings if names dont match**
|
||||
|
||||
elem table {
|
||||
}
|
||||
|
||||
**elem is a keyword specifying that the next token will implement some type of rendering behaviour in this case, it is a table.**
|
||||
|
||||
elem table : globalTableFormatting {
|
||||
meta tableFormatting {
|
||||
}
|
||||
}
|
||||
|
||||
meta globalTableFormatting {
|
||||
|
||||
}
|
||||
|
||||
**meta is a keyword specifying that the next token will contain some subset of the data that an elem that needs to render.**
|
||||
|
||||
|
||||
===== Nesting =====
|
||||
|
||||
**There is no way around a tree structure in the markup.**
|
||||
|
||||
elem div {
|
||||
|
||||
}
|
||||
|
||||
elem table {
|
||||
meta tableFormatting {
|
||||
color: Black,
|
||||
}
|
||||
elem tr {
|
||||
elem tc {
|
||||
text: "testText1"
|
||||
}
|
||||
elem tc {
|
||||
text: "testText2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
**But I think I can strongly type the nesting structure, e.g**
|
||||
|
||||
struct Table {
|
||||
fn addChild(child: TableRow)
|
||||
}
|
||||
elem!(table, Table)
|
||||
|
||||
struct TableRow {
|
||||
fn addChild(child: TableColumn)
|
||||
}
|
||||
elem!(table, TableRow)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
40
notes/paste.txt
Normal file
40
notes/paste.txt
Normal file
@@ -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
BIN
resources/edge-detect-screenshot.png
Normal file
BIN
resources/edge-detect-screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
BIN
resources/images/ford.png
Normal file
BIN
resources/images/ford.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
16
resources/scripts/scratch
Normal file
16
resources/scripts/scratch
Normal file
@@ -0,0 +1,16 @@
|
||||
# this is a comment
|
||||
elem table {
|
||||
elem tr {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
elem table {
|
||||
elem tr {
|
||||
|
||||
}
|
||||
elem tr {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BIN
resources/whiteboard-drawing.jpg
Normal file
BIN
resources/whiteboard-drawing.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 407 KiB |
@@ -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>;
|
||||
|
||||
// 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 receive events
|
||||
pub trait Eventable<T> {
|
||||
fn notify(&mut self, event: &Event<T>) -> ();
|
||||
}
|
||||
|
||||
/// 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,22 +160,149 @@ 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
|
||||
pub fn create_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<CanvasImageHandle> {
|
||||
let handle = Arc::new(CanvasImageHandle { handle: self.image_buffers.len() as u32 });
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
58
src/compu_system.rs
Normal file
58
src/compu_system.rs
Normal file
@@ -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()
|
||||
// }
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// Vec::new()
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
use std::sync::Arc;
|
||||
use crate::canvas::*;
|
||||
use crate::canvas::managed::handles::{CanvasFontHandle, CanvasImageHandle, CanvasTextureHandle, Handle};
|
||||
use crate::canvas::canvas_frame::{Drawable, Eventable, Updatable};
|
||||
use crate::util::vertex::{VertexType, TextureVertex3D, Vertex3D};
|
||||
use crate::canvas::canvas_frame::{Drawable};
|
||||
use crate::util::vertex::{VertexTypeContainer, TextureVertex3D, Vertex3D};
|
||||
use winit::event::{DeviceEvent, MouseButton, ElementState, Event, WindowEvent};
|
||||
use crate::util::tr_event::{TrEvent, TrWindowEvent, TrUIEvent};
|
||||
|
||||
|
||||
///
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Sprite {
|
||||
pub position: (f32, f32),
|
||||
pub size: (f32, f32),
|
||||
depth: f32,
|
||||
texture_handle: Arc<CanvasTextureHandle>,
|
||||
|
||||
}
|
||||
|
||||
/// Container class which implements drawable.
|
||||
impl Sprite {
|
||||
fn generate_verts(window_size: (u32, u32), position: (f32, f32), size: (f32, f32), depth: f32) -> Vec<TextureVertex3D> {
|
||||
|
||||
fn generate_verts(
|
||||
window_size: (u32, u32),
|
||||
position: (f32, f32),
|
||||
size: (f32, f32),
|
||||
depth: f32,
|
||||
) -> Vec<TextureVertex3D> {
|
||||
let ss_position = (
|
||||
position.0 / window_size.0 as f32 - 1.0,
|
||||
position.1 / window_size.1 as f32 - 1.0
|
||||
@@ -57,51 +61,50 @@ impl Sprite {
|
||||
}
|
||||
|
||||
///
|
||||
pub fn new(position: (f32, f32),
|
||||
size: (f32, f32),
|
||||
depth: u32,
|
||||
texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
|
||||
let normalized_depth = (depth as f32 / 255.0);
|
||||
|
||||
pub fn new(texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
|
||||
Sprite {
|
||||
position: position,
|
||||
size: size,
|
||||
depth: normalized_depth,
|
||||
texture_handle: texture_handle.clone(),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Drawable for Sprite {
|
||||
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> {
|
||||
let normalized_depth = (depth / 255.0);
|
||||
|
||||
vec![
|
||||
VertexType::TextureType(
|
||||
Sprite::generate_verts(window_size, self.position, self.size, self.depth),
|
||||
VertexTypeContainer::TextureType(
|
||||
Sprite::generate_verts(window_size, position, size, normalized_depth),
|
||||
self.texture_handle.clone())
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eventable<T> for Sprite {
|
||||
fn notify(&mut self, event: &Event<T>) -> () {
|
||||
match event {
|
||||
Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
|
||||
match button {
|
||||
MouseButton::Left => {
|
||||
if *state == ElementState::Pressed {
|
||||
self.position = (self.position.0, self.position.1 + 0.1);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Updatable for Sprite {
|
||||
fn update(&mut self, delta_time: f32) -> () {
|
||||
|
||||
}
|
||||
//
|
||||
// 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 {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// Vec::new()
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
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)]
|
||||
pub struct Text {
|
||||
pub verts: VertexType,
|
||||
pub verts: VertexTypeContainer,
|
||||
|
||||
position: (f32, f32),
|
||||
size: (f32, f32),
|
||||
@@ -129,7 +130,7 @@ impl Text {
|
||||
};
|
||||
|
||||
Text {
|
||||
verts: VertexType::TextType(verts),
|
||||
verts: VertexTypeContainer::TextType(verts),
|
||||
position: position,
|
||||
size: size,
|
||||
}
|
||||
@@ -137,7 +138,21 @@ impl Text {
|
||||
}
|
||||
|
||||
impl Drawable for Text {
|
||||
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()
|
||||
// }
|
||||
}
|
||||
|
||||
59
src/event_system.rs
Normal file
59
src/event_system.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use specs::{Component, Entities, Join, System, VecStorage, Write, WriteStorage};
|
||||
use vulkano::swapchain::Surface;
|
||||
use winit::window::Window;
|
||||
|
||||
use crate::PersistentState;
|
||||
use crate::render_system::Position;
|
||||
use crate::util::tr_event::{TrEvent, TrEventExtension, TrWindowEvent};
|
||||
use crate::vkprocessor::VkProcessor;
|
||||
use winit::event::ElementState;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Evented {
|
||||
pub subscribed: fn(event: TrEvent<TrEventExtension>) -> bool,
|
||||
}
|
||||
|
||||
impl Component for Evented {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
||||
pub struct EventSystem;
|
||||
|
||||
impl<'a> System<'a> for EventSystem {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
WriteStorage<'a, Evented>,
|
||||
Write<'a, PersistentState>,
|
||||
Write<'a, VkProcessor>,
|
||||
Write<'a, Vec<TrEvent<TrEventExtension>>>
|
||||
);
|
||||
|
||||
fn run(&mut self, (
|
||||
entity,
|
||||
mut evented_list,
|
||||
mut state,
|
||||
mut vk_processor,
|
||||
event_stack
|
||||
): Self::SystemData) {
|
||||
|
||||
for (evented) in (&evented_list).join() {
|
||||
for event in &*event_stack {
|
||||
match event {
|
||||
TrEvent::WindowEvent { window_id, event } => {
|
||||
match event {
|
||||
TrWindowEvent::MouseInput { device_id, state, button, modifiers } => {
|
||||
if *state == ElementState::Pressed {
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (entity, evented) in (&*entity, &mut evented_list).join() {}
|
||||
}
|
||||
}
|
||||
367
src/main.rs
367
src/main.rs
@@ -8,14 +8,19 @@ extern crate hprof;
|
||||
extern crate image;
|
||||
extern crate nalgebra as na;
|
||||
extern crate rand;
|
||||
extern crate specs;
|
||||
extern crate time;
|
||||
#[macro_use]
|
||||
extern crate nom;
|
||||
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use gilrs::{Button, Event as GilEvent, Gamepad, GamepadId, Gilrs};
|
||||
use specs::prelude::*;
|
||||
use vulkano::instance::debug::DebugCallback;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::swapchain::Surface;
|
||||
use vulkano::sync;
|
||||
use vulkano::sync::GpuFuture;
|
||||
use vulkano_win::VkSurfaceBuild;
|
||||
@@ -23,35 +28,75 @@ use winit::dpi::LogicalSize;
|
||||
use winit::event::{DeviceEvent, ElementState, Event, MouseButton, StartCause, VirtualKeyCode, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop, EventLoopProxy};
|
||||
use winit::platform::unix::WindowBuilderExtUnix;
|
||||
use winit::window::WindowBuilder;
|
||||
use winit::window::{Window, WindowBuilder};
|
||||
|
||||
use crate::canvas::canvas_frame::{CanvasFrame, Drawable, Eventable, Updatable};
|
||||
use canvas::compu_frame::CompuFrame;
|
||||
|
||||
use crate::canvas::canvas_frame::{CanvasFrame, Drawable};
|
||||
use crate::canvas::canvas_state::CanvasState;
|
||||
use crate::canvas::managed::handles::{CanvasFontHandle, CanvasTextureHandle, Handle};
|
||||
use crate::compute::compu_frame::CompuFrame;
|
||||
use crate::compute::managed::handles::{CompuBufferHandle, CompuKernelHandle};
|
||||
use crate::canvas::managed::handles::{CompuBufferHandle, CompuKernelHandle};
|
||||
use crate::drawables::compu_sprite::CompuSprite;
|
||||
use crate::drawables::rect::Rect;
|
||||
use crate::drawables::slider::Slider;
|
||||
use crate::drawables::sprite::Sprite;
|
||||
use crate::drawables::text::Text;
|
||||
use crate::render_system::{Geometry, Images, Position, RenderSystem, Textures};
|
||||
use crate::util::load_raw;
|
||||
use crate::util::timer::Timer;
|
||||
use crate::util::tr_event::TrEvent;
|
||||
use crate::util::vertex::{TextureVertex3D, VertexType};
|
||||
use crate::util::tr_event::{TrEvent, TrEventExtension};
|
||||
use crate::util::vertex::{TextureVertex3D, VertexTypeContainer};
|
||||
use crate::vkprocessor::VkProcessor;
|
||||
use crate::drawables::slider::Slider;
|
||||
use crate::compu_system::{CompuSystem, Compu};
|
||||
use crate::event_system::{EventSystem, Evented};
|
||||
use petgraph::Graph;
|
||||
use petgraph::graph::NodeIndex;
|
||||
|
||||
pub mod util;
|
||||
pub mod vkprocessor;
|
||||
pub mod drawables;
|
||||
pub mod canvas;
|
||||
pub mod compute;
|
||||
pub mod render_system;
|
||||
pub mod compu_system;
|
||||
pub mod event_system;
|
||||
pub mod parser;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PersistentState {
|
||||
surface: Option<Arc<Surface<Window>>>,
|
||||
window_size: (u32, u32),
|
||||
delta_time: f32,
|
||||
canvas_frame: CanvasFrame,
|
||||
compu_frame: CompuFrame,
|
||||
}
|
||||
|
||||
struct TrSprite {
|
||||
entity: Entity,
|
||||
}
|
||||
|
||||
|
||||
use std::fs;
|
||||
use nom::sequence::{preceded, tuple};
|
||||
use nom::bytes::complete::{take_while1, tag, take_while_m_n};
|
||||
use nom::character::complete::line_ending;
|
||||
use nom::error::ErrorKind;
|
||||
use nom::combinator::map_res;
|
||||
use nom::IResult;
|
||||
use crate::parser::parser::{Color, hex_color, parse_script};
|
||||
|
||||
|
||||
pub fn main() {
|
||||
hprof::start_frame();
|
||||
|
||||
let q1 = hprof::enter("setup");
|
||||
//https://dylanede.github.io/cassowary-rs/cassowary/index.html
|
||||
|
||||
let input_string = fs::read_to_string("./resources/scripts/scratch").unwrap();
|
||||
|
||||
parse_script::<(&str, ErrorKind)>(&input_string);
|
||||
|
||||
return;
|
||||
|
||||
//hprof::start_frame();
|
||||
//let g = hprof::enter("vulkan preload");
|
||||
|
||||
let instance = {
|
||||
let extensions = vulkano_win::required_extensions();
|
||||
@@ -62,32 +107,27 @@ pub fn main() {
|
||||
println!("Debug callback: {:?}", msg.description);
|
||||
}).ok();
|
||||
|
||||
let mut events_loop = EventLoop::<TrEvent>::with_user_event();
|
||||
let mut events_loop = EventLoop::<TrEventExtension>::with_user_event();
|
||||
|
||||
let mut surface = WindowBuilder::new()
|
||||
.with_inner_size(LogicalSize::new(800, 800))
|
||||
.build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
|
||||
let mut processor = VkProcessor::new(instance.clone(), surface.clone());
|
||||
processor.create_swapchain(instance.clone(), surface.clone());
|
||||
processor.preload_kernels();
|
||||
processor.preload_shaders();
|
||||
processor.preload_textures();
|
||||
processor.preload_fonts();
|
||||
|
||||
{
|
||||
let g = hprof::enter("vulkan preload");
|
||||
processor.create_swapchain(instance.clone(), surface.clone());
|
||||
processor.preload_kernels();
|
||||
processor.preload_shaders();
|
||||
processor.preload_textures();
|
||||
processor.preload_fonts();
|
||||
}
|
||||
|
||||
let q2 = hprof::enter("Game Objects");
|
||||
|
||||
let mut timer = Timer::new();
|
||||
let mut frame_future: Box<dyn GpuFuture> =
|
||||
Box::new(sync::now(processor.device.clone())) as Box<dyn GpuFuture>;
|
||||
Box::new(sync::now(processor.device.clone().unwrap())) as Box<dyn GpuFuture>;
|
||||
|
||||
let step_size: f32 = 0.005;
|
||||
let mut elapsed_time: f32 = timer.elap_time();
|
||||
;
|
||||
|
||||
let mut delta_time: f32 = 0.0;
|
||||
let mut accumulator_time: f32 = 0.0;
|
||||
let mut current_time: f32 = timer.elap_time();
|
||||
@@ -95,12 +135,7 @@ pub fn main() {
|
||||
let image_data = load_raw(String::from("ford2.jpg"));
|
||||
let image_dimensions_f: (f32, f32) = ((image_data.1).clone().0 as f32, (image_data.1).clone().1 as f32);
|
||||
let image_dimensions_u: (u32, u32) = image_data.1;
|
||||
let compu_sprite1: CompuSprite =
|
||||
CompuSprite::new((-1.0, -1.0), (1.0, 1.0), 0, image_dimensions_f,
|
||||
// Swap image to render the result to. Must match dimensions
|
||||
processor.new_swap_image(image_dimensions_u));
|
||||
|
||||
// Need to
|
||||
let compute_buffer: Arc<CompuBufferHandle> =
|
||||
processor.new_compute_buffer(image_data.0.clone(), image_data.1, 4);
|
||||
|
||||
@@ -111,29 +146,83 @@ pub fn main() {
|
||||
processor.get_kernel_handle(String::from("simple-edge.compute"))
|
||||
.expect("Can't find that kernel");
|
||||
|
||||
let compu_image = processor.new_swap_image(image_dimensions_u);
|
||||
|
||||
// Get the handles for the assets
|
||||
let funky_handle: Arc<CanvasTextureHandle> =
|
||||
processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap();
|
||||
let sfml_handle: Arc<CanvasTextureHandle> =
|
||||
processor.get_texture_handle(String::from("sfml.png")).unwrap();
|
||||
//let font_handle : Arc<CanvasFontHandle> =
|
||||
// processor.get_font_handle(String::from("sansation.ttf")).unwrap();
|
||||
|
||||
let mut funky_sprite = Sprite::new(
|
||||
(200.0, 200.0),
|
||||
(100.0, 150.0), 10, funky_handle.clone());
|
||||
let sfml_sprite = Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone());
|
||||
let mut world = World::new();
|
||||
world.register::<Evented>();
|
||||
world.register::<Compu>();
|
||||
world.register::<Position>();
|
||||
world.register::<Geometry>();
|
||||
world.register::<Textures>();
|
||||
world.register::<Images>();
|
||||
world.insert::<VkProcessor>(processor);
|
||||
world.insert::<Vec<TrEvent<TrEventExtension>>>(Vec::new());
|
||||
world.insert::<PersistentState>(PersistentState {
|
||||
surface: Some(surface.clone()),
|
||||
window_size: (0, 0),
|
||||
delta_time,
|
||||
canvas_frame: CanvasFrame::new((0, 0)),
|
||||
compu_frame: CompuFrame::new((0, 0)),
|
||||
});
|
||||
|
||||
let slider = Slider::new((300.0, 50.0), (550.0, 100.0), 30000);
|
||||
/*
|
||||
let mut g = Graph::new();
|
||||
let mut matrix : Vec<Vec<NodeIndex<u32>>> = vec![vec![NodeIndex::new(1); 20]; 20];
|
||||
|
||||
//let sfml_sprite = Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone());
|
||||
//let text_sprite = Text::new((-0.1, -0.1), (10.0, 10.0), 1);
|
||||
//let test_polygon = Poly::new_with_color((-0.5, -0.5), (0.5, 0.5), 1, (1.0,0.0,0.0,0.0));
|
||||
for x in 0..20 {
|
||||
for y in 0..20 {
|
||||
matrix[x][y] = g.add_node(((x, y), 0.));
|
||||
}
|
||||
}
|
||||
|
||||
drop(q2);
|
||||
drop(q1);
|
||||
|
||||
let l = hprof::enter("Loop");
|
||||
for x in 0..20 {
|
||||
for y in 0..20 {
|
||||
|
||||
|
||||
matrix[x][y] = g.add_node(((x, y), 0.));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
g.extend_with_edges(&[
|
||||
(a, b, 1),
|
||||
(a, d, 1),
|
||||
(b, c, 1),
|
||||
(b, f, 1),
|
||||
(c, e, 1),
|
||||
(e, f, 1),
|
||||
(d, e, 1),
|
||||
]);*/
|
||||
|
||||
// and the thing that renders it
|
||||
world.create_entity()
|
||||
.with(Compu { kernels: vec![compute_kernel], buffers: vec![compute_buffer] })// just a drawable
|
||||
.with(Position { x: 900.0, y: 900.0, z: 0 })
|
||||
.with(Geometry { size_x: 600.0, size_y: 600.0, rotation: 0.0 })
|
||||
.with(Images { images: vec![compu_image], image_resolutions: vec![image_dimensions_u] })
|
||||
.build();
|
||||
|
||||
let sprite = world.create_entity()
|
||||
.with(Evented { subscribed: |event| {true} })
|
||||
.with(Position { x: 0.0, y: 0.0, z: 0 })
|
||||
.with(Geometry { size_x: 300.0, size_y: 300.0, rotation: 0.0 })
|
||||
.with(Textures { textures: vec![funky_handle] })
|
||||
.build();
|
||||
|
||||
|
||||
// call the run method for the following systems & deps
|
||||
let mut dispatcher = DispatcherBuilder::new()
|
||||
// .with(SysA, "sys_a", &[])
|
||||
.with(EventSystem, "event_s", &[])
|
||||
.with(CompuSystem, "compu_s", &["event_s"])
|
||||
.with(RenderSystem, "render_s", &["event_s", "compu_s"]).build();
|
||||
|
||||
let event_loop_proxy = events_loop.create_proxy();
|
||||
|
||||
@@ -153,7 +242,7 @@ pub fn main() {
|
||||
while let Some(GilEvent { id, event, time }) = gilrs.next_event() {
|
||||
println!("{:?} New event from {}: {:?}", time, id, event);
|
||||
active_gamepad = Some(id);
|
||||
event_loop_proxy.send_event(TrEvent::GamepadEvent {
|
||||
event_loop_proxy.send_event(TrEventExtension::GamepadEvent {
|
||||
gil_event: GilEvent { id, event, time }
|
||||
}).ok();
|
||||
}
|
||||
@@ -169,39 +258,39 @@ pub fn main() {
|
||||
}
|
||||
});
|
||||
|
||||
let mut window_size: (u32, u32) = (0, 0);
|
||||
|
||||
let mut canvas_frame = CanvasFrame::new(window_size);
|
||||
let mut compu_frame = CompuFrame::new(window_size);
|
||||
|
||||
let mut big_container = vec![
|
||||
Box::new(Slider::new((0.1, 0.1), (0.9, 0.9), 5000)),
|
||||
Box::new(Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone())),
|
||||
];
|
||||
//container.push(Sprite::new((0.1)));
|
||||
|
||||
|
||||
// Events loop is borrowed from the surface
|
||||
events_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Poll;
|
||||
|
||||
for eventable in &mut big_container {
|
||||
eventable.notify(&event);
|
||||
}
|
||||
|
||||
for drawable in &mut big_container {
|
||||
canvas_frame.draw(&drawable);
|
||||
}
|
||||
|
||||
// The incoming event type will indicate what section of the event loop we are in
|
||||
match event {
|
||||
Event::NewEvents(cause) => {
|
||||
if cause == StartCause::Init {
|
||||
canvas_frame.draw(&funky_sprite);
|
||||
canvas_frame.draw(&compu_sprite1);
|
||||
canvas_frame.draw(&slider);
|
||||
|
||||
window_size = surface.window().inner_size().into();
|
||||
world.write_resource::<PersistentState>()
|
||||
.window_size = surface.window().inner_size().into();
|
||||
} else {
|
||||
// println!("{}", world.write_resource::<Vec<TrEvent<TrEventExtension>>>().len());
|
||||
world.write_resource::<Vec<TrEvent<TrEventExtension>>>().clear();
|
||||
}
|
||||
}
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
||||
*control_flow = ControlFlow::Exit
|
||||
}
|
||||
Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
|
||||
match button {
|
||||
MouseButton::Left => {
|
||||
if state == ElementState::Pressed {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Event::WindowEvent { event: WindowEvent::Resized(new_size), .. } => {
|
||||
world.write_resource::<VkProcessor>()
|
||||
.swapchain_recreate_needed = true;
|
||||
world.write_resource::<PersistentState>()
|
||||
.window_size = (new_size.width, new_size.height);
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
elapsed_time = timer.elap_time();
|
||||
delta_time = elapsed_time - current_time;
|
||||
current_time = elapsed_time;
|
||||
@@ -209,102 +298,74 @@ pub fn main() {
|
||||
delta_time = 0.02;
|
||||
}
|
||||
accumulator_time += delta_time;
|
||||
}
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
||||
*control_flow = ControlFlow::Exit
|
||||
}
|
||||
Event::WindowEvent { event: WindowEvent::Resized(new_size), .. } => {
|
||||
processor.swapchain_recreate_needed = true;
|
||||
let size = (new_size.width, new_size.height);
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::MouseInput {
|
||||
device_id, state, button, modifiers
|
||||
}, ..
|
||||
} => {}
|
||||
Event::UserEvent(TrEvent::KeyHeldEvent {}) => {}
|
||||
Event::UserEvent(TrEvent::MouseHeldEvent {}) => {}
|
||||
Event::UserEvent(TrEvent::GamepadEvent { gil_event }) => {}
|
||||
Event::DeviceEvent { device_id, event } => {
|
||||
match event {
|
||||
DeviceEvent::Key(keyboard_input) => {
|
||||
match keyboard_input.virtual_keycode.unwrap() {
|
||||
VirtualKeyCode::A => {
|
||||
if keyboard_input.state == ElementState::Pressed {}
|
||||
}
|
||||
VirtualKeyCode::S => {
|
||||
if keyboard_input.state == ElementState::Pressed {}
|
||||
}
|
||||
VirtualKeyCode::P => {
|
||||
if keyboard_input.state == ElementState::Pressed {
|
||||
let data = processor.read_compute_buffer(compute_buffer.clone());
|
||||
image::save_buffer(&Path::new("image.png"), data.as_slice(), (image_data.1).0, (image_data.1).1, image::RGBA(8));
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Event::MainEventsCleared => {
|
||||
funky_sprite.update(delta_time);
|
||||
|
||||
canvas_frame = CanvasFrame::new(window_size);
|
||||
canvas_frame.draw(&funky_sprite);
|
||||
//canvas_frame.draw(&container);
|
||||
// canvas_frame.draw(&compu_sprite1);
|
||||
canvas_frame.draw(&slider);
|
||||
|
||||
compu_frame = CompuFrame::new(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());
|
||||
|
||||
{
|
||||
let g = hprof::enter("Run");
|
||||
processor.run(&surface.clone(),
|
||||
&canvas_frame,
|
||||
&compu_frame);
|
||||
}
|
||||
|
||||
// This dispatches all the systems in parallel (but blocking).
|
||||
world.write_resource::<PersistentState>()
|
||||
.delta_time = delta_time;
|
||||
dispatcher.dispatch(&mut world);
|
||||
// while (accumulator_time - step_size) >= step_size {
|
||||
// accumulator_time -= step_size;
|
||||
// }
|
||||
}
|
||||
_ => ()
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// bucket the events out, but not really
|
||||
// match
|
||||
// event {
|
||||
// Event::NewEvents(_) => {}
|
||||
// Event::WindowEvent { window_id, event } => {}
|
||||
// Event::DeviceEvent { device_id, event } => {}
|
||||
// Event::UserEvent(tr_event) => {}
|
||||
// Event::Suspended => {}
|
||||
// Event::Resumed => {}
|
||||
// Event::MainEventsCleared => {}
|
||||
// Event::RedrawRequested(_) => {}
|
||||
// Event::RedrawEventsCleared => {}
|
||||
// Event::LoopDestroyed => {}
|
||||
// }
|
||||
// Each NewEvents event will clear this event stack
|
||||
world.write_resource::<Vec<TrEvent<TrEventExtension>>>().push(event.into());
|
||||
|
||||
/*
|
||||
match event {
|
||||
|
||||
Event::UserEvent(TrEventExtension::KeyHeldEvent {}) => {}
|
||||
Event::UserEvent(TrEventExtension::MouseHeldEvent {}) => {}
|
||||
Event::UserEvent(TrEventExtension::GamepadEvent { gil_event }) => {}
|
||||
Event::DeviceEvent { device_id, event } => {
|
||||
match event {
|
||||
DeviceEvent::Key(keyboard_input) => {
|
||||
match keyboard_input.virtual_keycode.unwrap() {
|
||||
VirtualKeyCode::A => {
|
||||
if keyboard_input.state == ElementState::Pressed {}
|
||||
}
|
||||
VirtualKeyCode::S => {
|
||||
if keyboard_input.state == ElementState::Pressed {}
|
||||
}
|
||||
VirtualKeyCode::P => {
|
||||
if keyboard_input.state == ElementState::Pressed {
|
||||
let data = world.write_resource::<VkProcessor>().read_compute_buffer(compute_buffer.clone());
|
||||
image::save_buffer(&Path::new("image.png"), data.as_slice(), (image_data.1).0, (image_data.1).1, image::RGBA(8));
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_ => ()
|
||||
}
|
||||
|
||||
bucket the events out, but not really
|
||||
match
|
||||
event {
|
||||
Event::NewEvents(_) => {}
|
||||
Event::WindowEvent { window_id, event } => {}
|
||||
Event::DeviceEvent { device_id, event } => {}
|
||||
Event::UserEvent(tr_event) => {}
|
||||
Event::Suspended => {}
|
||||
Event::Resumed => {}
|
||||
Event::MainEventsCleared => {}
|
||||
Event::RedrawRequested(_) => {}
|
||||
Event::RedrawEventsCleared => {}
|
||||
Event::LoopDestroyed => {}
|
||||
}*/
|
||||
});
|
||||
|
||||
drop(l);
|
||||
|
||||
hprof::end_frame();
|
||||
hprof::profiler().print_timing();
|
||||
}
|
||||
|
||||
|
||||
pub fn click_test(event_loop_proxy: EventLoopProxy<TrEvent>, canvas_state: &CanvasState) {
|
||||
// for i in canvas_state. {
|
||||
// event_loop_proxy.send_event(TrEvent::MouseClickEvent {
|
||||
// position: (0.0, 0.0),
|
||||
// button: MouseButton::Left,
|
||||
// }).ok();
|
||||
// }
|
||||
// hprof::end_frame();
|
||||
// hprof::profiler().print_timing();
|
||||
}
|
||||
|
||||
|
||||
@@ -324,7 +385,5 @@ pub fn click_test(event_loop_proxy: EventLoopProxy<TrEvent>, canvas_state: &Canv
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1
src/parser/mod.rs
Normal file
1
src/parser/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod parser;
|
||||
270
src/parser/parser.rs
Normal file
270
src/parser/parser.rs
Normal file
@@ -0,0 +1,270 @@
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::{escaped, is_not, take, take_till, take_until, take_while};
|
||||
use nom::bytes::complete::{tag, take_while1, take_while_m_n};
|
||||
use nom::character::complete::{anychar, char, line_ending, multispace1, newline, not_line_ending, one_of};
|
||||
use nom::character::complete::alphanumeric1 as alphanumeric;
|
||||
use nom::character::is_alphabetic;
|
||||
use nom::combinator::{cut, map, map_opt, map_res, opt, value, verify};
|
||||
use nom::error::{FromExternalError, ParseError};
|
||||
use nom::IResult;
|
||||
use nom::multi::{fold_many0, many0};
|
||||
use nom::number::complete::be_u16;
|
||||
use nom::sequence::{delimited, preceded, terminated, tuple};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Color {
|
||||
pub red: u8,
|
||||
pub green: u8,
|
||||
pub blue: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum StringFragment<'a> {
|
||||
Literal(&'a str),
|
||||
EscapedChar(char),
|
||||
EscapedWS,
|
||||
}
|
||||
|
||||
pub enum ScriptMeta {
|
||||
Comment(String),
|
||||
Element(String),
|
||||
Meta(String),
|
||||
}
|
||||
|
||||
// I think this is the space for petgraph...
|
||||
pub enum ElementGraph {
|
||||
|
||||
}
|
||||
|
||||
pub struct ElemBuilder();
|
||||
|
||||
impl ElemBuilder {
|
||||
|
||||
}
|
||||
|
||||
// ENTRY
|
||||
pub fn parse_script<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, ScriptMeta, E> {
|
||||
println!("Full input string : {:?}\n", input);
|
||||
|
||||
let mut remaining_str = input;
|
||||
let mut scope = Vec::new();
|
||||
|
||||
// While there is text left in the string
|
||||
while remaining_str.len() > 0 {
|
||||
println!("Remaining Length : {:?}", remaining_str.len());
|
||||
println!("Remaining String: {:?}", remaining_str);
|
||||
|
||||
// Consume whitespace and test
|
||||
let match_type = delimited(
|
||||
sp,
|
||||
alt((
|
||||
map(comment, |s| ScriptMeta::Comment(String::from(s))),
|
||||
// consume an element by pulling all metadata
|
||||
map(elem::<'a, E>, |s| ScriptMeta::Element(String::from(s))),
|
||||
)),
|
||||
opt(sp),
|
||||
)(remaining_str);
|
||||
|
||||
|
||||
remaining_str = match_type.unwrap().0;
|
||||
}
|
||||
|
||||
return Ok((remaining_str, ScriptMeta::Comment(String::default())));
|
||||
}
|
||||
|
||||
pub fn scope<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str> {
|
||||
let (input, _) = delimited(opt(sp), delimited(char('{'), is_not("}"), char('}')), opt(sp))(input)?;
|
||||
//let (input, _) = delimited(char('{'), is_not("}"), char('}'))(input)?;
|
||||
|
||||
Ok((input, input))
|
||||
}
|
||||
|
||||
pub fn elem<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str> {
|
||||
let (input, _) = delimited(opt(sp), tag("elem"), sp)(input)?;
|
||||
|
||||
let (input, elem_name) = parse_token(input)?;
|
||||
|
||||
let (input, _) = scope::<'a, E>(input)?;
|
||||
|
||||
println!("elem , name : {:?} || scope : {:?}", elem_name, input);
|
||||
|
||||
Ok((input, elem_name))
|
||||
}
|
||||
|
||||
// Parse a single alphanumeric token delimited by spaces
|
||||
fn parse_token<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
|
||||
let chars = "\n";
|
||||
escaped(alphanumeric, '\\', one_of(""))(i)
|
||||
}
|
||||
|
||||
// Parse from a # to a newline character
|
||||
pub fn comment<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> {
|
||||
let v = preceded(char('#'),
|
||||
cut(terminated(
|
||||
is_not("\n"),
|
||||
newline,
|
||||
)),
|
||||
)(input)?;
|
||||
|
||||
println!("comment : # {:?}", v.1);
|
||||
|
||||
Ok((v.0, v.0))
|
||||
}
|
||||
|
||||
// Eat up whitespace characters
|
||||
fn sp<'a>(i: &'a str) -> IResult<&'a str, &'a str> {
|
||||
let chars = " \t\r\n";
|
||||
take_while(move |c| chars.contains(c))(i)
|
||||
}
|
||||
|
||||
fn parse_unicode<'a, E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>>(input: &'a str)
|
||||
-> IResult<&'a str, char, E> {
|
||||
// `take_while_m_n` parses between `m` and `n` bytes (inclusive) that match
|
||||
// a predicate. `parse_hex` here parses between 1 and 6 hexadecimal numerals.
|
||||
let parse_hex = take_while_m_n(1, 6, |c: char| c.is_ascii_hexdigit());
|
||||
|
||||
// `preceeded` takes a prefix parser, and if it succeeds, returns the result
|
||||
// of the body parser. In this case, it parses u{XXXX}.
|
||||
let parse_delimited_hex = preceded(
|
||||
char('u'),
|
||||
// `delimited` is like `preceded`, but it parses both a prefix and a suffix.
|
||||
// It returns the result of the middle parser. In this case, it parses
|
||||
// {XXXX}, where XXXX is 1 to 6 hex numerals, and returns XXXX
|
||||
delimited(char('{'), parse_hex, char('}')),
|
||||
);
|
||||
|
||||
// `map_res` takes the result of a parser and applies a function that returns
|
||||
// a Result. In this case we take the hex bytes from parse_hex and attempt to
|
||||
// convert them to a u32.
|
||||
let parse_u32 = map_res(parse_delimited_hex, move |hex| u32::from_str_radix(hex, 16));
|
||||
|
||||
// map_opt is like map_res, but it takes an Option instead of a Result. If
|
||||
// the function returns None, map_opt returns an error. In this case, because
|
||||
// not all u32 values are valid unicode code points, we have to fallibly
|
||||
// convert to char with from_u32.
|
||||
map_opt(parse_u32, |value| std::char::from_u32(value))(input)
|
||||
}
|
||||
|
||||
/// Parse an escaped character: \n, \t, \r, \u{00AC}, etc.
|
||||
fn parse_escaped_char<'a, E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>>(input: &'a str)
|
||||
-> IResult<&'a str, char, E> {
|
||||
preceded(
|
||||
char('\\'),
|
||||
// `alt` tries each parser in sequence, returning the result of
|
||||
// the first successful match
|
||||
alt((
|
||||
parse_unicode,
|
||||
// The `value` parser returns a fixed value (the first argument) if its
|
||||
// parser (the second argument) succeeds. In these cases, it looks for
|
||||
// the marker characters (n, r, t, etc) and returns the matching
|
||||
// character (\n, \r, \t, etc).
|
||||
value('\n', char('n')),
|
||||
value('\r', char('r')),
|
||||
value('\t', char('t')),
|
||||
value('\u{08}', char('b')),
|
||||
value('\u{0C}', char('f')),
|
||||
value('\\', char('\\')),
|
||||
value('/', char('/')),
|
||||
value('"', char('"')),
|
||||
)),
|
||||
)(input)
|
||||
}
|
||||
|
||||
/// Parse a backslash, followed by any amount of whitespace. This is used later
|
||||
/// to discard any escaped whitespace.
|
||||
fn parse_escaped_whitespace<'a, E: ParseError<&'a str>>(
|
||||
input: &'a str,
|
||||
) -> IResult<&'a str, &'a str, E> {
|
||||
preceded(char('\\'), multispace1)(input)
|
||||
}
|
||||
|
||||
/// Parse a non-empty block of text that doesn't include \ or "
|
||||
fn parse_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> {
|
||||
// `is_not` parses a string of 0 or more characters that aren't one of the
|
||||
// given characters.
|
||||
let not_quote_slash = is_not("\"\\");
|
||||
|
||||
// `verify` runs a parser, then runs a verification function on the output of
|
||||
// the parser. The verification function accepts out output only if it
|
||||
// returns true. In this case, we want to ensure that the output of is_not
|
||||
// is non-empty.
|
||||
verify(not_quote_slash, |s: &str| !s.is_empty())(input)
|
||||
}
|
||||
|
||||
/// Combine parse_literal, parse_escaped_whitespace, and parse_escaped_char
|
||||
/// into a StringFragment.
|
||||
fn parse_fragment<'a, E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>>(
|
||||
input: &'a str,
|
||||
) -> IResult<&'a str, StringFragment<'a>, E> {
|
||||
alt((
|
||||
// The `map` combinator runs a parser, then applies a function to the output
|
||||
// of that parser.
|
||||
map(parse_literal, StringFragment::Literal),
|
||||
map(parse_escaped_char, StringFragment::EscapedChar),
|
||||
value(StringFragment::EscapedWS, parse_escaped_whitespace),
|
||||
))(input)
|
||||
}
|
||||
|
||||
/// Parse a string. Use a loop of parse_fragment and push all of the fragments
|
||||
/// into an output string.
|
||||
fn parse_string<'a, E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>>(input: &'a str) -> IResult<&'a str, String, E> {
|
||||
// fold_many0 is the equivalent of iterator::fold. It runs a parser in a loop,
|
||||
// and for each output value, calls a folding function on each output value.
|
||||
let build_string = fold_many0(
|
||||
// Our parser function– parses a single string fragment
|
||||
parse_fragment,
|
||||
// Our init value, an empty string
|
||||
String::new(),
|
||||
// Our folding function. For each fragment, append the fragment to the
|
||||
// string.
|
||||
|mut string, fragment| {
|
||||
match fragment {
|
||||
StringFragment::Literal(s) => string.push_str(s),
|
||||
StringFragment::EscapedChar(c) => string.push(c),
|
||||
StringFragment::EscapedWS => {}
|
||||
}
|
||||
string
|
||||
},
|
||||
);
|
||||
|
||||
delimited(char('"'), build_string, char('"'))(input)
|
||||
}
|
||||
|
||||
// Unused stuff
|
||||
pub fn length_value(input: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
let (input, length) = be_u16(input)?;
|
||||
take(length)(input)
|
||||
}
|
||||
|
||||
pub fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> {
|
||||
u8::from_str_radix(input, 16)
|
||||
}
|
||||
|
||||
pub fn is_hex_digit(c: char) -> bool {
|
||||
c.is_digit(16)
|
||||
}
|
||||
|
||||
pub fn hex_primary(input: &str) -> IResult<&str, u8> {
|
||||
map_res(
|
||||
take_while_m_n(2, 2, is_hex_digit),
|
||||
from_hex,
|
||||
)(input)
|
||||
}
|
||||
|
||||
pub fn hex_color(input: &str) -> IResult<&str, Color> {
|
||||
let (input, _) = tag("#")(input)?;
|
||||
let (input, (red, green, blue)) = tuple((hex_primary, hex_primary, hex_primary))(input)?;
|
||||
|
||||
Ok((input, Color { red, green, blue }))
|
||||
}
|
||||
|
||||
/*
|
||||
// ( and any amount of bytes ). Returns the bytes between the ()
|
||||
fn parens(input: &str) -> IResult<&str, &str> {
|
||||
delimited(char('('), is_not(")"), char(')'))(input)
|
||||
}
|
||||
|
||||
// `take_while_m_n` parses between `m` and `n` bytes (inclusive) that match
|
||||
// a predicate. `parse_hex` here parses between 1 and 6 hexadecimal numerals.
|
||||
let parse_hex = take_while_m_n(1, 6, |c: char| c.is_ascii_hexdigit());
|
||||
*/
|
||||
220
src/render_system.rs
Normal file
220
src/render_system.rs
Normal file
@@ -0,0 +1,220 @@
|
||||
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};
|
||||
use crate::PersistentState;
|
||||
use crate::util::vertex::{ImageVertex3D, TextureVertex3D, VertexTypeContainer};
|
||||
use crate::vkprocessor::VkProcessor;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Position {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub z: u8,
|
||||
}
|
||||
|
||||
impl Component for Position {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Geometry {
|
||||
pub size_x: f32,
|
||||
pub size_y: f32,
|
||||
pub rotation: f32,
|
||||
}
|
||||
|
||||
impl Component for Geometry {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Textures {
|
||||
pub textures: Vec<Arc<CanvasTextureHandle>>,
|
||||
}
|
||||
|
||||
impl Component for Textures {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Images {
|
||||
pub images: Vec<Arc<CanvasImageHandle>>,
|
||||
pub image_resolutions: Vec<(u32, u32)>,
|
||||
}
|
||||
|
||||
impl Component for Images {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
||||
pub struct RenderSystem;
|
||||
|
||||
impl<'a> System<'a> for RenderSystem {
|
||||
type SystemData = (
|
||||
WriteStorage<'a, Position>,
|
||||
WriteStorage<'a, Geometry>,
|
||||
WriteStorage<'a, Textures>,
|
||||
WriteStorage<'a, Images>,
|
||||
Write<'a, PersistentState>, // delta_time, window size, etc.
|
||||
Write<'a, VkProcessor>, // Renderer
|
||||
);
|
||||
|
||||
fn run(&mut self, (
|
||||
mut pos_list,
|
||||
mut geom_list,
|
||||
mut textures_list,
|
||||
mut images_list,
|
||||
mut state,
|
||||
mut vk_processor
|
||||
): Self::SystemData) {
|
||||
state.canvas_frame = CanvasFrame::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 (position, geometry, textures) in (&mut pos_list, &mut geom_list, &mut textures_list).join() {
|
||||
// geom.pos_x += mv.vel_x * state.delta_time;
|
||||
// geom.pos_y += mv.vel_y * state.delta_time;
|
||||
|
||||
let window_size = state.window_size.clone();
|
||||
let pos = (position.x, position.y);
|
||||
let size = (geometry.size_x, geometry.size_y);
|
||||
let normalized_depth = position.z as f32 / 255.0;
|
||||
|
||||
let textured_vertices = vec![
|
||||
VertexTypeContainer::TextureType(
|
||||
generate_textured_verts(window_size, pos, size, normalized_depth),
|
||||
textures.textures.get(0).unwrap().clone(),
|
||||
)
|
||||
];
|
||||
|
||||
state.canvas_frame.add(textured_vertices);
|
||||
}
|
||||
|
||||
for (position, geometry, images) in (&mut pos_list, &mut geom_list, &mut images_list).join() {
|
||||
// geom.pos_x += mv.vel_x * state.delta_time;
|
||||
// geom.pos_y += mv.vel_y * state.delta_time;
|
||||
|
||||
let window_size = state.window_size.clone();
|
||||
let pos = (position.x, position.y);
|
||||
let size = (geometry.size_x, geometry.size_y);
|
||||
let normalized_depth = position.z as f32 / 255.0;
|
||||
|
||||
let textured_vertices = vec![
|
||||
VertexTypeContainer::ImageType(
|
||||
generate_image_verts(window_size, pos, size, images.image_resolutions.get(0).unwrap().clone(), normalized_depth),
|
||||
images.images.get(0).unwrap().clone(),
|
||||
)
|
||||
];
|
||||
|
||||
state.canvas_frame.add(textured_vertices);
|
||||
}
|
||||
|
||||
let compu_frame = &state.compu_frame;
|
||||
vk_processor.run(&state.surface.clone().unwrap(),
|
||||
&state.canvas_frame,
|
||||
compu_frame);
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_image_verts(
|
||||
window_size: (u32, u32),
|
||||
position: (f32, f32),
|
||||
size: (f32, f32),
|
||||
image_size: (u32, u32),
|
||||
depth: f32,
|
||||
) -> Vec<ImageVertex3D> {
|
||||
let image_size = (image_size.0 as f32, image_size.1 as f32);
|
||||
|
||||
// screen space position
|
||||
let ss_position = (
|
||||
position.0 / window_size.0 as f32 - 1.0,
|
||||
position.1 / window_size.1 as f32 - 1.0
|
||||
);
|
||||
|
||||
// screen space size
|
||||
let ss_size = (
|
||||
size.0 / window_size.0 as f32,
|
||||
size.1 / window_size.1 as f32
|
||||
);
|
||||
|
||||
// pub fn new(position: (f32, f32),
|
||||
// size: (f32, f32),
|
||||
// depth: u32,
|
||||
// image_size: (f32, f32),
|
||||
// image_handle: Arc<CanvasImageHandle>) -> CompuSprite {
|
||||
|
||||
vec![
|
||||
ImageVertex3D {
|
||||
v_position: [ss_position.0, ss_position.1, depth], // top left
|
||||
ti_position: [-0.0, -0.0],
|
||||
},
|
||||
ImageVertex3D {
|
||||
v_position: [ss_position.0, ss_position.1 + ss_size.1, depth], // bottom left
|
||||
ti_position: [-0.0, image_size.1],
|
||||
},
|
||||
ImageVertex3D {
|
||||
v_position: [ss_position.0 + ss_size.0, ss_position.1 + ss_size.1, depth], // bottom right
|
||||
ti_position: [image_size.0, image_size.1],
|
||||
},
|
||||
ImageVertex3D {
|
||||
v_position: [ss_position.0, ss_position.1, depth], // top left
|
||||
ti_position: [-0.0, -0.0],
|
||||
},
|
||||
ImageVertex3D {
|
||||
v_position: [ss_position.0 + ss_size.0, ss_position.1 + ss_size.1, depth], // bottom right
|
||||
ti_position: [image_size.0, image_size.1],
|
||||
},
|
||||
ImageVertex3D {
|
||||
v_position: [ss_position.0 + ss_size.0, ss_position.1, depth], // top right
|
||||
ti_position: [image_size.0, -0.0],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn generate_textured_verts(
|
||||
window_size: (u32, u32),
|
||||
position: (f32, f32),
|
||||
size: (f32, f32),
|
||||
depth: f32,
|
||||
) -> Vec<TextureVertex3D> {
|
||||
let ss_position = (
|
||||
position.0 / window_size.0 as f32 - 1.0,
|
||||
position.1 / window_size.1 as f32 - 1.0
|
||||
);
|
||||
|
||||
let ss_size = (
|
||||
size.0 / window_size.0 as f32,
|
||||
size.1 / window_size.1 as f32
|
||||
);
|
||||
|
||||
vec![
|
||||
TextureVertex3D {
|
||||
v_position: [ss_position.0, ss_position.1, depth], // top left
|
||||
ti_position: [-0.0, -0.0],
|
||||
},
|
||||
TextureVertex3D {
|
||||
v_position: [ss_position.0, ss_position.1 + ss_size.1, depth], // bottom left
|
||||
ti_position: [-0.0, 1.0],
|
||||
},
|
||||
TextureVertex3D {
|
||||
v_position: [ss_position.0 + ss_size.0, ss_position.1 + ss_size.1, depth], // bottom right
|
||||
ti_position: [1.0, 1.0],
|
||||
},
|
||||
TextureVertex3D {
|
||||
v_position: [ss_position.0, ss_position.1, depth], // top left
|
||||
ti_position: [-0.0, -0.0],
|
||||
},
|
||||
TextureVertex3D {
|
||||
v_position: [ss_position.0 + ss_size.0, ss_position.1 + ss_size.1, depth], // bottom right
|
||||
ti_position: [1.0, 1.0],
|
||||
},
|
||||
TextureVertex3D {
|
||||
v_position: [ss_position.0 + ss_size.0, ss_position.1, depth], // top right
|
||||
ti_position: [1.0, -0.0],
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -1,25 +1,214 @@
|
||||
use winit::window::WindowId;
|
||||
use winit::event::{WindowEvent, DeviceId, DeviceEvent, KeyboardInput, ModifiersState, MouseScrollDelta, TouchPhase, ElementState, MouseButton, AxisId, Touch};
|
||||
use winit::window::{WindowId, Theme};
|
||||
use winit::event::{WindowEvent, DeviceId, DeviceEvent, KeyboardInput, ModifiersState, MouseScrollDelta, TouchPhase, ElementState, MouseButton, AxisId, Touch, StartCause, Event};
|
||||
use std::path::PathBuf;
|
||||
use winit::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use gilrs::Event as GilEvent;
|
||||
use vulkano::pipeline::shader::GeometryShaderExecutionMode::TrianglesWithAdjacency;
|
||||
|
||||
pub enum TrEvent {
|
||||
MouseFocusEvent {
|
||||
position : (f32, f32),
|
||||
},
|
||||
MouseClickEvent {
|
||||
position : (f32, f32),
|
||||
button : MouseButton,
|
||||
},
|
||||
MouseHeldEvent {
|
||||
#[derive(Clone)]
|
||||
pub enum TrUIEvent<T> {
|
||||
UIEvent(T)
|
||||
}
|
||||
|
||||
},
|
||||
KeyHeldEvent {
|
||||
#[derive(Clone)]
|
||||
pub enum TrEventExtension {
|
||||
|
||||
},
|
||||
/// Custom events here
|
||||
MouseHeldEvent {},
|
||||
KeyHeldEvent {},
|
||||
GamepadEvent {
|
||||
gil_event: GilEvent,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TrEvent<T> {
|
||||
|
||||
/// Custom events here
|
||||
MouseHeldEvent {},
|
||||
KeyHeldEvent {},
|
||||
GamepadEvent {
|
||||
gil_event: GilEvent,
|
||||
},
|
||||
|
||||
/// Winit events here
|
||||
NewEvents(StartCause),
|
||||
WindowEvent {
|
||||
window_id: WindowId,
|
||||
event: TrWindowEvent,
|
||||
},
|
||||
DeviceEvent {
|
||||
device_id: DeviceId,
|
||||
event: DeviceEvent,
|
||||
},
|
||||
UserEvent(T),
|
||||
Suspended,
|
||||
Resumed,
|
||||
MainEventsCleared,
|
||||
RedrawRequested(WindowId),
|
||||
RedrawEventsCleared,
|
||||
LoopDestroyed,
|
||||
}
|
||||
|
||||
|
||||
impl<T> From<Event<'_, T>> for TrEvent<T> {
|
||||
fn from(event: Event<T>) -> Self {
|
||||
match event {
|
||||
Event::NewEvents(cause) => {
|
||||
TrEvent::NewEvents(cause)
|
||||
},
|
||||
Event::WindowEvent { window_id: window_id, event: event } => {
|
||||
TrEvent::WindowEvent {
|
||||
window_id: window_id,
|
||||
event: match event {
|
||||
WindowEvent::AxisMotion { device_id, axis, value } => {
|
||||
TrWindowEvent::AxisMotion { device_id, axis, value }
|
||||
},
|
||||
WindowEvent::Resized(physical_size) => {
|
||||
TrWindowEvent::Resized(physical_size)
|
||||
}
|
||||
WindowEvent::Moved(physical_position) => {
|
||||
TrWindowEvent::Moved(physical_position)
|
||||
}
|
||||
WindowEvent::CloseRequested => {
|
||||
TrWindowEvent::CloseRequested
|
||||
}
|
||||
WindowEvent::Destroyed => {
|
||||
TrWindowEvent::Destroyed
|
||||
}
|
||||
WindowEvent::DroppedFile(path_buf) => {
|
||||
TrWindowEvent::DroppedFile(path_buf)
|
||||
}
|
||||
WindowEvent::HoveredFile(path_buf) => {
|
||||
TrWindowEvent::HoveredFile(path_buf)
|
||||
}
|
||||
WindowEvent::HoveredFileCancelled => {
|
||||
TrWindowEvent::HoveredFileCancelled
|
||||
}
|
||||
WindowEvent::ReceivedCharacter(char) => {
|
||||
TrWindowEvent::ReceivedCharacter(char)
|
||||
}
|
||||
WindowEvent::Focused(bool) => {
|
||||
TrWindowEvent::Focused(bool)
|
||||
}
|
||||
WindowEvent::KeyboardInput { device_id: device_id, input: input, is_synthetic: is_synthetic } => {
|
||||
TrWindowEvent::KeyboardInput { device_id, input, is_synthetic }
|
||||
}
|
||||
WindowEvent::ModifiersChanged(modifiers_state) => {
|
||||
TrWindowEvent::ModifiersChanged(modifiers_state)
|
||||
}
|
||||
WindowEvent::CursorMoved { device_id: device_id, position: position, modifiers: modifiers } => {
|
||||
TrWindowEvent::CursorMoved { device_id, position, modifiers }
|
||||
}
|
||||
WindowEvent::CursorEntered { device_id: device_id } => {
|
||||
TrWindowEvent::CursorEntered { device_id }
|
||||
}
|
||||
WindowEvent::CursorLeft { device_id: device_id } => {
|
||||
TrWindowEvent::CursorLeft { device_id }
|
||||
}
|
||||
WindowEvent::MouseWheel { device_id: device_id, delta: delta, phase: phase, modifiers: modifiers } => {
|
||||
TrWindowEvent::MouseWheel { device_id, delta, phase, modifiers }
|
||||
}
|
||||
WindowEvent::MouseInput { device_id: device_id, state: state, button: button, modifiers: modifiers } => {
|
||||
TrWindowEvent::MouseInput { device_id, state, button, modifiers }
|
||||
}
|
||||
WindowEvent::TouchpadPressure { device_id: device_id, pressure: pressure, stage: stage } => {
|
||||
TrWindowEvent::TouchpadPressure { device_id, pressure, stage }
|
||||
}
|
||||
WindowEvent::Touch(touch) => {
|
||||
TrWindowEvent::Touch(touch)
|
||||
}
|
||||
WindowEvent::ScaleFactorChanged { scale_factor: scale_factor, new_inner_size: new_inner_size } => {
|
||||
TrWindowEvent::ScaleFactorChanged { scale_factor, new_inner_size: PhysicalSize { width: new_inner_size.width, height: new_inner_size.height } }
|
||||
}
|
||||
WindowEvent::ThemeChanged(theme) => {
|
||||
TrWindowEvent::ThemeChanged(theme)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::DeviceEvent { device_id: device_id, event: event } => {
|
||||
TrEvent::DeviceEvent { device_id, event }
|
||||
}
|
||||
Event::UserEvent(user_event) => {
|
||||
TrEvent::UserEvent(user_event)
|
||||
}
|
||||
Event::Suspended => {
|
||||
TrEvent::Suspended
|
||||
}
|
||||
Event::Resumed => {
|
||||
TrEvent::Resumed
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
TrEvent::MainEventsCleared
|
||||
}
|
||||
Event::RedrawRequested(window_id) => {
|
||||
TrEvent::RedrawRequested(window_id)
|
||||
}
|
||||
Event::RedrawEventsCleared => {
|
||||
TrEvent::RedrawEventsCleared
|
||||
}
|
||||
Event::LoopDestroyed => {
|
||||
TrEvent::LoopDestroyed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum TrWindowEvent {
|
||||
|
||||
Resized(PhysicalSize<u32>),
|
||||
Moved(PhysicalPosition<i32>),
|
||||
CloseRequested,
|
||||
Destroyed,
|
||||
DroppedFile(PathBuf),
|
||||
HoveredFile(PathBuf),
|
||||
HoveredFileCancelled,
|
||||
ReceivedCharacter(char),
|
||||
Focused(bool),
|
||||
KeyboardInput {
|
||||
device_id: DeviceId,
|
||||
input: KeyboardInput,
|
||||
is_synthetic: bool,
|
||||
},
|
||||
ModifiersChanged(ModifiersState),
|
||||
CursorMoved {
|
||||
device_id: DeviceId,
|
||||
position: PhysicalPosition<f64>,
|
||||
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
|
||||
modifiers: ModifiersState,
|
||||
},
|
||||
CursorEntered { device_id: DeviceId },
|
||||
CursorLeft { device_id: DeviceId },
|
||||
MouseWheel {
|
||||
device_id: DeviceId,
|
||||
delta: MouseScrollDelta,
|
||||
phase: TouchPhase,
|
||||
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
|
||||
modifiers: ModifiersState,
|
||||
},
|
||||
MouseInput {
|
||||
device_id: DeviceId,
|
||||
state: ElementState,
|
||||
button: MouseButton,
|
||||
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
|
||||
modifiers: ModifiersState,
|
||||
},
|
||||
TouchpadPressure {
|
||||
device_id: DeviceId,
|
||||
pressure: f32,
|
||||
stage: i64,
|
||||
},
|
||||
AxisMotion {
|
||||
device_id: DeviceId,
|
||||
axis: AxisId,
|
||||
value: f64,
|
||||
},
|
||||
Touch(Touch),
|
||||
ScaleFactorChanged {
|
||||
scale_factor: f64,
|
||||
new_inner_size: PhysicalSize<u32>,
|
||||
},
|
||||
ThemeChanged(Theme),
|
||||
}
|
||||
@@ -51,13 +51,12 @@ vulkano::impl_vertex!(GlyphInstance, screen_position, atlas_position, atlas_size
|
||||
// ==============================================================================
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum VertexType {
|
||||
pub enum VertexTypeContainer {
|
||||
TextureType(Vec<TextureVertex3D>, Arc<CanvasTextureHandle>),
|
||||
ImageType(Vec<ImageVertex3D>, Arc<CanvasImageHandle>),
|
||||
ColorType(Vec<ColorVertex3D>),
|
||||
ThreeDType(Vec<Vertex3D>),
|
||||
TextType(Vec<ColorVertex3D>),
|
||||
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
@@ -7,9 +7,8 @@ use vulkano::sync;
|
||||
use std::sync::Arc;
|
||||
use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError, Capabilities, FullscreenExclusive, ColorSpace};
|
||||
use vulkano::image::swapchain::SwapchainImage;
|
||||
use crate::compute::compu_state::CompuState;
|
||||
use vulkano::image::ImageUsage;
|
||||
use crate::compute::compu_frame::CompuFrame;
|
||||
use crate::canvas::compu_frame::CompuFrame;
|
||||
use crate::canvas::canvas_frame::{CanvasFrame};
|
||||
use std::time::Duration;
|
||||
use vulkano::pipeline::depth_stencil::{DynamicStencilValue, StencilFaceFlags};
|
||||
@@ -18,24 +17,26 @@ use crate::canvas::canvas_state::CanvasState;
|
||||
use crate::canvas::managed::shader::generic_shader::GenericShader;
|
||||
use crate::canvas::managed::shader::text_shader::TextShader;
|
||||
use crate::canvas::managed::handles::{CanvasTextureHandle, CompiledShaderHandle, CanvasFontHandle, CanvasImageHandle};
|
||||
use crate::compute::managed::handles::{CompuKernelHandle, CompuBufferHandle};
|
||||
use crate::util::vertex::{VertexType, ColorVertex3D, TextVertex3D, TextureVertex3D, ImageVertex3D};
|
||||
use crate::canvas::managed::handles::{CompuKernelHandle, CompuBufferHandle};
|
||||
use crate::util::vertex::{VertexTypeContainer, ColorVertex3D, TextVertex3D, TextureVertex3D, ImageVertex3D};
|
||||
use vulkano_text::DrawText;
|
||||
use winit::window::{Window, WindowBuilder};
|
||||
use vulkano::instance::debug::DebugCallback;
|
||||
use winit::dpi::LogicalSize;
|
||||
use vulkano_win::VkSurfaceBuild;
|
||||
use winit::event_loop::EventLoop;
|
||||
use specs::prelude::Resource;
|
||||
|
||||
|
||||
/// VKProcessor holds the vulkan instance information, the swapchain,
|
||||
/// and the compute and canvas states
|
||||
#[derive(Default)]
|
||||
pub struct VkProcessor {
|
||||
|
||||
// Vulkan state fields
|
||||
//pub physical: PhysicalDevice<'a>,
|
||||
pub device: Arc<Device>,
|
||||
pub queues: QueuesIter,
|
||||
pub queue: Arc<Queue>,
|
||||
pub device: Option<Arc<Device>>,
|
||||
pub queues: Option<QueuesIter>,
|
||||
pub queue: Option<Arc<Queue>>,
|
||||
|
||||
pub swapchain: Option<Arc<Swapchain<Window>>>,
|
||||
pub swapchain_images: Option<Vec<Arc<SwapchainImage<Window>>>>,
|
||||
@@ -45,14 +46,10 @@ pub struct VkProcessor {
|
||||
/// State holding textures, images, and their related vertex buffers
|
||||
canvas_state: CanvasState,
|
||||
|
||||
/// State holding
|
||||
compute_state: CompuState,
|
||||
|
||||
capabilities: Capabilities,
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl VkProcessor {
|
||||
/// Creates a new VkProcessor from an instance and surface
|
||||
/// This includes the physical device, queues, compute and canvas state
|
||||
@@ -78,14 +75,12 @@ impl VkProcessor {
|
||||
let capabilities = surface.capabilities(physical).unwrap();
|
||||
|
||||
VkProcessor {
|
||||
device: device.clone(),
|
||||
queue: queue.clone(),
|
||||
queues: queues,
|
||||
device: Some(device.clone()),
|
||||
queue: Some(queue.clone()),
|
||||
queues: Some(queues),
|
||||
swapchain: None,
|
||||
swapchain_images: None,
|
||||
swapchain_recreate_needed: false,
|
||||
compute_state: CompuState::new(),
|
||||
capabilities: capabilities.clone(),
|
||||
canvas_state: CanvasState::new(queue, device, physical, capabilities),
|
||||
}
|
||||
}
|
||||
@@ -115,14 +110,14 @@ impl VkProcessor {
|
||||
panic!("window closed");
|
||||
};
|
||||
|
||||
Swapchain::new(self.device.clone(),
|
||||
Swapchain::new(self.device.clone().unwrap(),
|
||||
surface.clone(),
|
||||
capabilities.min_image_count, // number of attachment images
|
||||
format,
|
||||
initial_dimensions,
|
||||
1, // Layers
|
||||
ImageUsage::color_attachment(),
|
||||
&self.queue,
|
||||
(&self.queue).as_ref().unwrap(),
|
||||
SurfaceTransform::Identity,
|
||||
alpha,
|
||||
PresentMode::Immediate,
|
||||
@@ -168,16 +163,16 @@ impl VkProcessor {
|
||||
|
||||
/// A hardcoded list of kernels which can be preloaded from this function
|
||||
pub fn preload_kernels(&mut self) {
|
||||
self.compute_state.new_kernel(String::from("simple-homogenize.compute"), self.device.clone());
|
||||
self.compute_state.new_kernel(String::from("simple-edge.compute"), self.device.clone());
|
||||
self.canvas_state.new_kernel(String::from("simple-homogenize.compute"), self.device.clone().unwrap());
|
||||
self.canvas_state.new_kernel(String::from("simple-edge.compute"), self.device.clone().unwrap());
|
||||
}
|
||||
|
||||
/// A hardcoded list of shaders which can be preloaded from this function
|
||||
pub fn preload_shaders(&mut self) {
|
||||
self.canvas_state.load_shader::<GenericShader, ColorVertex3D>(String::from("color-passthrough"), self.capabilities.clone());
|
||||
self.canvas_state.load_shader::<GenericShader, TextureVertex3D>(String::from("simple_texture"), self.capabilities.clone());
|
||||
self.canvas_state.load_shader::<GenericShader, ImageVertex3D>(String::from("simple_image"), self.capabilities.clone());
|
||||
self.canvas_state.load_shader::<TextShader, ColorVertex3D>(String::from("simple_text"), self.capabilities.clone());
|
||||
self.canvas_state.load_shader::<GenericShader, ColorVertex3D>(String::from("color-passthrough"));
|
||||
self.canvas_state.load_shader::<GenericShader, TextureVertex3D>(String::from("simple_texture"));
|
||||
self.canvas_state.load_shader::<GenericShader, ImageVertex3D>(String::from("simple_image"));
|
||||
self.canvas_state.load_shader::<TextShader, ColorVertex3D>(String::from("simple_text"));
|
||||
}
|
||||
|
||||
/// A hardcoded list of shaders which can be proloaded from this function
|
||||
@@ -192,7 +187,7 @@ impl VkProcessor {
|
||||
|
||||
/// O(n) Lookup for the matching kernel string
|
||||
pub fn get_kernel_handle(&self, kernel_name: String) -> Option<Arc<CompuKernelHandle>> {
|
||||
self.compute_state.get_kernel_handle(kernel_name)
|
||||
self.canvas_state.get_kernel_handle(kernel_name)
|
||||
}
|
||||
|
||||
/// O(n) Lookup for the matching shader string
|
||||
@@ -215,17 +210,17 @@ impl VkProcessor {
|
||||
|
||||
/// Builds a compute buffer and returns it's handle
|
||||
pub fn new_compute_buffer(&mut self, data: Vec<u8>, dimensions: (u32, u32), stride: u32) -> Arc<CompuBufferHandle> {
|
||||
self.compute_state.new_compute_buffer(data, dimensions, stride, self.device.clone())
|
||||
self.canvas_state.new_compute_buffer(data, dimensions, stride, self.device.clone().unwrap())
|
||||
}
|
||||
|
||||
/// Takes a compute buffer handle and returns the read data
|
||||
pub fn read_compute_buffer(&mut self, handle: Arc<CompuBufferHandle>) -> Vec<u8> {
|
||||
self.compute_state.read_compute_buffer(handle)
|
||||
self.canvas_state.read_compute_buffer(handle)
|
||||
}
|
||||
|
||||
/// Takes a compute buffer handle and writes the received data
|
||||
pub fn write_compute_buffer(&self, handle: Arc<CompuBufferHandle>, data: Vec<u8>) {
|
||||
self.compute_state.write_compute_buffer(handle, data)
|
||||
self.canvas_state.write_compute_buffer(handle, data)
|
||||
}
|
||||
|
||||
/// Run the VKprocessor for a single frame, consuming the Canvas/Compu Frames
|
||||
@@ -236,7 +231,7 @@ impl VkProcessor {
|
||||
) {
|
||||
{
|
||||
let g = hprof::enter("Waiting at queue");
|
||||
self.queue.wait();
|
||||
self.queue.as_ref().unwrap().wait();
|
||||
}
|
||||
|
||||
let g = hprof::enter("Frame buffer, future, swapchain recreate");
|
||||
@@ -283,11 +278,11 @@ impl VkProcessor {
|
||||
// let mut draw_text = DrawText::new(self.device.clone(), self.queue.clone(), self.swapchain.unwrap().clone(), &self.swapchain_images.images);
|
||||
|
||||
let mut command_buffer =
|
||||
AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family()).unwrap();
|
||||
AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone().unwrap(), self.queue.as_ref().unwrap().family()).unwrap();
|
||||
|
||||
let g = hprof::enter("Push compute commands to command buffer");
|
||||
// Add the compute commands
|
||||
self.compute_state.compute_commands(compute_frame, &mut command_buffer, &self.canvas_state);
|
||||
self.canvas_state.compute_commands(compute_frame, &mut command_buffer);
|
||||
drop(g);
|
||||
|
||||
let g = hprof::enter("Push draw commands to command buffer");
|
||||
@@ -303,15 +298,15 @@ impl VkProcessor {
|
||||
// Wait on the previous frame, then execute the command buffer and present the image
|
||||
{
|
||||
let g = hprof::enter("Joining on the framebuffer");
|
||||
let mut future = sync::now(self.device.clone())
|
||||
let mut future = sync::now(self.device.clone().unwrap())
|
||||
.join(acquire_future);
|
||||
drop(g);
|
||||
|
||||
let g = hprof::enter("Running the kernel and waiting on the future");
|
||||
|
||||
let future = future
|
||||
.then_execute(self.queue.clone(), command_buffer).unwrap()
|
||||
.then_swapchain_present(self.queue.clone(), self.swapchain.clone().unwrap().clone(), image_num)
|
||||
.then_execute(self.queue.clone().unwrap(), command_buffer).unwrap()
|
||||
.then_swapchain_present(self.queue.clone().unwrap(), self.swapchain.clone().unwrap().clone(), image_num)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
||||
Reference in New Issue
Block a user