vsync, better sliders

This commit is contained in:
griffi-gh 2024-09-01 17:01:41 +02:00
parent bb4d2a80bf
commit d0c75d9397
3 changed files with 103 additions and 28 deletions

View file

@ -8,6 +8,13 @@ use winit::{
}; };
use crate::settings::{GameSettings, FullscreenMode}; use crate::settings::{GameSettings, FullscreenMode};
const fn get_vsync_mode(vsync: bool) -> wgpu::PresentMode {
match vsync {
true => wgpu::PresentMode::AutoVsync,
false => wgpu::PresentMode::AutoNoVsync,
}
}
#[derive(Unique)] #[derive(Unique)]
pub struct Renderer { pub struct Renderer {
window: Arc<Window>, window: Arc<Window>,
@ -116,12 +123,26 @@ impl Renderer {
None, None,
).block_on().unwrap(); ).block_on().unwrap();
let surface_config = surface.get_default_config(&adapter, size.width, size.height).unwrap(); let mut surface_config = surface.get_default_config(&adapter, size.width, size.height).unwrap();
surface_config.present_mode = get_vsync_mode(settings.vsync);
surface.configure(&device, &surface_config); surface.configure(&device, &surface_config);
Self { window, instance, surface, device, queue, surface_config, size } Self { window, instance, surface, device, queue, surface_config, size }
} }
pub fn reload_settings(&mut self, settings: &GameSettings) {
// TODO update fullscreen mode
let mut should_reconfigure = false;
should_reconfigure |= get_vsync_mode(settings.vsync) != self.surface_config.present_mode;
self.surface_config.present_mode = get_vsync_mode(settings.vsync);
if should_reconfigure {
self.reconfigure();
}
}
pub fn resize(&mut self, size: PhysicalSize<u32>) { pub fn resize(&mut self, size: PhysicalSize<u32>) {
if size.width == 0 || size.height == 0 { if size.width == 0 || size.height == 0 {
log::warn!("Ignoring resize event with zero width or height"); log::warn!("Ignoring resize event with zero width or height");
@ -135,7 +156,7 @@ impl Renderer {
self.size = size; self.size = size;
self.surface_config.width = size.width; self.surface_config.width = size.width;
self.surface_config.height = size.height; self.surface_config.height = size.height;
self.surface.configure(&self.device, &self.surface_config); self.reconfigure();
} }
pub fn reconfigure(&self) { pub fn reconfigure(&self) {

View file

@ -11,7 +11,7 @@ pub struct FullscreenSettings {
#[derive(Unique)] #[derive(Unique)]
pub struct GameSettings { pub struct GameSettings {
// pub vsync: bool, pub vsync: bool,
pub fullscreen: Option<FullscreenSettings>, pub fullscreen: Option<FullscreenSettings>,
// pub msaa: Option<u8>, // pub msaa: Option<u8>,
// pub max_anisotropy: Option<u16>, // pub max_anisotropy: Option<u16>,
@ -24,7 +24,7 @@ pub struct GameSettings {
impl Default for GameSettings { impl Default for GameSettings {
fn default() -> Self { fn default() -> Self {
Self { Self {
// vsync: false, vsync: true,
fullscreen: None, fullscreen: None,
// msaa: Some(4), // msaa: Some(4),
// max_anisotropy: Some(16), // max_anisotropy: Some(16),

View file

@ -1,24 +1,74 @@
use hui::{ use hui::{
element::{br::Break, container::Container, slider::Slider, text::Text, UiElementExt}, element::{br::Break, container::Container, slider::Slider, text::Text, ElementList, UiElementExt},
layout::{Alignment, Direction}, layout::{Alignment, Direction},
signal::Signal, signal::Signal,
rect_frame, size, rect_frame,
size,
}; };
use shipyard::{NonSendSync, UniqueView, UniqueViewMut}; use shipyard::{NonSendSync, UniqueView, UniqueViewMut};
use winit::keyboard::KeyCode; use winit::keyboard::KeyCode;
use crate::{hui_integration::UiState, input::RawKbmInputState, rendering::Renderer, settings::GameSettings}; use crate::{
hui_integration::UiState,
input::RawKbmInputState,
rendering::Renderer,
settings::GameSettings
};
#[derive(Signal)] #[derive(Signal)]
enum SettingsSignal { enum SettingsSignal {
SetRenderDistance(u8), SetRenderDistance(u8),
SetEnableDynamicCrosshair(bool), SetEnableDynamicCrosshair(bool),
SetEnableVsync(bool),
SetEnableDebugChunkBorder(bool), SetEnableDebugChunkBorder(bool),
SetMouseSensitivity(f32), SetMouseSensitivity(f32),
} }
// hUI doesn't have a checkbox element yet
// so we'll have to use sliders for now
fn checkbox(
ui: &mut ElementList,
text: &'static str,
value: bool,
signal: impl Fn(bool) -> SettingsSignal + 'static,
) {
const WIDTH: f32 = 50.;
const HEIGHT: f32 = WIDTH / 2.;
const TRACK_HEIGHT_RATIO: f32 = 0.75;
Container::default()
.with_direction(Direction::Horizontal)
.with_align(Alignment::Center)
.with_gap(5.)
.with_children(|ui| {
Text::new(text)
.add_child(ui);
Slider::new(value as u32 as f32)
.with_size(size!(WIDTH, HEIGHT))
.with_track_height(TRACK_HEIGHT_RATIO)
.with_track(rect_frame! {
color: (0.5, 0.5, 0.5),
corner_radius: TRACK_HEIGHT_RATIO * HEIGHT * 0.5,
})
.with_track_active(rect_frame! {
color: (0., 0., 0.75),
corner_radius: TRACK_HEIGHT_RATIO * HEIGHT * 0.5,
})
.with_handle_size((25., 1.))
.with_handle(rect_frame! {
color: (0., 0., 1.),
corner_radius: HEIGHT * 0.5,
})
.on_change(move |f| signal(f >= 0.5))
.add_child(ui);
Text::new(if value { "On" } else { "Off" })
.add_child(ui);
})
.add_child(ui);
}
pub fn render_settings_ui( pub fn render_settings_ui(
mut ui: NonSendSync<UniqueViewMut<UiState>>, mut ui: NonSendSync<UniqueViewMut<UiState>>,
ren: UniqueView<Renderer>, mut ren: UniqueViewMut<Renderer>,
mut settings: UniqueViewMut<GameSettings>, mut settings: UniqueViewMut<GameSettings>,
kbd: UniqueView<RawKbmInputState>, kbd: UniqueView<RawKbmInputState>,
) { ) {
@ -64,28 +114,28 @@ pub fn render_settings_ui(
.add_child(ui); .add_child(ui);
Break.add_child(ui); Break.add_child(ui);
Text::new("Dynamic Crosshair") checkbox(
.add_child(ui); ui,
Slider::new(settings.dynamic_crosshair as u32 as f32) "Vsync",
.with_size(size!(50, auto)) settings.vsync,
.with_track_height(1.) SettingsSignal::SetEnableVsync
.with_handle_size((25., 1.)) );
.on_change(|f| SettingsSignal::SetEnableDynamicCrosshair(f >= 0.5))
.add_child(ui);
Text::new(if settings.dynamic_crosshair { "On" } else { "Off" })
.add_child(ui);
Break.add_child(ui); Break.add_child(ui);
Text::new("Enable debug chunk border") checkbox(
.add_child(ui); ui,
Slider::new(settings.debug_draw_current_chunk_border as u32 as f32) "Dynamic Crosshair",
.with_size(size!(50, (Slider::DEFAULT_HEIGHT))) settings.dynamic_crosshair,
.with_track_height(1.) SettingsSignal::SetEnableDynamicCrosshair
.with_handle_size((25., 1.)) );
.on_change(|f| SettingsSignal::SetEnableDebugChunkBorder(f >= 0.5)) Break.add_child(ui);
.add_child(ui);
Text::new(if settings.debug_draw_current_chunk_border { "On" } else { "Off" }) checkbox(
.add_child(ui); ui,
"Debug Chunk Border",
settings.debug_draw_current_chunk_border,
SettingsSignal::SetEnableDebugChunkBorder
);
Break.add_child(ui); Break.add_child(ui);
Text::new("Mouse Sensitivity") Text::new("Mouse Sensitivity")
@ -104,6 +154,10 @@ pub fn render_settings_ui(
ui.hui.process_signals(|signal: SettingsSignal| match signal { ui.hui.process_signals(|signal: SettingsSignal| match signal {
SettingsSignal::SetRenderDistance(value) => settings.render_distance = value, SettingsSignal::SetRenderDistance(value) => settings.render_distance = value,
SettingsSignal::SetEnableDynamicCrosshair(value) => settings.dynamic_crosshair = value, SettingsSignal::SetEnableDynamicCrosshair(value) => settings.dynamic_crosshair = value,
SettingsSignal::SetEnableVsync(value) => {
settings.vsync = value;
ren.reload_settings(&settings);
},
SettingsSignal::SetEnableDebugChunkBorder(value) => settings.debug_draw_current_chunk_border = value && cfg!(not(target_os = "android")), SettingsSignal::SetEnableDebugChunkBorder(value) => settings.debug_draw_current_chunk_border = value && cfg!(not(target_os = "android")),
SettingsSignal::SetMouseSensitivity(value) => settings.mouse_sensitivity = value, SettingsSignal::SetMouseSensitivity(value) => settings.mouse_sensitivity = value,
}); });