From aab059a450b5f635777129ff82cc15b662965c3c Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 24 Feb 2020 15:14:06 +0000 Subject: [PATCH] Added LoD slider --- assets/voxygen/shaders/include/lod.glsl | 2 +- voxygen/src/hud/mod.rs | 4 +++ voxygen/src/hud/settings_window.rs | 41 +++++++++++++++++++++- voxygen/src/scene/lod.rs | 45 +++++++++++++++++++------ voxygen/src/scene/mod.rs | 14 +++++--- voxygen/src/session.rs | 14 ++++++-- voxygen/src/settings.rs | 2 ++ 7 files changed, 102 insertions(+), 20 deletions(-) diff --git a/assets/voxygen/shaders/include/lod.glsl b/assets/voxygen/shaders/include/lod.glsl index 78e5d5e065..672c7930bc 100644 --- a/assets/voxygen/shaders/include/lod.glsl +++ b/assets/voxygen/shaders/include/lod.glsl @@ -3,7 +3,7 @@ uniform sampler2D t_map; vec2 pos_to_uv(vec2 pos) { - vec2 uv_pos = pos / 32768.0; + vec2 uv_pos = (pos + 16) / 32768.0; return vec2(uv_pos.x, 1.0 - uv_pos.y); } diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 760bd4a2ef..a9876a06a8 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -196,6 +196,7 @@ pub enum Event { ToggleZoomInvert(bool), ToggleMouseYInvert(bool), AdjustViewDistance(u32), + AdjustLodDetail(u32), AdjustMusicVolume(f32), AdjustSfxVolume(f32), ChangeAudioDevice(String), @@ -1744,6 +1745,9 @@ impl Hud { settings_window::Event::AdjustViewDistance(view_distance) => { events.push(Event::AdjustViewDistance(view_distance)); }, + settings_window::Event::AdjustLodDetail(lod_detail) => { + events.push(Event::AdjustLodDetail(lod_detail)); + }, settings_window::Event::CrosshairTransp(crosshair_transp) => { events.push(Event::CrosshairTransp(crosshair_transp)); }, diff --git a/voxygen/src/hud/settings_window.rs b/voxygen/src/hud/settings_window.rs index 1c63978804..0a12ba9a6b 100644 --- a/voxygen/src/hud/settings_window.rs +++ b/voxygen/src/hud/settings_window.rs @@ -83,6 +83,9 @@ widget_ids! { vd_slider, vd_text, vd_value, + lod_detail_slider, + lod_detail_text, + lod_detail_value, max_fps_slider, max_fps_text, max_fps_value, @@ -202,6 +205,7 @@ pub enum Event { ToggleMouseYInvert(bool), AdjustViewDistance(u32), AdjustFOV(u16), + AdjustLodDetail(u32), AdjustGamma(f32), AdjustWindowSize([u16; 2]), ToggleFullscreen, @@ -1558,9 +1562,44 @@ impl<'a> Widget for SettingsWindow<'a> { .color(TEXT_COLOR) .set(state.ids.fov_value, ui); + // LoD detail + Text::new(&self.localized_strings.get("hud.settings.lod_detail")) + .down_from(state.ids.fov_slider, 10.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.lod_detail_text, ui); + + if let Some(new_val) = ImageSlider::discrete( + self.global_state.settings.graphics.lod_detail, + 100, + 2000, + self.imgs.slider_indicator, + self.imgs.slider, + ) + .w_h(104.0, 22.0) + .down_from(state.ids.lod_detail_text, 8.0) + .track_breadth(12.0) + .slider_length(10.0) + .pad_track((5.0, 5.0)) + .set(state.ids.lod_detail_slider, ui) + { + events.push(Event::AdjustLodDetail(new_val as u32)); + } + + Text::new(&format!( + "{}", + self.global_state.settings.graphics.lod_detail + )) + .right_from(state.ids.lod_detail_slider, 8.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.lod_detail_value, ui); + // Gamma Text::new(&self.localized_strings.get("hud.settings.gamma")) - .down_from(state.ids.fov_slider, 10.0) + .down_from(state.ids.lod_detail_slider, 10.0) .font_size(self.fonts.cyri.scale(14)) .font_id(self.fonts.cyri.conrod_id) .color(TEXT_COLOR) diff --git a/voxygen/src/scene/lod.rs b/voxygen/src/scene/lod.rs index 2ef87559a7..290bdd9a76 100644 --- a/voxygen/src/scene/lod.rs +++ b/voxygen/src/scene/lod.rs @@ -1,38 +1,61 @@ -use crate::render::{ - pipelines::lod_terrain::{Locals, Vertex}, - Consts, FilterMethod, Globals, LodTerrainPipeline, Mesh, Model, Quad, Renderer, Texture, +use crate::{ + render::{ + pipelines::lod_terrain::{Locals, Vertex}, + Consts, FilterMethod, Globals, LodTerrainPipeline, Mesh, Model, Quad, Renderer, Texture, + }, + settings::Settings, }; use client::Client; use common::spiral::Spiral2d; use vek::*; pub struct Lod { - model: Model, + model: Option<(u32, Model)>, locals: Consts, map: Texture, + tgt_detail: u32, } impl Lod { - pub fn new(renderer: &mut Renderer, client: &Client) -> Self { + pub fn new(renderer: &mut Renderer, client: &Client, settings: &Settings) -> Self { Self { - model: renderer - .create_model(&create_lod_terrain_mesh(500)) - .unwrap(), + model: None, locals: renderer.create_consts(&[Locals::default()]).unwrap(), map: renderer .create_texture(&client.world_map.0, Some(FilterMethod::Trilinear), None) .expect("Failed to generate map texture"), + tgt_detail: settings.graphics.lod_detail, + } + } + + pub fn set_detail(&mut self, detail: u32) { self.tgt_detail = detail.max(100).min(2000); } + + pub fn maintain(&mut self, renderer: &mut Renderer) { + if self + .model + .as_ref() + .map(|(detail, _)| *detail != self.tgt_detail) + .unwrap_or(true) + { + self.model = Some(( + self.tgt_detail, + renderer + .create_model(&create_lod_terrain_mesh(self.tgt_detail)) + .unwrap(), + )); } } pub fn render(&self, renderer: &mut Renderer, globals: &Consts) { - renderer.render_lod_terrain(&self.model, globals, &self.locals, &self.map); + if let Some((_, model)) = self.model.as_ref() { + renderer.render_lod_terrain(&model, globals, &self.locals, &self.map); + } } } -fn create_lod_terrain_mesh(detail: usize) -> Mesh { +fn create_lod_terrain_mesh(detail: u32) -> Mesh { Spiral2d::new() - .take(detail * detail) + .take((detail * detail) as usize) .map(|pos| { let x = pos.x + detail as i32 / 2; let y = pos.y + detail as i32 / 2; diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 23943e8752..4a13689f75 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -17,6 +17,7 @@ use crate::{ create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals, PostProcessPipeline, Renderer, Shadow, SkyboxLocals, SkyboxPipeline, }, + settings::Settings, window::Event, }; use client::Client; @@ -56,7 +57,7 @@ pub struct Scene { skybox: Skybox, postprocess: PostProcess, terrain: Terrain, - lod: Lod, + pub lod: Lod, loaded_distance: f32, select_pos: Option>, @@ -67,7 +68,7 @@ pub struct Scene { impl Scene { /// Create a new `Scene` with default parameters. - pub fn new(renderer: &mut Renderer, client: &Client) -> Self { + pub fn new(renderer: &mut Renderer, client: &Client, settings: &Settings) -> Self { let resolution = renderer.get_resolution().map(|e| e as f32); Self { @@ -91,7 +92,7 @@ impl Scene { .unwrap(), }, terrain: Terrain::new(renderer), - lod: Lod::new(renderer, client), + lod: Lod::new(renderer, client, settings), loaded_distance: 0.0, select_pos: None, @@ -153,7 +154,7 @@ impl Scene { renderer: &mut Renderer, audio: &mut AudioFrontend, client: &Client, - gamma: f32, + settings: &Settings, ) { // Get player position. let player_pos = client @@ -301,10 +302,13 @@ impl Scene { .map(|b| b.kind()) .unwrap_or(BlockKind::Air), self.select_pos, - gamma, + settings.graphics.gamma, )]) .expect("Failed to update global constants"); + // Maintain LoD. + self.lod.maintain(renderer); + // Maintain the terrain. self.terrain.maintain( renderer, diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 16ff5f1742..7444ac9247 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -39,7 +39,11 @@ impl SessionState { pub fn new(global_state: &mut GlobalState, client: Rc>) -> Self { // Create a scene for this session. The scene handles visible elements of the // game world. - let mut scene = Scene::new(global_state.window.renderer_mut(), &*client.borrow()); + let mut scene = Scene::new( + global_state.window.renderer_mut(), + &*client.borrow(), + &global_state.settings, + ); scene .camera_mut() .set_fov_deg(global_state.settings.graphics.fov); @@ -484,6 +488,12 @@ impl PlayState for SessionState { global_state.settings.graphics.view_distance = view_distance; global_state.settings.save_to_file_warn(); }, + HudEvent::AdjustLodDetail(lod_detail) => { + self.scene.lod.set_detail(lod_detail); + + global_state.settings.graphics.lod_detail = lod_detail; + global_state.settings.save_to_file_warn(); + }, HudEvent::CrosshairTransp(crosshair_transp) => { global_state.settings.gameplay.crosshair_transp = crosshair_transp; global_state.settings.save_to_file_warn(); @@ -614,7 +624,7 @@ impl PlayState for SessionState { global_state.window.renderer_mut(), &mut global_state.audio, &self.client.borrow(), - global_state.settings.graphics.gamma, + &global_state.settings, ); // Render the session. diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 8d339f2837..0d33c3e9d5 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -197,6 +197,7 @@ pub struct GraphicsSettings { pub fluid_mode: FluidMode, pub window_size: [u16; 2], pub fullscreen: bool, + pub lod_detail: u32, } impl Default for GraphicsSettings { @@ -211,6 +212,7 @@ impl Default for GraphicsSettings { fluid_mode: FluidMode::Shiny, window_size: [1920, 1080], fullscreen: false, + lod_detail: 500, } } }