Add toggle particles graphics setting

This commit is contained in:
scott-c 2020-07-25 23:46:45 +08:00
parent f9f9e9e190
commit 5acfe44cbb
11 changed files with 79 additions and 108 deletions

View File

@ -297,6 +297,7 @@ magically infused items?"#,
"hud.settings.fluid_rendering_mode.cheap": "Cheap", "hud.settings.fluid_rendering_mode.cheap": "Cheap",
"hud.settings.fluid_rendering_mode.shiny": "Shiny", "hud.settings.fluid_rendering_mode.shiny": "Shiny",
"hud.settings.cloud_rendering_mode.regular": "Regular", "hud.settings.cloud_rendering_mode.regular": "Regular",
"hud.settings.particles": "Particles",
"hud.settings.fullscreen": "Fullscreen", "hud.settings.fullscreen": "Fullscreen",
"hud.settings.save_window_size": "Save window size", "hud.settings.save_window_size": "Save window size",

View File

@ -17,7 +17,6 @@ uniform u_globals {
// 1 - ThirdPerson // 1 - ThirdPerson
uint cam_mode; uint cam_mode;
float sprite_render_distance; float sprite_render_distance;
float particle_render_distance;
}; };
// Specifies the pattern used in the player dithering // Specifies the pattern used in the player dithering

View File

@ -34,5 +34,5 @@ void main() {
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds); vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds);
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a); vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
tgt_color = vec4(color, 1.0 - clamp((distance(focus_pos.xy, f_pos.xy) - (particle_render_distance - FADE_DIST)) / FADE_DIST, 0, 1)); tgt_color = vec4(color, 1.0 - clamp((distance(focus_pos.xy, f_pos.xy) - (1000.0 - FADE_DIST)) / FADE_DIST, 0, 1));
} }

View File

