veloren/voxygen/src/window.rs

182 lines
6.1 KiB
Rust
Raw Normal View History

use vek::*;
use std::collections::HashMap;
2019-01-07 21:10:31 +00:00
use crate::{
Error,
2019-01-11 17:30:13 +00:00
render::{
Renderer,
TgtColorFmt,
TgtDepthFmt,
},
ui,
2019-01-07 21:10:31 +00:00
};
pub struct Window {
2019-01-11 17:30:13 +00:00
events_loop: glutin::EventsLoop,
2019-01-07 21:10:31 +00:00
renderer: Renderer,
window: glutin::GlWindow,
cursor_grabbed: bool,
key_map: HashMap<glutin::VirtualKeyCode, Key>,
}
impl Window {
pub fn new() -> Result<Window, Error> {
2019-01-11 17:30:13 +00:00
let events_loop = glutin::EventsLoop::new();
2019-01-11 17:30:13 +00:00
let win_builder = glutin::WindowBuilder::new()
.with_title("Veloren")
.with_dimensions(glutin::dpi::LogicalSize::new(1366.0, 768.0))
.with_maximized(true);
2019-01-11 17:30:13 +00:00
let ctx_builder = glutin::ContextBuilder::new()
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)))
.with_vsync(false);
2019-01-11 17:30:13 +00:00
let (
window,
device,
factory,
tgt_color_view,
tgt_depth_view,
) = gfx_window_glutin::init::<TgtColorFmt, TgtDepthFmt>(
win_builder,
ctx_builder,
&events_loop,
).map_err(|err| Error::BackendError(Box::new(err)))?;
let mut key_map = HashMap::new();
key_map.insert(glutin::VirtualKeyCode::Tab, Key::ToggleCursor);
key_map.insert(glutin::VirtualKeyCode::Escape, Key::Escape);
key_map.insert(glutin::VirtualKeyCode::W, Key::MoveForward);
key_map.insert(glutin::VirtualKeyCode::A, Key::MoveLeft);
key_map.insert(glutin::VirtualKeyCode::S, Key::MoveBack);
key_map.insert(glutin::VirtualKeyCode::D, Key::MoveRight);
2019-01-07 21:10:31 +00:00
let tmp = Ok(Self {
events_loop,
2019-01-11 17:30:13 +00:00
renderer: Renderer::new(
device,
factory,
tgt_color_view,
tgt_depth_view,
)?,
window,
cursor_grabbed: false,
key_map,
2019-01-07 21:10:31 +00:00
});
tmp
}
2019-01-07 21:10:31 +00:00
pub fn renderer(&self) -> &Renderer { &self.renderer }
pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer }
2019-01-02 22:08:13 +00:00
2019-01-07 21:10:31 +00:00
pub fn fetch_events(&mut self) -> Vec<Event> {
// Copy data that is needed by the events closure to avoid lifetime errors
// TODO: Remove this if/when the compiler permits it
let cursor_grabbed = self.cursor_grabbed;
2019-01-23 22:39:31 +00:00
let renderer = &mut self.renderer;
let window = &mut self.window;
let key_map = &self.key_map;
2019-01-07 21:10:31 +00:00
let mut events = vec![];
self.events_loop.poll_events(|event| {
// Get events for ui
if let Some(event) = ui::Event::try_from(event.clone(), &window) {
events.push(Event::Ui(event));
}
match event {
glutin::Event::WindowEvent { event, .. } => match event {
glutin::WindowEvent::CloseRequested => events.push(Event::Close),
glutin::WindowEvent::Resized(glutin::dpi::LogicalSize { width, height }) => {
let (mut color_view, mut depth_view) = renderer.target_views_mut();
gfx_window_glutin::update_views(
&window,
&mut color_view,
&mut depth_view,
);
events.push(Event::Resize(Vec2::new(width as u32, height as u32)));
},
glutin::WindowEvent::ReceivedCharacter(c) => events.push(Event::Char(c)),
glutin::WindowEvent::KeyboardInput { input, .. } => match input.virtual_keycode {
Some(keycode) => match key_map.get(&keycode) {
Some(&key) => events.push(match input.state {
glutin::ElementState::Pressed => Event::KeyDown(key),
_ => Event::KeyUp(key),
}),
_ => {},
},
_ => {},
},
_ => {},
},
glutin::Event::DeviceEvent { event, .. } => match event {
glutin::DeviceEvent::MouseMotion { delta: (dx, dy), .. } if cursor_grabbed =>
events.push(Event::CursorPan(Vec2::new(dx as f32, dy as f32))),
glutin::DeviceEvent::MouseWheel {
delta: glutin::MouseScrollDelta::LineDelta(_x, y),
..
} if cursor_grabbed => events.push(Event::Zoom(y as f32)),
_ => {},
},
_ => {},
}
});
2019-01-07 21:10:31 +00:00
events
}
pub fn swap_buffers(&self) -> Result<(), Error> {
2019-01-11 17:30:13 +00:00
self.window.swap_buffers()
.map_err(|err| Error::BackendError(Box::new(err)))
}
pub fn is_cursor_grabbed(&self) -> bool {
self.cursor_grabbed
}
pub fn grab_cursor(&mut self, grab: bool) {
self.cursor_grabbed = grab;
self.window.hide_cursor(grab);
self.window.grab_cursor(grab)
.expect("Failed to grab/ungrab cursor");
}
pub fn logical_size(&self) -> Vec2<f64> {
let (w, h) = self.window.get_inner_size().unwrap_or(glutin::dpi::LogicalSize::new(0.0, 0.0)).into();
Vec2::new(w, h)
}
}
/// Represents a key that the game recognises after keyboard mapping
#[derive(Clone, Copy)]
pub enum Key {
ToggleCursor,
MoveForward,
MoveBack,
MoveLeft,
MoveRight,
Escape,
}
/// Represents an incoming event from the window
#[derive(Clone)]
pub enum Event {
/// The window has been requested to close.
Close,
2019-01-23 22:39:31 +00:00
/// The window has been resized
Resize(Vec2<u32>),
/// A key has been typed that corresponds to a specific character.
Char(char),
/// The cursor has been panned across the screen while grabbed.
CursorPan(Vec2<f32>),
/// The camera has been requested to zoom.
Zoom(f32),
/// A key that the game recognises has been pressed down
KeyDown(Key),
/// A key that the game recognises has been released down
KeyUp(Key),
/// Event that the ui uses
Ui(ui::Event),
}