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};
const fn get_vsync_mode(vsync: bool) -> wgpu::PresentMode {
match vsync {
true => wgpu::PresentMode::AutoVsync,
false => wgpu::PresentMode::AutoNoVsync,
}
}
#[derive(Unique)]
pub struct Renderer {
window: Arc<Window>,
@ -116,12 +123,26 @@ impl Renderer {
None,
).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);
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>) {
if size.width == 0 || size.height == 0 {
log::warn!("Ignoring resize event with zero width or height");
@ -135,7 +156,7 @@ impl Renderer {
self.size = size;
self.surface_config.width = size.width;
self.surface_config.height = size.height;
self.surface.configure(&self.device, &self.surface_config);
self.reconfigure();
}
pub fn reconfigure(&self) {

View file

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

View file

@ -1,24 +1,74 @@
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},
signal::Signal,
rect_frame, size,
rect_frame,
size,
};
use shipyard::{NonSendSync, UniqueView, UniqueViewMut};
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)]
enum SettingsSignal {
SetRenderDistance(u8),
SetEnableDynamicCrosshair(bool),
SetEnableVsync(bool),
SetEnableDebugChunkBorder(bool),
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(
mut ui: NonSendSync<UniqueViewMut<UiState>>,
ren: UniqueView<Renderer>,
mut ren: UniqueViewMut<Renderer>,
mut settings: UniqueViewMut<GameSettings>,
kbd: UniqueView<RawKbmInputState>,
) {
@ -64,28 +114,28 @@ pub fn render_settings_ui(
.add_child(ui);
Break.add_child(ui);
Text::new("Dynamic Crosshair")
.add_child(ui);
Slider::new(settings.dynamic_crosshair as u32 as f32)
.with_size(size!(50, auto))
.with_track_height(1.)
.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);
checkbox(
ui,
"Vsync",
settings.vsync,
SettingsSignal::SetEnableVsync
);
Break.add_child(ui);
Text::new("Enable debug chunk border")
.add_child(ui);
Slider::new(settings.debug_draw_current_chunk_border as u32 as f32)
.with_size(size!(50, (Slider::DEFAULT_HEIGHT)))
.with_track_height(1.)
.with_handle_size((25., 1.))
.on_change(|f| SettingsSignal::SetEnableDebugChunkBorder(f >= 0.5))
.add_child(ui);
Text::new(if settings.debug_draw_current_chunk_border { "On" } else { "Off" })
.add_child(ui);
checkbox(
ui,
"Dynamic Crosshair",
settings.dynamic_crosshair,
SettingsSignal::SetEnableDynamicCrosshair
);
Break.add_child(ui);
checkbox(
ui,
"Debug Chunk Border",
settings.debug_draw_current_chunk_border,
SettingsSignal::SetEnableDebugChunkBorder
);
Break.add_child(ui);
Text::new("Mouse Sensitivity")
@ -104,6 +154,10 @@ pub fn render_settings_ui(
ui.hui.process_signals(|signal: SettingsSignal| match signal {
SettingsSignal::SetRenderDistance(value) => settings.render_distance = 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::SetMouseSensitivity(value) => settings.mouse_sensitivity = value,
});