You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Trac3r-rust/src/main.rs

472 lines
15 KiB

6 years ago
#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_mut)]
6 years ago
6 years ago
extern crate cgmath;
extern crate hprof;
extern crate image;
6 years ago
extern crate nalgebra as na;
extern crate rand;
extern crate time;
use std::path::Path;
use std::sync::Arc;
use gilrs::{Button, Event as GilEvent, Gamepad, GamepadId, Gilrs};
use vulkano::instance::debug::DebugCallback;
use vulkano::instance::Instance;
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano_win::VkSurfaceBuild;
use winit::dpi::LogicalSize;
5 years ago
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, Window};
use crate::canvas::canvas_frame::{CanvasFrame, Drawable, Eventable, Updatable};
use crate::canvas::canvas_state::CanvasState;
use crate::canvas::managed::handles::{CanvasFontHandle, CanvasTextureHandle, Handle};
use canvas::compu_frame::CompuFrame;
use crate::canvas::managed::handles::{CompuBufferHandle, CompuKernelHandle};
use crate::drawables::compu_sprite::CompuSprite;
use crate::drawables::rect::Rect;
use crate::drawables::sprite::Sprite;
use crate::drawables::text::Text;
use crate::util::load_raw;
use crate::util::timer::Timer;
use crate::util::tr_event::{TrEventExtension, TrEvent};
use crate::util::vertex::{TextureVertex3D, VertexTypeContainer};
5 years ago
use crate::vkprocessor::VkProcessor;
use crate::drawables::slider::Slider;
6 years ago
pub mod util;
pub mod vkprocessor;
pub mod drawables;
6 years ago
pub mod canvas;
5 years ago
5 years ago
extern crate specs;
use specs::prelude::*;
use vulkano::swapchain::Surface;
5 years ago
5 years ago
//struct Draws(Box<dyn Drawable + Sync + Send>, Box<dyn Eventable<TrEventExtension> + Sync + Send>);
struct SSprite(Box<dyn Drawable + Sync + Send>);
5 years ago
impl Component for SSprite {
type Storage = VecStorage<Self>;
}
pub struct Move {
vel_x: f32,
vel_y: f32,
5 years ago
}
5 years ago
impl Component for Move {
5 years ago
type Storage = VecStorage<Self>;
}
pub struct Geom {
5 years ago
pos_x: f32,
pos_y: f32,
size_x: f32,
size_y: f32,
rotation: f32,
depth: f32,
5 years ago
}
5 years ago
impl Component for Geom {
5 years ago
type Storage = VecStorage<Self>;
}
#[derive(Default)]
struct PersistentState {
surface: Option<Arc<Surface<Window>>>,
window_size: (u32, u32),
5 years ago
delta_time: f32,
canvas_frame: CanvasFrame,
compu_frame: CompuFrame,
}
5 years ago
// 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
*/
struct RenderSystem;
5 years ago
impl<'a> System<'a> for RenderSystem {
type SystemData = (
5 years ago
WriteStorage<'a, Move>, // its velocity
WriteStorage<'a, Geom>, // its size, position & rotation
WriteStorage<'a, SSprite>, // generates the vertices
Write<'a, PersistentState>, // delta_time, window size, etc.
Write<'a, VkProcessor>, // Renderer
);
fn run(&mut self, (mut mv, mut geom, mut draw, mut state, mut vk_processor): Self::SystemData) {
state.canvas_frame = CanvasFrame::new(state.window_size);
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 (mv, geom, draw) in (&mut mv, &mut geom, &mut draw).join() {
5 years ago
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();
state.canvas_frame.add(draw.0.get(
window_size,
5 years ago
(geom.pos_x, geom.pos_y),
geom.rotation,
(geom.size_x, geom.size_y),
geom.depth,
));
5 years ago
}
for draw_data in (&draw).join() {
let size = state.window_size.clone();
}
vk_processor.run(&state.surface.clone().unwrap(),
5 years ago
&state.canvas_frame,
&state.compu_frame);
}
}
5 years ago
struct EventSystem;
impl<'a> System<'a> for EventSystem {
type SystemData = (
5 years ago
WriteStorage<'a, SSprite>,
Write<'a, PersistentState>,
Write<'a, VkProcessor>,
Write<'a, Vec<TrEvent<TrEventExtension>>>
);
fn run(&mut self, (mut draw, mut state, mut vk_processor, event_stack): Self::SystemData) {
for draw_data in (&mut draw).join() {
for event in event_stack.iter() {
draw_data.1.notify(event)
}
}
}
}
struct Eventt(u32);
6 years ago
pub fn main() {
//hprof::start_frame();
//let g = hprof::enter("vulkan preload");
let instance = {
let extensions = vulkano_win::required_extensions();
Instance::new(None, &extensions, None).unwrap()
};
5 years ago
let _callback = DebugCallback::errors_and_warnings(&instance, |msg| {
println!("Debug callback: {:?}", msg.description);
}).ok();
let mut events_loop = EventLoop::<TrEventExtension>::with_user_event();
5 years ago
let mut surface = WindowBuilder::new()
.with_inner_size(LogicalSize::new(800, 800))
.build_vk_surface(&events_loop, instance.clone()).unwrap();
5 years ago
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();
5 years ago
let mut timer = Timer::new();
let mut frame_future: Box<dyn GpuFuture> =
Box::new(sync::now(processor.device.clone().unwrap())) as Box<dyn GpuFuture>;
5 years ago
let step_size: f32 = 0.005;
let mut elapsed_time: f32 = timer.elap_time();
let mut delta_time: f32 = 0.0;
5 years ago
let mut accumulator_time: f32 = 0.0;
let mut current_time: f32 = timer.elap_time();
5 years ago
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);
5 years ago
let image_dimensions_u: (u32, u32) = image_data.1;
5 years ago
let compu_sprite1: CompuSprite =
CompuSprite::new((-1.0, -1.0), (1.0, 1.0), 0, image_dimensions_f,
5 years ago
// Swap image to render the result to. Must match dimensions
processor.new_swap_image(image_dimensions_u));
5 years ago
let compute_buffer: Arc<CompuBufferHandle> =
processor.new_compute_buffer(image_data.0.clone(), image_data.1, 4);
let first_output_buffer: Arc<CompuBufferHandle> =
processor.new_compute_buffer(image_data.0.clone(), image_data.1.clone(), 4);
5 years ago
let compute_kernel: Arc<CompuKernelHandle> =
processor.get_kernel_handle(String::from("simple-edge.compute"))
.expect("Can't find that kernel");
5 years ago
// 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 mut world = World::new();
world.register::<Move>();
world.register::<Geom>();
5 years ago
world.register::<SSprite>();
world.insert::<VkProcessor>(processor);
world.insert::<Vec<TrEvent<TrEventExtension>>>(Vec::new());
world.insert::<PersistentState>(PersistentState {
surface: Some(surface.clone()),
window_size: (0, 0),
5 years ago
delta_time,
5 years ago
canvas_frame: CanvasFrame::new((0, 0)),
compu_frame: CompuFrame::new((0, 0)),
});
let thing = Box::new(Sprite::new(funky_handle.clone()));
// An entity may or may not contain some component.
5 years ago
let t = world.create_entity()
.with(Move { vel_x: 0.0, vel_y: 0.0})
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0, pos_x: 100.0, pos_y: 400.0 })
.with(SSprite(thing.clone(), thing.clone()))
5 years ago
.build();
world.create_entity()
5 years ago
.with(Move { vel_x: 0.0, vel_y: 0.0 })
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0, pos_x: 100.0, pos_y: 400.0 })
.with(SSprite(thing.clone(), thing))
.build();
let thing2 = Box::new(Slider::new((300.0, 50.0), (550.0, 100.0), 30000));
world.create_entity()
5 years ago
.with(Move { vel_x: 0.0, vel_y: 0.0 })
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0, pos_x: 100.0, pos_y: 400.0 })
.with(SSprite(thing2.clone(), thing2))
.build();
// call the run method for the following systems & deps
let mut dispatcher = DispatcherBuilder::new()
// .with(SysA, "sys_a", &[])
.with(EventSystem, "event_s", &[])
.with(RenderSystem, "render_s", &["event_s"]).build();
let event_loop_proxy = events_loop.create_proxy();
std::thread::spawn(move || {
let mut gilrs = Gilrs::new().unwrap();
// Iterate over all connected gamepads
let mut gamepad: Option<Gamepad> = None;
for (_id, gamepad_) in gilrs.gamepads() {
if gamepad_.name() == "PS4" {
gamepad = Some(gamepad_);
}
println!("{} is {:?} {:?}", gamepad_.name(), gamepad_.power_info(), gamepad_.id());
}
let mut active_gamepad = None;
loop {
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(TrEventExtension::GamepadEvent {
gil_event: GilEvent { id, event, time }
}).ok();
}
// // You can also use cached gamepad state
// if let Some(gamepad) = active_gamepad.map(|id| gilrs.gamepad(id)) {
// if gamepad.is_pressed(Button::South) {
// println!("Button South is pressed (XBox - A, PS - X)");
// }
// }
std::thread::sleep(std::time::Duration::from_millis(50));
}
});
5 years ago
// Events loop is borrowed from the surface
events_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
5 years ago
Event::NewEvents(cause) => {
if cause == StartCause::Init {
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();
5 years ago
}
}
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;
if delta_time > 0.02 {
delta_time = 0.02;
}
accumulator_time += delta_time;
// 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;
// }
}
_ => {}
}
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
5 years ago
// 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 => {}
// }
});
// hprof::end_frame();
// hprof::profiler().print_timing();
}