mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'new_keys' into 'master'
Added Keys for Fullscreen, Screenshots, and the Debug Window See merge request veloren/veloren!151 Former-commit-id: 287a6b6582e3f5fb13a5d220f6648de5e4f50baa
This commit is contained in:
commit
47502b8a7b
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@ settings.toml
|
|||||||
*.rar
|
*.rar
|
||||||
*.log
|
*.log
|
||||||
run.sh
|
run.sh
|
||||||
|
screenshots
|
@ -463,6 +463,10 @@ impl Hud {
|
|||||||
pub fn handle_event(&mut self, event: WinEvent, global_state: &mut GlobalState) -> bool {
|
pub fn handle_event(&mut self, event: WinEvent, global_state: &mut GlobalState) -> bool {
|
||||||
let cursor_grabbed = global_state.window.is_cursor_grabbed();
|
let cursor_grabbed = global_state.window.is_cursor_grabbed();
|
||||||
let handled = match event {
|
let handled = match event {
|
||||||
|
WinEvent::SettingsChanged => {
|
||||||
|
self.settings = global_state.settings.clone();
|
||||||
|
false
|
||||||
|
}
|
||||||
WinEvent::Ui(event) => {
|
WinEvent::Ui(event) => {
|
||||||
if (self.typing() && event.is_keyboard() && self.show.ui)
|
if (self.typing() && event.is_keyboard() && self.show.ui)
|
||||||
|| !(cursor_grabbed && event.is_keyboard_or_mouse())
|
|| !(cursor_grabbed && event.is_keyboard_or_mouse())
|
||||||
@ -534,6 +538,10 @@ impl Hud {
|
|||||||
self.show.toggle_help();
|
self.show.toggle_help();
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
Key::ToggleDebug => {
|
||||||
|
self.show.debug = !self.show.debug;
|
||||||
|
true
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
WinEvent::KeyDown(key) | WinEvent::KeyUp(key) => match key {
|
WinEvent::KeyDown(key) | WinEvent::KeyUp(key) => match key {
|
||||||
@ -541,10 +549,6 @@ impl Hud {
|
|||||||
_ => self.typing(),
|
_ => self.typing(),
|
||||||
},
|
},
|
||||||
WinEvent::Char(_) => self.typing(),
|
WinEvent::Char(_) => self.typing(),
|
||||||
WinEvent::SettingsChanged => {
|
|
||||||
self.settings = global_state.settings.clone();
|
|
||||||
true
|
|
||||||
}
|
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
// Handle cursor grab.
|
// Handle cursor grab.
|
||||||
|
@ -42,6 +42,8 @@ pub enum RenderError {
|
|||||||
CombinedError(gfx::CombinedError),
|
CombinedError(gfx::CombinedError),
|
||||||
BufferCreationError(gfx::buffer::CreationError),
|
BufferCreationError(gfx::buffer::CreationError),
|
||||||
IncludeError(glsl_include::Error),
|
IncludeError(glsl_include::Error),
|
||||||
|
MappingError(gfx::mapping::Error),
|
||||||
|
CopyError(gfx::CopyError<[u16; 3], usize>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used to represent a specific rendering configuration.
|
/// Used to represent a specific rendering configuration.
|
||||||
|
@ -306,6 +306,55 @@ impl Renderer {
|
|||||||
texture.update(&mut self.encoder, offset, size, data)
|
texture.update(&mut self.encoder, offset, size, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a download buffer, downloads the win_color_view, and converts to a image::DynamicImage.
|
||||||
|
pub fn create_screenshot(&mut self) -> Result<image::DynamicImage, RenderError> {
|
||||||
|
let (width, height) = self.get_resolution().into_tuple();
|
||||||
|
use gfx::{
|
||||||
|
format::{Formatted, SurfaceTyped},
|
||||||
|
memory::Typed,
|
||||||
|
};
|
||||||
|
type WinSurfaceData = <<WinColorFmt as Formatted>::Surface as SurfaceTyped>::DataType;
|
||||||
|
let mut download = self
|
||||||
|
.factory
|
||||||
|
.create_download_buffer::<WinSurfaceData>(width as usize * height as usize)
|
||||||
|
.map_err(|err| RenderError::BufferCreationError(err))?;
|
||||||
|
self.encoder
|
||||||
|
.copy_texture_to_buffer_raw(
|
||||||
|
self.win_color_view.raw().get_texture(),
|
||||||
|
None,
|
||||||
|
gfx::texture::RawImageInfo {
|
||||||
|
xoffset: 0,
|
||||||
|
yoffset: 0,
|
||||||
|
zoffset: 0,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
depth: 0,
|
||||||
|
format: WinColorFmt::get_format(),
|
||||||
|
mipmap: 0,
|
||||||
|
},
|
||||||
|
download.raw(),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
.map_err(|err| RenderError::CopyError(err))?;
|
||||||
|
self.flush();
|
||||||
|
|
||||||
|
// Assumes that the format is Rgba8.
|
||||||
|
let raw_data = self
|
||||||
|
.factory
|
||||||
|
.read_mapping(&download)
|
||||||
|
.map_err(|err| RenderError::MappingError(err))?
|
||||||
|
.chunks_exact(width as usize)
|
||||||
|
.rev()
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
.map(|&e| e)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
Ok(image::DynamicImage::ImageRgba8(
|
||||||
|
// Should not fail if the dimensions are correct.
|
||||||
|
image::ImageBuffer::from_raw(width as u32, height as u32, raw_data).unwrap(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// Queue the rendering of the provided skybox model in the upcoming frame.
|
/// Queue the rendering of the provided skybox model in the upcoming frame.
|
||||||
pub fn render_skybox(
|
pub fn render_skybox(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -35,6 +35,9 @@ pub struct ControlSettings {
|
|||||||
pub settings: VirtualKeyCode,
|
pub settings: VirtualKeyCode,
|
||||||
pub help: VirtualKeyCode,
|
pub help: VirtualKeyCode,
|
||||||
pub toggle_interface: VirtualKeyCode,
|
pub toggle_interface: VirtualKeyCode,
|
||||||
|
pub toggle_debug: VirtualKeyCode,
|
||||||
|
pub fullscreen: VirtualKeyCode,
|
||||||
|
pub screenshot: VirtualKeyCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
@ -71,6 +74,9 @@ impl Default for Settings {
|
|||||||
settings: VirtualKeyCode::N,
|
settings: VirtualKeyCode::N,
|
||||||
help: VirtualKeyCode::F1,
|
help: VirtualKeyCode::F1,
|
||||||
toggle_interface: VirtualKeyCode::F2,
|
toggle_interface: VirtualKeyCode::F2,
|
||||||
|
toggle_debug: VirtualKeyCode::F3,
|
||||||
|
fullscreen: VirtualKeyCode::F11,
|
||||||
|
screenshot: VirtualKeyCode::F4,
|
||||||
},
|
},
|
||||||
networking: NetworkingSettings {
|
networking: NetworkingSettings {
|
||||||
username: "Username".to_string(),
|
username: "Username".to_string(),
|
||||||
|
@ -55,7 +55,7 @@ impl GraphicCache {
|
|||||||
mut cacher: F,
|
mut cacher: F,
|
||||||
) -> Option<Aabr<u16>>
|
) -> Option<Aabr<u16>>
|
||||||
where
|
where
|
||||||
F: FnMut(Aabr<u16>, Vec<[u8; 4]>),
|
F: FnMut(Aabr<u16>, &[[u8; 4]]),
|
||||||
{
|
{
|
||||||
match self
|
match self
|
||||||
.rect_map
|
.rect_map
|
||||||
@ -94,6 +94,7 @@ impl GraphicCache {
|
|||||||
image::FilterType::Nearest,
|
image::FilterType::Nearest,
|
||||||
)
|
)
|
||||||
.to_rgba()
|
.to_rgba()
|
||||||
|
// TODO: might be a better way to do this
|
||||||
.pixels()
|
.pixels()
|
||||||
.map(|p| p.data)
|
.map(|p| p.data)
|
||||||
.collect::<Vec<[u8; 4]>>(),
|
.collect::<Vec<[u8; 4]>>(),
|
||||||
@ -103,7 +104,7 @@ impl GraphicCache {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Draw to allocated area.
|
// Draw to allocated area.
|
||||||
cacher(aabr, data);
|
cacher(aabr, &data);
|
||||||
|
|
||||||
// Insert area into map for retrieval.
|
// Insert area into map for retrieval.
|
||||||
self.rect_map
|
self.rect_map
|
||||||
|
@ -347,7 +347,7 @@ impl Ui {
|
|||||||
|aabr, data| {
|
|aabr, data| {
|
||||||
let offset = aabr.min.into_array();
|
let offset = aabr.min.into_array();
|
||||||
let size = aabr.size().into_array();
|
let size = aabr.size().into_array();
|
||||||
renderer.update_texture(cache_tex, offset, size, &data);
|
renderer.update_texture(cache_tex, offset, size, data);
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Some(aabr) => Aabr {
|
Some(aabr) => Aabr {
|
||||||
|
@ -11,6 +11,7 @@ pub struct Window {
|
|||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
window: glutin::GlWindow,
|
window: glutin::GlWindow,
|
||||||
cursor_grabbed: bool,
|
cursor_grabbed: bool,
|
||||||
|
fullscreen: bool,
|
||||||
needs_refresh_resize: bool,
|
needs_refresh_resize: bool,
|
||||||
key_map: HashMap<glutin::VirtualKeyCode, Key>,
|
key_map: HashMap<glutin::VirtualKeyCode, Key>,
|
||||||
supplement_events: Vec<Event>,
|
supplement_events: Vec<Event>,
|
||||||
@ -56,12 +57,16 @@ impl Window {
|
|||||||
key_map.insert(settings.controls.settings, Key::Settings);
|
key_map.insert(settings.controls.settings, Key::Settings);
|
||||||
key_map.insert(settings.controls.help, Key::Help);
|
key_map.insert(settings.controls.help, Key::Help);
|
||||||
key_map.insert(settings.controls.toggle_interface, Key::ToggleInterface);
|
key_map.insert(settings.controls.toggle_interface, Key::ToggleInterface);
|
||||||
|
key_map.insert(settings.controls.toggle_debug, Key::ToggleDebug);
|
||||||
|
key_map.insert(settings.controls.fullscreen, Key::Fullscreen);
|
||||||
|
key_map.insert(settings.controls.screenshot, Key::Screenshot);
|
||||||
|
|
||||||
let tmp = Ok(Self {
|
let tmp = Ok(Self {
|
||||||
events_loop,
|
events_loop,
|
||||||
renderer: Renderer::new(device, factory, win_color_view, win_depth_view)?,
|
renderer: Renderer::new(device, factory, win_color_view, win_depth_view)?,
|
||||||
window,
|
window,
|
||||||
cursor_grabbed: false,
|
cursor_grabbed: false,
|
||||||
|
fullscreen: false,
|
||||||
needs_refresh_resize: false,
|
needs_refresh_resize: false,
|
||||||
key_map,
|
key_map,
|
||||||
supplement_events: vec![],
|
supplement_events: vec![],
|
||||||
@ -91,6 +96,8 @@ impl Window {
|
|||||||
let renderer = &mut self.renderer;
|
let renderer = &mut self.renderer;
|
||||||
let window = &mut self.window;
|
let window = &mut self.window;
|
||||||
let key_map = &self.key_map;
|
let key_map = &self.key_map;
|
||||||
|
let mut toggle_fullscreen = false;
|
||||||
|
let mut take_screenshot = false;
|
||||||
|
|
||||||
self.events_loop.poll_events(|event| {
|
self.events_loop.poll_events(|event| {
|
||||||
// Get events for ui.
|
// Get events for ui.
|
||||||
@ -112,9 +119,19 @@ impl Window {
|
|||||||
glutin::WindowEvent::KeyboardInput { input, .. } => match input.virtual_keycode
|
glutin::WindowEvent::KeyboardInput { input, .. } => match input.virtual_keycode
|
||||||
{
|
{
|
||||||
Some(keycode) => match key_map.get(&keycode) {
|
Some(keycode) => match key_map.get(&keycode) {
|
||||||
|
Some(Key::Fullscreen) => match input.state {
|
||||||
|
glutin::ElementState::Pressed => {
|
||||||
|
toggle_fullscreen = !toggle_fullscreen
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
Some(Key::Screenshot) => match input.state {
|
||||||
|
glutin::ElementState::Pressed => take_screenshot = true,
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
Some(&key) => events.push(match input.state {
|
Some(&key) => events.push(match input.state {
|
||||||
glutin::ElementState::Pressed => Event::KeyDown(key),
|
glutin::ElementState::Pressed => Event::KeyDown(key),
|
||||||
_ => Event::KeyUp(key),
|
glutin::ElementState::Released => Event::KeyUp(key),
|
||||||
}),
|
}),
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
@ -137,6 +154,15 @@ impl Window {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if take_screenshot {
|
||||||
|
self.take_screenshot();
|
||||||
|
}
|
||||||
|
|
||||||
|
if toggle_fullscreen {
|
||||||
|
self.fullscreen(!self.is_fullscreen());
|
||||||
|
}
|
||||||
|
|
||||||
events
|
events
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +182,20 @@ impl Window {
|
|||||||
let _ = self.window.grab_cursor(grab);
|
let _ = self.window.grab_cursor(grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_fullscreen(&self) -> bool {
|
||||||
|
self.fullscreen
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fullscreen(&mut self, fullscreen: bool) {
|
||||||
|
self.fullscreen = fullscreen;
|
||||||
|
if fullscreen {
|
||||||
|
self.window
|
||||||
|
.set_fullscreen(Some(self.window.get_current_monitor()));
|
||||||
|
} else {
|
||||||
|
self.window.set_fullscreen(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn needs_refresh_resize(&mut self) {
|
pub fn needs_refresh_resize(&mut self) {
|
||||||
self.needs_refresh_resize = true;
|
self.needs_refresh_resize = true;
|
||||||
}
|
}
|
||||||
@ -172,6 +212,34 @@ impl Window {
|
|||||||
pub fn send_supplement_event(&mut self, event: Event) {
|
pub fn send_supplement_event(&mut self, event: Event) {
|
||||||
self.supplement_events.push(event)
|
self.supplement_events.push(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn take_screenshot(&mut self) {
|
||||||
|
match self.renderer.create_screenshot() {
|
||||||
|
Ok(img) => {
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
use std::{path::PathBuf, time::SystemTime};
|
||||||
|
// Check if folder exists and create it if it does not
|
||||||
|
let mut path = std::path::PathBuf::from("./screenshots");
|
||||||
|
if !path.exists() {
|
||||||
|
if let Err(err) = std::fs::create_dir(&path) {
|
||||||
|
log::error!("Coudn't create folder for screenshot: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path.push(format!(
|
||||||
|
"screenshot_{}.png",
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.map(|d| d.as_millis())
|
||||||
|
.unwrap_or(0)
|
||||||
|
));
|
||||||
|
if let Err(err) = img.save(&path) {
|
||||||
|
log::error!("Coudn't save screenshot: {:?}", err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err(err) => log::error!("Coudn't create screenshot due to renderer error: {:?}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a key that the game recognises after keyboard mapping.
|
/// Represents a key that the game recognises after keyboard mapping.
|
||||||
@ -195,6 +263,9 @@ pub enum Key {
|
|||||||
Settings,
|
Settings,
|
||||||
ToggleInterface,
|
ToggleInterface,
|
||||||
Help,
|
Help,
|
||||||
|
ToggleDebug,
|
||||||
|
Fullscreen,
|
||||||
|
Screenshot,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an incoming event from the window.
|
/// Represents an incoming event from the window.
|
||||||
|
Loading…
Reference in New Issue
Block a user