#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] extern crate cgmath; extern crate hprof; extern crate image; 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; 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}; use crate::vkprocessor::VkProcessor; use crate::drawables::slider::Slider; pub mod util; pub mod vkprocessor; pub mod drawables; pub mod canvas; extern crate specs; use specs::prelude::*; use vulkano::swapchain::Surface; //struct Draws(Box, Box + Sync + Send>); struct SSprite(Box); impl Component for SSprite { type Storage = VecStorage; } pub struct Move { vel_x: f32, vel_y: f32, } impl Component for Move { type Storage = VecStorage; } pub struct Geom { pos_x: f32, pos_y: f32, size_x: f32, size_y: f32, rotation: f32, depth: f32, } impl Component for Geom { type Storage = VecStorage; } #[derive(Default)] struct PersistentState { surface: Option>>, window_size: (u32, u32), delta_time: f32, canvas_frame: CanvasFrame, compu_frame: CompuFrame, } // 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; impl<'a> System<'a> for RenderSystem { type SystemData = ( 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() { 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, (geom.pos_x, geom.pos_y), geom.rotation, (geom.size_x, geom.size_y), geom.depth, )); } for draw_data in (&draw).join() { let size = state.window_size.clone(); } vk_processor.run(&state.surface.clone().unwrap(), &state.canvas_frame, &state.compu_frame); } } struct EventSystem; impl<'a> System<'a> for EventSystem { type SystemData = ( WriteStorage<'a, SSprite>, Write<'a, PersistentState>, Write<'a, VkProcessor>, Write<'a, Vec>> ); 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); 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() }; let _callback = DebugCallback::errors_and_warnings(&instance, |msg| { println!("Debug callback: {:?}", msg.description); }).ok(); let mut events_loop = EventLoop::::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 mut timer = Timer::new(); let mut frame_future: Box = Box::new(sync::now(processor.device.clone().unwrap())) as Box; 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(); 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)); let compute_buffer: Arc = processor.new_compute_buffer(image_data.0.clone(), image_data.1, 4); let first_output_buffer: Arc = processor.new_compute_buffer(image_data.0.clone(), image_data.1.clone(), 4); let compute_kernel: Arc = processor.get_kernel_handle(String::from("simple-edge.compute")) .expect("Can't find that kernel"); // Get the handles for the assets let funky_handle: Arc = processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap(); let sfml_handle: Arc = processor.get_texture_handle(String::from("sfml.png")).unwrap(); let mut world = World::new(); world.register::(); world.register::(); world.register::(); world.insert::(processor); world.insert::>>(Vec::new()); world.insert::(PersistentState { surface: Some(surface.clone()), window_size: (0, 0), delta_time, 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. 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())) .build(); 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)) .build(); let thing2 = Box::new(Slider::new((300.0, 50.0), (550.0, 100.0), 30000)); 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(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 = 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)); } }); // Events loop is borrowed from the surface events_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Poll; match event { Event::NewEvents(cause) => { if cause == StartCause::Init { world.write_resource::() .window_size = surface.window().inner_size().into(); } else { // println!("{}", world.write_resource::>>().len()); world.write_resource::>>().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::() .swapchain_recreate_needed = true; world.write_resource::() .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::() .delta_time = delta_time; dispatcher.dispatch(&mut world); // while (accumulator_time - step_size) >= step_size { // accumulator_time -= step_size; // } } _ => {} } world.write_resource::>>().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::().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 => {} // } }); // hprof::end_frame(); // hprof::profiler().print_timing(); }