use cyborg::camera::Camera; use cyborg::pass::{mesh, RenderPassBox}; use cyborg::shader; use cyborg::storage::mesh::*; use cyborg::viewport::*; use cyborg::Renderer; use legion::*; use std::sync::Arc; use winit::{ event::*, event_loop::{ControlFlow, EventLoop}, window::WindowBuilder, }; fn main() { let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); let viewport = pollster::block_on(WinitViewport::from_window(&window)); let mut world = World::new(Default::default()); let mut resources = Resources::default(); let renderer = Renderer::new(viewport.device.clone(), viewport.queue.clone()); resources.insert(renderer); resources.insert(viewport.get_info().to_owned()); let mut flycam = cyborg::camera::Flycam::new(0.002, 10.0, 0.25); let mut is_grabbed = false; let shader_store = Arc::new(shader::ShaderStore::new(viewport.device.clone())); let shaders_dir = std::env::current_dir().unwrap(); let shaders_dir = shaders_dir.join("shaders/"); let shader_watcher = shader::ShaderWatcher::new(shader_store.to_owned(), shaders_dir).unwrap(); let mesh_forward = shader_watcher.add_file("mesh_forward.wgsl").unwrap(); let mesh_skinning = shader_watcher.add_file("mesh_skinning.wgsl").unwrap(); let mesh_shaders = mesh::ShaderInfo { store: shader_store.clone(), forward: mesh_forward, skinning: mesh_skinning, }; resources.insert(mesh_shaders); let mut render_schedule = Schedule::builder(); cyborg::legion::build_renderer(&mut resources, &mut render_schedule); let mut render_schedule = render_schedule.build(); let example_vertices = vec![ mesh::Vertex { position: [-0.5, 0.0, 0.5], tan_frame: 0, }, mesh::Vertex { position: [0.5, 0.0, 0.5], tan_frame: 0, }, mesh::Vertex { position: [0.0, -0.5, -0.5], tan_frame: 0, }, mesh::Vertex { position: [0.0, 0.5, -0.5], tan_frame: 0, }, ]; let mesh_pass = resources.get::>().unwrap(); let example_vertices = AttrBuffer { id: mesh_pass.get_vertex_attr_id(), count: example_vertices.len(), data: bytemuck::cast_slice(&example_vertices).to_vec(), }; let example_indices: Vec = vec![0, 1, 2, 1, 2, 3, 2, 3, 0, 0, 2, 3]; let example_indices = AttrBuffer { id: mesh_pass.get_index_attr_id(), count: example_indices.len(), data: bytemuck::cast_slice(&example_indices).to_vec(), }; let mut example_mesh = MeshBuffer::default(); example_mesh.attributes.push(example_vertices); example_mesh.attributes.push(example_indices); let example_mesh = mesh_pass.get_mesh_pool().load(example_mesh).unwrap(); drop(mesh_pass); let example_debug_draw = cyborg::scene::DebugDrawList { vertices: vec![ cyborg::scene::DebugVertex { position: [0.0, 0.0, -0.5], color: [1.0, 0.0, 0.0], }, cyborg::scene::DebugVertex { position: [0.0, 0.0, 0.5], color: [0.0, 0.0, 1.0], }, ], indices: vec![0, 1], }; let r = 4; for x in -r..r { for y in -r..r { for z in -r..r { let translation = glam::Vec3::new(x as f32, y as f32, z as f32); let transform = glam::Mat4::from_translation(translation); world.push(( cyborg::scene::TransformedMesh { transform, mesh: example_mesh.clone(), }, cyborg::scene::Transform { transform }, example_debug_draw.clone(), )); } } } let viewport_entity = world.push((viewport, flycam.get_camera())); event_loop.run(move |event, _, control_flow| match event { Event::RedrawRequested(_) => { let mut viewport_entry = world.entry_mut(viewport_entity).unwrap(); let viewport = viewport_entry.get_component_mut::().unwrap(); match viewport.acquire() { Err(wgpu::SurfaceError::Lost) => viewport.resize(viewport.size), Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, Err(e) => eprintln!("error: {:?}", e), Ok(_) => { render_schedule.execute(&mut world, &mut resources); } } } Event::MainEventsCleared => { shader_watcher.watch(); flycam.update(); window.request_redraw(); let mut viewport_entry = world.entry_mut(viewport_entity).unwrap(); let camera = viewport_entry.get_component_mut::().unwrap(); let _ = std::mem::replace(camera, flycam.get_camera()); } Event::DeviceEvent { ref event, .. } => match event { DeviceEvent::MouseMotion { delta } => { if is_grabbed { flycam.process_mouse(delta.0, delta.1); } } _ => {} }, Event::WindowEvent { ref event, window_id, } if window_id == window.id() => match event { WindowEvent::KeyboardInput { input: KeyboardInput { virtual_keycode: Some(key), state, .. }, .. } => { if *state == ElementState::Pressed && *key == VirtualKeyCode::Escape { if is_grabbed { window.set_cursor_grab(false).unwrap(); window.set_cursor_visible(true); is_grabbed = false; } } else { flycam.process_keyboard(*key, *state); } } WindowEvent::MouseInput { button: MouseButton::Left, state: ElementState::Pressed, .. } => { if !is_grabbed { window.set_cursor_grab(true).unwrap(); window.set_cursor_visible(false); is_grabbed = true; } } WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, WindowEvent::Resized(physical_size) => { let mut viewport_entry = world.entry_mut(viewport_entity).unwrap(); let viewport = viewport_entry.get_component_mut::().unwrap(); viewport.resize(*physical_size); flycam.resize(physical_size.width, physical_size.height); } WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { let mut viewport_entry = world.entry_mut(viewport_entity).unwrap(); let viewport = viewport_entry.get_component_mut::().unwrap(); viewport.resize(**new_inner_size); flycam.resize(new_inner_size.width, new_inner_size.height); } _ => {} }, _ => {} }); }