@ -269,7 +269,6 @@ pub enum Event {
ToggleSmoothPan(bool), ToggleSmoothPan(bool),
AdjustViewDistance(u32), AdjustViewDistance(u32),
AdjustSpriteRenderDistance(u32), AdjustSpriteRenderDistance(u32),
AdjustParticleRenderDistance(u32),
AdjustFigureLoDRenderDistance(u32), AdjustFigureLoDRenderDistance(u32),
AdjustMusicVolume(f32), AdjustMusicVolume(f32),
AdjustSfxVolume(f32), AdjustSfxVolume(f32),
@ -279,6 +278,7 @@ pub enum Event {
ChangeGamma(f32), ChangeGamma(f32),
MapZoom(f64), MapZoom(f64),
AdjustWindowSize([u16; 2]), AdjustWindowSize([u16; 2]),
ToggleParticlesEnabled(bool),
ToggleFullscreen, ToggleFullscreen,
ChangeAaMode(AaMode), ChangeAaMode(AaMode),
ChangeCloudMode(CloudMode), ChangeCloudMode(CloudMode),
@ -1911,6 +1911,9 @@ impl Hud {
settings_window::Event::ChangeLanguage(language) => { settings_window::Event::ChangeLanguage(language) => {
events.push(Event::ChangeLanguage(language)); events.push(Event::ChangeLanguage(language));
}, },
settings_window::Event::ToggleParticlesEnabled(particles_enabled) => {
events.push(Event::ToggleParticlesEnabled(particles_enabled));
},
settings_window::Event::ToggleFullscreen => { settings_window::Event::ToggleFullscreen => {
events.push(Event::ToggleFullscreen); events.push(Event::ToggleFullscreen);
}, },

View File

@ -111,6 +111,8 @@ widget_ids! {
cloud_mode_list, cloud_mode_list,
fluid_mode_text, fluid_mode_text,
fluid_mode_list, fluid_mode_list,
particles_button,
particles_label,
fullscreen_button, fullscreen_button,
fullscreen_label, fullscreen_label,
save_window_size_button, save_window_size_button,
@ -232,6 +234,7 @@ pub enum Event {
AdjustFOV(u16), AdjustFOV(u16),
AdjustGamma(f32), AdjustGamma(f32),
AdjustWindowSize([u16; 2]), AdjustWindowSize([u16; 2]),
ToggleParticlesEnabled(bool),
ToggleFullscreen, ToggleFullscreen,
ChangeAaMode(AaMode), ChangeAaMode(AaMode),
ChangeCloudMode(CloudMode), ChangeCloudMode(CloudMode),
@ -1845,7 +1848,6 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.sprite_dist_text, ui); .set(state.ids.sprite_dist_text, ui);
Text::new(&format!( Text::new(&format!(
"{}", "{}",
self.global_state.settings.graphics.sprite_render_distance self.global_state.settings.graphics.sprite_render_distance
@ -1899,8 +1901,6 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.figure_dist_value, ui); .set(state.ids.figure_dist_value, ui);
// TODO: Particle View Distance slider.
// AaMode // AaMode
Text::new(&self.localized_strings.get("hud.settings.antialiasing_mode")) Text::new(&self.localized_strings.get("hud.settings.antialiasing_mode"))
.down_from(state.ids.gamma_slider, 8.0) .down_from(state.ids.gamma_slider, 8.0)
@ -2016,11 +2016,34 @@ impl<'a> Widget for SettingsWindow<'a> {
events.push(Event::ChangeFluidMode(mode_list[clicked])); events.push(Event::ChangeFluidMode(mode_list[clicked]));
} }
// Particles
Text::new(&self.localized_strings.get("hud.settings.particles"))
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.down_from(state.ids.fluid_mode_list, 8.0)
.color(TEXT_COLOR)
.set(state.ids.particles_label, ui);
let particles_enabled = ToggleButton::new(
self.global_state.settings.graphics.particles_enabled,
self.imgs.checkbox,
self.imgs.checkbox_checked,
)
.w_h(18.0, 18.0)
.right_from(state.ids.particles_label, 10.0)
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
.set(state.ids.particles_button, ui);
if self.global_state.settings.graphics.particles_enabled != particles_enabled {
events.push(Event::ToggleParticlesEnabled(particles_enabled));
}
// Fullscreen // Fullscreen
Text::new(&self.localized_strings.get("hud.settings.fullscreen")) Text::new(&self.localized_strings.get("hud.settings.fullscreen"))
.font_size(self.fonts.cyri.scale(14)) .font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.down_from(state.ids.fluid_mode_list, 8.0) .down_from(state.ids.particles_label, 8.0)
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.fullscreen_label, ui); .set(state.ids.fullscreen_label, ui);

View File

@ -1,9 +1,9 @@
pub mod figure; pub mod figure;
pub mod fluid; pub mod fluid;
pub mod particle;
pub mod postprocess; pub mod postprocess;
pub mod skybox; pub mod skybox;
pub mod sprite; pub mod sprite;
pub mod particle;
pub mod terrain; pub mod terrain;
pub mod ui; pub mod ui;
@ -30,7 +30,6 @@ gfx_defines! {
gamma: [f32; 4] = "gamma", gamma: [f32; 4] = "gamma",
cam_mode: u32 = "cam_mode", cam_mode: u32 = "cam_mode",
sprite_render_distance: f32 = "sprite_render_distance", sprite_render_distance: f32 = "sprite_render_distance",
particle_render_distance: f32 = "particle_render_distance",
} }
constant Light { constant Light {
@ -63,7 +62,6 @@ impl Globals {
gamma: f32, gamma: f32,
cam_mode: CameraMode, cam_mode: CameraMode,
sprite_render_distance: f32, sprite_render_distance: f32,
particle_render_distance: f32,
) -> Self { ) -> Self {
Self { Self {
view_mat: view_mat.into_col_arrays(), view_mat: view_mat.into_col_arrays(),
@ -84,7 +82,6 @@ impl Globals {
gamma: [gamma; 4], gamma: [gamma; 4],
cam_mode: cam_mode as u32, cam_mode: cam_mode as u32,
sprite_render_distance, sprite_render_distance,
particle_render_distance,
} }
} }
} }
@ -107,7 +104,6 @@ impl Default for Globals {
1.0, 1.0,
CameraMode::ThirdPerson, CameraMode::ThirdPerson,
250.0, 250.0,
250.0,
) )
} }
} }

View File

