From e0dc8444ca055e3e5f279142c4837f27c8c5e7b5 Mon Sep 17 00:00:00 2001 From: Serge Bazanski Date: Sun, 4 Apr 2021 16:51:26 +0000 Subject: [PATCH] engine/renderer: implement cursor locking --- engine/src/main.rs | 1 + engine/src/render/mod.rs | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/engine/src/main.rs b/engine/src/main.rs index 6f03255..948e2f5 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -185,6 +185,7 @@ impl<'a> ecs::System <'a> for Main { sd.scene_info.get().camera = camera; sd.scene_info.get().view = view; + sd.scene_info.get().lock_cursor = true; *sd.transforms.get_mut(self.light1).unwrap() = Transform::at( -0.0 + (position*3.0).sin() * 4.0, diff --git a/engine/src/render/mod.rs b/engine/src/render/mod.rs index efe6f34..2e39673 100644 --- a/engine/src/render/mod.rs +++ b/engine/src/render/mod.rs @@ -56,7 +56,10 @@ const HEIGHT: u32 = 600; pub struct Renderer { instance: vulkan::Instance, events_loop: EventLoop<()>, + surface: Arc>, rm: resource::Manager, + + cursor_locked: bool, } @@ -72,6 +75,8 @@ impl ecs::Global for Status {} pub struct SceneInfo { pub camera: cgm::Point3, pub view: cgm::Matrix4, + + pub lock_cursor: bool, } impl ecs::Global for SceneInfo {} @@ -94,7 +99,9 @@ impl<'a> ecs::System<'a> for Renderer { let transformedRenderables = (transforms, renderables); let mut input = input.get(); let mut status = status.get(); + let scene = scene.get(); + // Render sceneinfo and renderables. let mut rd = vulkan::RenderData { meshes: BTreeMap::new(), lights: Vec::new(), @@ -110,11 +117,11 @@ impl<'a> ecs::System<'a> for Renderer { _ => (), } } - - let camera = &scene.get().camera; - let view = &scene.get().view; + let camera = &scene.camera; + let view = &scene.view; self.instance.flip(camera, view, &rd, &self.rm); + // Retrieve current resolution into status. match self.instance.swapchain_dimensions() { Some(res) => { status.resolution = res.clone() @@ -122,6 +129,7 @@ impl<'a> ecs::System<'a> for Renderer { None => (), } + // Process events. if status.input_device_id == 0 { status.input_device_id = input.allocate_device(); } @@ -146,6 +154,25 @@ impl<'a> ecs::System<'a> for Renderer { } } } + + let window = self.surface.window(); + if self.cursor_locked { + if let Some(res) = self.instance.swapchain_dimensions() { + let (x, y) = (res[0], res[1]); + window.set_cursor_position(winit::dpi::PhysicalPosition::new(x / 2, y / 2)); + } + } + + // Lock cursor, if requested. + if scene.lock_cursor && !self.cursor_locked { + window.set_cursor_visible(false); + window.set_cursor_grab(true); + self.cursor_locked = true; + } else if self.cursor_locked && !scene.lock_cursor { + window.set_cursor_visible(true); + window.set_cursor_grab(false); + self.cursor_locked = false; + } } } @@ -161,6 +188,7 @@ impl Renderer { world.set_global(SceneInfo { camera: cgm::Point3::new(0.0, 0.0, 0.0), view: cgm::Matrix4::identity(), + lock_cursor: false, }); world.set_global(Status { closed: false, @@ -175,7 +203,10 @@ impl Renderer { Self { instance, events_loop, + surface, rm: resource::Manager::new(), + + cursor_locked: false, } }