diff --git a/CHANGELOG.md b/CHANGELOG.md index 441c6acde3..c4050b6b67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Command to toggle experimental shaders. ### Changed @@ -15,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -## [0.14.0] - 2022-01-07 +## [0.14.0] - 2023-01-07 ### Added diff --git a/voxygen/src/cmd.rs b/voxygen/src/cmd.rs index 347364a841..fd286d12a5 100644 --- a/voxygen/src/cmd.rs +++ b/voxygen/src/cmd.rs @@ -1,12 +1,16 @@ use std::str::FromStr; -use crate::GlobalState; +use crate::{ + render::ExperimentalShader, session::settings_change::change_render_mode, GlobalState, +}; use client::Client; use common::{cmd::*, parse_cmd_args, uuid::Uuid}; +use strum::IntoEnumIterator; // Please keep this sorted alphabetically, same as with server commands :-) #[derive(Clone, Copy, strum::EnumIter)] pub enum ClientChatCommand { + ExperimentalShader, Mute, Unmute, } @@ -27,6 +31,17 @@ impl ClientChatCommand { "Unmutes a player muted with the 'mute' command.", None, ), + ClientChatCommand::ExperimentalShader => cmd( + vec![Enum( + "Shader", + ExperimentalShader::iter() + .map(|item| item.to_string()) + .collect(), + Optional, + )], + "Toggles an experimental shader.", + None, + ), } } @@ -34,6 +49,7 @@ impl ClientChatCommand { match self { ClientChatCommand::Mute => "mute", ClientChatCommand::Unmute => "unmute", + ClientChatCommand::ExperimentalShader => "experimental_shader", } } @@ -145,10 +161,13 @@ fn run_client_command( command: ClientChatCommand, args: Vec, ) -> Result { - match command { - ClientChatCommand::Mute => handle_mute(client, global_state, args), - ClientChatCommand::Unmute => handle_unmute(client, global_state, args), - } + let command = match command { + ClientChatCommand::Mute => handle_mute, + ClientChatCommand::Unmute => handle_unmute, + ClientChatCommand::ExperimentalShader => handle_experimental_shader, + }; + + command(client, global_state, args) } fn handle_mute( @@ -215,6 +234,60 @@ fn handle_unmute( } } +fn handle_experimental_shader( + _client: &Client, + global_state: &mut GlobalState, + args: Vec, +) -> Result { + if args.is_empty() { + ExperimentalShader::iter() + .map(|s| { + let is_active = global_state + .settings + .graphics + .render_mode + .experimental_shaders + .contains(&s); + format!("[{}] {}", if is_active { "x" } else { " " }, s) + }) + .reduce(|mut a, b| { + a.push('\n'); + a.push_str(&b); + a + }) + .ok_or("There are no experimental shaders.".to_string()) + } else if let Some(item) = parse_cmd_args!(args, String) { + if let Ok(shader) = ExperimentalShader::from_str(&item) { + let mut new_render_mode = global_state.settings.graphics.render_mode.clone(); + let res = if new_render_mode.experimental_shaders.remove(&shader) { + Ok(format!("Disabled {item}.")) + } else { + new_render_mode.experimental_shaders.insert(shader); + Ok(format!("Enabled {item}.")) + }; + + change_render_mode( + new_render_mode, + &mut global_state.window, + &mut global_state.settings, + ); + + res + } else { + Err(format!( + "{item} is not an expermimental shader, use this command with any arguments to \ + see a complete list." + )) + } + } else { + Err( + "You must specify a valid experimental shader, to get a list of experimental shaders, \ + use this command without any arguments." + .to_string(), + ) + } +} + /// A helper function to get the Uuid of a player with a given alias pub fn get_player_uuid(client: &Client, alias: &String) -> Option { client diff --git a/voxygen/src/session/settings_change.rs b/voxygen/src/session/settings_change.rs index 2ad2e94078..82c630f5d1 100644 --- a/voxygen/src/session/settings_change.rs +++ b/voxygen/src/session/settings_change.rs @@ -11,7 +11,7 @@ use crate::{ audio::AudioVolume, AudioSettings, ChatSettings, ControlSettings, Fps, GamepadSettings, GameplaySettings, GraphicsSettings, InterfaceSettings, }, - window::FullScreenSettings, + window::{FullScreenSettings, Window}, GlobalState, }; use i18n::{LanguageMetadata, LocalizationHandle}; @@ -465,13 +465,7 @@ impl SettingsChange { settings.graphics.ambiance = new_ambiance; }, Graphics::ChangeRenderMode(new_render_mode) => { - // Do this first so if it crashes the setting isn't saved :) - global_state - .window - .renderer_mut() - .set_render_mode((*new_render_mode).clone()) - .unwrap(); - settings.graphics.render_mode = *new_render_mode; + change_render_mode(*new_render_mode, &mut global_state.window, settings); }, Graphics::ChangeFullscreenMode(new_fullscreen_settings) => { global_state @@ -741,6 +735,19 @@ impl SettingsChange { use crate::settings::Settings; +pub fn change_render_mode( + new_render_mode: RenderMode, + window: &mut Window, + settings: &mut Settings, +) { + // Do this first so if it crashes the setting isn't saved :) + window + .renderer_mut() + .set_render_mode(new_render_mode.clone()) + .unwrap(); + settings.graphics.render_mode = new_render_mode; +} + fn adjust_terrain_view_distance( terrain_vd: u32, settings: &mut Settings,