@ -81,7 +81,7 @@ pub struct SceneData<'a> {
pub gamma: f32, pub gamma: f32,
pub mouse_smoothing: bool, pub mouse_smoothing: bool,
pub sprite_render_distance: f32, pub sprite_render_distance: f32,
pub particle_render_distance: f32, pub particles_enabled: bool,
pub figure_lod_render_distance: f32, pub figure_lod_render_distance: f32,
pub is_aiming: bool, pub is_aiming: bool,
} }
@ -377,7 +377,6 @@ impl Scene {
scene_data.gamma, scene_data.gamma,
self.camera.get_mode(), self.camera.get_mode(),
scene_data.sprite_render_distance as f32 - 20.0, scene_data.sprite_render_distance as f32 - 20.0,
scene_data.particle_render_distance as f32 - 20.0,
)]) )])
.expect("Failed to update global constants"); .expect("Failed to update global constants");
@ -437,6 +436,7 @@ impl Scene {
self.particle_mgr.render( self.particle_mgr.render(
renderer, renderer,
scene_data,
&self.globals, &self.globals,
&self.lights, &self.lights,
&self.shadows, &self.shadows,

View File

@ -48,11 +48,9 @@ impl ParticleMgr {
) )
.0; .0;
let model = renderer renderer
.create_model(mesh) .create_model(mesh)
.expect("Failed to create particle model"); .expect("Failed to create particle model");
model
}); });
let insts = Vec::new(); let insts = Vec::new();
@ -73,31 +71,37 @@ impl ParticleMgr {
pub fn particle_count_visible(&self) -> usize { self.instances.count() } pub fn particle_count_visible(&self) -> usize { self.instances.count() }
pub fn maintain(&mut self, renderer: &mut Renderer, scene_data: &SceneData) { pub fn maintain(&mut self, renderer: &mut Renderer, scene_data: &SceneData) {
let now = Instant::now(); if scene_data.particles_enabled {
let now = Instant::now();
// remove dead particles // remove dead particles
self.particles.retain(|p| p.alive_until > now); self.particles.retain(|p| p.alive_until > now);
// let zxc = scene_data.particle_render_distance; self.maintain_body_particles(scene_data);
self.maintain_boost_particles(scene_data);
self.maintain_body_particles(renderer, scene_data); self.upload_particles(renderer);
} else {
self.maintain_boost_particles(renderer, scene_data); self.particles.clear();
}
}
fn upload_particles(&mut self, renderer: &mut Renderer) {
let all_cpu_instances = self let all_cpu_instances = self
.particles .particles
.iter() .iter()
.map(|p| p.instance) .map(|p| p.instance)
.collect::<Vec<ParticleInstance>>(); .collect::<Vec<ParticleInstance>>();
// TODO: upload just the ones that were created and added to queue, not all of // TODO: optimise buffer writes
// them. let gpu_instances = renderer
self.instances = renderer
.create_instances(&all_cpu_instances) .create_instances(&all_cpu_instances)
.expect("Failed to upload particle instances to the GPU!"); .expect("Failed to upload particle instances to the GPU!");
self.instances = gpu_instances;
} }
fn maintain_body_particles(&mut self, renderer: &mut Renderer, scene_data: &SceneData) { fn maintain_body_particles(&mut self, scene_data: &SceneData) {
let ecs = scene_data.state.ecs(); let ecs = scene_data.state.ecs();
for (_i, (_entity, body, pos)) in ( for (_i, (_entity, body, pos)) in (
&ecs.entities(), &ecs.entities(),
@ -109,31 +113,21 @@ impl ParticleMgr {
{ {
match body { match body {
Body::Object(object::Body::CampfireLit) => { Body::Object(object::Body::CampfireLit) => {
self.maintain_campfirelit_particles(renderer, scene_data, pos) self.maintain_campfirelit_particles(scene_data, pos)
}, },
Body::Object(object::Body::BoltFire) => { Body::Object(object::Body::BoltFire) => {
self.maintain_boltfire_particles(renderer, scene_data, pos) self.maintain_boltfire_particles(scene_data, pos)
}, },
Body::Object(object::Body::BoltFireBig) => { Body::Object(object::Body::BoltFireBig) => {
self.maintain_boltfirebig_particles(renderer, scene_data, pos) self.maintain_boltfirebig_particles(scene_data, pos)
}, },
Body::Object(object::Body::Bomb) => { Body::Object(object::Body::Bomb) => self.maintain_bomb_particles(scene_data, pos),
self.maintain_bomb_particles(renderer, scene_data, pos)
},
// Body::Object(object::Body::Pouch) => {
// self.maintain_pouch_particles(renderer, scene_data, pos)
// },
_ => {}, _ => {},
} }
} }
} }
fn maintain_campfirelit_particles( fn maintain_campfirelit_particles(&mut self, scene_data: &SceneData, pos: &Pos) {
&mut self,
renderer: &mut Renderer,
scene_data: &SceneData,
pos: &Pos,
) {
let time = scene_data.state.get_time(); let time = scene_data.state.get_time();
let now = Instant::now(); let now = Instant::now();
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
@ -149,12 +143,7 @@ impl ParticleMgr {
}); });
} }
fn maintain_boltfire_particles( fn maintain_boltfire_particles(&mut self, scene_data: &SceneData, pos: &Pos) {
&mut self,
renderer: &mut Renderer,
scene_data: &SceneData,
pos: &Pos,
) {
let time = scene_data.state.get_time(); let time = scene_data.state.get_time();
let now = Instant::now(); let now = Instant::now();
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
@ -170,12 +159,7 @@ impl ParticleMgr {
}); });
} }
fn maintain_boltfirebig_particles( fn maintain_boltfirebig_particles(&mut self, scene_data: &SceneData, pos: &Pos) {
&mut self,
renderer: &mut Renderer,
scene_data: &SceneData,
pos: &Pos,
) {
let time = scene_data.state.get_time(); let time = scene_data.state.get_time();
let now = Instant::now(); let now = Instant::now();
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
@ -205,12 +189,7 @@ impl ParticleMgr {
}); });
} }
fn maintain_bomb_particles( fn maintain_bomb_particles(&mut self, scene_data: &SceneData, pos: &Pos) {
&mut self,
renderer: &mut Renderer,
scene_data: &SceneData,
pos: &Pos,
) {
let time = scene_data.state.get_time(); let time = scene_data.state.get_time();
let now = Instant::now(); let now = Instant::now();
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
@ -244,34 +223,7 @@ impl ParticleMgr {
}); });
} }
// fn maintain_pouch_particles( fn maintain_boost_particles(&mut self, scene_data: &SceneData) {
// &mut self,
// renderer: &mut Renderer,
// scene_data: &SceneData,
// pos: &Pos,
// ) {
// let time = scene_data.state.get_time();
// let now = Instant::now();
// let mut rng = rand::thread_rng();
// let smoke_cpu_insts = vec![ParticleInstance::new(
// time,
// rng.gen(),
// ParticleMode::CampfireSmoke,
// pos.0,
// )];
// let smoke_cpu_insts = renderer
// .create_instances(&smoke_cpu_insts)
// .expect("Failed to upload particle instances to the GPU!");
// self.particles.push(Particles {
// alive_until: now + Duration::from_secs(1),
// instances: smoke_cpu_insts,
// });
// }
fn maintain_boost_particles(&mut self, renderer: &mut Renderer, scene_data: &SceneData) {
let state = scene_data.state; let state = scene_data.state;
let ecs = state.ecs(); let ecs = state.ecs();
let time = state.get_time(); let time = state.get_time();
@ -303,15 +255,18 @@ impl ParticleMgr {
pub fn render( pub fn render(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
scene_data: &SceneData,
globals: &Consts<Globals>, globals: &Consts<Globals>,
lights: &Consts<Light>, lights: &Consts<Light>,
shadows: &Consts<Shadow>, shadows: &Consts<Shadow>,
) { ) {
let model = &self if scene_data.particles_enabled {
.model_cache let model = &self
.get(MODEL_KEY) .model_cache
.expect("Expected particle model in cache"); .get(MODEL_KEY)
.expect("Expected particle model in cache");
renderer.render_particles(model, globals, &self.instances, lights, shadows); renderer.render_particles(model, globals, &self.instances, lights, shadows);
}
} }
} }

