mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added LoD slider
This commit is contained in:
parent
779c36b538
commit
aab059a450
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
},
|
||||
|
@ -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)
|
||||
|
@ -1,38 +1,61 @@
|
||||
use crate::render::{
|
||||
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<LodTerrainPipeline>,
|
||||
model: Option<(u32, Model<LodTerrainPipeline>)>,
|
||||
locals: Consts<Locals>,
|
||||
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<Globals>) {
|
||||
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<LodTerrainPipeline> {
|
||||
fn create_lod_terrain_mesh(detail: u32) -> Mesh<LodTerrainPipeline> {
|
||||
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;
|
||||
|
@ -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<TerrainChunk>,
|
||||
lod: Lod,
|
||||
pub lod: Lod,
|
||||
loaded_distance: f32,
|
||||
select_pos: Option<Vec3<i32>>,
|
||||
|
||||
@ -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,
|
||||
|
@ -39,7 +39,11 @@ impl SessionState {
|
||||
pub fn new(global_state: &mut GlobalState, client: Rc<RefCell<Client>>) -> 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.
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user