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.shiny": "Shiny",
"hud.settings.cloud_rendering_mode.regular": "Regular",
"hud.settings.particles": "Particles",
"hud.settings.fullscreen": "Fullscreen",
"hud.settings.save_window_size": "Save window size",

View File

@ -17,7 +17,6 @@ uniform u_globals {
// 1 - ThirdPerson
uint cam_mode;
float sprite_render_distance;
float particle_render_distance;
};
// 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 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),
AdjustViewDistance(u32),
AdjustSpriteRenderDistance(u32),
AdjustParticleRenderDistance(u32),
AdjustFigureLoDRenderDistance(u32),
AdjustMusicVolume(f32),
AdjustSfxVolume(f32),
@ -279,6 +278,7 @@ pub enum Event {
ChangeGamma(f32),
MapZoom(f64),
AdjustWindowSize([u16; 2]),
ToggleParticlesEnabled(bool),
ToggleFullscreen,
ChangeAaMode(AaMode),
ChangeCloudMode(CloudMode),
@ -1911,6 +1911,9 @@ impl Hud {
settings_window::Event::ChangeLanguage(language) => {
events.push(Event::ChangeLanguage(language));
},
settings_window::Event::ToggleParticlesEnabled(particles_enabled) => {
events.push(Event::ToggleParticlesEnabled(particles_enabled));
},
settings_window::Event::ToggleFullscreen => {
events.push(Event::ToggleFullscreen);
},

View File

@ -111,6 +111,8 @@ widget_ids! {
cloud_mode_list,
fluid_mode_text,
fluid_mode_list,
particles_button,
particles_label,
fullscreen_button,
fullscreen_label,
save_window_size_button,
@ -232,6 +234,7 @@ pub enum Event {
AdjustFOV(u16),
AdjustGamma(f32),
AdjustWindowSize([u16; 2]),
ToggleParticlesEnabled(bool),
ToggleFullscreen,
ChangeAaMode(AaMode),
ChangeCloudMode(CloudMode),
@ -1845,7 +1848,6 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(TEXT_COLOR)
.set(state.ids.sprite_dist_text, ui);
Text::new(&format!(
"{}",
self.global_state.settings.graphics.sprite_render_distance
@ -1899,8 +1901,6 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(TEXT_COLOR)
.set(state.ids.figure_dist_value, ui);
// TODO: Particle View Distance slider.
// AaMode
Text::new(&self.localized_strings.get("hud.settings.antialiasing_mode"))
.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]));
}
// 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
Text::new(&self.localized_strings.get("hud.settings.fullscreen"))
.font_size(self.fonts.cyri.scale(14))
.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)
.set(state.ids.fullscreen_label, ui);

View File

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

View File

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

View File

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

View File

@ -788,11 +788,6 @@ impl PlayState for SessionState {
sprite_render_distance;
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) => {
global_state.settings.graphics.figure_lod_render_distance =
figure_lod_render_distance;
@ -942,6 +937,10 @@ impl PlayState for SessionState {
self.voxygen_i18n.log_missing_entries();
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 => {
global_state
.window
@ -1006,11 +1005,7 @@ impl PlayState for SessionState {
mouse_smoothing: global_state.settings.gameplay.smooth_pan_enable,
sprite_render_distance: global_state.settings.graphics.sprite_render_distance
as f32,
particle_render_distance: global_state
.settings
.graphics
.particle_render_distance
as f32,
particles_enabled: global_state.settings.graphics.particles_enabled,
figure_lod_render_distance: global_state
.settings
.graphics
@ -1066,7 +1061,7 @@ impl PlayState for SessionState {
mouse_smoothing: settings.gameplay.smooth_pan_enable,
sprite_render_distance: settings.graphics.sprite_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,
};
self.scene.render(

View File

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