diff options
author | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-02-28 18:14:06 +0100 |
---|---|---|
committer | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-02-28 18:14:06 +0100 |
commit | a87186860ec602c19f0d11528bef2d5123bc7e48 (patch) | |
tree | 1a5bfc0b554cd0ed195b61b1bc19f2dd250f8c8c /src/gfx.rs | |
parent | 146702340fbad28f9146d75e298234f63c0d5033 (diff) | |
download | mt_client-a87186860ec602c19f0d11528bef2d5123bc7e48.tar.xz |
Basic map rendering
Diffstat (limited to 'src/gfx.rs')
-rw-r--r-- | src/gfx.rs | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/gfx.rs b/src/gfx.rs new file mode 100644 index 0000000..e3fb073 --- /dev/null +++ b/src/gfx.rs @@ -0,0 +1,141 @@ +use crate::{GfxEvent::*, NetEvent}; +use cgmath::Rad; +use std::time::Instant; +use tokio::sync::mpsc; +use winit::{ + event::{DeviceEvent::*, Event::*, WindowEvent::*}, + event_loop::ControlFlow::ExitWithCode, + platform::run_return::EventLoopExtRunReturn, + window::CursorGrabMode, +}; + +mod map; +mod media; +mod state; +mod util; + +pub async fn run( + mut event_loop: winit::event_loop::EventLoop<crate::GfxEvent>, + net_events: mpsc::UnboundedSender<NetEvent>, +) { + let window = winit::window::WindowBuilder::new() + .build(&event_loop) + .unwrap(); + + window + .set_cursor_grab(CursorGrabMode::Locked) + .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Confined)) + .unwrap(); + + window.set_cursor_visible(false); + + let mut state = state::State::new(&window).await; + let mut map = None; + let mut media = media::MediaMgr::new(); + + let mut nodedefs = None; + + let mut last_frame = Instant::now(); + + event_loop.run_return(move |event, _, flow| match event { + MainEventsCleared => window.request_redraw(), + RedrawRequested(id) if id == window.id() => { + let now = Instant::now(); + let dt = now - last_frame; + last_frame = now; + + state.update(dt); + net_events + .send(NetEvent::PlayerPos( + state.camera.position.into(), + Rad(state.camera.yaw).into(), + Rad(state.camera.pitch).into(), + )) + .ok(); + + use wgpu::SurfaceError::*; + match state.render(&map) { + Ok(_) => {} + Err(Lost) => state.configure_surface(), + Err(OutOfMemory) => *flow = ExitWithCode(0), + Err(err) => eprintln!("gfx error: {err:?}"), + } + } + WindowEvent { + ref event, + window_id: id, + } if id == window.id() => match event { + CloseRequested => *flow = ExitWithCode(0), + Resized(size) => state.resize(*size), + ScaleFactorChanged { new_inner_size, .. } => state.resize(**new_inner_size), + KeyboardInput { + input: + winit::event::KeyboardInput { + virtual_keycode: Some(key), + state: key_state, + .. + }, + .. + } => { + use fps_camera::Actions; + use winit::event::{ElementState::*, VirtualKeyCode as Key}; + + let actions = match key { + Key::W => Actions::MOVE_FORWARD, + Key::A => Actions::STRAFE_LEFT, + Key::S => Actions::MOVE_BACKWARD, + Key::D => Actions::STRAFE_RIGHT, + Key::Space => Actions::FLY_UP, + Key::LShift => Actions::FLY_DOWN, + _ => Actions::empty(), + }; + + match key_state { + Pressed => state.camera.enable_actions(actions), + Released => state.camera.disable_action(actions), + } + } + _ => {} + }, + DeviceEvent { + event: MouseMotion { delta }, + .. + } => { + state.camera.update_mouse(delta.0 as f32, delta.1 as f32); + window + .set_cursor_position(winit::dpi::PhysicalPosition::new( + state.config.width / 2, + state.config.height / 2, + )) + .ok(); + } + UserEvent(event) => match event { + Close => *flow = ExitWithCode(0), + NodeDefs(defs) => nodedefs = Some(defs), + MapBlock(pos, blk) => { + if let Some(map) = map.as_mut() { + map.add_block(&mut state, pos, blk); + } + } + Media(files, finished) => { + media.add_server_media(files); + + if finished { + map = Some(map::MapRender::new( + &mut state, + &media, + nodedefs.take().unwrap_or_default(), + )); + + net_events.send(NetEvent::Ready).ok(); + } + } + PlayerPos(pos, pitch, yaw) => { + state.camera.position = pos.into(); + state.camera.pitch = Rad::<f32>::from(pitch).0; + state.camera.yaw = Rad::<f32>::from(yaw).0; + } + }, + _ => {} + }); +} |