View File

@ -190,7 +190,6 @@ impl Scene {
scene_data.gamma, scene_data.gamma,
self.camera.get_mode(), self.camera.get_mode(),
250.0, 250.0,
250.0,
)]) { )]) {
error!(?e, "Renderer failed to update"); error!(?e, "Renderer failed to update");
} }

View File

@ -788,11 +788,6 @@ impl PlayState for SessionState {
sprite_render_distance; sprite_render_distance;
global_state.settings.save_to_file_warn(); global_state.settings.save_to_file_warn();
}, },
HudEvent::AdjustParticleRenderDistance(particle_render_distance) => {
global_state.settings.graphics.particle_render_distance =
particle_render_distance;
global_state.settings.save_to_file_warn();
},
HudEvent::AdjustFigureLoDRenderDistance(figure_lod_render_distance) => { HudEvent::AdjustFigureLoDRenderDistance(figure_lod_render_distance) => {
global_state.settings.graphics.figure_lod_render_distance = global_state.settings.graphics.figure_lod_render_distance =
figure_lod_render_distance; figure_lod_render_distance;
@ -942,6 +937,10 @@ impl PlayState for SessionState {
self.voxygen_i18n.log_missing_entries(); self.voxygen_i18n.log_missing_entries();
self.hud.update_language(self.voxygen_i18n.clone()); self.hud.update_language(self.voxygen_i18n.clone());
}, },
HudEvent::ToggleParticlesEnabled(particles_enabled) => {
global_state.settings.graphics.particles_enabled = particles_enabled;
global_state.settings.save_to_file_warn();
},
HudEvent::ToggleFullscreen => { HudEvent::ToggleFullscreen => {
global_state global_state
.window .window
@ -1006,11 +1005,7 @@ impl PlayState for SessionState {
mouse_smoothing: global_state.settings.gameplay.smooth_pan_enable, mouse_smoothing: global_state.settings.gameplay.smooth_pan_enable,
sprite_render_distance: global_state.settings.graphics.sprite_render_distance sprite_render_distance: global_state.settings.graphics.sprite_render_distance
as f32, as f32,
particle_render_distance: global_state particles_enabled: global_state.settings.graphics.particles_enabled,
.settings
.graphics
.particle_render_distance
as f32,
figure_lod_render_distance: global_state figure_lod_render_distance: global_state
.settings .settings
.graphics .graphics
@ -1066,7 +1061,7 @@ impl PlayState for SessionState {
mouse_smoothing: settings.gameplay.smooth_pan_enable, mouse_smoothing: settings.gameplay.smooth_pan_enable,
sprite_render_distance: settings.graphics.sprite_render_distance as f32, sprite_render_distance: settings.graphics.sprite_render_distance as f32,
figure_lod_render_distance: settings.graphics.figure_lod_render_distance as f32, figure_lod_render_distance: settings.graphics.figure_lod_render_distance as f32,
particle_render_distance: settings.graphics.particle_render_distance as f32, particles_enabled: settings.graphics.particles_enabled,
is_aiming: self.is_aiming, is_aiming: self.is_aiming,
}; };
self.scene.render( self.scene.render(

View File

@ -603,7 +603,7 @@ impl Default for Log {
pub struct GraphicsSettings { pub struct GraphicsSettings {
pub view_distance: u32, pub view_distance: u32,
pub sprite_render_distance: u32, pub sprite_render_distance: u32,
pub particle_render_distance: u32, pub particles_enabled: bool,
pub figure_lod_render_distance: u32, pub figure_lod_render_distance: u32,
pub max_fps: u32, pub max_fps: u32,
pub fov: u16, pub fov: u16,
@ -620,7 +620,7 @@ impl Default for GraphicsSettings {
Self { Self {
view_distance: 10, view_distance: 10,
sprite_render_distance: 150, sprite_render_distance: 150,
particle_render_distance: 150, particles_enabled: true,
figure_lod_render_distance: 250, figure_lod_render_distance: 250,
max_fps: 60, max_fps: 60,
fov: 50, fov: 50,